2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <arpa/inet.h>
34 #include <linux/netlink.h>
35 #include <linux/rtnetlink.h>
36 #include <linux/sockios.h>
37 #include <net/ethernet.h>
39 #include <net/if_arp.h>
40 #include <netinet/in.h>
41 #include <sys/inotify.h>
42 #include <sys/ioctl.h>
43 #include <sys/param.h>
44 #include <sys/socket.h>
46 #include <sys/types.h>
59 #include <../include/ifaddrs.h>
63 #include "include/strlcpy.h"
67 #define IFLA_LINKMODE 17
71 #define IFLA_LINKINFO 18
74 #ifndef IFLA_NET_NS_PID
75 #define IFLA_NET_NS_PID 19
78 #ifndef IFLA_INFO_KIND
79 #define IFLA_INFO_KIND 1
83 #define IFLA_VLAN_ID 1
86 #ifndef IFLA_INFO_DATA
87 #define IFLA_INFO_DATA 2
90 #ifndef VETH_INFO_PEER
91 #define VETH_INFO_PEER 1
94 #ifndef IFLA_MACVLAN_MODE
95 #define IFLA_MACVLAN_MODE 1
98 lxc_log_define(network
, lxc
);
100 typedef int (*instantiate_cb
)(struct lxc_handler
*, struct lxc_netdev
*);
102 static int instantiate_veth(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
104 int bridge_index
, err
;
106 char veth1buf
[IFNAMSIZ
], veth2buf
[IFNAMSIZ
];
107 unsigned int mtu
= 0;
109 if (netdev
->priv
.veth_attr
.pair
[0] != '\0') {
110 veth1
= netdev
->priv
.veth_attr
.pair
;
111 if (handler
->conf
->reboot
)
112 lxc_netdev_delete_by_name(veth1
);
114 err
= snprintf(veth1buf
, sizeof(veth1buf
), "vethXXXXXX");
115 if (err
< 0 || (size_t)err
>= sizeof(veth1buf
))
118 veth1
= lxc_mkifname(veth1buf
);
122 /* store away for deconf */
123 memcpy(netdev
->priv
.veth_attr
.veth1
, veth1
, IFNAMSIZ
);
126 err
= snprintf(veth2buf
, sizeof(veth2buf
), "vethXXXXXX");
127 if (err
< 0 || (size_t)err
>= sizeof(veth2buf
))
130 veth2
= lxc_mkifname(veth2buf
);
134 err
= lxc_veth_create(veth1
, veth2
);
137 SYSERROR("Failed to create veth pair \"%s\" and \"%s\"", veth1
, veth2
);
141 /* changing the high byte of the mac address to 0xfe, the bridge interface
142 * will always keep the host's mac address and not take the mac address
144 err
= setup_private_host_hw_addr(veth1
);
147 SYSERROR("Failed to change mac address of host interface \"%s\"", veth1
);
151 /* Retrieve ifindex of the host's veth device. */
152 netdev
->priv
.veth_attr
.ifindex
= if_nametoindex(veth1
);
153 if (!netdev
->priv
.veth_attr
.ifindex
) {
154 ERROR("Failed to retrieve ifindex for \"%s\"", veth1
);
158 /* Note that we're retrieving the container's ifindex in the host's
159 * network namespace because we need it to move the device from the
160 * host's network namespace to the container's network namespace later
163 netdev
->ifindex
= if_nametoindex(veth2
);
164 if (!netdev
->ifindex
) {
165 ERROR("Failed to retrieve ifindex for \"%s\"", veth2
);
170 if (lxc_safe_uint(netdev
->mtu
, &mtu
) < 0)
171 WARN("Failed to parse mtu");
173 INFO("Retrieved mtu %d", mtu
);
174 } else if (netdev
->link
[0] != '\0') {
175 bridge_index
= if_nametoindex(netdev
->link
);
177 mtu
= netdev_get_mtu(bridge_index
);
178 INFO("Retrieved mtu %d from %s", mtu
, netdev
->link
);
180 mtu
= netdev_get_mtu(netdev
->ifindex
);
181 INFO("Retrieved mtu %d from %s", mtu
, veth2
);
186 err
= lxc_netdev_set_mtu(veth1
, mtu
);
188 err
= lxc_netdev_set_mtu(veth2
, mtu
);
192 SYSERROR("Failed to set mtu \"%d\" for veth pair \"%s\" "
193 "and \"%s\"", mtu
, veth1
, veth2
);
198 if (netdev
->link
[0] != '\0') {
199 err
= lxc_bridge_attach(netdev
->link
, veth1
);
202 SYSERROR("Failed to attach \"%s\" to bridge \"%s\"",
203 veth1
, netdev
->link
);
206 INFO("Attached \"%s\" to bridge \"%s\"", veth1
, netdev
->link
);
209 err
= lxc_netdev_up(veth1
);
212 SYSERROR("Failed to set \"%s\" up", veth1
);
216 if (netdev
->upscript
) {
224 err
= run_script_argv(handler
->name
,
225 handler
->conf
->hooks_version
, "net",
226 netdev
->upscript
, "up", argv
);
231 DEBUG("Instantiated veth \"%s/%s\", index is \"%d\"", veth1
, veth2
,
237 if (netdev
->ifindex
!= 0)
238 lxc_netdev_delete_by_name(veth1
);
242 static int instantiate_macvlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
244 char peerbuf
[IFNAMSIZ
], *peer
;
247 if (netdev
->link
[0] == '\0') {
248 ERROR("No link for macvlan network device specified");
252 err
= snprintf(peerbuf
, sizeof(peerbuf
), "mcXXXXXX");
253 if (err
< 0 || (size_t)err
>= sizeof(peerbuf
))
256 peer
= lxc_mkifname(peerbuf
);
260 err
= lxc_macvlan_create(netdev
->link
, peer
,
261 netdev
->priv
.macvlan_attr
.mode
);
264 SYSERROR("Failed to create macvlan interface \"%s\" on \"%s\"",
269 netdev
->ifindex
= if_nametoindex(peer
);
270 if (!netdev
->ifindex
) {
271 ERROR("Failed to retrieve ifindex for \"%s\"", peer
);
275 if (netdev
->upscript
) {
282 err
= run_script_argv(handler
->name
,
283 handler
->conf
->hooks_version
, "net",
284 netdev
->upscript
, "up", argv
);
289 DEBUG("Instantiated macvlan \"%s\" with ifindex is %d and mode %d",
290 peer
, netdev
->ifindex
, netdev
->priv
.macvlan_attr
.mode
);
295 lxc_netdev_delete_by_name(peer
);
299 static int instantiate_vlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
303 static uint16_t vlan_cntr
= 0;
304 unsigned int mtu
= 0;
306 if (netdev
->link
[0] == '\0') {
307 ERROR("No link for vlan network device specified");
311 err
= snprintf(peer
, sizeof(peer
), "vlan%d-%d", netdev
->priv
.vlan_attr
.vid
, vlan_cntr
++);
312 if (err
< 0 || (size_t)err
>= sizeof(peer
))
315 err
= lxc_vlan_create(netdev
->link
, peer
, netdev
->priv
.vlan_attr
.vid
);
318 SYSERROR("Failed to create vlan interface \"%s\" on \"%s\"",
323 netdev
->ifindex
= if_nametoindex(peer
);
324 if (!netdev
->ifindex
) {
325 ERROR("Failed to retrieve ifindex for \"%s\"", peer
);
326 lxc_netdev_delete_by_name(peer
);
330 DEBUG("Instantiated vlan \"%s\" with ifindex is \"%d\" (vlan1000)",
331 peer
, netdev
->ifindex
);
333 if (lxc_safe_uint(netdev
->mtu
, &mtu
) < 0) {
334 ERROR("Failed to retrieve mtu from \"%d\"/\"%s\".",
336 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)");
340 err
= lxc_netdev_set_mtu(peer
, mtu
);
343 SYSERROR("Failed to set mtu \"%s\" for \"%s\"",
345 lxc_netdev_delete_by_name(peer
);
353 static int instantiate_phys(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
362 if (netdev
->link
[0] == '\0') {
363 ERROR("No link for physical interface specified");
367 /* Note that we're retrieving the container's ifindex in the host's
368 * network namespace because we need it to move the device from the
369 * host's network namespace to the container's network namespace later
371 * Note that netdev->link will contain the name of the physical network
372 * device in the host's namespace.
374 netdev
->ifindex
= if_nametoindex(netdev
->link
);
375 if (!netdev
->ifindex
) {
376 ERROR("Failed to retrieve ifindex for \"%s\"", netdev
->link
);
380 /* Store the ifindex of the host's network device in the host's
383 netdev
->priv
.phys_attr
.ifindex
= netdev
->ifindex
;
385 if (!netdev
->upscript
)
388 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
389 "net", netdev
->upscript
, "up", argv
);
396 static int instantiate_empty(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
405 if (!netdev
->upscript
)
408 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
409 "net", netdev
->upscript
, "up", argv
);
416 static int instantiate_none(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
422 static instantiate_cb netdev_conf
[LXC_NET_MAXCONFTYPE
+ 1] = {
423 [LXC_NET_VETH
] = instantiate_veth
,
424 [LXC_NET_MACVLAN
] = instantiate_macvlan
,
425 [LXC_NET_VLAN
] = instantiate_vlan
,
426 [LXC_NET_PHYS
] = instantiate_phys
,
427 [LXC_NET_EMPTY
] = instantiate_empty
,
428 [LXC_NET_NONE
] = instantiate_none
,
431 static int shutdown_veth(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
441 if (!netdev
->downscript
)
444 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
445 argv
[2] = netdev
->priv
.veth_attr
.pair
;
447 argv
[2] = netdev
->priv
.veth_attr
.veth1
;
449 ret
= run_script_argv(handler
->name
,
450 handler
->conf
->hooks_version
, "net",
451 netdev
->downscript
, "down", argv
);
458 static int shutdown_macvlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
467 if (!netdev
->downscript
)
470 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
471 "net", netdev
->downscript
, "down", argv
);
478 static int shutdown_vlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
483 static int shutdown_phys(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
492 if (!netdev
->downscript
)
495 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
496 "net", netdev
->downscript
, "down", argv
);
503 static int shutdown_empty(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
511 if (!netdev
->downscript
)
514 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
515 "net", netdev
->downscript
, "down", argv
);
522 static int shutdown_none(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
527 static instantiate_cb netdev_deconf
[LXC_NET_MAXCONFTYPE
+ 1] = {
528 [LXC_NET_VETH
] = shutdown_veth
,
529 [LXC_NET_MACVLAN
] = shutdown_macvlan
,
530 [LXC_NET_VLAN
] = shutdown_vlan
,
531 [LXC_NET_PHYS
] = shutdown_phys
,
532 [LXC_NET_EMPTY
] = shutdown_empty
,
533 [LXC_NET_NONE
] = shutdown_none
,
536 int lxc_netdev_move_by_index(int ifindex
, pid_t pid
, const char *ifname
)
539 struct nl_handler nlh
;
540 struct ifinfomsg
*ifi
;
541 struct nlmsg
*nlmsg
= NULL
;
543 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
548 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
552 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
553 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
555 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
558 ifi
->ifi_family
= AF_UNSPEC
;
559 ifi
->ifi_index
= ifindex
;
561 if (nla_put_u32(nlmsg
, IFLA_NET_NS_PID
, pid
))
564 if (ifname
!= NULL
) {
565 if (nla_put_string(nlmsg
, IFLA_IFNAME
, ifname
))
569 err
= netlink_transaction(&nlh
, nlmsg
, nlmsg
);
576 /* If we are asked to move a wireless interface, then we must actually move its
577 * phyN device. Detect that condition and return the physname here. The physname
578 * will be passed to lxc_netdev_move_wlan() which will free it when done.
580 #define PHYSNAME "/sys/class/net/%s/phy80211/name"
581 static char *is_wlan(const char *ifname
)
588 char *physname
= NULL
;
590 len
= strlen(ifname
) + strlen(PHYSNAME
) - 1;
591 path
= alloca(len
+ 1);
592 ret
= snprintf(path
, len
, PHYSNAME
, ifname
);
593 if (ret
< 0 || (size_t)ret
>= len
)
596 f
= fopen(path
, "r");
600 /* Feh - sb.st_size is always 4096. */
601 fseek(f
, 0, SEEK_END
);
603 fseek(f
, 0, SEEK_SET
);
609 physname
= malloc(physlen
+ 1);
615 memset(physname
, 0, physlen
+ 1);
616 ret
= fread(physname
, 1, physlen
, f
);
621 for (i
= 0; i
< physlen
; i
++) {
622 if (physname
[i
] == '\n')
625 if (physname
[i
] == '\0')
636 static int lxc_netdev_rename_by_name_in_netns(pid_t pid
, const char *old
,
646 return wait_for_pid(fpid
);
648 if (!switch_to_ns(pid
, "net"))
651 _exit(lxc_netdev_rename_by_name(old
, new));
654 static int lxc_netdev_move_wlan(char *physname
, const char *ifname
, pid_t pid
,
661 /* Move phyN into the container. TODO - do this using netlink.
662 * However, IIUC this involves a bit more complicated work to talk to
663 * the 80211 module, so for now just call out to iw.
665 cmd
= on_path("iw", NULL
);
676 sprintf(pidstr
, "%d", pid
);
677 execlp("iw", "iw", "phy", physname
, "set", "netns", pidstr
,
682 if (wait_for_pid(fpid
))
687 err
= lxc_netdev_rename_by_name_in_netns(pid
, ifname
, newname
);
694 int lxc_netdev_move_by_name(const char *ifname
, pid_t pid
, const char* newname
)
702 index
= if_nametoindex(ifname
);
706 physname
= is_wlan(ifname
);
708 return lxc_netdev_move_wlan(physname
, ifname
, pid
, newname
);
710 return lxc_netdev_move_by_index(index
, pid
, newname
);
713 int lxc_netdev_delete_by_index(int ifindex
)
716 struct ifinfomsg
*ifi
;
717 struct nl_handler nlh
;
718 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
720 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
725 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
729 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
733 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_ACK
| NLM_F_REQUEST
;
734 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_DELLINK
;
736 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
739 ifi
->ifi_family
= AF_UNSPEC
;
740 ifi
->ifi_index
= ifindex
;
742 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
750 int lxc_netdev_delete_by_name(const char *name
)
754 index
= if_nametoindex(name
);
758 return lxc_netdev_delete_by_index(index
);
761 int lxc_netdev_rename_by_index(int ifindex
, const char *newname
)
764 struct ifinfomsg
*ifi
;
765 struct nl_handler nlh
;
766 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
768 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
772 len
= strlen(newname
);
773 if (len
== 1 || len
>= IFNAMSIZ
)
777 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
781 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
785 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_ACK
| NLM_F_REQUEST
;
786 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
788 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
791 ifi
->ifi_family
= AF_UNSPEC
;
792 ifi
->ifi_index
= ifindex
;
794 if (nla_put_string(nlmsg
, IFLA_IFNAME
, newname
))
797 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
805 int lxc_netdev_rename_by_name(const char *oldname
, const char *newname
)
809 len
= strlen(oldname
);
810 if (len
== 1 || len
>= IFNAMSIZ
)
813 index
= if_nametoindex(oldname
);
817 return lxc_netdev_rename_by_index(index
, newname
);
820 int netdev_set_flag(const char *name
, int flag
)
823 struct ifinfomsg
*ifi
;
824 struct nl_handler nlh
;
825 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
827 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
833 if (len
== 1 || len
>= IFNAMSIZ
)
837 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
841 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
846 index
= if_nametoindex(name
);
850 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
851 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
853 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
858 ifi
->ifi_family
= AF_UNSPEC
;
859 ifi
->ifi_index
= index
;
860 ifi
->ifi_change
|= IFF_UP
;
861 ifi
->ifi_flags
|= flag
;
863 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
871 int netdev_get_flag(const char *name
, int *flag
)
874 struct ifinfomsg
*ifi
;
875 struct nl_handler nlh
;
876 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
881 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
887 if (len
== 1 || len
>= IFNAMSIZ
)
891 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
895 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
900 index
= if_nametoindex(name
);
904 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
;
905 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETLINK
;
907 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
912 ifi
->ifi_family
= AF_UNSPEC
;
913 ifi
->ifi_index
= index
;
915 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
919 ifi
= NLMSG_DATA(answer
->nlmsghdr
);
921 *flag
= ifi
->ifi_flags
;
930 * \brief Check a interface is up or not.
932 * \param name: name for the interface.
935 * 0 means interface is down.
936 * 1 means interface is up.
937 * Others means error happened, and ret-value is the error number.
939 int lxc_netdev_isup(const char *name
)
943 err
= netdev_get_flag(name
, &flag
);
953 int netdev_get_mtu(int ifindex
)
955 int answer_len
, err
, res
;
956 struct nl_handler nlh
;
957 struct ifinfomsg
*ifi
;
958 struct nlmsghdr
*msg
;
959 int readmore
= 0, recv_len
= 0;
960 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
962 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
967 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
971 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
975 /* Save the answer buffer length, since it will be overwritten
976 * on the first receive (and we might need to receive more than
979 answer_len
= answer
->nlmsghdr
->nlmsg_len
;
981 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_DUMP
;
982 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETLINK
;
984 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
987 ifi
->ifi_family
= AF_UNSPEC
;
989 /* Send the request for addresses, which returns all addresses
990 * on all interfaces. */
991 err
= netlink_send(&nlh
, nlmsg
);
996 /* Restore the answer buffer length, it might have been
997 * overwritten by a previous receive.
999 answer
->nlmsghdr
->nlmsg_len
= answer_len
;
1001 /* Get the (next) batch of reply messages */
1002 err
= netlink_rcv(&nlh
, answer
);
1008 /* Satisfy the typing for the netlink macros */
1009 msg
= answer
->nlmsghdr
;
1011 while (NLMSG_OK(msg
, recv_len
)) {
1013 /* Stop reading if we see an error message */
1014 if (msg
->nlmsg_type
== NLMSG_ERROR
) {
1015 struct nlmsgerr
*errmsg
=
1016 (struct nlmsgerr
*)NLMSG_DATA(msg
);
1017 err
= errmsg
->error
;
1021 /* Stop reading if we see a NLMSG_DONE message */
1022 if (msg
->nlmsg_type
== NLMSG_DONE
) {
1027 ifi
= NLMSG_DATA(msg
);
1028 if (ifi
->ifi_index
== ifindex
) {
1029 struct rtattr
*rta
= IFLA_RTA(ifi
);
1031 msg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
1033 while (RTA_OK(rta
, attr_len
)) {
1034 /* Found a local address for the
1035 * requested interface, return it.
1037 if (rta
->rta_type
== IFLA_MTU
) {
1038 memcpy(&res
, RTA_DATA(rta
),
1043 rta
= RTA_NEXT(rta
, attr_len
);
1047 /* Keep reading more data from the socket if the last
1048 * message had the NLF_F_MULTI flag set.
1050 readmore
= (msg
->nlmsg_flags
& NLM_F_MULTI
);
1052 /* Look at the next message received in this buffer. */
1053 msg
= NLMSG_NEXT(msg
, recv_len
);
1057 /* If we end up here, we didn't find any result, so signal an error. */
1061 netlink_close(&nlh
);
1067 int lxc_netdev_set_mtu(const char *name
, int mtu
)
1069 int err
, index
, len
;
1070 struct ifinfomsg
*ifi
;
1071 struct nl_handler nlh
;
1072 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1074 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1080 if (len
== 1 || len
>= IFNAMSIZ
)
1084 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1088 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1093 index
= if_nametoindex(name
);
1097 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1098 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1100 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1105 ifi
->ifi_family
= AF_UNSPEC
;
1106 ifi
->ifi_index
= index
;
1108 if (nla_put_u32(nlmsg
, IFLA_MTU
, mtu
))
1111 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1113 netlink_close(&nlh
);
1119 int lxc_netdev_up(const char *name
)
1121 return netdev_set_flag(name
, IFF_UP
);
1124 int lxc_netdev_down(const char *name
)
1126 return netdev_set_flag(name
, 0);
1129 int lxc_veth_create(const char *name1
, const char *name2
)
1132 struct ifinfomsg
*ifi
;
1133 struct nl_handler nlh
;
1134 struct rtattr
*nest1
, *nest2
, *nest3
;
1135 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1137 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1142 len
= strlen(name1
);
1143 if (len
== 1 || len
>= IFNAMSIZ
)
1146 len
= strlen(name2
);
1147 if (len
== 1 || len
>= IFNAMSIZ
)
1151 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1155 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1159 nlmsg
->nlmsghdr
->nlmsg_flags
=
1160 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1161 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1163 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1166 ifi
->ifi_family
= AF_UNSPEC
;
1169 nest1
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1173 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "veth"))
1176 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1180 nest3
= nla_begin_nested(nlmsg
, VETH_INFO_PEER
);
1184 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1190 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name2
))
1193 nla_end_nested(nlmsg
, nest3
);
1194 nla_end_nested(nlmsg
, nest2
);
1195 nla_end_nested(nlmsg
, nest1
);
1197 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name1
))
1200 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1202 netlink_close(&nlh
);
1208 /* TODO: merge with lxc_macvlan_create */
1209 int lxc_vlan_create(const char *master
, const char *name
, unsigned short vlanid
)
1211 int err
, len
, lindex
;
1212 struct ifinfomsg
*ifi
;
1213 struct nl_handler nlh
;
1214 struct rtattr
*nest
, *nest2
;
1215 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1217 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1222 len
= strlen(master
);
1223 if (len
== 1 || len
>= IFNAMSIZ
)
1227 if (len
== 1 || len
>= IFNAMSIZ
)
1231 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1235 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1240 lindex
= if_nametoindex(master
);
1244 nlmsg
->nlmsghdr
->nlmsg_flags
=
1245 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1246 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1248 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1253 ifi
->ifi_family
= AF_UNSPEC
;
1255 nest
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1259 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "vlan"))
1262 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1266 if (nla_put_u16(nlmsg
, IFLA_VLAN_ID
, vlanid
))
1269 nla_end_nested(nlmsg
, nest2
);
1270 nla_end_nested(nlmsg
, nest
);
1272 if (nla_put_u32(nlmsg
, IFLA_LINK
, lindex
))
1275 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name
))
1278 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1284 netlink_close(&nlh
);
1288 int lxc_macvlan_create(const char *master
, const char *name
, int mode
)
1290 int err
, index
, len
;
1291 struct ifinfomsg
*ifi
;
1292 struct nl_handler nlh
;
1293 struct rtattr
*nest
, *nest2
;
1294 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1296 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1301 len
= strlen(master
);
1302 if (len
== 1 || len
>= IFNAMSIZ
)
1306 if (len
== 1 || len
>= IFNAMSIZ
)
1310 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1314 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1319 index
= if_nametoindex(master
);
1323 nlmsg
->nlmsghdr
->nlmsg_flags
=
1324 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1325 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1327 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1332 ifi
->ifi_family
= AF_UNSPEC
;
1334 nest
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1338 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "macvlan"))
1342 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1346 if (nla_put_u32(nlmsg
, IFLA_MACVLAN_MODE
, mode
))
1349 nla_end_nested(nlmsg
, nest2
);
1352 nla_end_nested(nlmsg
, nest
);
1354 if (nla_put_u32(nlmsg
, IFLA_LINK
, index
))
1357 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name
))
1360 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1362 netlink_close(&nlh
);
1368 static int proc_sys_net_write(const char *path
, const char *value
)
1373 fd
= open(path
, O_WRONLY
);
1377 if (lxc_write_nointr(fd
, value
, strlen(value
)) < 0)
1384 static int neigh_proxy_set(const char *ifname
, int family
, int flag
)
1387 char path
[MAXPATHLEN
];
1389 if (family
!= AF_INET
&& family
!= AF_INET6
)
1392 ret
= snprintf(path
, MAXPATHLEN
, "/proc/sys/net/%s/conf/%s/%s",
1393 family
== AF_INET
? "ipv4" : "ipv6", ifname
,
1394 family
== AF_INET
? "proxy_arp" : "proxy_ndp");
1395 if (ret
< 0 || (size_t)ret
>= MAXPATHLEN
)
1398 return proc_sys_net_write(path
, flag
? "1" : "0");
1401 int lxc_neigh_proxy_on(const char *name
, int family
)
1403 return neigh_proxy_set(name
, family
, 1);
1406 int lxc_neigh_proxy_off(const char *name
, int family
)
1408 return neigh_proxy_set(name
, family
, 0);
1411 int lxc_convert_mac(char *macaddr
, struct sockaddr
*sockaddr
)
1416 unsigned char *data
;
1418 sockaddr
->sa_family
= ARPHRD_ETHER
;
1419 data
= (unsigned char *)sockaddr
->sa_data
;
1421 while ((*macaddr
!= '\0') && (i
< ETH_ALEN
)) {
1425 else if (c
>= 'a' && c
<= 'f')
1427 else if (c
>= 'A' && c
<= 'F')
1436 else if (c
>= 'a' && c
<= 'f')
1437 val
|= c
- 'a' + 10;
1438 else if (c
>= 'A' && c
<= 'F')
1439 val
|= c
- 'A' + 10;
1440 else if (c
== ':' || c
== 0)
1446 *data
++ = (unsigned char)(val
& 0377);
1449 if (*macaddr
== ':')
1456 static int ip_addr_add(int family
, int ifindex
, void *addr
, void *bcast
,
1457 void *acast
, int prefix
)
1460 struct ifaddrmsg
*ifa
;
1461 struct nl_handler nlh
;
1462 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1464 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1465 : sizeof(struct in6_addr
);
1467 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1472 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1476 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1480 nlmsg
->nlmsghdr
->nlmsg_flags
=
1481 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1482 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWADDR
;
1484 ifa
= nlmsg_reserve(nlmsg
, sizeof(struct ifaddrmsg
));
1487 ifa
->ifa_prefixlen
= prefix
;
1488 ifa
->ifa_index
= ifindex
;
1489 ifa
->ifa_family
= family
;
1493 if (nla_put_buffer(nlmsg
, IFA_LOCAL
, addr
, addrlen
))
1496 if (nla_put_buffer(nlmsg
, IFA_ADDRESS
, addr
, addrlen
))
1499 if (nla_put_buffer(nlmsg
, IFA_BROADCAST
, bcast
, addrlen
))
1502 /* TODO: multicast, anycast with ipv6 */
1503 err
= -EPROTONOSUPPORT
;
1504 if (family
== AF_INET6
&&
1505 (memcmp(bcast
, &in6addr_any
, sizeof(in6addr_any
)) ||
1506 memcmp(acast
, &in6addr_any
, sizeof(in6addr_any
))))
1509 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1511 netlink_close(&nlh
);
1517 int lxc_ipv6_addr_add(int ifindex
, struct in6_addr
*addr
,
1518 struct in6_addr
*mcast
, struct in6_addr
*acast
,
1521 return ip_addr_add(AF_INET6
, ifindex
, addr
, mcast
, acast
, prefix
);
1524 int lxc_ipv4_addr_add(int ifindex
, struct in_addr
*addr
, struct in_addr
*bcast
,
1527 return ip_addr_add(AF_INET
, ifindex
, addr
, bcast
, NULL
, prefix
);
1530 /* Find an IFA_LOCAL (or IFA_ADDRESS if not IFA_LOCAL is present) address from
1531 * the given RTM_NEWADDR message. Allocates memory for the address and stores
1532 * that pointer in *res (so res should be an in_addr** or in6_addr**).
1534 static int ifa_get_local_ip(int family
, struct nlmsghdr
*msg
, void **res
)
1537 struct ifaddrmsg
*ifa
= NLMSG_DATA(msg
);
1538 struct rtattr
*rta
= IFA_RTA(ifa
);
1539 int attr_len
= NLMSG_PAYLOAD(msg
, sizeof(struct ifaddrmsg
));
1541 if (ifa
->ifa_family
!= family
)
1544 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1545 : sizeof(struct in6_addr
);
1547 /* Loop over the rtattr's in this message */
1548 while (RTA_OK(rta
, attr_len
)) {
1549 /* Found a local address for the requested interface,
1552 if (rta
->rta_type
== IFA_LOCAL
||
1553 rta
->rta_type
== IFA_ADDRESS
) {
1554 /* Sanity check. The family check above should make sure
1555 * the address length is correct, but check here just in
1558 if (RTA_PAYLOAD(rta
) != addrlen
)
1561 /* We might have found an IFA_ADDRESS before, which we
1562 * now overwrite with an IFA_LOCAL.
1565 *res
= malloc(addrlen
);
1570 memcpy(*res
, RTA_DATA(rta
), addrlen
);
1571 if (rta
->rta_type
== IFA_LOCAL
)
1574 rta
= RTA_NEXT(rta
, attr_len
);
1579 static int ip_addr_get(int family
, int ifindex
, void **res
)
1581 int answer_len
, err
;
1582 struct ifaddrmsg
*ifa
;
1583 struct nl_handler nlh
;
1584 struct nlmsghdr
*msg
;
1585 int readmore
= 0, recv_len
= 0;
1586 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1588 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1593 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1597 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1601 /* Save the answer buffer length, since it will be overwritten on the
1602 * first receive (and we might need to receive more than once).
1604 answer_len
= answer
->nlmsghdr
->nlmsg_len
;
1606 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ROOT
;
1607 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETADDR
;
1609 ifa
= nlmsg_reserve(nlmsg
, sizeof(struct ifaddrmsg
));
1612 ifa
->ifa_family
= family
;
1614 /* Send the request for addresses, which returns all addresses on all
1617 err
= netlink_send(&nlh
, nlmsg
);
1622 /* Restore the answer buffer length, it might have been
1623 * overwritten by a previous receive.
1625 answer
->nlmsghdr
->nlmsg_len
= answer_len
;
1627 /* Get the (next) batch of reply messages. */
1628 err
= netlink_rcv(&nlh
, answer
);
1635 /* Satisfy the typing for the netlink macros. */
1636 msg
= answer
->nlmsghdr
;
1638 while (NLMSG_OK(msg
, recv_len
)) {
1639 /* Stop reading if we see an error message. */
1640 if (msg
->nlmsg_type
== NLMSG_ERROR
) {
1641 struct nlmsgerr
*errmsg
=
1642 (struct nlmsgerr
*)NLMSG_DATA(msg
);
1643 err
= errmsg
->error
;
1647 /* Stop reading if we see a NLMSG_DONE message. */
1648 if (msg
->nlmsg_type
== NLMSG_DONE
) {
1653 if (msg
->nlmsg_type
!= RTM_NEWADDR
) {
1658 ifa
= (struct ifaddrmsg
*)NLMSG_DATA(msg
);
1659 if (ifa
->ifa_index
== ifindex
) {
1660 if (ifa_get_local_ip(family
, msg
, res
) < 0) {
1665 /* Found a result, stop searching. */
1670 /* Keep reading more data from the socket if the last
1671 * message had the NLF_F_MULTI flag set.
1673 readmore
= (msg
->nlmsg_flags
& NLM_F_MULTI
);
1675 /* Look at the next message received in this buffer. */
1676 msg
= NLMSG_NEXT(msg
, recv_len
);
1680 /* If we end up here, we didn't find any result, so signal an
1686 netlink_close(&nlh
);
1692 int lxc_ipv6_addr_get(int ifindex
, struct in6_addr
**res
)
1694 return ip_addr_get(AF_INET6
, ifindex
, (void **)res
);
1697 int lxc_ipv4_addr_get(int ifindex
, struct in_addr
**res
)
1699 return ip_addr_get(AF_INET
, ifindex
, (void **)res
);
1702 static int ip_gateway_add(int family
, int ifindex
, void *gw
)
1705 struct nl_handler nlh
;
1707 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1709 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1710 : sizeof(struct in6_addr
);
1712 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1717 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1721 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1725 nlmsg
->nlmsghdr
->nlmsg_flags
=
1726 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1727 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWROUTE
;
1729 rt
= nlmsg_reserve(nlmsg
, sizeof(struct rtmsg
));
1732 rt
->rtm_family
= family
;
1733 rt
->rtm_table
= RT_TABLE_MAIN
;
1734 rt
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1735 rt
->rtm_protocol
= RTPROT_BOOT
;
1736 rt
->rtm_type
= RTN_UNICAST
;
1737 /* "default" destination */
1738 rt
->rtm_dst_len
= 0;
1741 if (nla_put_buffer(nlmsg
, RTA_GATEWAY
, gw
, addrlen
))
1744 /* Adding the interface index enables the use of link-local
1745 * addresses for the gateway.
1747 if (nla_put_u32(nlmsg
, RTA_OIF
, ifindex
))
1750 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1752 netlink_close(&nlh
);
1758 int lxc_ipv4_gateway_add(int ifindex
, struct in_addr
*gw
)
1760 return ip_gateway_add(AF_INET
, ifindex
, gw
);
1763 int lxc_ipv6_gateway_add(int ifindex
, struct in6_addr
*gw
)
1765 return ip_gateway_add(AF_INET6
, ifindex
, gw
);
1768 static int ip_route_dest_add(int family
, int ifindex
, void *dest
)
1771 struct nl_handler nlh
;
1773 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1775 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1776 : sizeof(struct in6_addr
);
1778 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1783 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1787 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1791 nlmsg
->nlmsghdr
->nlmsg_flags
=
1792 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1793 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWROUTE
;
1795 rt
= nlmsg_reserve(nlmsg
, sizeof(struct rtmsg
));
1798 rt
->rtm_family
= family
;
1799 rt
->rtm_table
= RT_TABLE_MAIN
;
1800 rt
->rtm_scope
= RT_SCOPE_LINK
;
1801 rt
->rtm_protocol
= RTPROT_BOOT
;
1802 rt
->rtm_type
= RTN_UNICAST
;
1803 rt
->rtm_dst_len
= addrlen
* 8;
1806 if (nla_put_buffer(nlmsg
, RTA_DST
, dest
, addrlen
))
1808 if (nla_put_u32(nlmsg
, RTA_OIF
, ifindex
))
1810 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1812 netlink_close(&nlh
);
1818 int lxc_ipv4_dest_add(int ifindex
, struct in_addr
*dest
)
1820 return ip_route_dest_add(AF_INET
, ifindex
, dest
);
1823 int lxc_ipv6_dest_add(int ifindex
, struct in6_addr
*dest
)
1825 return ip_route_dest_add(AF_INET6
, ifindex
, dest
);
1828 bool is_ovs_bridge(const char *bridge
)
1832 char brdirname
[22 + IFNAMSIZ
+ 1] = {0};
1834 ret
= snprintf(brdirname
, 22 + IFNAMSIZ
+ 1, "/sys/class/net/%s/bridge",
1836 if (ret
< 0 || (size_t)ret
>= 22 + IFNAMSIZ
+ 1)
1839 ret
= stat(brdirname
, &sb
);
1840 if (ret
< 0 && errno
== ENOENT
)
1846 struct ovs_veth_args
{
1851 /* Called from a background thread - when nic goes away, remove it from the
1854 static int lxc_ovs_delete_port_exec(void *data
)
1856 struct ovs_veth_args
*args
= data
;
1858 execlp("ovs-vsctl", "ovs-vsctl", "del-port", args
->bridge
, args
->nic
,
1863 int lxc_ovs_delete_port(const char *bridge
, const char *nic
)
1866 char cmd_output
[MAXPATHLEN
];
1867 struct ovs_veth_args args
;
1869 args
.bridge
= bridge
;
1871 ret
= run_command(cmd_output
, sizeof(cmd_output
),
1872 lxc_ovs_delete_port_exec
, (void *)&args
);
1874 ERROR("Failed to delete \"%s\" from openvswitch bridge \"%s\": "
1875 "%s", bridge
, nic
, cmd_output
);
1882 static int lxc_ovs_attach_bridge_exec(void *data
)
1884 struct ovs_veth_args
*args
= data
;
1886 execlp("ovs-vsctl", "ovs-vsctl", "add-port", args
->bridge
, args
->nic
,
1891 static int lxc_ovs_attach_bridge(const char *bridge
, const char *nic
)
1894 char cmd_output
[MAXPATHLEN
];
1895 struct ovs_veth_args args
;
1897 args
.bridge
= bridge
;
1899 ret
= run_command(cmd_output
, sizeof(cmd_output
),
1900 lxc_ovs_attach_bridge_exec
, (void *)&args
);
1902 ERROR("Failed to attach \"%s\" to openvswitch bridge \"%s\": %s",
1903 bridge
, nic
, cmd_output
);
1910 int lxc_bridge_attach(const char *bridge
, const char *ifname
)
1916 if (strlen(ifname
) >= IFNAMSIZ
)
1919 index
= if_nametoindex(ifname
);
1923 if (is_ovs_bridge(bridge
))
1924 return lxc_ovs_attach_bridge(bridge
, ifname
);
1926 fd
= socket(AF_INET
, SOCK_STREAM
, 0);
1930 retlen
= strlcpy(ifr
.ifr_name
, bridge
, IFNAMSIZ
);
1931 if (retlen
>= IFNAMSIZ
) {
1936 ifr
.ifr_name
[IFNAMSIZ
- 1] = '\0';
1937 ifr
.ifr_ifindex
= index
;
1938 err
= ioctl(fd
, SIOCBRADDIF
, &ifr
);
1946 static const char *const lxc_network_types
[LXC_NET_MAXCONFTYPE
+ 1] = {
1947 [LXC_NET_EMPTY
] = "empty",
1948 [LXC_NET_VETH
] = "veth",
1949 [LXC_NET_MACVLAN
] = "macvlan",
1950 [LXC_NET_PHYS
] = "phys",
1951 [LXC_NET_VLAN
] = "vlan",
1952 [LXC_NET_NONE
] = "none",
1955 const char *lxc_net_type_to_str(int type
)
1957 if (type
< 0 || type
> LXC_NET_MAXCONFTYPE
)
1960 return lxc_network_types
[type
];
1963 static const char padchar
[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1965 char *lxc_mkifname(char *template)
1968 struct ifaddrs
*ifa
, *ifaddr
;
1969 char name
[IFNAMSIZ
];
1970 bool exists
= false;
1975 seed
= randseed(false);
1978 (void)randseed(true);
1981 if (strlen(template) >= IFNAMSIZ
)
1984 /* Get all the network interfaces. */
1985 ret
= getifaddrs(&ifaddr
);
1987 SYSERROR("Failed to get network interfaces");
1991 /* Generate random names until we find one that doesn't exist. */
1994 (void)strlcpy(name
, template, IFNAMSIZ
);
1998 for (i
= 0; i
< strlen(name
); i
++) {
1999 if (name
[i
] == 'X') {
2001 name
[i
] = padchar
[rand_r(&seed
) % (strlen(padchar
) - 1)];
2003 name
[i
] = padchar
[rand() % (strlen(padchar
) - 1)];
2008 for (ifa
= ifaddr
; ifa
!= NULL
; ifa
= ifa
->ifa_next
) {
2009 if (!strcmp(ifa
->ifa_name
, name
)) {
2019 freeifaddrs(ifaddr
);
2020 (void)strlcpy(template, name
, strlen(template) + 1);
2025 int setup_private_host_hw_addr(char *veth1
)
2030 sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
2034 err
= snprintf((char *)ifr
.ifr_name
, IFNAMSIZ
, "%s", veth1
);
2035 if (err
< 0 || (size_t)err
>= IFNAMSIZ
) {
2040 err
= ioctl(sockfd
, SIOCGIFHWADDR
, &ifr
);
2046 ifr
.ifr_hwaddr
.sa_data
[0] = 0xfe;
2047 err
= ioctl(sockfd
, SIOCSIFHWADDR
, &ifr
);
2055 int lxc_find_gateway_addresses(struct lxc_handler
*handler
)
2057 struct lxc_list
*network
= &handler
->conf
->network
;
2058 struct lxc_list
*iterator
;
2059 struct lxc_netdev
*netdev
;
2062 lxc_list_for_each(iterator
, network
) {
2063 netdev
= iterator
->elem
;
2065 if (!netdev
->ipv4_gateway_auto
&& !netdev
->ipv6_gateway_auto
)
2068 if (netdev
->type
!= LXC_NET_VETH
&& netdev
->type
!= LXC_NET_MACVLAN
) {
2069 ERROR("Automatic gateway detection is only supported "
2070 "for veth and macvlan");
2074 if (netdev
->link
[0] == '\0') {
2075 ERROR("Automatic gateway detection needs a link interface");
2079 link_index
= if_nametoindex(netdev
->link
);
2083 if (netdev
->ipv4_gateway_auto
) {
2084 if (lxc_ipv4_addr_get(link_index
, &netdev
->ipv4_gateway
)) {
2085 ERROR("Failed to automatically find ipv4 gateway "
2086 "address from link interface \"%s\"", netdev
->link
);
2091 if (netdev
->ipv6_gateway_auto
) {
2092 if (lxc_ipv6_addr_get(link_index
, &netdev
->ipv6_gateway
)) {
2093 ERROR("Failed to automatically find ipv6 gateway "
2094 "address from link interface \"%s\"", netdev
->link
);
2103 #define LXC_USERNIC_PATH LIBEXECDIR "/lxc/lxc-user-nic"
2104 static int lxc_create_network_unpriv_exec(const char *lxcpath
, const char *lxcname
,
2105 struct lxc_netdev
*netdev
, pid_t pid
, unsigned int hooks_version
)
2109 int bytes
, pipefd
[2];
2110 char *token
, *saveptr
= NULL
;
2111 char netdev_link
[IFNAMSIZ
];
2112 char buffer
[MAXPATHLEN
] = {0};
2115 if (netdev
->type
!= LXC_NET_VETH
) {
2116 ERROR("Network type %d not support for unprivileged use", netdev
->type
);
2122 SYSERROR("Failed to create pipe");
2128 SYSERROR("Failed to create new process");
2137 char pidstr
[LXC_NUMSTRLEN64
];
2141 ret
= dup2(pipefd
[1], STDOUT_FILENO
);
2143 ret
= dup2(pipefd
[1], STDERR_FILENO
);
2146 SYSERROR("Failed to duplicate std{err,out} file descriptor");
2147 _exit(EXIT_FAILURE
);
2150 if (netdev
->link
[0] != '\0')
2151 retlen
= strlcpy(netdev_link
, netdev
->link
, IFNAMSIZ
);
2153 retlen
= strlcpy(netdev_link
, "none", IFNAMSIZ
);
2154 if (retlen
>= IFNAMSIZ
) {
2155 SYSERROR("Invalid network device name");
2156 _exit(EXIT_FAILURE
);
2159 ret
= snprintf(pidstr
, LXC_NUMSTRLEN64
, "%d", pid
);
2160 if (ret
< 0 || ret
>= LXC_NUMSTRLEN64
)
2161 _exit(EXIT_FAILURE
);
2162 pidstr
[LXC_NUMSTRLEN64
- 1] = '\0';
2164 INFO("Execing lxc-user-nic create %s %s %s veth %s %s", lxcpath
,
2165 lxcname
, pidstr
, netdev_link
,
2166 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)");
2167 if (netdev
->name
[0] != '\0')
2168 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "create",
2169 lxcpath
, lxcname
, pidstr
, "veth", netdev_link
,
2170 netdev
->name
, (char *)NULL
);
2172 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "create",
2173 lxcpath
, lxcname
, pidstr
, "veth", netdev_link
,
2175 SYSERROR("Failed to execute lxc-user-nic");
2176 _exit(EXIT_FAILURE
);
2179 /* close the write-end of the pipe */
2182 bytes
= lxc_read_nointr(pipefd
[0], &buffer
, MAXPATHLEN
);
2184 SYSERROR("Failed to read from pipe file descriptor");
2187 buffer
[bytes
- 1] = '\0';
2190 ret
= wait_for_pid(child
);
2192 if (ret
!= 0 || bytes
< 0) {
2193 ERROR("lxc-user-nic failed to configure requested network: %s",
2194 buffer
[0] != '\0' ? buffer
: "(null)");
2197 TRACE("Received output \"%s\" from lxc-user-nic", buffer
);
2200 token
= strtok_r(buffer
, ":", &saveptr
);
2202 ERROR("Failed to parse lxc-user-nic output");
2206 memset(netdev
->name
, 0, IFNAMSIZ
);
2207 memcpy(netdev
->name
, token
, IFNAMSIZ
- 1);
2209 /* netdev->ifindex */
2210 token
= strtok_r(NULL
, ":", &saveptr
);
2212 ERROR("Failed to parse lxc-user-nic output");
2216 ret
= lxc_safe_int(token
, &netdev
->ifindex
);
2219 SYSERROR("Failed to convert string \"%s\" to integer", token
);
2223 /* netdev->priv.veth_attr.veth1 */
2224 token
= strtok_r(NULL
, ":", &saveptr
);
2226 ERROR("Failed to parse lxc-user-nic output");
2230 retlen
= strlcpy(netdev
->priv
.veth_attr
.veth1
, token
, IFNAMSIZ
);
2231 if (retlen
>= IFNAMSIZ
) {
2232 ERROR("Host side veth device name returned by lxc-user-nic is "
2237 /* netdev->priv.veth_attr.ifindex */
2238 token
= strtok_r(NULL
, ":", &saveptr
);
2240 ERROR("Failed to parse lxc-user-nic output");
2244 ret
= lxc_safe_int(token
, &netdev
->priv
.veth_attr
.ifindex
);
2247 SYSERROR("Failed to convert string \"%s\" to integer", token
);
2251 if (netdev
->upscript
) {
2255 netdev
->priv
.veth_attr
.veth1
,
2259 ret
= run_script_argv(lxcname
,
2260 hooks_version
, "net",
2261 netdev
->upscript
, "up", argv
);
2269 static int lxc_delete_network_unpriv_exec(const char *lxcpath
, const char *lxcname
,
2270 struct lxc_netdev
*netdev
,
2271 const char *netns_path
)
2276 char buffer
[MAXPATHLEN
] = {0};
2278 if (netdev
->type
!= LXC_NET_VETH
) {
2279 ERROR("Network type %d not support for unprivileged use", netdev
->type
);
2285 SYSERROR("Failed to create pipe");
2291 SYSERROR("Failed to create new process");
2303 ret
= dup2(pipefd
[1], STDOUT_FILENO
);
2305 ret
= dup2(pipefd
[1], STDERR_FILENO
);
2308 SYSERROR("Failed to duplicate std{err,out} file descriptor");
2309 _exit(EXIT_FAILURE
);
2312 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2313 hostveth
= netdev
->priv
.veth_attr
.pair
;
2315 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2316 if (hostveth
[0] == '\0') {
2317 SYSERROR("Host side veth device name is missing");
2318 _exit(EXIT_FAILURE
);
2321 if (netdev
->link
[0] == '\0') {
2322 SYSERROR("Network link for network device \"%s\" is "
2323 "missing", netdev
->priv
.veth_attr
.veth1
);
2324 _exit(EXIT_FAILURE
);
2327 INFO("Execing lxc-user-nic delete %s %s %s veth %s %s", lxcpath
,
2328 lxcname
, netns_path
, netdev
->link
, hostveth
);
2329 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "delete", lxcpath
,
2330 lxcname
, netns_path
, "veth", netdev
->link
, hostveth
,
2332 SYSERROR("Failed to exec lxc-user-nic.");
2333 _exit(EXIT_FAILURE
);
2338 bytes
= lxc_read_nointr(pipefd
[0], &buffer
, MAXPATHLEN
);
2340 SYSERROR("Failed to read from pipe file descriptor.");
2343 buffer
[bytes
- 1] = '\0';
2346 ret
= wait_for_pid(child
);
2348 if (ret
!= 0 || bytes
< 0) {
2349 ERROR("lxc-user-nic failed to delete requested network: %s",
2350 buffer
[0] != '\0' ? buffer
: "(null)");
2357 bool lxc_delete_network_unpriv(struct lxc_handler
*handler
)
2360 struct lxc_list
*iterator
;
2361 struct lxc_list
*network
= &handler
->conf
->network
;
2362 /* strlen("/proc/") = 6
2366 * strlen("/fd/") = 4
2372 char netns_path
[6 + LXC_NUMSTRLEN64
+ 4 + LXC_NUMSTRLEN64
+ 1];
2376 if (handler
->nsfd
[LXC_NS_NET
] < 0) {
2377 DEBUG("Cannot not guarantee safe deletion of network devices. "
2378 "Manual cleanup maybe needed");
2382 ret
= snprintf(netns_path
, sizeof(netns_path
), "/proc/%d/fd/%d",
2383 lxc_raw_getpid(), handler
->nsfd
[LXC_NS_NET
]);
2384 if (ret
< 0 || ret
>= sizeof(netns_path
))
2387 lxc_list_for_each(iterator
, network
) {
2388 char *hostveth
= NULL
;
2389 struct lxc_netdev
*netdev
= iterator
->elem
;
2391 /* We can only delete devices whose ifindex we have. If we don't
2392 * have the index it means that we didn't create it.
2394 if (!netdev
->ifindex
)
2397 if (netdev
->type
== LXC_NET_PHYS
) {
2398 ret
= lxc_netdev_rename_by_index(netdev
->ifindex
,
2401 WARN("Failed to rename interface with index %d "
2402 "to its initial name \"%s\"",
2403 netdev
->ifindex
, netdev
->link
);
2405 TRACE("Renamed interface with index %d to its "
2406 "initial name \"%s\"",
2407 netdev
->ifindex
, netdev
->link
);
2408 goto clear_ifindices
;
2411 ret
= netdev_deconf
[netdev
->type
](handler
, netdev
);
2413 WARN("Failed to deconfigure network device");
2415 if (netdev
->type
!= LXC_NET_VETH
)
2416 goto clear_ifindices
;
2418 if (netdev
->link
[0] == '\0' || !is_ovs_bridge(netdev
->link
))
2419 goto clear_ifindices
;
2421 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2422 hostveth
= netdev
->priv
.veth_attr
.pair
;
2424 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2425 if (hostveth
[0] == '\0')
2426 goto clear_ifindices
;
2428 ret
= lxc_delete_network_unpriv_exec(handler
->lxcpath
,
2429 handler
->name
, netdev
,
2432 WARN("Failed to remove port \"%s\" from openvswitch "
2433 "bridge \"%s\"", hostveth
, netdev
->link
);
2434 goto clear_ifindices
;
2436 INFO("Removed interface \"%s\" from \"%s\"", hostveth
,
2440 /* We need to clear any ifindeces we recorded so liblxc won't
2441 * have cached stale data which would cause it to fail on reboot
2442 * we're we don't re-read the on-disk config file.
2444 netdev
->ifindex
= 0;
2445 if (netdev
->type
== LXC_NET_PHYS
) {
2446 netdev
->priv
.phys_attr
.ifindex
= 0;
2447 } else if (netdev
->type
== LXC_NET_VETH
) {
2448 netdev
->priv
.veth_attr
.veth1
[0] = '\0';
2449 netdev
->priv
.veth_attr
.ifindex
= 0;
2456 int lxc_create_network_priv(struct lxc_handler
*handler
)
2458 struct lxc_list
*iterator
;
2459 struct lxc_list
*network
= &handler
->conf
->network
;
2461 if (!handler
->am_root
)
2464 lxc_list_for_each(iterator
, network
) {
2465 struct lxc_netdev
*netdev
= iterator
->elem
;
2467 if (netdev
->type
< 0 || netdev
->type
> LXC_NET_MAXCONFTYPE
) {
2468 ERROR("Invalid network configuration type %d", netdev
->type
);
2472 if (netdev_conf
[netdev
->type
](handler
, netdev
)) {
2473 ERROR("Failed to create network device");
2482 int lxc_network_move_created_netdev_priv(const char *lxcpath
, const char *lxcname
,
2483 struct lxc_list
*network
, pid_t pid
)
2486 char ifname
[IFNAMSIZ
];
2487 struct lxc_list
*iterator
;
2489 if (am_guest_unpriv())
2492 lxc_list_for_each(iterator
, network
) {
2493 struct lxc_netdev
*netdev
= iterator
->elem
;
2495 if (!netdev
->ifindex
)
2498 /* retrieve the name of the interface */
2499 if (!if_indextoname(netdev
->ifindex
, ifname
)) {
2500 ERROR("No interface corresponding to ifindex \"%d\"",
2505 ret
= lxc_netdev_move_by_name(ifname
, pid
, NULL
);
2508 SYSERROR("Failed to move network device \"%s\" to "
2509 "network namespace %d", ifname
, pid
);
2513 DEBUG("Moved network device \"%s\"/\"%s\" to network namespace "
2515 ifname
, netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2522 int lxc_create_network_unpriv(const char *lxcpath
, const char *lxcname
,
2523 struct lxc_list
*network
, pid_t pid
, unsigned int hooks_version
)
2525 struct lxc_list
*iterator
;
2527 if (!am_guest_unpriv())
2530 lxc_list_for_each(iterator
, network
) {
2531 struct lxc_netdev
*netdev
= iterator
->elem
;
2533 if (netdev
->type
== LXC_NET_EMPTY
)
2536 if (netdev
->type
== LXC_NET_NONE
)
2539 if (netdev
->type
!= LXC_NET_VETH
) {
2540 ERROR("Networks of type %s are not supported by "
2541 "unprivileged containers",
2542 lxc_net_type_to_str(netdev
->type
));
2547 INFO("mtu ignored due to insufficient privilege");
2549 if (lxc_create_network_unpriv_exec(lxcpath
, lxcname
, netdev
, pid
, hooks_version
))
2556 bool lxc_delete_network_priv(struct lxc_handler
*handler
)
2559 struct lxc_list
*iterator
;
2560 struct lxc_list
*network
= &handler
->conf
->network
;
2562 lxc_list_for_each(iterator
, network
) {
2563 char *hostveth
= NULL
;
2564 struct lxc_netdev
*netdev
= iterator
->elem
;
2566 /* We can only delete devices whose ifindex we have. If we don't
2567 * have the index it means that we didn't create it.
2569 if (!netdev
->ifindex
)
2572 if (netdev
->type
== LXC_NET_PHYS
) {
2573 ret
= lxc_netdev_rename_by_index(netdev
->ifindex
, netdev
->link
);
2575 WARN("Failed to rename interface with index %d "
2576 "from \"%s\" to its initial name \"%s\"",
2577 netdev
->ifindex
, netdev
->name
, netdev
->link
);
2579 TRACE("Renamed interface with index %d from "
2580 "\"%s\" to its initial name \"%s\"",
2581 netdev
->ifindex
, netdev
->name
,
2583 goto clear_ifindices
;
2586 ret
= netdev_deconf
[netdev
->type
](handler
, netdev
);
2588 WARN("Failed to deconfigure network device");
2590 /* Recent kernels remove the virtual interfaces when the network
2591 * namespace is destroyed but in case we did not move the
2592 * interface to the network namespace, we have to destroy it.
2594 ret
= lxc_netdev_delete_by_index(netdev
->ifindex
);
2595 if (-ret
== ENODEV
) {
2596 INFO("Interface \"%s\" with index %d already "
2597 "deleted or existing in different network "
2599 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2601 } else if (ret
< 0) {
2603 SYSWARN("Failed to remove interface \"%s\" with index %d",
2604 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2606 goto clear_ifindices
;
2608 INFO("Removed interface \"%s\" with index %d",
2609 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2612 if (netdev
->type
!= LXC_NET_VETH
)
2613 goto clear_ifindices
;
2615 /* Explicitly delete host veth device to prevent lingering
2616 * devices. We had issues in LXD around this.
2618 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2619 hostveth
= netdev
->priv
.veth_attr
.pair
;
2621 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2622 if (hostveth
[0] == '\0')
2623 goto clear_ifindices
;
2625 ret
= lxc_netdev_delete_by_name(hostveth
);
2628 SYSWARN("Failed to remove interface \"%s\" from \"%s\"",
2629 hostveth
, netdev
->link
);
2630 goto clear_ifindices
;
2632 INFO("Removed interface \"%s\" from \"%s\"", hostveth
, netdev
->link
);
2634 if (netdev
->link
[0] == '\0' || !is_ovs_bridge(netdev
->link
)) {
2635 netdev
->priv
.veth_attr
.veth1
[0] = '\0';
2636 netdev
->ifindex
= 0;
2637 netdev
->priv
.veth_attr
.ifindex
= 0;
2638 goto clear_ifindices
;
2641 /* Delete the openvswitch port. */
2642 ret
= lxc_ovs_delete_port(netdev
->link
, hostveth
);
2644 WARN("Failed to remove port \"%s\" from openvswitch "
2645 "bridge \"%s\"", hostveth
, netdev
->link
);
2647 INFO("Removed port \"%s\" from openvswitch bridge \"%s\"",
2648 hostveth
, netdev
->link
);
2651 /* We need to clear any ifindeces we recorded so liblxc won't
2652 * have cached stale data which would cause it to fail on reboot
2653 * we're we don't re-read the on-disk config file.
2655 netdev
->ifindex
= 0;
2656 if (netdev
->type
== LXC_NET_PHYS
) {
2657 netdev
->priv
.phys_attr
.ifindex
= 0;
2658 } else if (netdev
->type
== LXC_NET_VETH
) {
2659 netdev
->priv
.veth_attr
.veth1
[0] = '\0';
2660 netdev
->priv
.veth_attr
.ifindex
= 0;
2667 int lxc_requests_empty_network(struct lxc_handler
*handler
)
2669 struct lxc_list
*network
= &handler
->conf
->network
;
2670 struct lxc_list
*iterator
;
2671 bool found_none
= false, found_nic
= false;
2673 if (lxc_list_empty(network
))
2676 lxc_list_for_each(iterator
, network
) {
2677 struct lxc_netdev
*netdev
= iterator
->elem
;
2679 if (netdev
->type
== LXC_NET_NONE
)
2684 if (found_none
&& !found_nic
)
2689 /* try to move physical nics to the init netns */
2690 int lxc_restore_phys_nics_to_netns(struct lxc_handler
*handler
)
2694 char ifname
[IFNAMSIZ
];
2695 struct lxc_list
*iterator
;
2696 int netnsfd
= handler
->nsfd
[LXC_NS_NET
];
2697 struct lxc_conf
*conf
= handler
->conf
;
2699 /* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
2700 * the parent network namespace. We won't have this capability if we are
2703 if (!handler
->am_root
)
2706 TRACE("Moving physical network devices back to parent network namespace");
2708 oldfd
= lxc_preserve_ns(lxc_raw_getpid(), "net");
2710 SYSERROR("Failed to preserve network namespace");
2714 ret
= setns(netnsfd
, CLONE_NEWNET
);
2716 SYSERROR("Failed to enter network namespace");
2721 lxc_list_for_each(iterator
, &conf
->network
) {
2722 struct lxc_netdev
*netdev
= iterator
->elem
;
2724 if (netdev
->type
!= LXC_NET_PHYS
)
2727 /* Retrieve the name of the interface in the container's network
2730 if (!if_indextoname(netdev
->ifindex
, ifname
)) {
2731 WARN("No interface corresponding to ifindex %d",
2736 ret
= lxc_netdev_move_by_name(ifname
, 1, netdev
->link
);
2738 WARN("Error moving network device \"%s\" back to "
2739 "network namespace", ifname
);
2741 TRACE("Moved network device \"%s\" back to network "
2742 "namespace", ifname
);
2745 ret
= setns(oldfd
, CLONE_NEWNET
);
2748 SYSERROR("Failed to enter network namespace");
2755 static int setup_hw_addr(char *hwaddr
, const char *ifname
)
2757 struct sockaddr sockaddr
;
2761 ret
= lxc_convert_mac(hwaddr
, &sockaddr
);
2764 SYSERROR("Mac address \"%s\" conversion failed", hwaddr
);
2768 memcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
2769 ifr
.ifr_name
[IFNAMSIZ
-1] = '\0';
2770 memcpy((char *) &ifr
.ifr_hwaddr
, (char *) &sockaddr
, sizeof(sockaddr
));
2772 fd
= socket(AF_INET
, SOCK_DGRAM
, 0);
2776 ret
= ioctl(fd
, SIOCSIFHWADDR
, &ifr
);
2778 SYSERROR("Failed to perform ioctl");
2782 DEBUG("Mac address \"%s\" on \"%s\" has been setup", hwaddr
,
2788 static int setup_ipv4_addr(struct lxc_list
*ip
, int ifindex
)
2790 struct lxc_list
*iterator
;
2793 lxc_list_for_each(iterator
, ip
) {
2794 struct lxc_inetdev
*inetdev
= iterator
->elem
;
2796 err
= lxc_ipv4_addr_add(ifindex
, &inetdev
->addr
,
2797 &inetdev
->bcast
, inetdev
->prefix
);
2800 SYSERROR("Failed to setup ipv4 address for network device "
2801 "with eifindex %d", ifindex
);
2809 static int setup_ipv6_addr(struct lxc_list
*ip
, int ifindex
)
2811 struct lxc_list
*iterator
;
2814 lxc_list_for_each(iterator
, ip
) {
2815 struct lxc_inet6dev
*inet6dev
= iterator
->elem
;
2817 err
= lxc_ipv6_addr_add(ifindex
, &inet6dev
->addr
,
2818 &inet6dev
->mcast
, &inet6dev
->acast
,
2822 SYSERROR("Failed to setup ipv6 address for network device "
2823 "with eifindex %d", ifindex
);
2831 static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev
*netdev
)
2833 char ifname
[IFNAMSIZ
];
2835 const char *net_type_name
;
2836 char *current_ifname
= ifname
;
2838 /* empty network namespace */
2839 if (!netdev
->ifindex
) {
2840 if (netdev
->flags
& IFF_UP
) {
2841 err
= lxc_netdev_up("lo");
2844 SYSERROR("Failed to set the loopback network device up");
2849 if (netdev
->type
== LXC_NET_EMPTY
)
2852 if (netdev
->type
== LXC_NET_NONE
)
2855 if (netdev
->type
!= LXC_NET_VETH
) {
2856 net_type_name
= lxc_net_type_to_str(netdev
->type
);
2857 ERROR("%s networks are not supported for containers "
2858 "not setup up by privileged users", net_type_name
);
2862 netdev
->ifindex
= if_nametoindex(netdev
->name
);
2865 /* get the new ifindex in case of physical netdev */
2866 if (netdev
->type
== LXC_NET_PHYS
) {
2867 netdev
->ifindex
= if_nametoindex(netdev
->link
);
2868 if (!netdev
->ifindex
) {
2869 ERROR("Failed to get ifindex for network device \"%s\"",
2875 /* retrieve the name of the interface */
2876 if (!if_indextoname(netdev
->ifindex
, current_ifname
)) {
2877 ERROR("Failed get name for network device with ifindex %d",
2882 /* Default: let the system to choose one interface name.
2883 * When the IFLA_IFNAME attribute is passed something like "<prefix>%d"
2884 * netlink will replace the format specifier with an appropriate index.
2886 if (netdev
->name
[0] == '\0') {
2887 if (netdev
->type
== LXC_NET_PHYS
)
2888 (void)strlcpy(netdev
->name
, netdev
->link
, IFNAMSIZ
);
2890 (void)strlcpy(netdev
->name
, "eth%d", IFNAMSIZ
);
2893 /* rename the interface name */
2894 if (strcmp(ifname
, netdev
->name
) != 0) {
2895 err
= lxc_netdev_rename_by_name(ifname
, netdev
->name
);
2898 SYSERROR("Failed to rename network device \"%s\" to \"%s\"",
2899 ifname
, netdev
->name
);
2904 /* Re-read the name of the interface because its name has changed
2905 * and would be automatically allocated by the system
2907 if (!if_indextoname(netdev
->ifindex
, current_ifname
)) {
2908 ERROR("Failed get name for network device with ifindex %d",
2913 /* Now update the recorded name of the network device to reflect the
2914 * name of the network device in the child's network namespace. We will
2915 * later on send this information back to the parent.
2917 (void)strlcpy(netdev
->name
, current_ifname
, IFNAMSIZ
);
2919 /* set a mac address */
2920 if (netdev
->hwaddr
) {
2921 if (setup_hw_addr(netdev
->hwaddr
, current_ifname
)) {
2922 ERROR("Failed to setup hw address for network device \"%s\"",
2928 /* setup ipv4 addresses on the interface */
2929 if (setup_ipv4_addr(&netdev
->ipv4
, netdev
->ifindex
)) {
2930 ERROR("Failed to setup ip addresses for network device \"%s\"",
2935 /* setup ipv6 addresses on the interface */
2936 if (setup_ipv6_addr(&netdev
->ipv6
, netdev
->ifindex
)) {
2937 ERROR("Failed to setup ipv6 addresses for network device \"%s\"",
2942 /* set the network device up */
2943 if (netdev
->flags
& IFF_UP
) {
2946 err
= lxc_netdev_up(current_ifname
);
2949 SYSERROR("Failed to set network device \"%s\" up",
2954 /* the network is up, make the loopback up too */
2955 err
= lxc_netdev_up("lo");
2958 SYSERROR("Failed to set the loopback network device up");
2963 /* We can only set up the default routes after bringing
2964 * up the interface, sine bringing up the interface adds
2965 * the link-local routes and we can't add a default
2966 * route if the gateway is not reachable. */
2968 /* setup ipv4 gateway on the interface */
2969 if (netdev
->ipv4_gateway
) {
2970 if (!(netdev
->flags
& IFF_UP
)) {
2971 ERROR("Cannot add ipv4 gateway for network device "
2972 "\"%s\" when not bringing up the interface", ifname
);
2976 if (lxc_list_empty(&netdev
->ipv4
)) {
2977 ERROR("Cannot add ipv4 gateway for network device "
2978 "\"%s\" when not assigning an address", ifname
);
2982 err
= lxc_ipv4_gateway_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2984 err
= lxc_ipv4_dest_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2987 SYSERROR("Failed to add ipv4 dest for network device \"%s\"",
2991 err
= lxc_ipv4_gateway_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2994 SYSERROR("Failed to setup ipv4 gateway for network device \"%s\"",
2997 if (netdev
->ipv4_gateway_auto
) {
2998 char buf
[INET_ADDRSTRLEN
];
2999 inet_ntop(AF_INET
, netdev
->ipv4_gateway
, buf
, sizeof(buf
));
3000 ERROR("Fried to set autodetected ipv4 gateway \"%s\"", buf
);
3007 /* setup ipv6 gateway on the interface */
3008 if (netdev
->ipv6_gateway
) {
3009 if (!(netdev
->flags
& IFF_UP
)) {
3010 ERROR("Cannot add ipv6 gateway for network device "
3011 "\"%s\" when not bringing up the interface", ifname
);
3015 if (lxc_list_empty(&netdev
->ipv6
) && !IN6_IS_ADDR_LINKLOCAL(netdev
->ipv6_gateway
)) {
3016 ERROR("Cannot add ipv6 gateway for network device "
3017 "\"%s\" when not assigning an address", ifname
);
3021 err
= lxc_ipv6_gateway_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
3023 err
= lxc_ipv6_dest_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
3026 SYSERROR("Failed to add ipv6 dest for network device \"%s\"",
3030 err
= lxc_ipv6_gateway_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
3033 SYSERROR("Failed to setup ipv6 gateway for network device \"%s\"",
3036 if (netdev
->ipv6_gateway_auto
) {
3037 char buf
[INET6_ADDRSTRLEN
];
3038 inet_ntop(AF_INET6
, netdev
->ipv6_gateway
, buf
, sizeof(buf
));
3039 ERROR("Tried to set autodetected ipv6 "
3040 "gateway for network device "
3048 DEBUG("Network device \"%s\" has been setup", current_ifname
);
3053 int lxc_setup_network_in_child_namespaces(const struct lxc_conf
*conf
,
3054 struct lxc_list
*network
)
3056 struct lxc_list
*iterator
;
3057 struct lxc_netdev
*netdev
;
3059 lxc_list_for_each(iterator
, network
) {
3060 netdev
= iterator
->elem
;
3062 if (lxc_setup_netdev_in_child_namespaces(netdev
)) {
3063 ERROR("failed to setup netdev");
3068 if (!lxc_list_empty(network
))
3069 INFO("network has been setup");
3074 int lxc_network_send_veth_names_to_child(struct lxc_handler
*handler
)
3076 struct lxc_list
*iterator
;
3077 struct lxc_list
*network
= &handler
->conf
->network
;
3078 int data_sock
= handler
->data_sock
[0];
3080 if (handler
->am_root
)
3083 lxc_list_for_each(iterator
, network
) {
3085 struct lxc_netdev
*netdev
= iterator
->elem
;
3087 if (netdev
->type
!= LXC_NET_VETH
)
3090 ret
= send(data_sock
, netdev
->name
, IFNAMSIZ
, MSG_NOSIGNAL
);
3093 TRACE("Sent network device name \"%s\" to child", netdev
->name
);
3099 int lxc_network_recv_veth_names_from_parent(struct lxc_handler
*handler
)
3101 struct lxc_list
*iterator
;
3102 struct lxc_list
*network
= &handler
->conf
->network
;
3103 int data_sock
= handler
->data_sock
[1];
3105 if (handler
->am_root
)
3108 lxc_list_for_each(iterator
, network
) {
3110 struct lxc_netdev
*netdev
= iterator
->elem
;
3112 if (netdev
->type
!= LXC_NET_VETH
)
3115 ret
= recv(data_sock
, netdev
->name
, IFNAMSIZ
, 0);
3118 TRACE("Received network device name \"%s\" from parent", netdev
->name
);
3124 int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler
*handler
)
3126 struct lxc_list
*iterator
, *network
;
3127 int data_sock
= handler
->data_sock
[0];
3129 if (!handler
->am_root
)
3132 network
= &handler
->conf
->network
;
3133 lxc_list_for_each(iterator
, network
) {
3135 struct lxc_netdev
*netdev
= iterator
->elem
;
3137 /* Send network device name in the child's namespace to parent. */
3138 ret
= send(data_sock
, netdev
->name
, IFNAMSIZ
, MSG_NOSIGNAL
);
3142 /* Send network device ifindex in the child's namespace to
3145 ret
= send(data_sock
, &netdev
->ifindex
, sizeof(netdev
->ifindex
), MSG_NOSIGNAL
);
3150 TRACE("Sent network device names and ifindeces to parent");
3154 int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler
*handler
)
3156 struct lxc_list
*iterator
, *network
;
3157 int data_sock
= handler
->data_sock
[1];
3159 if (!handler
->am_root
)
3162 network
= &handler
->conf
->network
;
3163 lxc_list_for_each(iterator
, network
) {
3165 struct lxc_netdev
*netdev
= iterator
->elem
;
3167 /* Receive network device name in the child's namespace to
3170 ret
= recv(data_sock
, netdev
->name
, IFNAMSIZ
, 0);
3174 /* Receive network device ifindex in the child's namespace to
3177 ret
= recv(data_sock
, &netdev
->ifindex
, sizeof(netdev
->ifindex
), 0);
3185 void lxc_delete_network(struct lxc_handler
*handler
)
3189 if (handler
->am_root
)
3190 bret
= lxc_delete_network_priv(handler
);
3192 bret
= lxc_delete_network_unpriv(handler
);
3194 DEBUG("Failed to delete network devices");
3196 DEBUG("Deleted network devices");