Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
8b4aaf8b
Unverified
Commit
8b4aaf8b
authored
Jul 11, 2019
by
Christian Brauner
Committed by
GitHub
Jul 11, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2921 from tomponline/tp-2019-03-26/routedveth
Adds veth router mode
parents
bc554fdf
3e5c2e69
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
336 additions
and
67 deletions
+336
-67
api-extensions.md
doc/api-extensions.md
+9
-0
lxc.container.conf.sgml.in
doc/lxc.container.conf.sgml.in
+11
-2
api_extensions.h
src/lxc/api_extensions.h
+1
-0
confile.c
src/lxc/confile.c
+70
-0
confile_utils.c
src/lxc/confile_utils.c
+22
-0
confile_utils.h
src/lxc/confile_utils.h
+1
-0
log.h
src/lxc/log.h
+7
-0
macro.h
src/lxc/macro.h
+8
-0
network.c
src/lxc/network.c
+200
-65
network.h
src/lxc/network.h
+7
-0
No files found.
doc/api-extensions.md
View file @
8b4aaf8b
...
@@ -96,3 +96,12 @@ This is primarily intended for use with layer 3 networking devices, such as IPVL
...
@@ -96,3 +96,12 @@ This is primarily intended for use with layer 3 networking devices, such as IPVL
This introduces the ability to specify a custom MTU for
`phys`
and
`macvlan`
devices using the
This introduces the ability to specify a custom MTU for
`phys`
and
`macvlan`
devices using the
`lxc.net.[i].mtu`
property.
`lxc.net.[i].mtu`
property.
# network\_veth\_router
This introduces the ability to specify a
`lxc.net.[i].veth.mode`
setting, which takes a value of
"bridge" or "router". This defaults to "bridge".
In "router" mode static routes are created on the host for the container's IP addresses pointing to
the host side veth interface. In addition to the routes, a static IP neighbour proxy is added to
the host side veth interface for the IPv4 and IPv6 gateway IPs.
doc/lxc.container.conf.sgml.in
View file @
8b4aaf8b
...
@@ -443,14 +443,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
...
@@ -443,14 +443,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<para>
<para>
<option>veth:</option> a virtual ethernet pair
<option>veth:</option> a virtual ethernet pair
device is created with one side assigned to the container
device is created with one side assigned to the container
and the other side attached to a bridge specified by
and the other side on the host.
<option>lxc.net.[i].veth.mode</option> specifies the
mode the veth parent will use on the host.
The accepted modes are <option>bridge</option> and <option>router</option>.
The mode defaults to bridge if not specified.
In <option>bridge</option> mode the host side is attached to a bridge specified by
the <option>lxc.net.[i].link</option> option.
the <option>lxc.net.[i].link</option> option.
If the bridge is not specified, then the veth pair device
If the bridge
link
is not specified, then the veth pair device
will be created but not attached to any bridge.
will be created but not attached to any bridge.
Otherwise, the bridge has to be created on the system
Otherwise, the bridge has to be created on the system
before starting the container.
before starting the container.
<command>lxc</command> won't handle any
<command>lxc</command> won't handle any
configuration outside of the container.
configuration outside of the container.
In <option>router</option> mode static routes are created on the host for the
container's IP addresses pointing to the host side veth interface.
Additionally Proxy ARP and Proxy NDP entries are added on the host side veth interface
for the gateway IPs defined in the container to allow the container to reach the host.
By default, <command>lxc</command> chooses a name for the
By default, <command>lxc</command> chooses a name for the
network device belonging to the outside of the
network device belonging to the outside of the
container, but if you wish to handle
container, but if you wish to handle
...
...
src/lxc/api_extensions.h
View file @
8b4aaf8b
...
@@ -49,6 +49,7 @@ static char *api_extensions[] = {
...
@@ -49,6 +49,7 @@ static char *api_extensions[] = {
"network_l2proxy"
,
"network_l2proxy"
,
"network_gateway_device_route"
,
"network_gateway_device_route"
,
"network_phys_macvlan_mtu"
,
"network_phys_macvlan_mtu"
,
"network_veth_router"
,
};
};
static
size_t
nr_api_extensions
=
sizeof
(
api_extensions
)
/
sizeof
(
*
api_extensions
);
static
size_t
nr_api_extensions
=
sizeof
(
api_extensions
)
/
sizeof
(
*
api_extensions
);
...
...
src/lxc/confile.c
View file @
8b4aaf8b
...
@@ -139,6 +139,7 @@ lxc_config_define(net_nic);
...
@@ -139,6 +139,7 @@ lxc_config_define(net_nic);
lxc_config_define
(
net_script_down
);
lxc_config_define
(
net_script_down
);
lxc_config_define
(
net_script_up
);
lxc_config_define
(
net_script_up
);
lxc_config_define
(
net_type
);
lxc_config_define
(
net_type
);
lxc_config_define
(
net_veth_mode
);
lxc_config_define
(
net_veth_pair
);
lxc_config_define
(
net_veth_pair
);
lxc_config_define
(
net_veth_ipv4_route
);
lxc_config_define
(
net_veth_ipv4_route
);
lxc_config_define
(
net_veth_ipv6_route
);
lxc_config_define
(
net_veth_ipv6_route
);
...
@@ -234,6 +235,7 @@ static struct lxc_config_t config_jump_table[] = {
...
@@ -234,6 +235,7 @@ static struct lxc_config_t config_jump_table[] = {
{
"lxc.net.script.up"
,
set_config_net_script_up
,
get_config_net_script_up
,
clr_config_net_script_up
,
},
{
"lxc.net.script.up"
,
set_config_net_script_up
,
get_config_net_script_up
,
clr_config_net_script_up
,
},
{
"lxc.net.type"
,
set_config_net_type
,
get_config_net_type
,
clr_config_net_type
,
},
{
"lxc.net.type"
,
set_config_net_type
,
get_config_net_type
,
clr_config_net_type
,
},
{
"lxc.net.vlan.id"
,
set_config_net_vlan_id
,
get_config_net_vlan_id
,
clr_config_net_vlan_id
,
},
{
"lxc.net.vlan.id"
,
set_config_net_vlan_id
,
get_config_net_vlan_id
,
clr_config_net_vlan_id
,
},
{
"lxc.net.veth.mode"
,
set_config_net_veth_mode
,
get_config_net_veth_mode
,
clr_config_net_veth_mode
,
},
{
"lxc.net.veth.pair"
,
set_config_net_veth_pair
,
get_config_net_veth_pair
,
clr_config_net_veth_pair
,
},
{
"lxc.net.veth.pair"
,
set_config_net_veth_pair
,
get_config_net_veth_pair
,
clr_config_net_veth_pair
,
},
{
"lxc.net.veth.ipv4.route"
,
set_config_net_veth_ipv4_route
,
get_config_net_veth_ipv4_route
,
clr_config_net_veth_ipv4_route
,
},
{
"lxc.net.veth.ipv4.route"
,
set_config_net_veth_ipv4_route
,
get_config_net_veth_ipv4_route
,
clr_config_net_veth_ipv4_route
,
},
{
"lxc.net.veth.ipv6.route"
,
set_config_net_veth_ipv6_route
,
get_config_net_veth_ipv6_route
,
clr_config_net_veth_ipv6_route
,
},
{
"lxc.net.veth.ipv6.route"
,
set_config_net_veth_ipv6_route
,
get_config_net_veth_ipv6_route
,
clr_config_net_veth_ipv6_route
,
},
...
@@ -303,6 +305,7 @@ static int set_config_net_type(const char *key, const char *value,
...
@@ -303,6 +305,7 @@ static int set_config_net_type(const char *key, const char *value,
netdev
->
type
=
LXC_NET_VETH
;
netdev
->
type
=
LXC_NET_VETH
;
lxc_list_init
(
&
netdev
->
priv
.
veth_attr
.
ipv4_routes
);
lxc_list_init
(
&
netdev
->
priv
.
veth_attr
.
ipv4_routes
);
lxc_list_init
(
&
netdev
->
priv
.
veth_attr
.
ipv6_routes
);
lxc_list_init
(
&
netdev
->
priv
.
veth_attr
.
ipv6_routes
);
lxc_veth_mode_to_flag
(
&
netdev
->
priv
.
veth_attr
.
mode
,
"bridge"
);
}
else
if
(
strcmp
(
value
,
"macvlan"
)
==
0
)
{
}
else
if
(
strcmp
(
value
,
"macvlan"
)
==
0
)
{
netdev
->
type
=
LXC_NET_MACVLAN
;
netdev
->
type
=
LXC_NET_MACVLAN
;
lxc_macvlan_mode_to_flag
(
&
netdev
->
priv
.
macvlan_attr
.
mode
,
"private"
);
lxc_macvlan_mode_to_flag
(
&
netdev
->
priv
.
macvlan_attr
.
mode
,
"private"
);
...
@@ -450,6 +453,21 @@ static int set_config_net_name(const char *key, const char *value,
...
@@ -450,6 +453,21 @@ static int set_config_net_name(const char *key, const char *value,
return
network_ifname
(
netdev
->
name
,
value
,
sizeof
(
netdev
->
name
));
return
network_ifname
(
netdev
->
name
,
value
,
sizeof
(
netdev
->
name
));
}
}
static
int
set_config_net_veth_mode
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
struct
lxc_netdev
*
netdev
=
data
;
if
(
lxc_config_value_empty
(
value
))
return
clr_config_net_veth_mode
(
key
,
lxc_conf
,
data
);
if
(
!
netdev
)
return
-
1
;
return
lxc_veth_mode_to_flag
(
&
netdev
->
priv
.
veth_attr
.
mode
,
value
);
}
static
int
set_config_net_veth_pair
(
const
char
*
key
,
const
char
*
value
,
static
int
set_config_net_veth_pair
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
{
...
@@ -5094,6 +5112,22 @@ static int clr_config_net_ipvlan_isolation(const char *key,
...
@@ -5094,6 +5112,22 @@ static int clr_config_net_ipvlan_isolation(const char *key,
return
0
;
return
0
;
}
}
static
int
clr_config_net_veth_mode
(
const
char
*
key
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_VETH
)
return
0
;
netdev
->
priv
.
veth_attr
.
mode
=
-
1
;
return
0
;
}
static
int
clr_config_net_veth_pair
(
const
char
*
key
,
struct
lxc_conf
*
lxc_conf
,
static
int
clr_config_net_veth_pair
(
const
char
*
key
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
void
*
data
)
{
{
...
@@ -5516,6 +5550,42 @@ static int get_config_net_ipvlan_isolation(const char *key, char *retv, int inle
...
@@ -5516,6 +5550,42 @@ static int get_config_net_ipvlan_isolation(const char *key, char *retv, int inle
return
fulllen
;
return
fulllen
;
}
}
static
int
get_config_net_veth_mode
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
{
int
len
;
int
fulllen
=
0
;
const
char
*
mode
;
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
retv
)
inlen
=
0
;
else
memset
(
retv
,
0
,
inlen
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_VETH
)
return
0
;
switch
(
netdev
->
priv
.
veth_attr
.
mode
)
{
case
VETH_MODE_BRIDGE
:
mode
=
"bridge"
;
break
;
case
VETH_MODE_ROUTER
:
mode
=
"router"
;
break
;
default:
mode
=
"(invalid)"
;
break
;
}
strprint
(
retv
,
inlen
,
"%s"
,
mode
);
return
fulllen
;
}
static
int
get_config_net_veth_pair
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
static
int
get_config_net_veth_pair
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
struct
lxc_conf
*
c
,
void
*
data
)
{
{
...
...
src/lxc/confile_utils.c
View file @
8b4aaf8b
...
@@ -501,6 +501,28 @@ void lxc_free_networks(struct lxc_list *networks)
...
@@ -501,6 +501,28 @@ void lxc_free_networks(struct lxc_list *networks)
lxc_list_init
(
networks
);
lxc_list_init
(
networks
);
}
}
static
struct
lxc_veth_mode
{
char
*
name
;
int
mode
;
}
veth_mode
[]
=
{
{
"bridge"
,
VETH_MODE_BRIDGE
},
{
"router"
,
VETH_MODE_ROUTER
},
};
int
lxc_veth_mode_to_flag
(
int
*
mode
,
const
char
*
value
)
{
for
(
size_t
i
=
0
;
i
<
sizeof
(
veth_mode
)
/
sizeof
(
veth_mode
[
0
]);
i
++
)
{
if
(
strcmp
(
veth_mode
[
i
].
name
,
value
)
!=
0
)
continue
;
*
mode
=
veth_mode
[
i
].
mode
;
return
0
;
}
return
minus_one_set_errno
(
EINVAL
);
}
static
struct
lxc_macvlan_mode
{
static
struct
lxc_macvlan_mode
{
char
*
name
;
char
*
name
;
int
mode
;
int
mode
;
...
...
src/lxc/confile_utils.h
View file @
8b4aaf8b
...
@@ -56,6 +56,7 @@ lxc_get_netdev_by_idx(struct lxc_conf *conf, unsigned int idx, bool allocate);
...
@@ -56,6 +56,7 @@ lxc_get_netdev_by_idx(struct lxc_conf *conf, unsigned int idx, bool allocate);
extern
void
lxc_log_configured_netdevs
(
const
struct
lxc_conf
*
conf
);
extern
void
lxc_log_configured_netdevs
(
const
struct
lxc_conf
*
conf
);
extern
bool
lxc_remove_nic_by_idx
(
struct
lxc_conf
*
conf
,
unsigned
int
idx
);
extern
bool
lxc_remove_nic_by_idx
(
struct
lxc_conf
*
conf
,
unsigned
int
idx
);
extern
void
lxc_free_networks
(
struct
lxc_list
*
networks
);
extern
void
lxc_free_networks
(
struct
lxc_list
*
networks
);
extern
int
lxc_veth_mode_to_flag
(
int
*
mode
,
const
char
*
value
);
extern
int
lxc_macvlan_mode_to_flag
(
int
*
mode
,
const
char
*
value
);
extern
int
lxc_macvlan_mode_to_flag
(
int
*
mode
,
const
char
*
value
);
extern
char
*
lxc_macvlan_flag_to_mode
(
int
mode
);
extern
char
*
lxc_macvlan_flag_to_mode
(
int
mode
);
extern
int
lxc_ipvlan_mode_to_flag
(
int
*
mode
,
const
char
*
value
);
extern
int
lxc_ipvlan_mode_to_flag
(
int
*
mode
,
const
char
*
value
);
...
...
src/lxc/log.h
View file @
8b4aaf8b
...
@@ -505,6 +505,13 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
...
@@ -505,6 +505,13 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
} while (0)
} while (0)
#endif
#endif
#define error_log_errno(__errno__, format, ...) \
({ \
errno = __errno__; \
SYSERROR(format, ##__VA_ARGS__); \
-1; \
})
extern
int
lxc_log_fd
;
extern
int
lxc_log_fd
;
extern
int
lxc_log_syslog
(
int
facility
);
extern
int
lxc_log_syslog
(
int
facility
);
...
...
src/lxc/macro.h
View file @
8b4aaf8b
...
@@ -281,6 +281,14 @@ extern int __build_bug_on_failed;
...
@@ -281,6 +281,14 @@ extern int __build_bug_on_failed;
#define VETH_INFO_PEER 1
#define VETH_INFO_PEER 1
#endif
#endif
#ifndef VETH_MODE_BRIDGE
#define VETH_MODE_BRIDGE 1
#endif
#ifndef VETH_MODE_ROUTER
#define VETH_MODE_ROUTER 2
#endif
#ifndef IFLA_MACVLAN_MODE
#ifndef IFLA_MACVLAN_MODE
#define IFLA_MACVLAN_MODE 1
#define IFLA_MACVLAN_MODE 1
#endif
#endif
...
...
src/lxc/network.c
View file @
8b4aaf8b
...
@@ -178,6 +178,118 @@ static int lxc_setup_ipv6_routes(struct lxc_list *ip, int ifindex)
...
@@ -178,6 +178,118 @@ static int lxc_setup_ipv6_routes(struct lxc_list *ip, int ifindex)
return
0
;
return
0
;
}
}
static
int
setup_ipv4_addr_routes
(
struct
lxc_list
*
ip
,
int
ifindex
)
{
struct
lxc_list
*
iterator
;
int
err
;
lxc_list_for_each
(
iterator
,
ip
)
{
struct
lxc_inetdev
*
inetdev
=
iterator
->
elem
;
err
=
lxc_ipv4_dest_add
(
ifindex
,
&
inetdev
->
addr
,
32
);
if
(
err
)
return
error_log_errno
(
err
,
"Failed to setup ipv4 address route for network device with eifindex %d"
,
ifindex
);
}
return
0
;
}
static
int
setup_ipv6_addr_routes
(
struct
lxc_list
*
ip
,
int
ifindex
)
{
struct
lxc_list
*
iterator
;
int
err
;
lxc_list_for_each
(
iterator
,
ip
)
{
struct
lxc_inet6dev
*
inet6dev
=
iterator
->
elem
;
err
=
lxc_ipv6_dest_add
(
ifindex
,
&
inet6dev
->
addr
,
128
);
if
(
err
)
return
error_log_errno
(
err
,
"Failed to setup ipv6 address route for network device with eifindex %d"
,
ifindex
);
}
return
0
;
}
struct
ip_proxy_args
{
const
char
*
ip
;
const
char
*
dev
;
};
static
int
lxc_add_ip_neigh_proxy_exec_wrapper
(
void
*
data
)
{
struct
ip_proxy_args
*
args
=
data
;
execlp
(
"ip"
,
"ip"
,
"neigh"
,
"add"
,
"proxy"
,
args
->
ip
,
"dev"
,
args
->
dev
,
(
char
*
)
NULL
);
return
-
1
;
}
static
int
lxc_del_ip_neigh_proxy_exec_wrapper
(
void
*
data
)
{
struct
ip_proxy_args
*
args
=
data
;
execlp
(
"ip"
,
"ip"
,
"neigh"
,
"flush"
,
"proxy"
,
args
->
ip
,
"dev"
,
args
->
dev
,
(
char
*
)
NULL
);
return
-
1
;
}
static
int
lxc_add_ip_neigh_proxy
(
const
char
*
ip
,
const
char
*
dev
)
{
int
ret
;
char
cmd_output
[
PATH_MAX
]
=
{
0
};
struct
ip_proxy_args
args
=
{
.
ip
=
ip
,
.
dev
=
dev
,
};
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
lxc_add_ip_neigh_proxy_exec_wrapper
,
&
args
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to add ip proxy
\"
%s
\"
to dev
\"
%s
\"
: %s"
,
ip
,
dev
,
cmd_output
);
return
-
1
;
}
return
0
;
}
static
int
lxc_del_ip_neigh_proxy
(
const
char
*
ip
,
const
char
*
dev
)
{
int
ret
;
char
cmd_output
[
PATH_MAX
]
=
{
0
};
struct
ip_proxy_args
args
=
{
.
ip
=
ip
,
.
dev
=
dev
,
};
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
lxc_del_ip_neigh_proxy_exec_wrapper
,
&
args
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to delete ip proxy
\"
%s
\"
to dev
\"
%s
\"
: %s"
,
ip
,
dev
,
cmd_output
);
return
-
1
;
}
return
0
;
}
static
int
lxc_is_ip_forwarding_enabled
(
const
char
*
ifname
,
int
family
)
{
int
ret
;
char
path
[
PATH_MAX
];
char
buf
[
1
]
=
""
;
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
minus_one_set_errno
(
EINVAL
);
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
"forwarding"
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
PATH_MAX
)
return
minus_one_set_errno
(
E2BIG
);
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
}
static
int
instantiate_veth
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
static
int
instantiate_veth
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
{
{
int
bridge_index
,
err
;
int
bridge_index
,
err
;
...
@@ -276,7 +388,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -276,7 +388,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
}
}
}
}
if
(
netdev
->
link
[
0
]
!=
'\0'
)
{
if
(
netdev
->
link
[
0
]
!=
'\0'
&&
netdev
->
priv
.
veth_attr
.
mode
==
VETH_MODE_BRIDGE
)
{
err
=
lxc_bridge_attach
(
netdev
->
link
,
veth1
);
err
=
lxc_bridge_attach
(
netdev
->
link
,
veth1
);
if
(
err
)
{
if
(
err
)
{
errno
=
-
err
;
errno
=
-
err
;
...
@@ -306,6 +418,78 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -306,6 +418,78 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
goto
out_delete
;
goto
out_delete
;
}
}
if
(
netdev
->
priv
.
veth_attr
.
mode
==
VETH_MODE_ROUTER
)
{
if
(
netdev
->
ipv4_gateway
)
{
char
bufinet4
[
INET_ADDRSTRLEN
];
if
(
!
inet_ntop
(
AF_INET
,
netdev
->
ipv4_gateway
,
bufinet4
,
sizeof
(
bufinet4
)))
{
error_log_errno
(
-
errno
,
"Failed to convert gateway ipv4 address on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
err
=
lxc_ip_forwarding_on
(
veth1
,
AF_INET
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to activate ipv4 forwarding on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
err
=
lxc_add_ip_neigh_proxy
(
bufinet4
,
veth1
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to add gateway ipv4 proxy on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
}
if
(
netdev
->
ipv6_gateway
)
{
char
bufinet6
[
INET6_ADDRSTRLEN
];
if
(
!
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
bufinet6
,
sizeof
(
bufinet6
)))
{
error_log_errno
(
-
errno
,
"Failed to convert gateway ipv6 address on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
/* Check for sysctl net.ipv6.conf.all.forwarding=1
Kernel requires this to route any packets for IPv6.
*/
err
=
lxc_is_ip_forwarding_enabled
(
"all"
,
AF_INET6
);
if
(
err
)
{
error_log_errno
(
err
,
"Requires sysctl net.ipv6.conf.all.forwarding=1"
);
goto
out_delete
;
}
err
=
lxc_ip_forwarding_on
(
veth1
,
AF_INET6
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to activate ipv6 forwarding on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
err
=
lxc_neigh_proxy_on
(
veth1
,
AF_INET6
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to activate proxy ndp on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
err
=
lxc_add_ip_neigh_proxy
(
bufinet6
,
veth1
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to add gateway ipv6 proxy on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
}
/* setup ipv4 address routes on the host interface */
err
=
setup_ipv4_addr_routes
(
&
netdev
->
ipv4
,
netdev
->
priv
.
veth_attr
.
ifindex
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
/* setup ipv6 address routes on the host interface */
err
=
setup_ipv6_addr_routes
(
&
netdev
->
ipv6
,
netdev
->
priv
.
veth_attr
.
ifindex
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
}
if
(
netdev
->
upscript
)
{
if
(
netdev
->
upscript
)
{
char
*
argv
[]
=
{
char
*
argv
[]
=
{
"veth"
,
"veth"
,
...
@@ -1798,22 +1982,30 @@ static int proc_sys_net_write(const char *path, const char *value)
...
@@ -1798,22 +1982,30 @@ static int proc_sys_net_write(const char *path, const char *value)
return
err
;
return
err
;
}
}
static
int
lxc_is_ip_forwarding_enabled
(
const
char
*
ifname
,
int
family
)
static
int
ip_forwarding_set
(
const
char
*
ifname
,
int
family
,
int
flag
)
{
{
int
ret
;
int
ret
;
char
path
[
PATH_MAX
];
char
path
[
PATH_MAX
];
char
buf
[
1
]
=
""
;
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
minus_one_set_errno
(
EINVAL
)
;
return
-
EINVAL
;
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
"forwarding"
);
"forwarding"
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
PATH_MAX
)
if
(
ret
<
0
||
(
size_t
)
ret
>=
PATH_MAX
)
return
minus_one_set_errno
(
E2BIG
)
;
return
-
E2BIG
;
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
}
int
lxc_ip_forwarding_on
(
const
char
*
name
,
int
family
)
{
return
ip_forwarding_set
(
name
,
family
,
1
);
}
int
lxc_ip_forwarding_off
(
const
char
*
name
,
int
family
)
{
return
ip_forwarding_set
(
name
,
family
,
0
);
}
}
static
int
neigh_proxy_set
(
const
char
*
ifname
,
int
family
,
int
flag
)
static
int
neigh_proxy_set
(
const
char
*
ifname
,
int
family
,
int
flag
)
...
@@ -2867,63 +3059,6 @@ clear_ifindices:
...
@@ -2867,63 +3059,6 @@ clear_ifindices:
return
true
;
return
true
;
}
}
struct
ip_proxy_args
{
const
char
*
ip
;
const
char
*
dev
;
};
static
int
lxc_add_ip_neigh_proxy_exec_wrapper
(
void
*
data
)
{
struct
ip_proxy_args
*
args
=
data
;
execlp
(
"ip"
,
"ip"
,
"neigh"
,
"add"
,
"proxy"
,
args
->
ip
,
"dev"
,
args
->
dev
,
(
char
*
)
NULL
);
return
-
1
;
}
static
int
lxc_del_ip_neigh_proxy_exec_wrapper
(
void
*
data
)
{
struct
ip_proxy_args
*
args
=
data
;
execlp
(
"ip"
,
"ip"
,
"neigh"
,
"flush"
,
"proxy"
,
args
->
ip
,
"dev"
,
args
->
dev
,
(
char
*
)
NULL
);
return
-
1
;
}
static
int
lxc_add_ip_neigh_proxy
(
const
char
*
ip
,
const
char
*
dev
)
{
int
ret
;
char
cmd_output
[
PATH_MAX
];
struct
ip_proxy_args
args
=
{
.
ip
=
ip
,
.
dev
=
dev
,
};
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
lxc_add_ip_neigh_proxy_exec_wrapper
,
&
args
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to add ip proxy
\"
%s
\"
to dev
\"
%s
\"
: %s"
,
ip
,
dev
,
cmd_output
);
return
-
1
;
}
return
0
;
}
static
int
lxc_del_ip_neigh_proxy
(
const
char
*
ip
,
const
char
*
dev
)
{
int
ret
;
char
cmd_output
[
PATH_MAX
];
struct
ip_proxy_args
args
=
{
.
ip
=
ip
,
.
dev
=
dev
,
};
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
lxc_del_ip_neigh_proxy_exec_wrapper
,
&
args
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to delete ip proxy
\"
%s
\"
to dev
\"
%s
\"
: %s"
,
ip
,
dev
,
cmd_output
);
return
-
1
;
}
return
0
;
}
static
int
lxc_setup_l2proxy
(
struct
lxc_netdev
*
netdev
)
{
static
int
lxc_setup_l2proxy
(
struct
lxc_netdev
*
netdev
)
{
struct
lxc_list
*
cur
,
*
next
;
struct
lxc_list
*
cur
,
*
next
;
struct
lxc_inetdev
*
inet4dev
;
struct
lxc_inetdev
*
inet4dev
;
...
...
src/lxc/network.h
View file @
8b4aaf8b
...
@@ -98,6 +98,7 @@ struct ifla_veth {
...
@@ -98,6 +98,7 @@ struct ifla_veth {
int
ifindex
;
int
ifindex
;
struct
lxc_list
ipv4_routes
;
struct
lxc_list
ipv4_routes
;
struct
lxc_list
ipv6_routes
;
struct
lxc_list
ipv6_routes
;
int
mode
;
/* bridge, router */
};
};
struct
ifla_vlan
{
struct
ifla_vlan
{
...
@@ -263,6 +264,12 @@ extern int lxc_neigh_proxy_on(const char *name, int family);
...
@@ -263,6 +264,12 @@ extern int lxc_neigh_proxy_on(const char *name, int family);
/* Disable neighbor proxying. */
/* Disable neighbor proxying. */
extern
int
lxc_neigh_proxy_off
(
const
char
*
name
,
int
family
);
extern
int
lxc_neigh_proxy_off
(
const
char
*
name
,
int
family
);
/* Activate IP forwarding. */
extern
int
lxc_ip_forwarding_on
(
const
char
*
name
,
int
family
);
/* Disable IP forwarding. */
extern
int
lxc_ip_forwarding_off
(
const
char
*
name
,
int
family
);
/* Generate a new unique network interface name.
/* Generate a new unique network interface name.
* Allocated memory must be freed by caller.
* Allocated memory must be freed by caller.
*/
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment