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
d42ec829
Unverified
Commit
d42ec829
authored
Mar 19, 2020
by
Stéphane Graber
Committed by
GitHub
Mar 19, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3310 from brauner/2020-03-19/fixes
network: fix ovs removal
parents
de95b436
d16bda44
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
358 additions
and
621 deletions
+358
-621
network.c
src/lxc/network.c
+348
-609
nl.c
src/lxc/nl.c
+2
-4
nl.h
src/lxc/nl.h
+5
-3
rtnl.c
src/lxc/rtnl.c
+2
-2
rtnl.h
src/lxc/rtnl.h
+1
-3
No files found.
src/lxc/network.c
View file @
d42ec829
...
@@ -52,26 +52,26 @@ static const char loop_device[] = "lo";
...
@@ -52,26 +52,26 @@ static const char loop_device[] = "lo";
static
int
lxc_ip_route_dest
(
__u16
nlmsg_type
,
int
family
,
int
ifindex
,
void
*
dest
,
unsigned
int
netmask
)
static
int
lxc_ip_route_dest
(
__u16
nlmsg_type
,
int
family
,
int
ifindex
,
void
*
dest
,
unsigned
int
netmask
)
{
{
int
addrlen
,
err
;
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
addrlen
,
err
;
struct
rtmsg
*
rt
;
struct
rtmsg
*
rt
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
:
sizeof
(
struct
in6_addr
);
:
sizeof
(
struct
in6_addr
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
-
ENOMEM
;
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
err
=
-
ENOMEM
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
...
@@ -79,7 +79,8 @@ static int lxc_ip_route_dest(__u16 nlmsg_type, int family, int ifindex, void *de
...
@@ -79,7 +79,8 @@ static int lxc_ip_route_dest(__u16 nlmsg_type, int family, int ifindex, void *de
rt
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
rtmsg
));
rt
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
rtmsg
));
if
(
!
rt
)
if
(
!
rt
)
goto
out
;
err
=
-
ENOMEM
;
rt
->
rtm_family
=
family
;
rt
->
rtm_family
=
family
;
rt
->
rtm_table
=
RT_TABLE_MAIN
;
rt
->
rtm_table
=
RT_TABLE_MAIN
;
rt
->
rtm_scope
=
RT_SCOPE_LINK
;
rt
->
rtm_scope
=
RT_SCOPE_LINK
;
...
@@ -87,17 +88,13 @@ static int lxc_ip_route_dest(__u16 nlmsg_type, int family, int ifindex, void *de
...
@@ -87,17 +88,13 @@ static int lxc_ip_route_dest(__u16 nlmsg_type, int family, int ifindex, void *de
rt
->
rtm_type
=
RTN_UNICAST
;
rt
->
rtm_type
=
RTN_UNICAST
;
rt
->
rtm_dst_len
=
netmask
;
rt
->
rtm_dst_len
=
netmask
;
err
=
-
EINVAL
;
if
(
nla_put_buffer
(
nlmsg
,
RTA_DST
,
dest
,
addrlen
))
if
(
nla_put_buffer
(
nlmsg
,
RTA_DST
,
dest
,
addrlen
))
goto
out
;
return
-
EINVAL
;
if
(
nla_put_u32
(
nlmsg
,
RTA_OIF
,
ifindex
))
if
(
nla_put_u32
(
nlmsg
,
RTA_OIF
,
ifindex
))
goto
out
;
return
-
EINVAL
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
answer
);
out:
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
answer
);
netlink_close
(
&
nlh
);
nlmsg_free
(
answer
);
nlmsg_free
(
nlmsg
);
return
err
;
}
}
static
int
lxc_ipv4_dest_add
(
int
ifindex
,
struct
in_addr
*
dest
,
unsigned
int
netmask
)
static
int
lxc_ipv4_dest_add
(
int
ifindex
,
struct
in_addr
*
dest
,
unsigned
int
netmask
)
...
@@ -129,11 +126,8 @@ static int lxc_setup_ipv4_routes(struct lxc_list *ip, int ifindex)
...
@@ -129,11 +126,8 @@ static int lxc_setup_ipv4_routes(struct lxc_list *ip, int ifindex)
struct
lxc_inetdev
*
inetdev
=
iterator
->
elem
;
struct
lxc_inetdev
*
inetdev
=
iterator
->
elem
;
err
=
lxc_ipv4_dest_add
(
ifindex
,
&
inetdev
->
addr
,
inetdev
->
prefix
);
err
=
lxc_ipv4_dest_add
(
ifindex
,
&
inetdev
->
addr
,
inetdev
->
prefix
);
if
(
err
)
{
if
(
err
)
SYSERROR
(
"Failed to setup ipv4 route for network device "
return
log_error_errno
(
-
1
,
-
err
,
"Failed to setup ipv4 route for network device with ifindex %d"
,
ifindex
);
"with ifindex %d"
,
ifindex
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
}
return
0
;
return
0
;
...
@@ -148,11 +142,8 @@ static int lxc_setup_ipv6_routes(struct lxc_list *ip, int ifindex)
...
@@ -148,11 +142,8 @@ static int lxc_setup_ipv6_routes(struct lxc_list *ip, int ifindex)
struct
lxc_inet6dev
*
inet6dev
=
iterator
->
elem
;
struct
lxc_inet6dev
*
inet6dev
=
iterator
->
elem
;
err
=
lxc_ipv6_dest_add
(
ifindex
,
&
inet6dev
->
addr
,
inet6dev
->
prefix
);
err
=
lxc_ipv6_dest_add
(
ifindex
,
&
inet6dev
->
addr
,
inet6dev
->
prefix
);
if
(
err
)
{
if
(
err
)
SYSERROR
(
"Failed to setup ipv6 route for network device "
return
log_error_errno
(
-
1
,
-
err
,
"Failed to setup ipv6 route for network device with ifindex %d"
,
ifindex
);
"with ifindex %d"
,
ifindex
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
}
return
0
;
return
0
;
...
@@ -169,9 +160,7 @@ static int setup_ipv4_addr_routes(struct lxc_list *ip, int ifindex)
...
@@ -169,9 +160,7 @@ static int setup_ipv4_addr_routes(struct lxc_list *ip, int ifindex)
err
=
lxc_ipv4_dest_add
(
ifindex
,
&
inetdev
->
addr
,
32
);
err
=
lxc_ipv4_dest_add
(
ifindex
,
&
inetdev
->
addr
,
32
);
if
(
err
)
if
(
err
)
return
log_error_errno
(
-
1
,
err
,
return
log_error_errno
(
-
1
,
err
,
"Failed to setup ipv4 address route for network device with eifindex %d"
,
ifindex
);
"Failed to setup ipv4 address route for network device with eifindex %d"
,
ifindex
);
}
}
return
0
;
return
0
;
...
@@ -187,9 +176,7 @@ static int setup_ipv6_addr_routes(struct lxc_list *ip, int ifindex)
...
@@ -187,9 +176,7 @@ static int setup_ipv6_addr_routes(struct lxc_list *ip, int ifindex)
err
=
lxc_ipv6_dest_add
(
ifindex
,
&
inet6dev
->
addr
,
128
);
err
=
lxc_ipv6_dest_add
(
ifindex
,
&
inet6dev
->
addr
,
128
);
if
(
err
)
if
(
err
)
return
log_error_errno
(
-
1
,
err
,
return
log_error_errno
(
-
1
,
err
,
"Failed to setup ipv6 address route for network device with eifindex %d"
,
ifindex
);
"Failed to setup ipv6 address route for network device with eifindex %d"
,
ifindex
);
}
}
return
0
;
return
0
;
...
@@ -202,47 +189,42 @@ struct ip_proxy_args {
...
@@ -202,47 +189,42 @@ struct ip_proxy_args {
static
int
lxc_ip_neigh_proxy
(
__u16
nlmsg_type
,
int
family
,
int
ifindex
,
void
*
dest
)
static
int
lxc_ip_neigh_proxy
(
__u16
nlmsg_type
,
int
family
,
int
ifindex
,
void
*
dest
)
{
{
int
addrlen
,
err
;
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
addrlen
,
err
;
struct
ndmsg
*
rt
;
struct
ndmsg
*
rt
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
:
sizeof
(
struct
in6_addr
);
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
:
sizeof
(
struct
in6_addr
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
-
ENOMEM
;
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
return
-
ENOMEM
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
nlmsg_type
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
nlmsg_type
;
rt
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ndmsg
));
rt
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ndmsg
));
if
(
!
rt
)
if
(
!
rt
)
goto
out
;
return
-
ENOMEM
;
rt
->
ndm_ifindex
=
ifindex
;
rt
->
ndm_ifindex
=
ifindex
;
rt
->
ndm_flags
=
NTF_PROXY
;
rt
->
ndm_flags
=
NTF_PROXY
;
rt
->
ndm_type
=
NDA_DST
;
rt
->
ndm_type
=
NDA_DST
;
rt
->
ndm_family
=
family
;
rt
->
ndm_family
=
family
;
err
=
-
EINVAL
;
if
(
nla_put_buffer
(
nlmsg
,
NDA_DST
,
dest
,
addrlen
))
if
(
nla_put_buffer
(
nlmsg
,
NDA_DST
,
dest
,
addrlen
))
goto
out
;
return
-
EINVAL
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
answer
);
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
answer
);
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
answer
);
nlmsg_free
(
nlmsg
);
return
err
;
}
}
static
int
lxc_is_ip_forwarding_enabled
(
const
char
*
ifname
,
int
family
)
static
int
lxc_is_ip_forwarding_enabled
(
const
char
*
ifname
,
int
family
)
...
@@ -254,10 +236,10 @@ static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
...
@@ -254,10 +236,10 @@ static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
ret_set_errno
(
-
1
,
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
ret
=
snprintf
(
path
,
sizeof
(
path
)
,
"/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
>=
sizeof
(
path
)
)
return
ret_set_errno
(
-
1
,
E2BIG
);
return
ret_set_errno
(
-
1
,
E2BIG
);
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
...
@@ -270,7 +252,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -270,7 +252,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
char
*
veth1
,
*
veth2
;
char
*
veth1
,
*
veth2
;
char
veth1buf
[
IFNAMSIZ
],
veth2buf
[
IFNAMSIZ
];
char
veth1buf
[
IFNAMSIZ
],
veth2buf
[
IFNAMSIZ
];
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
{
if
(
!
is_empty_string
(
netdev
->
priv
.
veth_attr
.
pair
)
)
{
veth1
=
netdev
->
priv
.
veth_attr
.
pair
;
veth1
=
netdev
->
priv
.
veth_attr
.
pair
;
if
(
handler
->
conf
->
reboot
)
if
(
handler
->
conf
->
reboot
)
lxc_netdev_delete_by_name
(
veth1
);
lxc_netdev_delete_by_name
(
veth1
);
...
@@ -299,7 +281,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -299,7 +281,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
if
(
netdev
->
mtu
)
{
if
(
netdev
->
mtu
)
{
if
(
lxc_safe_uint
(
netdev
->
mtu
,
&
mtu
))
if
(
lxc_safe_uint
(
netdev
->
mtu
,
&
mtu
))
return
log_error_errno
(
-
1
,
errno
,
"Failed to parse mtu"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to parse mtu"
);
}
else
if
(
netdev
->
link
[
0
]
!=
'\0'
)
{
}
else
if
(
!
is_empty_string
(
netdev
->
link
)
)
{
int
ifindex_mtu
;
int
ifindex_mtu
;
ifindex_mtu
=
if_nametoindex
(
netdev
->
link
);
ifindex_mtu
=
if_nametoindex
(
netdev
->
link
);
...
@@ -310,11 +292,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -310,11 +292,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
}
}
err
=
lxc_veth_create
(
veth1
,
veth2
,
handler
->
pid
,
mtu
);
err
=
lxc_veth_create
(
veth1
,
veth2
,
handler
->
pid
,
mtu
);
if
(
err
)
{
if
(
err
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to create veth pair
\"
%s
\"
and
\"
%s
\"
"
,
veth1
,
veth2
);
SYSERROR
(
"Failed to create veth pair
\"
%s
\"
and
\"
%s
\"
"
,
veth1
,
veth2
);
return
-
1
;
}
strlcpy
(
netdev
->
created_name
,
veth2
,
IFNAMSIZ
);
strlcpy
(
netdev
->
created_name
,
veth2
,
IFNAMSIZ
);
...
@@ -344,7 +323,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -344,7 +323,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
}
}
}
}
if
(
netdev
->
link
[
0
]
!=
'\0'
&&
netdev
->
priv
.
veth_attr
.
mode
==
VETH_MODE_BRIDGE
)
{
if
(
!
is_empty_string
(
netdev
->
link
)
&&
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
;
...
@@ -385,19 +364,19 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -385,19 +364,19 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
if
(
netdev
->
ipv4_gateway
)
{
if
(
netdev
->
ipv4_gateway
)
{
char
bufinet4
[
INET_ADDRSTRLEN
];
char
bufinet4
[
INET_ADDRSTRLEN
];
if
(
!
inet_ntop
(
AF_INET
,
netdev
->
ipv4_gateway
,
bufinet4
,
sizeof
(
bufinet4
)))
{
if
(
!
inet_ntop
(
AF_INET
,
netdev
->
ipv4_gateway
,
bufinet4
,
sizeof
(
bufinet4
)))
{
log_error_errno
(
-
1
,
-
errno
,
"Failed to convert gateway ipv4 address on
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to convert gateway ipv4 address on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
err
=
lxc_ip_forwarding_on
(
veth1
,
AF_INET
);
err
=
lxc_ip_forwarding_on
(
veth1
,
AF_INET
);
if
(
err
)
{
if
(
err
)
{
log_error_errno
(
-
1
,
err
,
"Failed to activate ipv4 forwarding on
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to activate ipv4 forwarding on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
err
=
lxc_ip_neigh_proxy
(
RTM_NEWNEIGH
,
AF_INET
,
netdev
->
priv
.
veth_attr
.
ifindex
,
netdev
->
ipv4_gateway
);
err
=
lxc_ip_neigh_proxy
(
RTM_NEWNEIGH
,
AF_INET
,
netdev
->
priv
.
veth_attr
.
ifindex
,
netdev
->
ipv4_gateway
);
if
(
err
)
{
if
(
err
)
{
log_error_errno
(
-
1
,
err
,
"Failed to add gateway ipv4 proxy on
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to add gateway ipv4 proxy on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
}
}
...
@@ -406,7 +385,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -406,7 +385,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
char
bufinet6
[
INET6_ADDRSTRLEN
];
char
bufinet6
[
INET6_ADDRSTRLEN
];
if
(
!
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
bufinet6
,
sizeof
(
bufinet6
)))
{
if
(
!
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
bufinet6
,
sizeof
(
bufinet6
)))
{
log_error_errno
(
-
1
,
-
errno
,
"Failed to convert gateway ipv6 address on
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to convert gateway ipv6 address on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
...
@@ -415,25 +394,25 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -415,25 +394,25 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
*/
*/
err
=
lxc_is_ip_forwarding_enabled
(
"all"
,
AF_INET6
);
err
=
lxc_is_ip_forwarding_enabled
(
"all"
,
AF_INET6
);
if
(
err
)
{
if
(
err
)
{
log_error_errno
(
-
1
,
err
,
"Requires sysctl net.ipv6.conf.all.forwarding=1"
);
SYSERROR
(
"Requires sysctl net.ipv6.conf.all.forwarding=1"
);
goto
out_delete
;
goto
out_delete
;
}
}
err
=
lxc_ip_forwarding_on
(
veth1
,
AF_INET6
);
err
=
lxc_ip_forwarding_on
(
veth1
,
AF_INET6
);
if
(
err
)
{
if
(
err
)
{
log_error_errno
(
-
1
,
err
,
"Failed to activate ipv6 forwarding on
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to activate ipv6 forwarding on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
err
=
lxc_neigh_proxy_on
(
veth1
,
AF_INET6
);
err
=
lxc_neigh_proxy_on
(
veth1
,
AF_INET6
);
if
(
err
)
{
if
(
err
)
{
log_error_errno
(
-
1
,
err
,
"Failed to activate proxy ndp on
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to activate proxy ndp on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
err
=
lxc_ip_neigh_proxy
(
RTM_NEWNEIGH
,
AF_INET6
,
netdev
->
priv
.
veth_attr
.
ifindex
,
netdev
->
ipv6_gateway
);
err
=
lxc_ip_neigh_proxy
(
RTM_NEWNEIGH
,
AF_INET6
,
netdev
->
priv
.
veth_attr
.
ifindex
,
netdev
->
ipv6_gateway
);
if
(
err
)
{
if
(
err
)
{
log_error_errno
(
-
1
,
err
,
"Failed to add gateway ipv6 proxy on
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to add gateway ipv6 proxy on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
}
}
...
@@ -441,14 +420,14 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -441,14 +420,14 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
/* setup ipv4 address routes on the host interface */
/* setup ipv4 address routes on the host interface */
err
=
setup_ipv4_addr_routes
(
&
netdev
->
ipv4
,
netdev
->
priv
.
veth_attr
.
ifindex
);
err
=
setup_ipv4_addr_routes
(
&
netdev
->
ipv4
,
netdev
->
priv
.
veth_attr
.
ifindex
);
if
(
err
)
{
if
(
err
)
{
log_error_errno
(
-
1
,
err
,
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
/* setup ipv6 address routes on the host interface */
/* setup ipv6 address routes on the host interface */
err
=
setup_ipv6_addr_routes
(
&
netdev
->
ipv6
,
netdev
->
priv
.
veth_attr
.
ifindex
);
err
=
setup_ipv6_addr_routes
(
&
netdev
->
ipv6
,
netdev
->
priv
.
veth_attr
.
ifindex
);
if
(
err
)
{
if
(
err
)
{
log_error_errno
(
-
1
,
err
,
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
SYSERROR
(
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
goto
out_delete
;
}
}
}
}
...
@@ -482,7 +461,7 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
...
@@ -482,7 +461,7 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
char
peer
[
IFNAMSIZ
];
char
peer
[
IFNAMSIZ
];
int
err
;
int
err
;
if
(
netdev
->
link
[
0
]
==
'\0'
)
{
if
(
is_empty_string
(
netdev
->
link
)
)
{
ERROR
(
"No link for macvlan network device specified"
);
ERROR
(
"No link for macvlan network device specified"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -557,69 +536,66 @@ on_error:
...
@@ -557,69 +536,66 @@ on_error:
static
int
lxc_ipvlan_create
(
const
char
*
master
,
const
char
*
name
,
int
mode
,
int
isolation
)
static
int
lxc_ipvlan_create
(
const
char
*
master
,
const
char
*
name
,
int
mode
,
int
isolation
)
{
{
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
err
,
index
,
len
;
int
err
,
index
,
len
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
rtattr
*
nest
,
*
nest2
;
struct
rtattr
*
nest
,
*
nest2
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
len
=
strlen
(
master
);
len
=
strlen
(
master
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
return
ret_
set_errno
(
-
1
,
EINVAL
);
return
ret_
errno
(
EINVAL
);
len
=
strlen
(
name
);
len
=
strlen
(
name
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
return
ret_
set_errno
(
-
1
,
EINVAL
);
return
ret_
errno
(
EINVAL
);
index
=
if_nametoindex
(
master
);
index
=
if_nametoindex
(
master
);
if
(
!
index
)
if
(
!
index
)
return
ret_
set_errno
(
-
1
,
EINVAL
);
return
ret_
errno
(
EINVAL
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
ret_
set_errno
(
-
1
,
-
err
);
return
ret_
errno
(
-
err
);
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
{
if
(
!
ifi
)
goto
out
;
return
ret_errno
(
ENOMEM
);
}
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_family
=
AF_UNSPEC
;
err
=
-
EPROTO
;
nest
=
nla_begin_nested
(
nlmsg
,
IFLA_LINKINFO
);
nest
=
nla_begin_nested
(
nlmsg
,
IFLA_LINKINFO
);
if
(
!
nest
)
if
(
!
nest
)
goto
out
;
return
ret_errno
(
EPROTO
)
;
if
(
nla_put_string
(
nlmsg
,
IFLA_INFO_KIND
,
"ipvlan"
))
if
(
nla_put_string
(
nlmsg
,
IFLA_INFO_KIND
,
"ipvlan"
))
goto
out
;
return
ret_errno
(
EPROTO
)
;
if
(
mode
)
{
if
(
mode
)
{
nest2
=
nla_begin_nested
(
nlmsg
,
IFLA_INFO_DATA
);
nest2
=
nla_begin_nested
(
nlmsg
,
IFLA_INFO_DATA
);
if
(
!
nest2
)
if
(
!
nest2
)
goto
out
;
return
ret_errno
(
EPROTO
)
;
if
(
nla_put_u32
(
nlmsg
,
IFLA_IPVLAN_MODE
,
mode
))
if
(
nla_put_u32
(
nlmsg
,
IFLA_IPVLAN_MODE
,
mode
))
goto
out
;
return
ret_errno
(
EPROTO
)
;
/* if_link.h does not define the isolation flag value for bridge mode so we define it as 0
/* if_link.h does not define the isolation flag value for bridge mode so we define it as 0
* and only send mode if mode >0 as default mode is bridge anyway according to ipvlan docs.
* and only send mode if mode >0 as default mode is bridge anyway according to ipvlan docs.
*/
*/
if
(
isolation
>
0
)
{
if
(
isolation
>
0
&&
if
(
nla_put_u16
(
nlmsg
,
IFLA_IPVLAN_ISOLATION
,
isolation
))
nla_put_u16
(
nlmsg
,
IFLA_IPVLAN_ISOLATION
,
isolation
))
goto
out
;
return
ret_errno
(
EPROTO
);
}
nla_end_nested
(
nlmsg
,
nest2
);
nla_end_nested
(
nlmsg
,
nest2
);
}
}
...
@@ -627,19 +603,12 @@ static int lxc_ipvlan_create(const char *master, const char *name, int mode, int
...
@@ -627,19 +603,12 @@ static int lxc_ipvlan_create(const char *master, const char *name, int mode, int
nla_end_nested
(
nlmsg
,
nest
);
nla_end_nested
(
nlmsg
,
nest
);
if
(
nla_put_u32
(
nlmsg
,
IFLA_LINK
,
index
))
if
(
nla_put_u32
(
nlmsg
,
IFLA_LINK
,
index
))
goto
out
;
return
ret_errno
(
EPROTO
)
;
if
(
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
name
))
if
(
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
name
))
goto
out
;
return
ret_errno
(
EPROTO
)
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
answer
);
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
answer
);
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
answer
);
nlmsg_free
(
nlmsg
);
if
(
err
<
0
)
return
ret_set_errno
(
-
1
,
-
err
);
return
0
;
}
}
static
int
instantiate_ipvlan
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
static
int
instantiate_ipvlan
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
...
@@ -647,7 +616,7 @@ static int instantiate_ipvlan(struct lxc_handler *handler, struct lxc_netdev *ne
...
@@ -647,7 +616,7 @@ static int instantiate_ipvlan(struct lxc_handler *handler, struct lxc_netdev *ne
char
peer
[
IFNAMSIZ
];
char
peer
[
IFNAMSIZ
];
int
err
;
int
err
;
if
(
netdev
->
link
[
0
]
==
'\0'
)
{
if
(
is_empty_string
(
netdev
->
link
)
)
{
ERROR
(
"No link for ipvlan network device specified"
);
ERROR
(
"No link for ipvlan network device specified"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -724,7 +693,7 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -724,7 +693,7 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
int
err
;
int
err
;
static
uint16_t
vlan_cntr
=
0
;
static
uint16_t
vlan_cntr
=
0
;
if
(
netdev
->
link
[
0
]
==
'\0'
)
{
if
(
is_empty_string
(
netdev
->
link
)
)
{
ERROR
(
"No link for vlan network device specified"
);
ERROR
(
"No link for vlan network device specified"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -798,10 +767,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -798,10 +767,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
{
{
int
err
,
mtu_orig
=
0
;
int
err
,
mtu_orig
=
0
;
if
(
netdev
->
link
[
0
]
==
'\0'
)
{
if
(
is_empty_string
(
netdev
->
link
))
ERROR
(
"No link for physical interface specified"
);
return
log_error_errno
(
-
1
,
errno
,
"No link for physical interface specified"
);
return
-
1
;
}
/*
/*
* Note that we're retrieving the container's ifindex in the host's
* Note that we're retrieving the container's ifindex in the host's
...
@@ -812,10 +779,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -812,10 +779,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
* device in the host's namespace.
* device in the host's namespace.
*/
*/
netdev
->
ifindex
=
if_nametoindex
(
netdev
->
link
);
netdev
->
ifindex
=
if_nametoindex
(
netdev
->
link
);
if
(
!
netdev
->
ifindex
)
{
if
(
!
netdev
->
ifindex
)
ERROR
(
"Failed to retrieve ifindex for
\"
%s
\"
"
,
netdev
->
link
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to retrieve ifindex for
\"
%s
\"
"
,
netdev
->
link
);
return
-
1
;
}
strlcpy
(
netdev
->
created_name
,
netdev
->
link
,
IFNAMSIZ
);
strlcpy
(
netdev
->
created_name
,
netdev
->
link
,
IFNAMSIZ
);
if
(
is_empty_string
(
netdev
->
name
))
if
(
is_empty_string
(
netdev
->
name
))
...
@@ -832,10 +797,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -832,10 +797,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
* container shutdown.
* container shutdown.
*/
*/
mtu_orig
=
netdev_get_mtu
(
netdev
->
ifindex
);
mtu_orig
=
netdev_get_mtu
(
netdev
->
ifindex
);
if
(
mtu_orig
<
0
)
{
if
(
mtu_orig
<
0
)
SYSERROR
(
"Failed to get original mtu for interface
\"
%s
\"
"
,
netdev
->
link
);
return
log_error_errno
(
-
1
,
-
mtu_orig
,
"Failed to get original mtu for interface
\"
%s
\"
"
,
netdev
->
link
);
return
ret_set_errno
(
-
1
,
-
mtu_orig
);
}
netdev
->
priv
.
phys_attr
.
mtu
=
mtu_orig
;
netdev
->
priv
.
phys_attr
.
mtu
=
mtu_orig
;
...
@@ -843,19 +806,12 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -843,19 +806,12 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
unsigned
int
mtu
;
unsigned
int
mtu
;
err
=
lxc_safe_uint
(
netdev
->
mtu
,
&
mtu
);
err
=
lxc_safe_uint
(
netdev
->
mtu
,
&
mtu
);
if
(
err
<
0
)
{
if
(
err
<
0
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to parse mtu
\"
%s
\"
for interface
\"
%s
\"
"
,
netdev
->
mtu
,
netdev
->
link
);
SYSERROR
(
"Failed to parse mtu
\"
%s
\"
for interface
\"
%s
\"
"
,
netdev
->
mtu
,
netdev
->
link
);
return
-
1
;
}
err
=
lxc_netdev_set_mtu
(
netdev
->
link
,
mtu
);
err
=
lxc_netdev_set_mtu
(
netdev
->
link
,
mtu
);
if
(
err
<
0
)
{
if
(
err
<
0
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to set mtu
\"
%s
\"
for interface
\"
%s
\"
"
,
netdev
->
mtu
,
netdev
->
link
);
SYSERROR
(
"Failed to set mtu
\"
%s
\"
for interface
\"
%s
\"
"
,
netdev
->
mtu
,
netdev
->
link
);
return
-
1
;
}
}
}
if
(
netdev
->
upscript
)
{
if
(
netdev
->
upscript
)
{
...
@@ -867,10 +823,9 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -867,10 +823,9 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
err
=
run_script_argv
(
handler
->
name
,
handler
->
conf
->
hooks_version
,
err
=
run_script_argv
(
handler
->
name
,
handler
->
conf
->
hooks_version
,
"net"
,
netdev
->
upscript
,
"up"
,
argv
);
"net"
,
netdev
->
upscript
,
"up"
,
argv
);
if
(
err
<
0
)
{
if
(
err
<
0
)
return
-
1
;
return
-
1
;
}
}
}
DEBUG
(
"Instantiated phys
\"
%s
\"
with ifindex is
\"
%d
\"
"
,
netdev
->
link
,
DEBUG
(
"Instantiated phys
\"
%s
\"
with ifindex is
\"
%d
\"
"
,
netdev
->
link
,
netdev
->
ifindex
);
netdev
->
ifindex
);
...
@@ -932,8 +887,7 @@ static int instantiate_ns_veth(struct lxc_netdev *netdev)
...
@@ -932,8 +887,7 @@ static int instantiate_ns_veth(struct lxc_netdev *netdev)
ret
=
lxc_netdev_rename_by_name
(
netdev
->
created_name
,
netdev
->
name
);
ret
=
lxc_netdev_rename_by_name
(
netdev
->
created_name
,
netdev
->
name
);
if
(
ret
)
if
(
ret
)
return
log_error_errno
(
-
1
,
return
log_error_errno
(
-
1
,
-
ret
,
"Failed to rename network device
\"
%s
\"
to
\"
%s
\"
"
,
-
ret
,
"Failed to rename network device
\"
%s
\"
to
\"
%s
\"
"
,
netdev
->
created_name
,
netdev
->
created_name
,
netdev
->
name
);
netdev
->
name
);
...
@@ -945,9 +899,7 @@ static int instantiate_ns_veth(struct lxc_netdev *netdev)
...
@@ -945,9 +899,7 @@ static int instantiate_ns_veth(struct lxc_netdev *netdev)
* would be automatically allocated by the system
* would be automatically allocated by the system
*/
*/
if
(
!
if_indextoname
(
netdev
->
ifindex
,
current_ifname
))
if
(
!
if_indextoname
(
netdev
->
ifindex
,
current_ifname
))
return
log_error_errno
(
-
1
,
return
log_error_errno
(
-
1
,
errno
,
"Failed get name for network device with ifindex %d"
,
netdev
->
ifindex
);
errno
,
"Failed get name for network device with ifindex %d"
,
netdev
->
ifindex
);
/*
/*
* Now update the recorded name of the network device to reflect the
* Now update the recorded name of the network device to reflect the
...
@@ -963,9 +915,7 @@ static int __instantiate_common(struct lxc_netdev *netdev)
...
@@ -963,9 +915,7 @@ static int __instantiate_common(struct lxc_netdev *netdev)
{
{
netdev
->
ifindex
=
if_nametoindex
(
netdev
->
name
);
netdev
->
ifindex
=
if_nametoindex
(
netdev
->
name
);
if
(
!
netdev
->
ifindex
)
if
(
!
netdev
->
ifindex
)
return
log_error_errno
(
-
1
,
return
log_error_errno
(
-
1
,
errno
,
"Failed to retrieve ifindex for network device with name %s"
,
netdev
->
name
);
errno
,
"Failed to retrieve ifindex for network device with name %s"
,
netdev
->
name
);
return
0
;
return
0
;
}
}
...
@@ -1023,7 +973,7 @@ static int shutdown_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
...
@@ -1023,7 +973,7 @@ static int shutdown_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
if
(
!
netdev
->
downscript
)
if
(
!
netdev
->
downscript
)
return
0
;
return
0
;
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
if
(
!
is_empty_string
(
netdev
->
priv
.
veth_attr
.
pair
)
)
argv
[
2
]
=
netdev
->
priv
.
veth_attr
.
pair
;
argv
[
2
]
=
netdev
->
priv
.
veth_attr
.
pair
;
else
else
argv
[
2
]
=
netdev
->
priv
.
veth_attr
.
veth1
;
argv
[
2
]
=
netdev
->
priv
.
veth_attr
.
veth1
;
...
@@ -1153,78 +1103,72 @@ static instantiate_cb netdev_deconf[LXC_NET_MAXCONFTYPE + 1] = {
...
@@ -1153,78 +1103,72 @@ static instantiate_cb netdev_deconf[LXC_NET_MAXCONFTYPE + 1] = {
static
int
lxc_netdev_move_by_index_fd
(
int
ifindex
,
int
fd
,
const
char
*
ifname
)
static
int
lxc_netdev_move_by_index_fd
(
int
ifindex
,
int
fd
,
const
char
*
ifname
)
{
{
int
err
;
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
err
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nlmsg
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
if
(
!
ifi
)
goto
out
;
return
ret_errno
(
ENOMEM
);
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_index
=
ifindex
;
ifi
->
ifi_index
=
ifindex
;
if
(
nla_put_u32
(
nlmsg
,
IFLA_NET_NS_FD
,
fd
))
if
(
nla_put_u32
(
nlmsg
,
IFLA_NET_NS_FD
,
fd
))
goto
out
;
return
ret_errno
(
ENOMEM
)
;
if
(
!
is_empty_string
(
ifname
)
&&
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
ifname
))
if
(
!
is_empty_string
(
ifname
)
&&
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
ifname
))
goto
out
;
return
ret_errno
(
ENOMEM
)
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
nlmsg
);
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
nlmsg
);
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
nlmsg
);
return
err
;
}
}
int
lxc_netdev_move_by_index
(
int
ifindex
,
pid_t
pid
,
const
char
*
ifname
)
int
lxc_netdev_move_by_index
(
int
ifindex
,
pid_t
pid
,
const
char
*
ifname
)
{
{
int
err
;
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
err
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nlmsg
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
if
(
!
ifi
)
goto
out
;
return
ret_errno
(
ENOMEM
);
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_index
=
ifindex
;
ifi
->
ifi_index
=
ifindex
;
if
(
nla_put_u32
(
nlmsg
,
IFLA_NET_NS_PID
,
pid
))
if
(
nla_put_u32
(
nlmsg
,
IFLA_NET_NS_PID
,
pid
))
goto
out
;
return
ret_errno
(
ENOMEM
)
;
if
(
!
is_empty_string
(
ifname
)
&&
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
ifname
))
if
(
!
is_empty_string
(
ifname
)
&&
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
ifname
))
goto
out
;
return
ret_errno
(
ENOMEM
)
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
nlmsg
);
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
nlmsg
);
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
nlmsg
);
return
err
;
}
}
/* If we are asked to move a wireless interface, then we must actually move its
/* If we are asked to move a wireless interface, then we must actually move its
...
@@ -1306,9 +1250,8 @@ int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
...
@@ -1306,9 +1250,8 @@ int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
* the 80211 module, so for now just call out to iw.
* the 80211 module, so for now just call out to iw.
*/
*/
cmd
=
on_path
(
"iw"
,
NULL
);
cmd
=
on_path
(
"iw"
,
NULL
);
if
(
!
cmd
)
{
if
(
!
cmd
)
return
-
1
;
return
-
1
;
}
fpid
=
fork
();
fpid
=
fork
();
if
(
fpid
<
0
)
if
(
fpid
<
0
)
...
@@ -1317,8 +1260,7 @@ int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
...
@@ -1317,8 +1260,7 @@ int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
if
(
fpid
==
0
)
{
if
(
fpid
==
0
)
{
char
pidstr
[
30
];
char
pidstr
[
30
];
sprintf
(
pidstr
,
"%d"
,
pid
);
sprintf
(
pidstr
,
"%d"
,
pid
);
execlp
(
"iw"
,
"iw"
,
"phy"
,
physname
,
"set"
,
"netns"
,
pidstr
,
execlp
(
"iw"
,
"iw"
,
"phy"
,
physname
,
"set"
,
"netns"
,
pidstr
,
(
char
*
)
NULL
);
(
char
*
)
NULL
);
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
...
@@ -1352,39 +1294,35 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
...
@@ -1352,39 +1294,35 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
int
lxc_netdev_delete_by_index
(
int
ifindex
)
int
lxc_netdev_delete_by_index
(
int
ifindex
)
{
{
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
err
;
int
err
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_DELLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_DELLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
if
(
!
ifi
)
goto
out
;
return
ret_errno
(
ENOMEM
);
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_index
=
ifindex
;
ifi
->
ifi_index
=
ifindex
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
answer
);
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
answer
);
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
answer
);
nlmsg_free
(
nlmsg
);
return
err
;
}
}
int
lxc_netdev_delete_by_name
(
const
char
*
name
)
int
lxc_netdev_delete_by_name
(
const
char
*
name
)
...
@@ -1400,48 +1338,42 @@ int lxc_netdev_delete_by_name(const char *name)
...
@@ -1400,48 +1338,42 @@ int lxc_netdev_delete_by_name(const char *name)
int
lxc_netdev_rename_by_index
(
int
ifindex
,
const
char
*
newname
)
int
lxc_netdev_rename_by_index
(
int
ifindex
,
const
char
*
newname
)
{
{
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
err
,
len
;
int
err
,
len
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
len
=
strlen
(
newname
);
len
=
strlen
(
newname
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
{
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
err
=
-
EINVAL
;
return
ret_errno
(
EINVAL
);
goto
out
;
}
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
if
(
!
ifi
)
goto
out
;
return
ret_errno
(
ENOMEM
);
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_index
=
ifindex
;
ifi
->
ifi_index
=
ifindex
;
if
(
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
newname
))
if
(
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
newname
))
goto
out
;
return
ret_errno
(
ENOMEM
)
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
answer
);
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
answer
);
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
answer
);
nlmsg_free
(
nlmsg
);
return
err
;
}
}
int
lxc_netdev_rename_by_name
(
const
char
*
oldname
,
const
char
*
newname
)
int
lxc_netdev_rename_by_name
(
const
char
*
oldname
,
const
char
*
newname
)
...
@@ -1461,110 +1393,95 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
...
@@ -1461,110 +1393,95 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
int
netdev_set_flag
(
const
char
*
name
,
int
flag
)
int
netdev_set_flag
(
const
char
*
name
,
int
flag
)
{
{
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
err
,
index
,
len
;
int
err
,
index
,
len
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
-
EINVAL
;
len
=
strlen
(
name
);
len
=
strlen
(
name
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
goto
out
;
return
ret_errno
(
EINVAL
)
;
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
err
=
-
EINVAL
;
index
=
if_nametoindex
(
name
);
index
=
if_nametoindex
(
name
);
if
(
!
index
)
if
(
!
index
)
goto
out
;
return
ret_errno
(
EINVAL
)
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
{
if
(
!
ifi
)
err
=
-
ENOMEM
;
return
ret_errno
(
ENOMEM
);
goto
out
;
}
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_index
=
index
;
ifi
->
ifi_index
=
index
;
ifi
->
ifi_change
|=
IFF_UP
;
ifi
->
ifi_change
|=
IFF_UP
;
ifi
->
ifi_flags
|=
flag
;
ifi
->
ifi_flags
|=
flag
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
answer
);
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
answer
);
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
nlmsg
);
nlmsg_free
(
answer
);
return
err
;
}
}
int
netdev_get_flag
(
const
char
*
name
,
int
*
flag
)
int
netdev_get_flag
(
const
char
*
name
,
int
*
flag
)
{
{
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
err
,
index
,
len
;
int
err
,
index
,
len
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
if
(
!
name
)
if
(
!
name
)
return
-
EINVAL
;
return
ret_errno
(
EINVAL
)
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
-
EINVAL
;
len
=
strlen
(
name
);
len
=
strlen
(
name
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
goto
out
;
return
ret_errno
(
EINVAL
)
;
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
return
ret_errno
(
ENOMEM
)
;
err
=
-
EINVAL
;
index
=
if_nametoindex
(
name
);
index
=
if_nametoindex
(
name
);
if
(
!
index
)
if
(
!
index
)
goto
out
;
return
ret_errno
(
EINVAL
)
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_GETLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_GETLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
{
if
(
!
ifi
)
err
=
-
ENOMEM
;
return
ret_errno
(
ENOMEM
);
goto
out
;
}
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_family
=
AF_UNSPEC
;
ifi
->
ifi_index
=
index
;
ifi
->
ifi_index
=
index
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
answer
);
err
=
netlink_transaction
(
nlh_ptr
,
nlmsg
,
answer
);
if
(
err
)
if
(
err
)
goto
out
;
return
ret_set_errno
(
-
1
,
errno
)
;
ifi
=
NLMSG_DATA
(
answer
->
nlmsghdr
);
ifi
=
NLMSG_DATA
(
answer
->
nlmsghdr
);
*
flag
=
ifi
->
ifi_flags
;
*
flag
=
ifi
->
ifi_flags
;
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
nlmsg
);
nlmsg_free
(
answer
);
return
err
;
return
err
;
}
}
...
@@ -1654,7 +1571,6 @@ int netdev_get_mtu(int ifindex)
...
@@ -1654,7 +1571,6 @@ int netdev_get_mtu(int ifindex)
msg
=
answer
->
nlmsghdr
;
msg
=
answer
->
nlmsghdr
;
while
(
NLMSG_OK
(
msg
,
recv_len
))
{
while
(
NLMSG_OK
(
msg
,
recv_len
))
{
/* Stop reading if we see an error message */
/* Stop reading if we see an error message */
if
(
msg
->
nlmsg_type
==
NLMSG_ERROR
)
{
if
(
msg
->
nlmsg_type
==
NLMSG_ERROR
)
{
struct
nlmsgerr
*
errmsg
=
struct
nlmsgerr
*
errmsg
=
...
@@ -1676,7 +1592,8 @@ int netdev_get_mtu(int ifindex)
...
@@ -1676,7 +1592,8 @@ int netdev_get_mtu(int ifindex)
msg
->
nlmsg_len
-
NLMSG_LENGTH
(
sizeof
(
*
ifi
));
msg
->
nlmsg_len
-
NLMSG_LENGTH
(
sizeof
(
*
ifi
));
res
=
0
;
res
=
0
;
while
(
RTA_OK
(
rta
,
attr_len
))
{
while
(
RTA_OK
(
rta
,
attr_len
))
{
/* Found a local address for the
/*
Found a local address for the
* requested interface, return it.
* requested interface, return it.
*/
*/
if
(
rta
->
rta_type
==
IFLA_MTU
)
{
if
(
rta
->
rta_type
==
IFLA_MTU
)
{
...
@@ -2039,9 +1956,9 @@ static int ip_forwarding_set(const char *ifname, int family, int flag)
...
@@ -2039,9 +1956,9 @@ static int ip_forwarding_set(const char *ifname, int family, int flag)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
-
EINVAL
;
return
-
EINVAL
;
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
ret
=
snprintf
(
path
,
sizeof
(
path
)
,
"/proc/sys/net/%s/conf/%s/%s"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
"forwarding"
);
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
"forwarding"
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
PATH_MAX
)
if
(
ret
<
0
||
(
size_t
)
ret
>=
sizeof
(
path
)
)
return
-
E2BIG
;
return
-
E2BIG
;
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
...
@@ -2065,10 +1982,10 @@ static int neigh_proxy_set(const char *ifname, int family, int flag)
...
@@ -2065,10 +1982,10 @@ static int neigh_proxy_set(const char *ifname, int family, int flag)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
-
EINVAL
;
return
-
EINVAL
;
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
ret
=
snprintf
(
path
,
sizeof
(
path
)
,
"/proc/sys/net/%s/conf/%s/%s"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
family
==
AF_INET
?
"proxy_arp"
:
"proxy_ndp"
);
family
==
AF_INET
?
"proxy_arp"
:
"proxy_ndp"
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
PATH_MAX
)
if
(
ret
<
0
||
(
size_t
)
ret
>=
sizeof
(
path
)
)
return
-
E2BIG
;
return
-
E2BIG
;
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
...
@@ -2083,10 +2000,10 @@ static int lxc_is_ip_neigh_proxy_enabled(const char *ifname, int family)
...
@@ -2083,10 +2000,10 @@ static int lxc_is_ip_neigh_proxy_enabled(const char *ifname, int family)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
ret_set_errno
(
-
1
,
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
ret
=
snprintf
(
path
,
sizeof
(
path
)
,
"/proc/sys/net/%s/conf/%s/%s"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
family
==
AF_INET
?
"proxy_arp"
:
"proxy_ndp"
);
family
==
AF_INET
?
"proxy_arp"
:
"proxy_ndp"
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
PATH_MAX
)
if
(
ret
<
0
||
(
size_t
)
ret
>=
sizeof
(
path
)
)
return
ret_set_errno
(
-
1
,
E2BIG
);
return
ret_set_errno
(
-
1
,
E2BIG
);
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
...
@@ -2502,8 +2419,7 @@ static int lxc_ovs_delete_port_exec(void *data)
...
@@ -2502,8 +2419,7 @@ static int lxc_ovs_delete_port_exec(void *data)
{
{
struct
ovs_veth_args
*
args
=
data
;
struct
ovs_veth_args
*
args
=
data
;
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"del-port"
,
args
->
bridge
,
args
->
nic
,
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"del-port"
,
args
->
bridge
,
args
->
nic
,
(
char
*
)
NULL
);
(
char
*
)
NULL
);
return
-
1
;
return
-
1
;
}
}
...
@@ -2517,11 +2433,8 @@ int lxc_ovs_delete_port(const char *bridge, const char *nic)
...
@@ -2517,11 +2433,8 @@ int lxc_ovs_delete_port(const char *bridge, const char *nic)
args
.
nic
=
nic
;
args
.
nic
=
nic
;
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
lxc_ovs_delete_port_exec
,
(
void
*
)
&
args
);
lxc_ovs_delete_port_exec
,
(
void
*
)
&
args
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
ERROR
(
"Failed to delete
\"
%s
\"
from openvswitch bridge
\"
%s
\"
: "
return
log_error
(
-
1
,
"Failed to delete
\"
%s
\"
from openvswitch bridge
\"
%s
\"
: %s"
,
nic
,
bridge
,
cmd_output
);
"%s"
,
nic
,
bridge
,
cmd_output
);
return
-
1
;
}
return
0
;
return
0
;
}
}
...
@@ -2530,8 +2443,7 @@ static int lxc_ovs_attach_bridge_exec(void *data)
...
@@ -2530,8 +2443,7 @@ static int lxc_ovs_attach_bridge_exec(void *data)
{
{
struct
ovs_veth_args
*
args
=
data
;
struct
ovs_veth_args
*
args
=
data
;
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"add-port"
,
args
->
bridge
,
args
->
nic
,
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"add-port"
,
args
->
bridge
,
args
->
nic
,
(
char
*
)
NULL
);
(
char
*
)
NULL
);
return
-
1
;
return
-
1
;
}
}
...
@@ -2545,11 +2457,8 @@ static int lxc_ovs_attach_bridge(const char *bridge, const char *nic)
...
@@ -2545,11 +2457,8 @@ static int lxc_ovs_attach_bridge(const char *bridge, const char *nic)
args
.
nic
=
nic
;
args
.
nic
=
nic
;
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
lxc_ovs_attach_bridge_exec
,
(
void
*
)
&
args
);
lxc_ovs_attach_bridge_exec
,
(
void
*
)
&
args
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
ERROR
(
"Failed to attach
\"
%s
\"
to openvswitch bridge
\"
%s
\"
: %s"
,
return
log_error
(
-
1
,
"Failed to attach
\"
%s
\"
to openvswitch bridge
\"
%s
\"
: %s"
,
nic
,
bridge
,
cmd_output
);
nic
,
bridge
,
cmd_output
);
return
-
1
;
}
return
0
;
return
0
;
}
}
...
@@ -2631,10 +2540,8 @@ char *lxc_mkifname(char *template)
...
@@ -2631,10 +2540,8 @@ char *lxc_mkifname(char *template)
/* Get all the network interfaces. */
/* Get all the network interfaces. */
ret
=
netns_getifaddrs
(
&
ifaddr
,
-
1
,
&
(
bool
){
false
});
ret
=
netns_getifaddrs
(
&
ifaddr
,
-
1
,
&
(
bool
){
false
});
if
(
ret
<
0
)
{
if
(
ret
<
0
)
SYSERROR
(
"Failed to get network interfaces"
);
return
log_error_errno
(
NULL
,
errno
,
"Failed to get network interfaces"
);
return
NULL
;
}
/* Generate random names until we find one that doesn't exist. */
/* Generate random names until we find one that doesn't exist. */
for
(;;)
{
for
(;;)
{
...
@@ -2713,14 +2620,11 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
...
@@ -2713,14 +2620,11 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
if
(
!
netdev
->
ipv4_gateway_auto
&&
!
netdev
->
ipv6_gateway_auto
)
if
(
!
netdev
->
ipv4_gateway_auto
&&
!
netdev
->
ipv6_gateway_auto
)
continue
;
continue
;
if
(
netdev
->
type
!=
LXC_NET_VETH
&&
netdev
->
type
!=
LXC_NET_MACVLAN
)
{
if
(
netdev
->
type
!=
LXC_NET_VETH
&&
netdev
->
type
!=
LXC_NET_MACVLAN
)
ERROR
(
"Automatic gateway detection is only supported for veth and macvlan"
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Automatic gateway detection is only supported for veth and macvlan"
);
return
-
1
;
}
if
(
netdev
->
link
[
0
]
==
'\0'
)
{
if
(
is_empty_string
(
netdev
->
link
))
{
ERROR
(
"Automatic gateway detection needs a link interface"
);
return
log_error_errno
(
-
1
,
errno
,
"Automatic gateway detection needs a link interface"
);
return
-
1
;
}
}
link_index
=
if_nametoindex
(
netdev
->
link
);
link_index
=
if_nametoindex
(
netdev
->
link
);
...
@@ -2728,19 +2632,13 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
...
@@ -2728,19 +2632,13 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
netdev
->
ipv4_gateway_auto
)
{
if
(
netdev
->
ipv4_gateway_auto
)
{
if
(
lxc_ipv4_addr_get
(
link_index
,
&
netdev
->
ipv4_gateway
))
{
if
(
lxc_ipv4_addr_get
(
link_index
,
&
netdev
->
ipv4_gateway
))
ERROR
(
"Failed to automatically find ipv4 gateway address from link interface
\"
%s
\"
"
,
return
log_error_errno
(
-
1
,
errno
,
"Failed to automatically find ipv4 gateway address from link interface
\"
%s
\"
"
,
netdev
->
link
);
netdev
->
link
);
return
-
1
;
}
}
}
if
(
netdev
->
ipv6_gateway_auto
)
{
if
(
netdev
->
ipv6_gateway_auto
)
{
if
(
lxc_ipv6_addr_get
(
link_index
,
&
netdev
->
ipv6_gateway
))
{
if
(
lxc_ipv6_addr_get
(
link_index
,
&
netdev
->
ipv6_gateway
))
ERROR
(
"Failed to automatically find ipv6 gateway address from link interface
\"
%s
\"
"
,
return
log_error_errno
(
-
1
,
errno
,
"Failed to automatically find ipv6 gateway address from link interface
\"
%s
\"
"
,
netdev
->
link
);
netdev
->
link
);
return
-
1
;
}
}
}
}
}
...
@@ -2759,23 +2657,18 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2759,23 +2657,18 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
char
buffer
[
PATH_MAX
]
=
{
0
};
char
buffer
[
PATH_MAX
]
=
{
0
};
size_t
retlen
;
size_t
retlen
;
if
(
netdev
->
type
!=
LXC_NET_VETH
)
{
if
(
netdev
->
type
!=
LXC_NET_VETH
)
ERROR
(
"Network type %d not support for unprivileged use"
,
netdev
->
type
);
return
log_error_errno
(
-
1
,
errno
,
"Network type %d not support for unprivileged use"
,
netdev
->
type
);
return
-
1
;
}
ret
=
pipe
(
pipefd
);
ret
=
pipe
(
pipefd
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
SYSERROR
(
"Failed to create pipe"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to create pipe"
);
return
-
1
;
}
child
=
fork
();
child
=
fork
();
if
(
child
<
0
)
{
if
(
child
<
0
)
{
SYSERROR
(
"Failed to create new process"
);
close
(
pipefd
[
0
]);
close
(
pipefd
[
0
]);
close
(
pipefd
[
1
]);
close
(
pipefd
[
1
]);
return
-
1
;
return
log_error_errno
(
-
1
,
errno
,
"Failed to create new process"
)
;
}
}
if
(
child
==
0
)
{
if
(
child
==
0
)
{
...
@@ -2792,7 +2685,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2792,7 +2685,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
if
(
netdev
->
link
[
0
]
!=
'\0'
)
if
(
!
is_empty_string
(
netdev
->
link
)
)
retlen
=
strlcpy
(
netdev_link
,
netdev
->
link
,
IFNAMSIZ
);
retlen
=
strlcpy
(
netdev_link
,
netdev
->
link
,
IFNAMSIZ
);
else
else
retlen
=
strlcpy
(
netdev_link
,
"none"
,
IFNAMSIZ
);
retlen
=
strlcpy
(
netdev_link
,
"none"
,
IFNAMSIZ
);
...
@@ -2824,7 +2717,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2824,7 +2717,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
/* close the write-end of the pipe */
/* close the write-end of the pipe */
close
(
pipefd
[
1
]);
close
(
pipefd
[
1
]);
bytes
=
lxc_read_nointr
(
pipefd
[
0
],
&
buffer
,
PATH_MAX
);
bytes
=
lxc_read_nointr
(
pipefd
[
0
],
&
buffer
,
sizeof
(
buffer
)
);
if
(
bytes
<
0
)
{
if
(
bytes
<
0
)
{
SYSERROR
(
"Failed to read from pipe file descriptor"
);
SYSERROR
(
"Failed to read from pipe file descriptor"
);
close
(
pipefd
[
0
]);
close
(
pipefd
[
0
]);
...
@@ -2834,19 +2727,14 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2834,19 +2727,14 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
ret
=
wait_for_pid
(
child
);
ret
=
wait_for_pid
(
child
);
close
(
pipefd
[
0
]);
close
(
pipefd
[
0
]);
if
(
ret
!=
0
||
bytes
<
0
)
{
if
(
ret
!=
0
||
bytes
<
0
)
ERROR
(
"lxc-user-nic failed to configure requested network: %s"
,
return
log_error
(
-
1
,
"lxc-user-nic failed to configure requested network: %s"
,
buffer
[
0
]
!=
'\0'
?
buffer
:
"(null)"
);
buffer
[
0
]
!=
'\0'
?
buffer
:
"(null)"
);
return
-
1
;
}
TRACE
(
"Received output
\"
%s
\"
from lxc-user-nic"
,
buffer
);
TRACE
(
"Received output
\"
%s
\"
from lxc-user-nic"
,
buffer
);
/* netdev->name */
/* netdev->name */
token
=
strtok_r
(
buffer
,
":"
,
&
saveptr
);
token
=
strtok_r
(
buffer
,
":"
,
&
saveptr
);
if
(
!
token
)
{
if
(
!
token
)
ERROR
(
"Failed to parse lxc-user-nic output"
);
return
log_error
(
-
1
,
"Failed to parse lxc-user-nic output"
);
return
-
1
;
}
/*
/*
* lxc-user-nic will take care of proper network device naming. So
* lxc-user-nic will take care of proper network device naming. So
...
@@ -2856,52 +2744,35 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2856,52 +2744,35 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
retlen
=
strlcpy
(
netdev
->
name
,
token
,
IFNAMSIZ
);
retlen
=
strlcpy
(
netdev
->
name
,
token
,
IFNAMSIZ
);
if
(
retlen
<
IFNAMSIZ
)
if
(
retlen
<
IFNAMSIZ
)
retlen
=
strlcpy
(
netdev
->
created_name
,
token
,
IFNAMSIZ
);
retlen
=
strlcpy
(
netdev
->
created_name
,
token
,
IFNAMSIZ
);
if
(
retlen
>=
IFNAMSIZ
)
{
if
(
retlen
>=
IFNAMSIZ
)
ERROR
(
"Container side veth device name returned by lxc-user-nic is too long"
);
return
log_error_errno
(
-
1
,
E2BIG
,
"Container side veth device name returned by lxc-user-nic is too long"
);
return
-
E2BIG
;
}
/* netdev->ifindex */
/* netdev->ifindex */
token
=
strtok_r
(
NULL
,
":"
,
&
saveptr
);
token
=
strtok_r
(
NULL
,
":"
,
&
saveptr
);
if
(
!
token
)
{
if
(
!
token
)
ERROR
(
"Failed to parse lxc-user-nic output"
);
return
log_error
(
-
1
,
"Failed to parse lxc-user-nic output"
);
return
-
1
;
}
ret
=
lxc_safe_int
(
token
,
&
netdev
->
ifindex
);
ret
=
lxc_safe_int
(
token
,
&
netdev
->
ifindex
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
errno
=
-
ret
;
return
log_error_errno
(
-
1
,
-
ret
,
"Failed to convert string
\"
%s
\"
to integer"
,
token
);
SYSERROR
(
"Failed to convert string
\"
%s
\"
to integer"
,
token
);
return
-
1
;
}
/* netdev->priv.veth_attr.veth1 */
/* netdev->priv.veth_attr.veth1 */
token
=
strtok_r
(
NULL
,
":"
,
&
saveptr
);
token
=
strtok_r
(
NULL
,
":"
,
&
saveptr
);
if
(
!
token
)
{
if
(
!
token
)
ERROR
(
"Failed to parse lxc-user-nic output"
);
return
log_error
(
-
1
,
"Failed to parse lxc-user-nic output"
);
return
-
1
;
}
retlen
=
strlcpy
(
netdev
->
priv
.
veth_attr
.
veth1
,
token
,
IFNAMSIZ
);
retlen
=
strlcpy
(
netdev
->
priv
.
veth_attr
.
veth1
,
token
,
IFNAMSIZ
);
if
(
retlen
>=
IFNAMSIZ
)
{
if
(
retlen
>=
IFNAMSIZ
)
ERROR
(
"Host side veth device name returned by lxc-user-nic is "
return
log_error_errno
(
-
1
,
E2BIG
,
"Host side veth device name returned by lxc-user-nic is too long"
);
"too long"
);
return
-
E2BIG
;
}
/* netdev->priv.veth_attr.ifindex */
/* netdev->priv.veth_attr.ifindex */
token
=
strtok_r
(
NULL
,
":"
,
&
saveptr
);
token
=
strtok_r
(
NULL
,
":"
,
&
saveptr
);
if
(
!
token
)
{
if
(
!
token
)
ERROR
(
"Failed to parse lxc-user-nic output"
);
return
log_error
(
-
1
,
"Failed to parse lxc-user-nic output"
);
return
-
1
;
}
ret
=
lxc_safe_int
(
token
,
&
netdev
->
priv
.
veth_attr
.
ifindex
);
ret
=
lxc_safe_int
(
token
,
&
netdev
->
priv
.
veth_attr
.
ifindex
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
errno
=
-
ret
;
return
log_error_errno
(
-
1
,
-
ret
,
"Failed to convert string
\"
%s
\"
to integer"
,
token
);
SYSERROR
(
"Failed to convert string
\"
%s
\"
to integer"
,
token
);
return
-
1
;
}
if
(
netdev
->
upscript
)
{
if
(
netdev
->
upscript
)
{
char
*
argv
[]
=
{
char
*
argv
[]
=
{
...
@@ -2929,23 +2800,18 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2929,23 +2800,18 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
int
pipefd
[
2
];
int
pipefd
[
2
];
char
buffer
[
PATH_MAX
]
=
{
0
};
char
buffer
[
PATH_MAX
]
=
{
0
};
if
(
netdev
->
type
!=
LXC_NET_VETH
)
{
if
(
netdev
->
type
!=
LXC_NET_VETH
)
ERROR
(
"Network type %d not support for unprivileged use"
,
netdev
->
type
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Network type %d not support for unprivileged use"
,
netdev
->
type
);
return
-
1
;
}
ret
=
pipe
(
pipefd
);
ret
=
pipe
(
pipefd
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
SYSERROR
(
"Failed to create pipe"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to create pipe"
);
return
-
1
;
}
child
=
fork
();
child
=
fork
();
if
(
child
<
0
)
{
if
(
child
<
0
)
{
SYSERROR
(
"Failed to create new process"
);
close
(
pipefd
[
0
]);
close
(
pipefd
[
0
]);
close
(
pipefd
[
1
]);
close
(
pipefd
[
1
]);
return
-
1
;
return
log_error_errno
(
-
1
,
errno
,
"Failed to create new process"
)
;
}
}
if
(
child
==
0
)
{
if
(
child
==
0
)
{
...
@@ -2962,18 +2828,17 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2962,18 +2828,17 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
if
(
!
is_empty_string
(
netdev
->
priv
.
veth_attr
.
pair
)
)
hostveth
=
netdev
->
priv
.
veth_attr
.
pair
;
hostveth
=
netdev
->
priv
.
veth_attr
.
pair
;
else
else
hostveth
=
netdev
->
priv
.
veth_attr
.
veth1
;
hostveth
=
netdev
->
priv
.
veth_attr
.
veth1
;
if
(
hostveth
[
0
]
==
'\0'
)
{
if
(
is_empty_string
(
hostveth
)
)
{
SYSERROR
(
"Host side veth device name is missing"
);
SYSERROR
(
"Host side veth device name is missing"
);
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
if
(
netdev
->
link
[
0
]
==
'\0'
)
{
if
(
is_empty_string
(
netdev
->
link
))
{
SYSERROR
(
"Network link for network device
\"
%s
\"
is "
SYSERROR
(
"Network link for network device
\"
%s
\"
is missing"
,
netdev
->
priv
.
veth_attr
.
veth1
);
"missing"
,
netdev
->
priv
.
veth_attr
.
veth1
);
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
...
@@ -2988,7 +2853,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2988,7 +2853,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
close
(
pipefd
[
1
]);
close
(
pipefd
[
1
]);
bytes
=
lxc_read_nointr
(
pipefd
[
0
],
&
buffer
,
PATH_MAX
);
bytes
=
lxc_read_nointr
(
pipefd
[
0
],
&
buffer
,
sizeof
(
buffer
)
);
if
(
bytes
<
0
)
{
if
(
bytes
<
0
)
{
SYSERROR
(
"Failed to read from pipe file descriptor."
);
SYSERROR
(
"Failed to read from pipe file descriptor."
);
close
(
pipefd
[
0
]);
close
(
pipefd
[
0
]);
...
@@ -2997,12 +2862,10 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
...
@@ -2997,12 +2862,10 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
}
}
ret
=
wait_for_pid
(
child
);
ret
=
wait_for_pid
(
child
);
close
(
pipefd
[
0
]);
close_prot_errno_disarm
(
pipefd
[
0
]);
if
(
ret
!=
0
||
bytes
<
0
)
{
if
(
ret
!=
0
||
bytes
<
0
)
ERROR
(
"lxc-user-nic failed to delete requested network: %s"
,
return
log_error_errno
(
-
1
,
errno
,
"lxc-user-nic failed to delete requested network: %s"
,
buffer
[
0
]
!=
'\0'
?
buffer
:
"(null)"
);
!
is_empty_string
(
buffer
)
?
buffer
:
"(null)"
);
return
-
1
;
}
return
0
;
return
0
;
}
}
...
@@ -3026,11 +2889,8 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
...
@@ -3026,11 +2889,8 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
*
netns_path
=
'\0'
;
*
netns_path
=
'\0'
;
if
(
handler
->
nsfd
[
LXC_NS_NET
]
<
0
)
{
if
(
handler
->
nsfd
[
LXC_NS_NET
]
<
0
)
DEBUG
(
"Cannot not guarantee safe deletion of network devices. "
return
log_debug
(
false
,
"Cannot not guarantee safe deletion of network devices. Manual cleanup maybe needed"
);
"Manual cleanup maybe needed"
);
return
false
;
}
ret
=
snprintf
(
netns_path
,
sizeof
(
netns_path
),
"/proc/%d/fd/%d"
,
ret
=
snprintf
(
netns_path
,
sizeof
(
netns_path
),
"/proc/%d/fd/%d"
,
lxc_raw_getpid
(),
handler
->
nsfd
[
LXC_NS_NET
]);
lxc_raw_getpid
(),
handler
->
nsfd
[
LXC_NS_NET
]);
...
@@ -3051,12 +2911,10 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
...
@@ -3051,12 +2911,10 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
ret
=
lxc_netdev_rename_by_index
(
netdev
->
ifindex
,
ret
=
lxc_netdev_rename_by_index
(
netdev
->
ifindex
,
netdev
->
link
);
netdev
->
link
);
if
(
ret
<
0
)
if
(
ret
<
0
)
WARN
(
"Failed to rename interface with index %d "
WARN
(
"Failed to rename interface with index %d to its initial name
\"
%s
\"
"
,
"to its initial name
\"
%s
\"
"
,
netdev
->
ifindex
,
netdev
->
link
);
netdev
->
ifindex
,
netdev
->
link
);
else
else
TRACE
(
"Renamed interface with index %d to its "
TRACE
(
"Renamed interface with index %d to its initial name
\"
%s
\"
"
,
"initial name
\"
%s
\"
"
,
netdev
->
ifindex
,
netdev
->
link
);
netdev
->
ifindex
,
netdev
->
link
);
ret
=
netdev_deconf
[
netdev
->
type
](
handler
,
netdev
);
ret
=
netdev_deconf
[
netdev
->
type
](
handler
,
netdev
);
...
@@ -3070,26 +2928,24 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
...
@@ -3070,26 +2928,24 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
if
(
netdev
->
type
!=
LXC_NET_VETH
)
if
(
netdev
->
type
!=
LXC_NET_VETH
)
goto
clear_ifindices
;
goto
clear_ifindices
;
if
(
netdev
->
link
[
0
]
==
'\0'
||
!
is_ovs_bridge
(
netdev
->
link
))
if
(
is_empty_string
(
netdev
->
link
)
||
!
is_ovs_bridge
(
netdev
->
link
))
goto
clear_ifindices
;
goto
clear_ifindices
;
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
if
(
!
is_empty_string
(
netdev
->
priv
.
veth_attr
.
pair
)
)
hostveth
=
netdev
->
priv
.
veth_attr
.
pair
;
hostveth
=
netdev
->
priv
.
veth_attr
.
pair
;
else
else
hostveth
=
netdev
->
priv
.
veth_attr
.
veth1
;
hostveth
=
netdev
->
priv
.
veth_attr
.
veth1
;
if
(
hostveth
[
0
]
==
'\0'
)
if
(
is_empty_string
(
hostveth
)
)
goto
clear_ifindices
;
goto
clear_ifindices
;
ret
=
lxc_delete_network_unpriv_exec
(
handler
->
lxcpath
,
ret
=
lxc_delete_network_unpriv_exec
(
handler
->
lxcpath
,
handler
->
name
,
netdev
,
handler
->
name
,
netdev
,
netns_path
);
netns_path
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
WARN
(
"Failed to remove port
\"
%s
\"
from openvswitch "
WARN
(
"Failed to remove port
\"
%s
\"
from openvswitch bridge
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
"bridge
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
goto
clear_ifindices
;
goto
clear_ifindices
;
}
}
INFO
(
"Removed interface
\"
%s
\"
from
\"
%s
\"
"
,
hostveth
,
INFO
(
"Removed interface
\"
%s
\"
from
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
netdev
->
link
);
clear_ifindices:
clear_ifindices:
/*
/*
...
@@ -3118,50 +2974,38 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
...
@@ -3118,50 +2974,38 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
unsigned
int
lo_ifindex
=
0
,
link_ifindex
=
0
;
unsigned
int
lo_ifindex
=
0
,
link_ifindex
=
0
;
link_ifindex
=
if_nametoindex
(
netdev
->
link
);
link_ifindex
=
if_nametoindex
(
netdev
->
link
);
if
(
link_ifindex
==
0
)
{
if
(
link_ifindex
==
0
)
ERROR
(
"Failed to retrieve ifindex for
\"
%s
\"
l2proxy setup"
,
netdev
->
link
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to retrieve ifindex for
\"
%s
\"
l2proxy setup"
,
netdev
->
link
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* If IPv4 addresses are specified, then check that sysctl is configured correctly. */
/* If IPv4 addresses are specified, then check that sysctl is configured correctly. */
if
(
!
lxc_list_empty
(
&
netdev
->
ipv4
))
{
if
(
!
lxc_list_empty
(
&
netdev
->
ipv4
))
{
/* Check for net.ipv4.conf.[link].forwarding=1 */
/* Check for net.ipv4.conf.[link].forwarding=1 */
if
(
lxc_is_ip_forwarding_enabled
(
netdev
->
link
,
AF_INET
)
<
0
)
{
if
(
lxc_is_ip_forwarding_enabled
(
netdev
->
link
,
AF_INET
)
<
0
)
ERROR
(
"Requires sysctl net.ipv4.conf.%s.forwarding=1"
,
netdev
->
link
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Requires sysctl net.ipv4.conf.%s.forwarding=1"
,
netdev
->
link
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
}
}
/* If IPv6 addresses are specified, then check that sysctl is configured correctly. */
/* If IPv6 addresses are specified, then check that sysctl is configured correctly. */
if
(
!
lxc_list_empty
(
&
netdev
->
ipv6
))
{
if
(
!
lxc_list_empty
(
&
netdev
->
ipv6
))
{
/* Check for net.ipv6.conf.[link].proxy_ndp=1 */
/* Check for net.ipv6.conf.[link].proxy_ndp=1 */
if
(
lxc_is_ip_neigh_proxy_enabled
(
netdev
->
link
,
AF_INET6
)
<
0
)
{
if
(
lxc_is_ip_neigh_proxy_enabled
(
netdev
->
link
,
AF_INET6
)
<
0
)
ERROR
(
"Requires sysctl net.ipv6.conf.%s.proxy_ndp=1"
,
netdev
->
link
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Requires sysctl net.ipv6.conf.%s.proxy_ndp=1"
,
netdev
->
link
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* Check for net.ipv6.conf.[link].forwarding=1 */
/* Check for net.ipv6.conf.[link].forwarding=1 */
if
(
lxc_is_ip_forwarding_enabled
(
netdev
->
link
,
AF_INET6
)
<
0
)
{
if
(
lxc_is_ip_forwarding_enabled
(
netdev
->
link
,
AF_INET6
)
<
0
)
ERROR
(
"Requires sysctl net.ipv6.conf.%s.forwarding=1"
,
netdev
->
link
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Requires sysctl net.ipv6.conf.%s.forwarding=1"
,
netdev
->
link
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
}
}
/* Perform IPVLAN specific checks. */
/* Perform IPVLAN specific checks. */
if
(
netdev
->
type
==
LXC_NET_IPVLAN
)
{
if
(
netdev
->
type
==
LXC_NET_IPVLAN
)
{
/* Check mode is l3s as other modes do not work with l2proxy. */
/* Check mode is l3s as other modes do not work with l2proxy. */
if
(
netdev
->
priv
.
ipvlan_attr
.
mode
!=
IPVLAN_MODE_L3S
)
{
if
(
netdev
->
priv
.
ipvlan_attr
.
mode
!=
IPVLAN_MODE_L3S
)
ERROR
(
"Requires ipvlan mode on dev
\"
%s
\"
be l3s when used with l2proxy"
,
netdev
->
link
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Requires ipvlan mode on dev
\"
%s
\"
be l3s when used with l2proxy"
,
netdev
->
link
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* Retrieve local-loopback interface index for use with IPVLAN static routes. */
/* Retrieve local-loopback interface index for use with IPVLAN static routes. */
lo_ifindex
=
if_nametoindex
(
loop_device
);
lo_ifindex
=
if_nametoindex
(
loop_device
);
if
(
lo_ifindex
==
0
)
{
if
(
lo_ifindex
==
0
)
ERROR
(
"Failed to retrieve ifindex for
\"
%s
\"
routing cleanup"
,
loop_device
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed to retrieve ifindex for
\"
%s
\"
routing cleanup"
,
loop_device
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
}
}
lxc_list_for_each_safe
(
cur
,
&
netdev
->
ipv4
,
next
)
{
lxc_list_for_each_safe
(
cur
,
&
netdev
->
ipv4
,
next
)
{
...
@@ -3175,10 +3019,8 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
...
@@ -3175,10 +3019,8 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
/* IPVLAN requires a route to local-loopback to trigger l2proxy. */
/* IPVLAN requires a route to local-loopback to trigger l2proxy. */
if
(
netdev
->
type
==
LXC_NET_IPVLAN
)
{
if
(
netdev
->
type
==
LXC_NET_IPVLAN
)
{
err
=
lxc_ipv4_dest_add
(
lo_ifindex
,
&
inet4dev
->
addr
,
32
);
err
=
lxc_ipv4_dest_add
(
lo_ifindex
,
&
inet4dev
->
addr
,
32
);
if
(
err
<
0
)
{
if
(
err
<
0
)
ERROR
(
"Failed to add ipv4 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet4
,
loop_device
);
return
log_error_errno
(
-
1
,
-
err
,
"Failed to add ipv4 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet4
,
loop_device
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
}
}
}
...
@@ -3193,70 +3035,66 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
...
@@ -3193,70 +3035,66 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
/* IPVLAN requires a route to local-loopback to trigger l2proxy. */
/* IPVLAN requires a route to local-loopback to trigger l2proxy. */
if
(
netdev
->
type
==
LXC_NET_IPVLAN
)
{
if
(
netdev
->
type
==
LXC_NET_IPVLAN
)
{
err
=
lxc_ipv6_dest_add
(
lo_ifindex
,
&
inet6dev
->
addr
,
128
);
err
=
lxc_ipv6_dest_add
(
lo_ifindex
,
&
inet6dev
->
addr
,
128
);
if
(
err
<
0
)
{
if
(
err
<
0
)
ERROR
(
"Failed to add ipv6 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet6
,
loop_device
);
return
log_error_errno
(
-
1
,
-
err
,
"Failed to add ipv6 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet6
,
loop_device
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
}
}
}
return
0
;
return
0
;
}
}
static
int
lxc_delete_ipv4_l2proxy
(
struct
in_addr
*
ip
,
char
*
link
,
unsigned
int
lo_ifindex
)
{
static
int
lxc_delete_ipv4_l2proxy
(
struct
in_addr
*
ip
,
char
*
link
,
unsigned
int
lo_ifindex
)
{
char
bufinet4
[
INET_ADDRSTRLEN
];
char
bufinet4
[
INET_ADDRSTRLEN
];
unsigned
int
errCount
=
0
,
link_ifindex
=
0
;
bool
had_error
=
false
;
unsigned
int
link_ifindex
=
0
;
if
(
!
inet_ntop
(
AF_INET
,
ip
,
bufinet4
,
sizeof
(
bufinet4
)))
{
if
(
!
inet_ntop
(
AF_INET
,
ip
,
bufinet4
,
sizeof
(
bufinet4
)))
SYSERROR
(
"Failed to convert IP for l2proxy ipv4 removal on dev
\"
%s
\"
"
,
link
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed to convert IP for l2proxy ipv4 removal on dev
\"
%s
\"
"
,
link
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* If a local-loopback ifindex supplied remove the static route to the lo device. */
/* If a local-loopback ifindex supplied remove the static route to the lo device. */
if
(
lo_ifindex
>
0
)
{
if
(
lo_ifindex
>
0
)
{
if
(
lxc_ipv4_dest_del
(
lo_ifindex
,
ip
,
32
)
<
0
)
{
if
(
lxc_ipv4_dest_del
(
lo_ifindex
,
ip
,
32
)
<
0
)
{
errCount
++
;
had_error
=
true
;
ERROR
(
"Failed to delete ipv4 dest
\"
%s
\"
for network ifindex
\"
%u
\"
"
,
bufinet4
,
lo_ifindex
);
ERROR
(
"Failed to delete ipv4 dest
\"
%s
\"
for network ifindex
\"
%u
\"
"
,
bufinet4
,
lo_ifindex
);
}
}
}
}
/* If link is supplied remove the IP neigh proxy entry for this IP on the device. */
/* If link is supplied remove the IP neigh proxy entry for this IP on the device. */
if
(
link
[
0
]
!=
'\0'
)
{
if
(
!
is_empty_string
(
link
)
)
{
link_ifindex
=
if_nametoindex
(
link
);
link_ifindex
=
if_nametoindex
(
link
);
if
(
link_ifindex
==
0
)
{
if
(
link_ifindex
==
0
)
ERROR
(
"Failed to retrieve ifindex for
\"
%s
\"
l2proxy cleanup"
,
link
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed to retrieve ifindex for
\"
%s
\"
l2proxy cleanup"
,
link
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
if
(
lxc_ip_neigh_proxy
(
RTM_DELNEIGH
,
AF_INET
,
link_ifindex
,
ip
)
<
0
)
if
(
lxc_ip_neigh_proxy
(
RTM_DELNEIGH
,
AF_INET
,
link_ifindex
,
ip
)
<
0
)
errCount
++
;
had_error
=
true
;
}
}
if
(
errCount
>
0
)
if
(
had_error
)
return
ret_set_errno
(
-
1
,
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
return
0
;
return
0
;
}
}
static
int
lxc_delete_ipv6_l2proxy
(
struct
in6_addr
*
ip
,
char
*
link
,
unsigned
int
lo_ifindex
)
{
static
int
lxc_delete_ipv6_l2proxy
(
struct
in6_addr
*
ip
,
char
*
link
,
unsigned
int
lo_ifindex
)
{
char
bufinet6
[
INET6_ADDRSTRLEN
];
char
bufinet6
[
INET6_ADDRSTRLEN
];
unsigned
int
errCount
=
0
,
link_ifindex
=
0
;
bool
had_error
=
false
;
unsigned
int
link_ifindex
=
0
;
if
(
!
inet_ntop
(
AF_INET6
,
ip
,
bufinet6
,
sizeof
(
bufinet6
)))
{
if
(
!
inet_ntop
(
AF_INET6
,
ip
,
bufinet6
,
sizeof
(
bufinet6
)))
SYSERROR
(
"Failed to convert IP for l2proxy ipv6 removal on dev
\"
%s
\"
"
,
link
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed to convert IP for l2proxy ipv6 removal on dev
\"
%s
\"
"
,
link
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* If a local-loopback ifindex supplied remove the static route to the lo device. */
/* If a local-loopback ifindex supplied remove the static route to the lo device. */
if
(
lo_ifindex
>
0
)
{
if
(
lo_ifindex
>
0
)
{
if
(
lxc_ipv6_dest_del
(
lo_ifindex
,
ip
,
128
)
<
0
)
{
if
(
lxc_ipv6_dest_del
(
lo_ifindex
,
ip
,
128
)
<
0
)
{
errCount
++
;
had_error
=
true
;
ERROR
(
"Failed to delete ipv6 dest
\"
%s
\"
for network ifindex
\"
%u
\"
"
,
bufinet6
,
lo_ifindex
);
ERROR
(
"Failed to delete ipv6 dest
\"
%s
\"
for network ifindex
\"
%u
\"
"
,
bufinet6
,
lo_ifindex
);
}
}
}
}
/* If link is supplied remove the IP neigh proxy entry for this IP on the device. */
/* If link is supplied remove the IP neigh proxy entry for this IP on the device. */
if
(
link
[
0
]
!=
'\0'
)
{
if
(
!
is_empty_string
(
link
)
)
{
link_ifindex
=
if_nametoindex
(
link
);
link_ifindex
=
if_nametoindex
(
link
);
if
(
link_ifindex
==
0
)
{
if
(
link_ifindex
==
0
)
{
ERROR
(
"Failed to retrieve ifindex for
\"
%s
\"
l2proxy cleanup"
,
link
);
ERROR
(
"Failed to retrieve ifindex for
\"
%s
\"
l2proxy cleanup"
,
link
);
...
@@ -3264,10 +3102,10 @@ static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned int
...
@@ -3264,10 +3102,10 @@ static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned int
}
}
if
(
lxc_ip_neigh_proxy
(
RTM_DELNEIGH
,
AF_INET6
,
link_ifindex
,
ip
)
<
0
)
if
(
lxc_ip_neigh_proxy
(
RTM_DELNEIGH
,
AF_INET6
,
link_ifindex
,
ip
)
<
0
)
errCount
++
;
had_error
=
true
;
}
}
if
(
errCount
>
0
)
if
(
had_error
)
return
ret_set_errno
(
-
1
,
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
return
0
;
return
0
;
...
@@ -3316,23 +3154,17 @@ static int lxc_create_network_priv(struct lxc_handler *handler)
...
@@ -3316,23 +3154,17 @@ static int lxc_create_network_priv(struct lxc_handler *handler)
lxc_list_for_each
(
iterator
,
network
)
{
lxc_list_for_each
(
iterator
,
network
)
{
struct
lxc_netdev
*
netdev
=
iterator
->
elem
;
struct
lxc_netdev
*
netdev
=
iterator
->
elem
;
if
(
netdev
->
type
<
0
||
netdev
->
type
>
LXC_NET_MAXCONFTYPE
)
{
if
(
netdev
->
type
<
0
||
netdev
->
type
>
LXC_NET_MAXCONFTYPE
)
ERROR
(
"Invalid network configuration type %d"
,
netdev
->
type
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Invalid network configuration type %d"
,
netdev
->
type
);
return
-
1
;
}
/* Setup l2proxy entries if enabled and used with a link property */
/* Setup l2proxy entries if enabled and used with a link property */
if
(
netdev
->
l2proxy
&&
netdev
->
link
[
0
]
!=
'\0'
)
{
if
(
netdev
->
l2proxy
&&
!
is_empty_string
(
netdev
->
link
))
{
if
(
lxc_setup_l2proxy
(
netdev
))
{
if
(
lxc_setup_l2proxy
(
netdev
))
ERROR
(
"Failed to setup l2proxy"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to setup l2proxy"
);
return
-
1
;
}
}
}
if
(
netdev_conf
[
netdev
->
type
](
handler
,
netdev
))
{
if
(
netdev_conf
[
netdev
->
type
](
handler
,
netdev
))
ERROR
(
"Failed to create network device"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to create network device"
);
return
-
1
;
}
}
}
return
0
;
return
0
;
...
@@ -3362,12 +3194,10 @@ int lxc_network_move_created_netdev_priv(struct lxc_handler *handler)
...
@@ -3362,12 +3194,10 @@ int lxc_network_move_created_netdev_priv(struct lxc_handler *handler)
ret
=
lxc_netdev_move_wlan
(
physname
,
netdev
->
link
,
pid
,
netdev
->
name
);
ret
=
lxc_netdev_move_wlan
(
physname
,
netdev
->
link
,
pid
,
netdev
->
name
);
else
else
ret
=
lxc_netdev_move_by_index
(
netdev
->
ifindex
,
pid
,
netdev
->
name
);
ret
=
lxc_netdev_move_by_index
(
netdev
->
ifindex
,
pid
,
netdev
->
name
);
if
(
ret
)
{
if
(
ret
)
errno
=
-
ret
;
return
log_error_errno
(
-
1
,
-
ret
,
"Failed to move network device
\"
%s
\"
with ifindex %d to network namespace %d"
,
SYSERROR
(
"Failed to move network device
\"
%s
\"
with ifindex %d to network namespace %d"
,
netdev
->
created_name
,
netdev
->
created_name
,
netdev
->
ifindex
,
pid
);
netdev
->
ifindex
,
pid
);
return
-
1
;
}
DEBUG
(
"Moved network device
\"
%s
\"
with ifindex %d to network namespace of %d"
,
DEBUG
(
"Moved network device
\"
%s
\"
with ifindex %d to network namespace of %d"
,
netdev
->
created_name
,
netdev
->
ifindex
,
pid
);
netdev
->
created_name
,
netdev
->
ifindex
,
pid
);
...
@@ -3402,11 +3232,9 @@ static int lxc_create_network_unpriv(struct lxc_handler *handler)
...
@@ -3402,11 +3232,9 @@ static int lxc_create_network_unpriv(struct lxc_handler *handler)
if
(
!
network_requires_advanced_setup
(
netdev
->
type
))
if
(
!
network_requires_advanced_setup
(
netdev
->
type
))
continue
;
continue
;
if
(
netdev
->
type
!=
LXC_NET_VETH
)
{
if
(
netdev
->
type
!=
LXC_NET_VETH
)
ERROR
(
"Networks of type %s are not supported by unprivileged containers"
,
return
log_error_errno
(
-
1
,
EINVAL
,
"Networks of type %s are not supported by unprivileged containers"
,
lxc_net_type_to_str
(
netdev
->
type
));
lxc_net_type_to_str
(
netdev
->
type
));
return
-
1
;
}
if
(
netdev
->
mtu
)
if
(
netdev
->
mtu
)
INFO
(
"mtu ignored due to insufficient privilege"
);
INFO
(
"mtu ignored due to insufficient privilege"
);
...
@@ -3442,7 +3270,7 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
...
@@ -3442,7 +3270,7 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
netdev
->
ifindex
=
if_nametoindex
(
netdev
->
name
);
netdev
->
ifindex
=
if_nametoindex
(
netdev
->
name
);
/* Delete l2proxy entries if enabled and used with a link property */
/* Delete l2proxy entries if enabled and used with a link property */
if
(
netdev
->
l2proxy
&&
netdev
->
link
[
0
]
!=
'\0'
)
{
if
(
netdev
->
l2proxy
&&
!
is_empty_string
(
netdev
->
link
)
)
{
if
(
lxc_delete_l2proxy
(
netdev
))
if
(
lxc_delete_l2proxy
(
netdev
))
WARN
(
"Failed to delete all l2proxy config"
);
WARN
(
"Failed to delete all l2proxy config"
);
/* Don't return, let the network be cleaned up as normal. */
/* Don't return, let the network be cleaned up as normal. */
...
@@ -3485,36 +3313,26 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
...
@@ -3485,36 +3313,26 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
/* Explicitly delete host veth device to prevent lingering
/* Explicitly delete host veth device to prevent lingering
* devices. We had issues in LXD around this.
* devices. We had issues in LXD around this.
*/
*/
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
if
(
!
is_empty_string
(
netdev
->
priv
.
veth_attr
.
pair
)
)
hostveth
=
netdev
->
priv
.
veth_attr
.
pair
;
hostveth
=
netdev
->
priv
.
veth_attr
.
pair
;
else
else
hostveth
=
netdev
->
priv
.
veth_attr
.
veth1
;
hostveth
=
netdev
->
priv
.
veth_attr
.
veth1
;
if
(
hostveth
[
0
]
==
'\0'
)
if
(
is_empty_string
(
hostveth
)
)
goto
clear_ifindices
;
goto
clear_ifindices
;
if
(
is_empty_string
(
netdev
->
link
)
||
!
is_ovs_bridge
(
netdev
->
link
))
{
ret
=
lxc_netdev_delete_by_name
(
hostveth
);
ret
=
lxc_netdev_delete_by_name
(
hostveth
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
WARN
(
"Failed to remove interface
\"
%s
\"
from
\"
%s
\"
"
,
WARN
(
"Failed to remove interface
\"
%s
\"
from
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
hostveth
,
netdev
->
link
);
goto
clear_ifindices
;
}
INFO
(
"Removed interface
\"
%s
\"
from
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
if
(
netdev
->
link
[
0
]
==
'\0'
||
!
is_ovs_bridge
(
netdev
->
link
))
{
netdev
->
priv
.
veth_attr
.
veth1
[
0
]
=
'\0'
;
netdev
->
ifindex
=
0
;
netdev
->
priv
.
veth_attr
.
ifindex
=
0
;
goto
clear_ifindices
;
}
/* Delete the openvswitch port. */
INFO
(
"Removed interface
\"
%s
\"
from
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
}
else
if
(
!
is_empty_string
(
netdev
->
link
))
{
ret
=
lxc_ovs_delete_port
(
netdev
->
link
,
hostveth
);
ret
=
lxc_ovs_delete_port
(
netdev
->
link
,
hostveth
);
if
(
ret
<
0
)
if
(
ret
<
0
)
WARN
(
"Failed to remove port
\"
%s
\"
from openvswitch "
WARN
(
"Failed to remove port
\"
%s
\"
from openvswitch bridge
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
"bridge
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
else
INFO
(
"Removed port
\"
%s
\"
from openvswitch bridge
\"
%s
\"
"
,
hostveth
,
netdev
->
link
);
INFO
(
"Removed port
\"
%s
\"
from openvswitch bridge
\"
%s
\"
"
,
}
hostveth
,
netdev
->
link
);
clear_ifindices:
clear_ifindices:
/* We need to clear any ifindices we recorded so liblxc won't
/* We need to clear any ifindices we recorded so liblxc won't
...
@@ -3542,7 +3360,7 @@ int lxc_requests_empty_network(struct lxc_handler *handler)
...
@@ -3542,7 +3360,7 @@ int lxc_requests_empty_network(struct lxc_handler *handler)
if
(
lxc_list_empty
(
network
))
if
(
lxc_list_empty
(
network
))
return
0
;
return
0
;
lxc_list_for_each
(
iterator
,
network
)
{
lxc_list_for_each
(
iterator
,
network
)
{
struct
lxc_netdev
*
netdev
=
iterator
->
elem
;
struct
lxc_netdev
*
netdev
=
iterator
->
elem
;
if
(
netdev
->
type
==
LXC_NET_NONE
)
if
(
netdev
->
type
==
LXC_NET_NONE
)
...
@@ -3550,20 +3368,22 @@ int lxc_requests_empty_network(struct lxc_handler *handler)
...
@@ -3550,20 +3368,22 @@ int lxc_requests_empty_network(struct lxc_handler *handler)
else
else
found_nic
=
true
;
found_nic
=
true
;
}
}
if
(
found_none
&&
!
found_nic
)
if
(
found_none
&&
!
found_nic
)
return
1
;
return
1
;
return
0
;
return
0
;
}
}
/* try to move physical nics to the init netns */
/* try to move physical nics to the init netns */
int
lxc_restore_phys_nics_to_netns
(
struct
lxc_handler
*
handler
)
int
lxc_restore_phys_nics_to_netns
(
struct
lxc_handler
*
handler
)
{
{
__do_close
int
oldfd
=
-
EBADF
;
int
netnsfd
=
handler
->
nsfd
[
LXC_NS_NET
];
struct
lxc_conf
*
conf
=
handler
->
conf
;
int
ret
;
int
ret
;
int
oldfd
;
char
ifname
[
IFNAMSIZ
];
char
ifname
[
IFNAMSIZ
];
struct
lxc_list
*
iterator
;
struct
lxc_list
*
iterator
;
int
netnsfd
=
handler
->
nsfd
[
LXC_NS_NET
];
struct
lxc_conf
*
conf
=
handler
->
conf
;
/* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
/* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
* the parent network namespace. We won't have this capability if we are
* the parent network namespace. We won't have this capability if we are
...
@@ -3575,17 +3395,12 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
...
@@ -3575,17 +3395,12 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
TRACE
(
"Moving physical network devices back to parent network namespace"
);
TRACE
(
"Moving physical network devices back to parent network namespace"
);
oldfd
=
lxc_preserve_ns
(
handler
->
monitor_pid
,
"net"
);
oldfd
=
lxc_preserve_ns
(
handler
->
monitor_pid
,
"net"
);
if
(
oldfd
<
0
)
{
if
(
oldfd
<
0
)
SYSERROR
(
"Failed to preserve network namespace"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to preserve network namespace"
);
return
-
1
;
}
ret
=
setns
(
netnsfd
,
CLONE_NEWNET
);
ret
=
setns
(
netnsfd
,
CLONE_NEWNET
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
SYSERROR
(
"Failed to enter network namespace"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to enter network namespace"
);
close
(
oldfd
);
return
-
1
;
}
lxc_list_for_each
(
iterator
,
&
conf
->
network
)
{
lxc_list_for_each
(
iterator
,
&
conf
->
network
)
{
struct
lxc_netdev
*
netdev
=
iterator
->
elem
;
struct
lxc_netdev
*
netdev
=
iterator
->
elem
;
...
@@ -3597,42 +3412,34 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
...
@@ -3597,42 +3412,34 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
* namespace.
* namespace.
*/
*/
if
(
!
if_indextoname
(
netdev
->
ifindex
,
ifname
))
{
if
(
!
if_indextoname
(
netdev
->
ifindex
,
ifname
))
{
WARN
(
"No interface corresponding to ifindex %d"
,
WARN
(
"No interface corresponding to ifindex %d"
,
netdev
->
ifindex
);
netdev
->
ifindex
);
continue
;
continue
;
}
}
ret
=
lxc_netdev_move_by_index_fd
(
netdev
->
ifindex
,
oldfd
,
netdev
->
link
);
ret
=
lxc_netdev_move_by_index_fd
(
netdev
->
ifindex
,
oldfd
,
netdev
->
link
);
if
(
ret
<
0
)
if
(
ret
<
0
)
WARN
(
"Error moving network device
\"
%s
\"
back to "
WARN
(
"Error moving network device
\"
%s
\"
back to network namespace"
,
ifname
);
"network namespace"
,
ifname
);
else
else
TRACE
(
"Moved network device
\"
%s
\"
back to network "
TRACE
(
"Moved network device
\"
%s
\"
back to network namespace"
,
ifname
);
"namespace"
,
ifname
);
}
}
ret
=
setns
(
oldfd
,
CLONE_NEWNET
);
ret
=
setns
(
oldfd
,
CLONE_NEWNET
);
close
(
oldfd
);
if
(
ret
<
0
)
if
(
ret
<
0
)
{
return
log_error_errno
(
-
1
,
errno
,
"Failed to enter network namespace"
);
SYSERROR
(
"Failed to enter network namespace"
);
return
-
1
;
}
return
0
;
return
0
;
}
}
static
int
setup_hw_addr
(
char
*
hwaddr
,
const
char
*
ifname
)
static
int
setup_hw_addr
(
char
*
hwaddr
,
const
char
*
ifname
)
{
{
__do_close
int
fd
=
-
EBADF
;
struct
sockaddr
sockaddr
;
struct
sockaddr
sockaddr
;
struct
ifreq
ifr
;
struct
ifreq
ifr
;
int
ret
,
fd
;
int
ret
;
ret
=
lxc_convert_mac
(
hwaddr
,
&
sockaddr
);
ret
=
lxc_convert_mac
(
hwaddr
,
&
sockaddr
);
if
(
ret
)
{
if
(
ret
)
errno
=
-
ret
;
return
log_error_errno
(
-
1
,
-
ret
,
"Mac address
\"
%s
\"
conversion failed"
,
hwaddr
);
SYSERROR
(
"Mac address
\"
%s
\"
conversion failed"
,
hwaddr
);
return
-
1
;
}
memcpy
(
ifr
.
ifr_name
,
ifname
,
IFNAMSIZ
);
memcpy
(
ifr
.
ifr_name
,
ifname
,
IFNAMSIZ
);
ifr
.
ifr_name
[
IFNAMSIZ
-
1
]
=
'\0'
;
ifr
.
ifr_name
[
IFNAMSIZ
-
1
]
=
'\0'
;
...
@@ -3646,10 +3453,7 @@ static int setup_hw_addr(char *hwaddr, const char *ifname)
...
@@ -3646,10 +3453,7 @@ static int setup_hw_addr(char *hwaddr, const char *ifname)
if
(
ret
)
if
(
ret
)
SYSERROR
(
"Failed to perform ioctl"
);
SYSERROR
(
"Failed to perform ioctl"
);
close
(
fd
);
DEBUG
(
"Mac address
\"
%s
\"
on
\"
%s
\"
has been setup"
,
hwaddr
,
ifr
.
ifr_name
);
DEBUG
(
"Mac address
\"
%s
\"
on
\"
%s
\"
has been setup"
,
hwaddr
,
ifr
.
ifr_name
);
return
ret
;
return
ret
;
}
}
...
@@ -3664,12 +3468,8 @@ static int setup_ipv4_addr(struct lxc_list *ip, int ifindex)
...
@@ -3664,12 +3468,8 @@ static int setup_ipv4_addr(struct lxc_list *ip, int ifindex)
err
=
lxc_ipv4_addr_add
(
ifindex
,
&
inetdev
->
addr
,
err
=
lxc_ipv4_addr_add
(
ifindex
,
&
inetdev
->
addr
,
&
inetdev
->
bcast
,
inetdev
->
prefix
);
&
inetdev
->
bcast
,
inetdev
->
prefix
);
if
(
err
)
{
if
(
err
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to setup ipv4 address for network device with ifindex %d"
,
ifindex
);
SYSERROR
(
"Failed to setup ipv4 address for network device "
"with ifindex %d"
,
ifindex
);
return
-
1
;
}
}
}
return
0
;
return
0
;
...
@@ -3686,12 +3486,8 @@ static int setup_ipv6_addr(struct lxc_list *ip, int ifindex)
...
@@ -3686,12 +3486,8 @@ static int setup_ipv6_addr(struct lxc_list *ip, int ifindex)
err
=
lxc_ipv6_addr_add
(
ifindex
,
&
inet6dev
->
addr
,
err
=
lxc_ipv6_addr_add
(
ifindex
,
&
inet6dev
->
addr
,
&
inet6dev
->
mcast
,
&
inet6dev
->
acast
,
&
inet6dev
->
mcast
,
&
inet6dev
->
acast
,
inet6dev
->
prefix
);
inet6dev
->
prefix
);
if
(
err
)
{
if
(
err
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to setup ipv6 address for network device with ifindex %d"
,
ifindex
);
SYSERROR
(
"Failed to setup ipv6 address for network device "
"with ifindex %d"
,
ifindex
);
return
-
1
;
}
}
}
return
0
;
return
0
;
...
@@ -3705,77 +3501,47 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
...
@@ -3705,77 +3501,47 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
/* empty network namespace */
/* empty network namespace */
if
(
!
netdev
->
ifindex
&&
netdev
->
flags
&
IFF_UP
)
{
if
(
!
netdev
->
ifindex
&&
netdev
->
flags
&
IFF_UP
)
{
err
=
lxc_netdev_up
(
"lo"
);
err
=
lxc_netdev_up
(
"lo"
);
if
(
err
)
{
if
(
err
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to set the loopback network device up"
);
SYSERROR
(
"Failed to set the loopback network device up"
);
return
-
1
;
}
}
}
/* set a mac address */
/* set a mac address */
if
(
netdev
->
hwaddr
)
{
if
(
netdev
->
hwaddr
&&
setup_hw_addr
(
netdev
->
hwaddr
,
netdev
->
name
))
if
(
setup_hw_addr
(
netdev
->
hwaddr
,
netdev
->
name
))
{
return
log_error_errno
(
-
1
,
errno
,
"Failed to setup hw address for network device
\"
%s
\"
"
,
netdev
->
name
);
ERROR
(
"Failed to setup hw address for network device
\"
%s
\"
"
,
netdev
->
name
);
return
-
1
;
}
}
/* setup ipv4 addresses on the interface */
/* setup ipv4 addresses on the interface */
if
(
setup_ipv4_addr
(
&
netdev
->
ipv4
,
netdev
->
ifindex
))
{
if
(
setup_ipv4_addr
(
&
netdev
->
ipv4
,
netdev
->
ifindex
))
ERROR
(
"Failed to setup ip addresses for network device
\"
%s
\"
"
,
return
log_error_errno
(
-
1
,
errno
,
"Failed to setup ip addresses for network device
\"
%s
\"
"
,
netdev
->
name
);
netdev
->
name
);
return
-
1
;
}
/* setup ipv6 addresses on the interface */
/* setup ipv6 addresses on the interface */
if
(
setup_ipv6_addr
(
&
netdev
->
ipv6
,
netdev
->
ifindex
))
{
if
(
setup_ipv6_addr
(
&
netdev
->
ipv6
,
netdev
->
ifindex
))
ERROR
(
"Failed to setup ipv6 addresses for network device
\"
%s
\"
"
,
return
log_error_errno
(
-
1
,
errno
,
"Failed to setup ipv6 addresses for network device
\"
%s
\"
"
,
netdev
->
name
);
netdev
->
name
);
return
-
1
;
}
/* set the network device up */
/* set the network device up */
if
(
netdev
->
flags
&
IFF_UP
)
{
if
(
netdev
->
flags
&
IFF_UP
)
{
err
=
lxc_netdev_up
(
netdev
->
name
);
err
=
lxc_netdev_up
(
netdev
->
name
);
if
(
err
)
{
if
(
err
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to set network device
\"
%s
\"
up"
,
netdev
->
name
);
SYSERROR
(
"Failed to set network device
\"
%s
\"
up"
,
netdev
->
name
);
return
-
1
;
}
/* the network is up, make the loopback up too */
/* the network is up, make the loopback up too */
err
=
lxc_netdev_up
(
"lo"
);
err
=
lxc_netdev_up
(
"lo"
);
if
(
err
)
{
if
(
err
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to set the loopback network device up"
);
SYSERROR
(
"Failed to set the loopback network device up"
);
return
-
1
;
}
}
}
/* setup ipv4 gateway on the interface */
/* setup ipv4 gateway on the interface */
if
(
netdev
->
ipv4_gateway
||
netdev
->
ipv4_gateway_dev
)
{
if
(
netdev
->
ipv4_gateway
||
netdev
->
ipv4_gateway_dev
)
{
if
(
!
(
netdev
->
flags
&
IFF_UP
))
{
if
(
!
(
netdev
->
flags
&
IFF_UP
))
ERROR
(
"Cannot add ipv4 gateway for network device "
return
log_error
(
-
1
,
"Cannot add ipv4 gateway for network device
\"
%s
\"
when not bringing up the interface"
,
netdev
->
name
);
"
\"
%s
\"
when not bringing up the interface"
,
netdev
->
name
);
return
-
1
;
}
if
(
lxc_list_empty
(
&
netdev
->
ipv4
))
{
if
(
lxc_list_empty
(
&
netdev
->
ipv4
))
ERROR
(
"Cannot add ipv4 gateway for network device "
return
log_error
(
-
1
,
"Cannot add ipv4 gateway for network device
\"
%s
\"
when not assigning an address"
,
netdev
->
name
);
"
\"
%s
\"
when not assigning an address"
,
netdev
->
name
);
return
-
1
;
}
/* Setup device route if ipv4_gateway_dev is enabled */
/* Setup device route if ipv4_gateway_dev is enabled */
if
(
netdev
->
ipv4_gateway_dev
)
{
if
(
netdev
->
ipv4_gateway_dev
)
{
err
=
lxc_ipv4_gateway_add
(
netdev
->
ifindex
,
NULL
);
err
=
lxc_ipv4_gateway_add
(
netdev
->
ifindex
,
NULL
);
if
(
err
<
0
)
{
if
(
err
<
0
)
SYSERROR
(
"Failed to setup ipv4 gateway to network device
\"
%s
\"
"
,
return
log_error_errno
(
-
1
,
-
err
,
"Failed to setup ipv4 gateway to network device
\"
%s
\"
"
,
netdev
->
name
);
netdev
->
name
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
else
{
}
else
{
/* Check the gateway address is valid */
/* Check the gateway address is valid */
if
(
!
inet_ntop
(
AF_INET
,
netdev
->
ipv4_gateway
,
bufinet4
,
sizeof
(
bufinet4
)))
if
(
!
inet_ntop
(
AF_INET
,
netdev
->
ipv4_gateway
,
bufinet4
,
sizeof
(
bufinet4
)))
...
@@ -3790,46 +3556,29 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
...
@@ -3790,46 +3556,29 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
* gateway address first, and then try again.
* gateway address first, and then try again.
*/
*/
err
=
lxc_ipv4_dest_add
(
netdev
->
ifindex
,
netdev
->
ipv4_gateway
,
32
);
err
=
lxc_ipv4_dest_add
(
netdev
->
ifindex
,
netdev
->
ipv4_gateway
,
32
);
if
(
err
<
0
)
{
if
(
err
<
0
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to add ipv4 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet4
,
netdev
->
name
);
SYSERROR
(
"Failed to add ipv4 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet4
,
netdev
->
name
);
return
-
1
;
}
err
=
lxc_ipv4_gateway_add
(
netdev
->
ifindex
,
netdev
->
ipv4_gateway
);
err
=
lxc_ipv4_gateway_add
(
netdev
->
ifindex
,
netdev
->
ipv4_gateway
);
if
(
err
<
0
)
{
if
(
err
<
0
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to setup ipv4 gateway
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet4
,
netdev
->
name
);
SYSERROR
(
"Failed to setup ipv4 gateway
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet4
,
netdev
->
name
);
return
-
1
;
}
}
}
}
}
}
}
/* setup ipv6 gateway on the interface */
/* setup ipv6 gateway on the interface */
if
(
netdev
->
ipv6_gateway
||
netdev
->
ipv6_gateway_dev
)
{
if
(
netdev
->
ipv6_gateway
||
netdev
->
ipv6_gateway_dev
)
{
if
(
!
(
netdev
->
flags
&
IFF_UP
))
{
if
(
!
(
netdev
->
flags
&
IFF_UP
))
ERROR
(
"Cannot add ipv6 gateway for network device
\"
%s
\"
when not bringing up the interface"
,
return
log_error
(
-
1
,
"Cannot add ipv6 gateway for network device
\"
%s
\"
when not bringing up the interface"
,
netdev
->
name
);
netdev
->
name
);
return
-
1
;
}
if
(
lxc_list_empty
(
&
netdev
->
ipv6
)
&&
!
IN6_IS_ADDR_LINKLOCAL
(
netdev
->
ipv6_gateway
))
{
if
(
lxc_list_empty
(
&
netdev
->
ipv6
)
&&
!
IN6_IS_ADDR_LINKLOCAL
(
netdev
->
ipv6_gateway
))
ERROR
(
"Cannot add ipv6 gateway for network device
\"
%s
\"
when not assigning an address"
,
return
log_error
(
-
1
,
"Cannot add ipv6 gateway for network device
\"
%s
\"
when not assigning an address"
,
netdev
->
name
);
netdev
->
name
);
return
-
1
;
}
/* Setup device route if ipv6_gateway_dev is enabled */
/* Setup device route if ipv6_gateway_dev is enabled */
if
(
netdev
->
ipv6_gateway_dev
)
{
if
(
netdev
->
ipv6_gateway_dev
)
{
err
=
lxc_ipv6_gateway_add
(
netdev
->
ifindex
,
NULL
);
err
=
lxc_ipv6_gateway_add
(
netdev
->
ifindex
,
NULL
);
if
(
err
<
0
)
{
if
(
err
<
0
)
SYSERROR
(
"Failed to setup ipv6 gateway to network device
\"
%s
\"
"
,
return
log_error_errno
(
-
1
,
-
err
,
"Failed to setup ipv6 gateway to network device
\"
%s
\"
"
,
netdev
->
name
);
netdev
->
name
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
else
{
}
else
{
/* Check the gateway address is valid */
/* Check the gateway address is valid */
if
(
!
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
bufinet6
,
sizeof
(
bufinet6
)))
if
(
!
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
bufinet6
,
sizeof
(
bufinet6
)))
...
@@ -3844,20 +3593,12 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
...
@@ -3844,20 +3593,12 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
* gateway address first, and then try again.
* gateway address first, and then try again.
*/
*/
err
=
lxc_ipv6_dest_add
(
netdev
->
ifindex
,
netdev
->
ipv6_gateway
,
128
);
err
=
lxc_ipv6_dest_add
(
netdev
->
ifindex
,
netdev
->
ipv6_gateway
,
128
);
if
(
err
<
0
)
{
if
(
err
<
0
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
errno
,
"Failed to add ipv6 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet6
,
netdev
->
name
);
SYSERROR
(
"Failed to add ipv6 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet6
,
netdev
->
name
);
return
-
1
;
}
err
=
lxc_ipv6_gateway_add
(
netdev
->
ifindex
,
netdev
->
ipv6_gateway
);
err
=
lxc_ipv6_gateway_add
(
netdev
->
ifindex
,
netdev
->
ipv6_gateway
);
if
(
err
<
0
)
{
if
(
err
<
0
)
errno
=
-
err
;
return
log_error_errno
(
-
1
,
-
err
,
"Failed to setup ipv6 gateway
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet6
,
netdev
->
name
);
SYSERROR
(
"Failed to setup ipv6 gateway
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet6
,
netdev
->
name
);
return
-
1
;
}
}
}
}
}
}
}
...
@@ -3879,10 +3620,8 @@ int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
...
@@ -3879,10 +3620,8 @@ int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
ret
=
netdev_ns_conf
[
netdev
->
type
](
netdev
);
ret
=
netdev_ns_conf
[
netdev
->
type
](
netdev
);
if
(
!
ret
)
if
(
!
ret
)
ret
=
lxc_network_setup_in_child_namespaces_common
(
netdev
);
ret
=
lxc_network_setup_in_child_namespaces_common
(
netdev
);
if
(
ret
)
{
if
(
ret
)
ERROR
(
"Failed to setup netdev"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to setup netdev"
);
return
-
1
;
}
}
}
if
(
!
lxc_list_empty
(
network
))
if
(
!
lxc_list_empty
(
network
))
...
...
src/lxc/nl.c
View file @
d42ec829
...
@@ -319,11 +319,9 @@ errclose:
...
@@ -319,11 +319,9 @@ errclose:
return
err
;
return
err
;
}
}
extern
int
netlink_close
(
struct
nl_handler
*
handler
)
extern
void
netlink_close
(
struct
nl_handler
*
handler
)
{
{
close
(
handler
->
fd
);
close_prot_errno_disarm
(
handler
->
fd
);
handler
->
fd
=
-
1
;
return
0
;
}
}
int
addattr
(
struct
nlmsghdr
*
n
,
size_t
maxlen
,
int
type
,
const
void
*
data
,
int
addattr
(
struct
nlmsghdr
*
n
,
size_t
maxlen
,
int
type
,
const
void
*
data
,
...
...
src/lxc/nl.h
View file @
d42ec829
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
#include <stdio.h>
#include <stdio.h>
#include "memory_utils.h"
/*
/*
* Use this as a good size to allocate generic netlink messages
* Use this as a good size to allocate generic netlink messages
*/
*/
...
@@ -64,10 +66,9 @@ int netlink_open(struct nl_handler *handler, int protocol);
...
@@ -64,10 +66,9 @@ int netlink_open(struct nl_handler *handler, int protocol);
* the handler is no longer valid
* the handler is no longer valid
*
*
* @handler: a handler to the netlink socket
* @handler: a handler to the netlink socket
*
* Returns 0 on success, < 0 otherwise
*/
*/
int
netlink_close
(
struct
nl_handler
*
handler
);
void
netlink_close
(
struct
nl_handler
*
handler
);
define_cleanup_function
(
struct
nl_handler
*
,
netlink_close
);
/*
/*
* netlink_rcv : receive a netlink message from the kernel.
* netlink_rcv : receive a netlink message from the kernel.
...
@@ -231,6 +232,7 @@ void *nlmsg_reserve(struct nlmsg *nlmsg, size_t len);
...
@@ -231,6 +232,7 @@ void *nlmsg_reserve(struct nlmsg *nlmsg, size_t len);
* @nlmsg: the netlink message to be freed
* @nlmsg: the netlink message to be freed
*/
*/
void
nlmsg_free
(
struct
nlmsg
*
nlmsg
);
void
nlmsg_free
(
struct
nlmsg
*
nlmsg
);
define_cleanup_function
(
struct
nlmsg
*
,
nlmsg_free
);
/*
/*
* nlmsg_data : returns a pointer to the data contained in the netlink message
* nlmsg_data : returns a pointer to the data contained in the netlink message
...
...
src/lxc/rtnl.c
View file @
d42ec829
...
@@ -21,9 +21,9 @@ extern int rtnetlink_open(struct rtnl_handler *handler)
...
@@ -21,9 +21,9 @@ extern int rtnetlink_open(struct rtnl_handler *handler)
return
netlink_open
(
&
handler
->
nlh
,
NETLINK_ROUTE
);
return
netlink_open
(
&
handler
->
nlh
,
NETLINK_ROUTE
);
}
}
extern
int
rtnetlink_close
(
struct
rtnl_handler
*
handler
)
extern
void
rtnetlink_close
(
struct
rtnl_handler
*
handler
)
{
{
return
netlink_close
(
&
handler
->
nlh
);
netlink_close
(
&
handler
->
nlh
);
}
}
#pragma GCC diagnostic push
#pragma GCC diagnostic push
...
...
src/lxc/rtnl.h
View file @
d42ec829
...
@@ -44,10 +44,8 @@ extern int rtnetlink_open(struct rtnl_handler *handler);
...
@@ -44,10 +44,8 @@ extern int rtnetlink_open(struct rtnl_handler *handler);
* genetlink_close : close a route netlink socket
* genetlink_close : close a route netlink socket
*
*
* @handler: the handler of the socket to be closed
* @handler: the handler of the socket to be closed
*
* Returns 0 on success, < 0 otherwise
*/
*/
extern
int
rtnetlink_close
(
struct
rtnl_handler
*
handler
);
extern
void
rtnetlink_close
(
struct
rtnl_handler
*
handler
);
/*
/*
* rtnetlink_rcv : receive a route netlink socket, it is up
* rtnetlink_rcv : receive a route netlink socket, it is up
...
...
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