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 #define IFLA_LINKMODE 17
67 #define IFLA_LINKINFO 18
70 #ifndef IFLA_NET_NS_PID
71 #define IFLA_NET_NS_PID 19
74 #ifndef IFLA_INFO_KIND
75 #define IFLA_INFO_KIND 1
79 #define IFLA_VLAN_ID 1
82 #ifndef IFLA_INFO_DATA
83 #define IFLA_INFO_DATA 2
86 #ifndef VETH_INFO_PEER
87 #define VETH_INFO_PEER 1
90 #ifndef IFLA_MACVLAN_MODE
91 #define IFLA_MACVLAN_MODE 1
94 lxc_log_define(lxc_network
, lxc
);
96 typedef int (*instantiate_cb
)(struct lxc_handler
*, struct lxc_netdev
*);
98 static int instantiate_veth(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
100 int bridge_index
, err
;
102 char veth1buf
[IFNAMSIZ
], veth2buf
[IFNAMSIZ
];
103 unsigned int mtu
= 0;
105 if (netdev
->priv
.veth_attr
.pair
[0] != '\0') {
106 veth1
= netdev
->priv
.veth_attr
.pair
;
107 if (handler
->conf
->reboot
)
108 lxc_netdev_delete_by_name(veth1
);
110 err
= snprintf(veth1buf
, sizeof(veth1buf
), "vethXXXXXX");
111 if (err
< 0 || (size_t)err
>= sizeof(veth1buf
))
114 veth1
= lxc_mkifname(veth1buf
);
118 /* store away for deconf */
119 memcpy(netdev
->priv
.veth_attr
.veth1
, veth1
, IFNAMSIZ
);
122 snprintf(veth2buf
, sizeof(veth2buf
), "vethXXXXXX");
123 veth2
= lxc_mkifname(veth2buf
);
127 err
= lxc_veth_create(veth1
, veth2
);
129 ERROR("Failed to create veth pair \"%s\" and \"%s\": %s", veth1
,
130 veth2
, strerror(-err
));
134 /* changing the high byte of the mac address to 0xfe, the bridge interface
135 * will always keep the host's mac address and not take the mac address
137 err
= setup_private_host_hw_addr(veth1
);
139 ERROR("Failed to change mac address of host interface \"%s\": %s",
140 veth1
, strerror(-err
));
144 /* Retrieve ifindex of the host's veth device. */
145 netdev
->priv
.veth_attr
.ifindex
= if_nametoindex(veth1
);
146 if (!netdev
->priv
.veth_attr
.ifindex
) {
147 ERROR("Failed to retrieve ifindex for \"%s\"", veth1
);
151 /* Note that we're retrieving the container's ifindex in the host's
152 * network namespace because we need it to move the device from the
153 * host's network namespace to the container's network namespace later
156 netdev
->ifindex
= if_nametoindex(veth2
);
157 if (!netdev
->ifindex
) {
158 ERROR("Failed to retrieve ifindex for \"%s\"", veth2
);
163 if (lxc_safe_uint(netdev
->mtu
, &mtu
) < 0)
164 WARN("Failed to parse mtu");
166 INFO("Retrieved mtu %d", mtu
);
167 } else if (netdev
->link
[0] != '\0') {
168 bridge_index
= if_nametoindex(netdev
->link
);
170 mtu
= netdev_get_mtu(bridge_index
);
171 INFO("Retrieved mtu %d from %s", mtu
, netdev
->link
);
173 mtu
= netdev_get_mtu(netdev
->ifindex
);
174 INFO("Retrieved mtu %d from %s", mtu
, veth2
);
179 err
= lxc_netdev_set_mtu(veth1
, mtu
);
181 err
= lxc_netdev_set_mtu(veth2
, mtu
);
183 ERROR("Failed to set mtu \"%d\" for veth pair \"%s\" "
185 mtu
, veth1
, veth2
, strerror(-err
));
190 if (netdev
->link
[0] != '\0') {
191 err
= lxc_bridge_attach(netdev
->link
, veth1
);
193 ERROR("Failed to attach \"%s\" to bridge \"%s\": %s",
194 veth1
, netdev
->link
, strerror(-err
));
197 INFO("Attached \"%s\" to bridge \"%s\"", veth1
, netdev
->link
);
200 err
= lxc_netdev_up(veth1
);
202 ERROR("Failed to set \"%s\" up: %s", veth1
, strerror(-err
));
206 if (netdev
->upscript
) {
214 err
= run_script_argv(handler
->name
,
215 handler
->conf
->hooks_version
, "net",
216 netdev
->upscript
, "up", argv
);
221 DEBUG("Instantiated veth \"%s/%s\", index is \"%d\"", veth1
, veth2
,
227 if (netdev
->ifindex
!= 0)
228 lxc_netdev_delete_by_name(veth1
);
232 static int instantiate_macvlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
234 char peerbuf
[IFNAMSIZ
], *peer
;
237 if (netdev
->link
[0] == '\0') {
238 ERROR("No link for macvlan network device specified");
242 err
= snprintf(peerbuf
, sizeof(peerbuf
), "mcXXXXXX");
243 if (err
< 0 || (size_t)err
>= sizeof(peerbuf
))
246 peer
= lxc_mkifname(peerbuf
);
250 err
= lxc_macvlan_create(netdev
->link
, peer
,
251 netdev
->priv
.macvlan_attr
.mode
);
253 ERROR("Failed to create macvlan interface \"%s\" on \"%s\": %s",
254 peer
, netdev
->link
, strerror(-err
));
258 netdev
->ifindex
= if_nametoindex(peer
);
259 if (!netdev
->ifindex
) {
260 ERROR("Failed to retrieve ifindex for \"%s\"", peer
);
264 if (netdev
->upscript
) {
271 err
= run_script_argv(handler
->name
,
272 handler
->conf
->hooks_version
, "net",
273 netdev
->upscript
, "up", argv
);
278 DEBUG("Instantiated macvlan \"%s\" with ifindex is %d and mode %d",
279 peer
, netdev
->ifindex
, netdev
->priv
.macvlan_attr
.mode
);
284 lxc_netdev_delete_by_name(peer
);
288 static int instantiate_vlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
292 static uint16_t vlan_cntr
= 0;
293 unsigned int mtu
= 0;
295 if (netdev
->link
[0] == '\0') {
296 ERROR("No link for vlan network device specified");
300 err
= snprintf(peer
, sizeof(peer
), "vlan%d-%d", netdev
->priv
.vlan_attr
.vid
, vlan_cntr
++);
301 if (err
< 0 || (size_t)err
>= sizeof(peer
))
304 err
= lxc_vlan_create(netdev
->link
, peer
, netdev
->priv
.vlan_attr
.vid
);
306 ERROR("Failed to create vlan interface \"%s\" on \"%s\": %s",
307 peer
, netdev
->link
, strerror(-err
));
311 netdev
->ifindex
= if_nametoindex(peer
);
312 if (!netdev
->ifindex
) {
313 ERROR("Failed to retrieve ifindex for \"%s\"", peer
);
314 lxc_netdev_delete_by_name(peer
);
318 DEBUG("Instantiated vlan \"%s\" with ifindex is \"%d\" (vlan1000)",
319 peer
, netdev
->ifindex
);
321 if (lxc_safe_uint(netdev
->mtu
, &mtu
) < 0) {
322 ERROR("Failed to retrieve mtu from \"%d\"/\"%s\".",
324 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)");
327 err
= lxc_netdev_set_mtu(peer
, mtu
);
329 ERROR("Failed to set mtu \"%s\" for \"%s\": %s",
330 netdev
->mtu
, peer
, strerror(-err
));
331 lxc_netdev_delete_by_name(peer
);
339 static int instantiate_phys(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
348 if (netdev
->link
[0] == '\0') {
349 ERROR("No link for physical interface specified");
353 /* Note that we're retrieving the container's ifindex in the host's
354 * network namespace because we need it to move the device from the
355 * host's network namespace to the container's network namespace later
357 * Note that netdev->link will contain the name of the physical network
358 * device in the host's namespace.
360 netdev
->ifindex
= if_nametoindex(netdev
->link
);
361 if (!netdev
->ifindex
) {
362 ERROR("Failed to retrieve ifindex for \"%s\"", netdev
->link
);
366 /* Store the ifindex of the host's network device in the host's
369 netdev
->priv
.phys_attr
.ifindex
= netdev
->ifindex
;
371 if (!netdev
->upscript
)
374 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
375 "net", netdev
->upscript
, "up", argv
);
382 static int instantiate_empty(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
391 if (!netdev
->upscript
)
394 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
395 "net", netdev
->upscript
, "up", argv
);
402 static int instantiate_none(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
408 static instantiate_cb netdev_conf
[LXC_NET_MAXCONFTYPE
+ 1] = {
409 [LXC_NET_VETH
] = instantiate_veth
,
410 [LXC_NET_MACVLAN
] = instantiate_macvlan
,
411 [LXC_NET_VLAN
] = instantiate_vlan
,
412 [LXC_NET_PHYS
] = instantiate_phys
,
413 [LXC_NET_EMPTY
] = instantiate_empty
,
414 [LXC_NET_NONE
] = instantiate_none
,
417 static int shutdown_veth(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
427 if (!netdev
->downscript
)
430 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
431 argv
[2] = netdev
->priv
.veth_attr
.pair
;
433 argv
[2] = netdev
->priv
.veth_attr
.veth1
;
435 ret
= run_script_argv(handler
->name
,
436 handler
->conf
->hooks_version
, "net",
437 netdev
->downscript
, "down", argv
);
444 static int shutdown_macvlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
453 if (!netdev
->downscript
)
456 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
457 "net", netdev
->downscript
, "down", argv
);
464 static int shutdown_vlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
469 static int shutdown_phys(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
478 if (!netdev
->downscript
)
481 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
482 "net", netdev
->downscript
, "down", argv
);
489 static int shutdown_empty(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
497 if (!netdev
->downscript
)
500 ret
= run_script_argv(handler
->name
, handler
->conf
->hooks_version
,
501 "net", netdev
->downscript
, "down", argv
);
508 static int shutdown_none(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
513 static instantiate_cb netdev_deconf
[LXC_NET_MAXCONFTYPE
+ 1] = {
514 [LXC_NET_VETH
] = shutdown_veth
,
515 [LXC_NET_MACVLAN
] = shutdown_macvlan
,
516 [LXC_NET_VLAN
] = shutdown_vlan
,
517 [LXC_NET_PHYS
] = shutdown_phys
,
518 [LXC_NET_EMPTY
] = shutdown_empty
,
519 [LXC_NET_NONE
] = shutdown_none
,
522 int lxc_netdev_move_by_index(int ifindex
, pid_t pid
, const char *ifname
)
525 struct nl_handler nlh
;
526 struct ifinfomsg
*ifi
;
527 struct nlmsg
*nlmsg
= NULL
;
529 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
534 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
538 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
539 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
541 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
544 ifi
->ifi_family
= AF_UNSPEC
;
545 ifi
->ifi_index
= ifindex
;
547 if (nla_put_u32(nlmsg
, IFLA_NET_NS_PID
, pid
))
550 if (ifname
!= NULL
) {
551 if (nla_put_string(nlmsg
, IFLA_IFNAME
, ifname
))
555 err
= netlink_transaction(&nlh
, nlmsg
, nlmsg
);
562 /* If we are asked to move a wireless interface, then we must actually move its
563 * phyN device. Detect that condition and return the physname here. The physname
564 * will be passed to lxc_netdev_move_wlan() which will free it when done.
566 #define PHYSNAME "/sys/class/net/%s/phy80211/name"
567 static char *is_wlan(const char *ifname
)
575 char *physname
= NULL
;
577 len
= strlen(ifname
) + strlen(PHYSNAME
) - 1;
578 path
= alloca(len
+ 1);
579 ret
= snprintf(path
, len
, PHYSNAME
, ifname
);
580 if (ret
< 0 || (size_t)ret
>= len
)
583 ret
= stat(path
, &sb
);
587 f
= fopen(path
, "r");
591 /* Feh - sb.st_size is always 4096. */
592 fseek(f
, 0, SEEK_END
);
594 fseek(f
, 0, SEEK_SET
);
596 physname
= malloc(physlen
+ 1);
602 memset(physname
, 0, physlen
+ 1);
603 ret
= fread(physname
, 1, physlen
, f
);
608 for (i
= 0; i
< physlen
; i
++) {
609 if (physname
[i
] == '\n')
612 if (physname
[i
] == '\0')
623 static int lxc_netdev_rename_by_name_in_netns(pid_t pid
, const char *old
,
633 return wait_for_pid(fpid
);
635 if (!switch_to_ns(pid
, "net"))
638 exit(lxc_netdev_rename_by_name(old
, new));
641 static int lxc_netdev_move_wlan(char *physname
, const char *ifname
, pid_t pid
,
648 /* Move phyN into the container. TODO - do this using netlink.
649 * However, IIUC this involves a bit more complicated work to talk to
650 * the 80211 module, so for now just call out to iw.
652 cmd
= on_path("iw", NULL
);
663 sprintf(pidstr
, "%d", pid
);
664 execlp("iw", "iw", "phy", physname
, "set", "netns", pidstr
,
669 if (wait_for_pid(fpid
))
674 err
= lxc_netdev_rename_by_name_in_netns(pid
, ifname
, newname
);
681 int lxc_netdev_move_by_name(const char *ifname
, pid_t pid
, const char* newname
)
689 index
= if_nametoindex(ifname
);
693 physname
= is_wlan(ifname
);
695 return lxc_netdev_move_wlan(physname
, ifname
, pid
, newname
);
697 return lxc_netdev_move_by_index(index
, pid
, newname
);
700 int lxc_netdev_delete_by_index(int ifindex
)
703 struct ifinfomsg
*ifi
;
704 struct nl_handler nlh
;
705 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
707 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
712 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
716 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
720 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_ACK
| NLM_F_REQUEST
;
721 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_DELLINK
;
723 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
726 ifi
->ifi_family
= AF_UNSPEC
;
727 ifi
->ifi_index
= ifindex
;
729 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
737 int lxc_netdev_delete_by_name(const char *name
)
741 index
= if_nametoindex(name
);
745 return lxc_netdev_delete_by_index(index
);
748 int lxc_netdev_rename_by_index(int ifindex
, const char *newname
)
751 struct ifinfomsg
*ifi
;
752 struct nl_handler nlh
;
753 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
755 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
759 len
= strlen(newname
);
760 if (len
== 1 || len
>= IFNAMSIZ
)
764 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
768 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
772 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_ACK
| NLM_F_REQUEST
;
773 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
775 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
778 ifi
->ifi_family
= AF_UNSPEC
;
779 ifi
->ifi_index
= ifindex
;
781 if (nla_put_string(nlmsg
, IFLA_IFNAME
, newname
))
784 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
792 int lxc_netdev_rename_by_name(const char *oldname
, const char *newname
)
796 len
= strlen(oldname
);
797 if (len
== 1 || len
>= IFNAMSIZ
)
800 index
= if_nametoindex(oldname
);
804 return lxc_netdev_rename_by_index(index
, newname
);
807 int netdev_set_flag(const char *name
, int flag
)
810 struct ifinfomsg
*ifi
;
811 struct nl_handler nlh
;
812 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
814 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
820 if (len
== 1 || len
>= IFNAMSIZ
)
824 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
828 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
833 index
= if_nametoindex(name
);
837 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
838 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
840 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
845 ifi
->ifi_family
= AF_UNSPEC
;
846 ifi
->ifi_index
= index
;
847 ifi
->ifi_change
|= IFF_UP
;
848 ifi
->ifi_flags
|= flag
;
850 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
858 int netdev_get_flag(const char *name
, int *flag
)
861 struct ifinfomsg
*ifi
;
862 struct nl_handler nlh
;
863 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
868 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
874 if (len
== 1 || len
>= IFNAMSIZ
)
878 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
882 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
887 index
= if_nametoindex(name
);
891 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
;
892 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETLINK
;
894 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
899 ifi
->ifi_family
= AF_UNSPEC
;
900 ifi
->ifi_index
= index
;
902 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
906 ifi
= NLMSG_DATA(answer
->nlmsghdr
);
908 *flag
= ifi
->ifi_flags
;
917 * \brief Check a interface is up or not.
919 * \param name: name for the interface.
922 * 0 means interface is down.
923 * 1 means interface is up.
924 * Others means error happened, and ret-value is the error number.
926 int lxc_netdev_isup(const char *name
)
930 err
= netdev_get_flag(name
, &flag
);
940 int netdev_get_mtu(int ifindex
)
942 int answer_len
, err
, res
;
943 struct nl_handler nlh
;
944 struct ifinfomsg
*ifi
;
945 struct nlmsghdr
*msg
;
946 int readmore
= 0, recv_len
= 0;
947 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
949 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
954 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
958 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
962 /* Save the answer buffer length, since it will be overwritten
963 * on the first receive (and we might need to receive more than
966 answer_len
= answer
->nlmsghdr
->nlmsg_len
;
968 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_DUMP
;
969 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETLINK
;
971 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
974 ifi
->ifi_family
= AF_UNSPEC
;
976 /* Send the request for addresses, which returns all addresses
977 * on all interfaces. */
978 err
= netlink_send(&nlh
, nlmsg
);
983 /* Restore the answer buffer length, it might have been
984 * overwritten by a previous receive.
986 answer
->nlmsghdr
->nlmsg_len
= answer_len
;
988 /* Get the (next) batch of reply messages */
989 err
= netlink_rcv(&nlh
, answer
);
995 /* Satisfy the typing for the netlink macros */
996 msg
= answer
->nlmsghdr
;
998 while (NLMSG_OK(msg
, recv_len
)) {
1000 /* Stop reading if we see an error message */
1001 if (msg
->nlmsg_type
== NLMSG_ERROR
) {
1002 struct nlmsgerr
*errmsg
=
1003 (struct nlmsgerr
*)NLMSG_DATA(msg
);
1004 err
= errmsg
->error
;
1008 /* Stop reading if we see a NLMSG_DONE message */
1009 if (msg
->nlmsg_type
== NLMSG_DONE
) {
1014 ifi
= NLMSG_DATA(msg
);
1015 if (ifi
->ifi_index
== ifindex
) {
1016 struct rtattr
*rta
= IFLA_RTA(ifi
);
1018 msg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
1020 while (RTA_OK(rta
, attr_len
)) {
1021 /* Found a local address for the
1022 * requested interface, return it.
1024 if (rta
->rta_type
== IFLA_MTU
) {
1025 memcpy(&res
, RTA_DATA(rta
),
1030 rta
= RTA_NEXT(rta
, attr_len
);
1034 /* Keep reading more data from the socket if the last
1035 * message had the NLF_F_MULTI flag set.
1037 readmore
= (msg
->nlmsg_flags
& NLM_F_MULTI
);
1039 /* Look at the next message received in this buffer. */
1040 msg
= NLMSG_NEXT(msg
, recv_len
);
1044 /* If we end up here, we didn't find any result, so signal an error. */
1048 netlink_close(&nlh
);
1054 int lxc_netdev_set_mtu(const char *name
, int mtu
)
1056 int err
, index
, len
;
1057 struct ifinfomsg
*ifi
;
1058 struct nl_handler nlh
;
1059 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1061 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1067 if (len
== 1 || len
>= IFNAMSIZ
)
1071 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1075 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1080 index
= if_nametoindex(name
);
1084 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1085 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1087 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1092 ifi
->ifi_family
= AF_UNSPEC
;
1093 ifi
->ifi_index
= index
;
1095 if (nla_put_u32(nlmsg
, IFLA_MTU
, mtu
))
1098 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1100 netlink_close(&nlh
);
1106 int lxc_netdev_up(const char *name
)
1108 return netdev_set_flag(name
, IFF_UP
);
1111 int lxc_netdev_down(const char *name
)
1113 return netdev_set_flag(name
, 0);
1116 int lxc_veth_create(const char *name1
, const char *name2
)
1119 struct ifinfomsg
*ifi
;
1120 struct nl_handler nlh
;
1121 struct rtattr
*nest1
, *nest2
, *nest3
;
1122 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1124 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1129 len
= strlen(name1
);
1130 if (len
== 1 || len
>= IFNAMSIZ
)
1133 len
= strlen(name2
);
1134 if (len
== 1 || len
>= IFNAMSIZ
)
1138 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1142 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1146 nlmsg
->nlmsghdr
->nlmsg_flags
=
1147 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1148 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1150 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1153 ifi
->ifi_family
= AF_UNSPEC
;
1156 nest1
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1160 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "veth"))
1163 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1167 nest3
= nla_begin_nested(nlmsg
, VETH_INFO_PEER
);
1171 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1177 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name2
))
1180 nla_end_nested(nlmsg
, nest3
);
1181 nla_end_nested(nlmsg
, nest2
);
1182 nla_end_nested(nlmsg
, nest1
);
1184 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name1
))
1187 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1189 netlink_close(&nlh
);
1195 /* TODO: merge with lxc_macvlan_create */
1196 int lxc_vlan_create(const char *master
, const char *name
, unsigned short vlanid
)
1198 int err
, len
, lindex
;
1199 struct ifinfomsg
*ifi
;
1200 struct nl_handler nlh
;
1201 struct rtattr
*nest
, *nest2
;
1202 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1204 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1209 len
= strlen(master
);
1210 if (len
== 1 || len
>= IFNAMSIZ
)
1214 if (len
== 1 || len
>= IFNAMSIZ
)
1218 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1222 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1227 lindex
= if_nametoindex(master
);
1231 nlmsg
->nlmsghdr
->nlmsg_flags
=
1232 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1233 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1235 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1240 ifi
->ifi_family
= AF_UNSPEC
;
1242 nest
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1246 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "vlan"))
1249 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1253 if (nla_put_u16(nlmsg
, IFLA_VLAN_ID
, vlanid
))
1256 nla_end_nested(nlmsg
, nest2
);
1257 nla_end_nested(nlmsg
, nest
);
1259 if (nla_put_u32(nlmsg
, IFLA_LINK
, lindex
))
1262 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name
))
1265 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1271 netlink_close(&nlh
);
1275 int lxc_macvlan_create(const char *master
, const char *name
, int mode
)
1277 int err
, index
, len
;
1278 struct ifinfomsg
*ifi
;
1279 struct nl_handler nlh
;
1280 struct rtattr
*nest
, *nest2
;
1281 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1283 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1288 len
= strlen(master
);
1289 if (len
== 1 || len
>= IFNAMSIZ
)
1293 if (len
== 1 || len
>= IFNAMSIZ
)
1297 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1301 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1306 index
= if_nametoindex(master
);
1310 nlmsg
->nlmsghdr
->nlmsg_flags
=
1311 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1312 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1314 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1319 ifi
->ifi_family
= AF_UNSPEC
;
1321 nest
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1325 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "macvlan"))
1329 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1333 if (nla_put_u32(nlmsg
, IFLA_MACVLAN_MODE
, mode
))
1336 nla_end_nested(nlmsg
, nest2
);
1339 nla_end_nested(nlmsg
, nest
);
1341 if (nla_put_u32(nlmsg
, IFLA_LINK
, index
))
1344 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name
))
1347 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1349 netlink_close(&nlh
);
1355 static int proc_sys_net_write(const char *path
, const char *value
)
1360 fd
= open(path
, O_WRONLY
);
1364 if (write(fd
, value
, strlen(value
)) < 0)
1371 static int neigh_proxy_set(const char *ifname
, int family
, int flag
)
1374 char path
[MAXPATHLEN
];
1376 if (family
!= AF_INET
&& family
!= AF_INET6
)
1379 ret
= snprintf(path
, MAXPATHLEN
, "/proc/sys/net/%s/conf/%s/%s",
1380 family
== AF_INET
? "ipv4" : "ipv6", ifname
,
1381 family
== AF_INET
? "proxy_arp" : "proxy_ndp");
1382 if (ret
< 0 || (size_t)ret
>= MAXPATHLEN
)
1385 return proc_sys_net_write(path
, flag
? "1" : "0");
1388 int lxc_neigh_proxy_on(const char *name
, int family
)
1390 return neigh_proxy_set(name
, family
, 1);
1393 int lxc_neigh_proxy_off(const char *name
, int family
)
1395 return neigh_proxy_set(name
, family
, 0);
1398 int lxc_convert_mac(char *macaddr
, struct sockaddr
*sockaddr
)
1403 unsigned char *data
;
1405 sockaddr
->sa_family
= ARPHRD_ETHER
;
1406 data
= (unsigned char *)sockaddr
->sa_data
;
1408 while ((*macaddr
!= '\0') && (i
< ETH_ALEN
)) {
1412 else if (c
>= 'a' && c
<= 'f')
1414 else if (c
>= 'A' && c
<= 'F')
1423 else if (c
>= 'a' && c
<= 'f')
1424 val
|= c
- 'a' + 10;
1425 else if (c
>= 'A' && c
<= 'F')
1426 val
|= c
- 'A' + 10;
1427 else if (c
== ':' || c
== 0)
1433 *data
++ = (unsigned char)(val
& 0377);
1436 if (*macaddr
== ':')
1443 static int ip_addr_add(int family
, int ifindex
, void *addr
, void *bcast
,
1444 void *acast
, int prefix
)
1447 struct ifaddrmsg
*ifa
;
1448 struct nl_handler nlh
;
1449 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1451 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1452 : sizeof(struct in6_addr
);
1454 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1459 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1463 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1467 nlmsg
->nlmsghdr
->nlmsg_flags
=
1468 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1469 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWADDR
;
1471 ifa
= nlmsg_reserve(nlmsg
, sizeof(struct ifaddrmsg
));
1474 ifa
->ifa_prefixlen
= prefix
;
1475 ifa
->ifa_index
= ifindex
;
1476 ifa
->ifa_family
= family
;
1480 if (nla_put_buffer(nlmsg
, IFA_LOCAL
, addr
, addrlen
))
1483 if (nla_put_buffer(nlmsg
, IFA_ADDRESS
, addr
, addrlen
))
1486 if (nla_put_buffer(nlmsg
, IFA_BROADCAST
, bcast
, addrlen
))
1489 /* TODO: multicast, anycast with ipv6 */
1490 err
= -EPROTONOSUPPORT
;
1491 if (family
== AF_INET6
&&
1492 (memcmp(bcast
, &in6addr_any
, sizeof(in6addr_any
)) ||
1493 memcmp(acast
, &in6addr_any
, sizeof(in6addr_any
))))
1496 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1498 netlink_close(&nlh
);
1504 int lxc_ipv6_addr_add(int ifindex
, struct in6_addr
*addr
,
1505 struct in6_addr
*mcast
, struct in6_addr
*acast
,
1508 return ip_addr_add(AF_INET6
, ifindex
, addr
, mcast
, acast
, prefix
);
1511 int lxc_ipv4_addr_add(int ifindex
, struct in_addr
*addr
, struct in_addr
*bcast
,
1514 return ip_addr_add(AF_INET
, ifindex
, addr
, bcast
, NULL
, prefix
);
1517 /* Find an IFA_LOCAL (or IFA_ADDRESS if not IFA_LOCAL is present) address from
1518 * the given RTM_NEWADDR message. Allocates memory for the address and stores
1519 * that pointer in *res (so res should be an in_addr** or in6_addr**).
1521 static int ifa_get_local_ip(int family
, struct nlmsghdr
*msg
, void **res
)
1524 struct ifaddrmsg
*ifa
= NLMSG_DATA(msg
);
1525 struct rtattr
*rta
= IFA_RTA(ifa
);
1526 int attr_len
= NLMSG_PAYLOAD(msg
, sizeof(struct ifaddrmsg
));
1528 if (ifa
->ifa_family
!= family
)
1531 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1532 : sizeof(struct in6_addr
);
1534 /* Loop over the rtattr's in this message */
1535 while (RTA_OK(rta
, attr_len
)) {
1536 /* Found a local address for the requested interface,
1539 if (rta
->rta_type
== IFA_LOCAL
||
1540 rta
->rta_type
== IFA_ADDRESS
) {
1541 /* Sanity check. The family check above should make sure
1542 * the address length is correct, but check here just in
1545 if (RTA_PAYLOAD(rta
) != addrlen
)
1548 /* We might have found an IFA_ADDRESS before, which we
1549 * now overwrite with an IFA_LOCAL.
1552 *res
= malloc(addrlen
);
1557 memcpy(*res
, RTA_DATA(rta
), addrlen
);
1558 if (rta
->rta_type
== IFA_LOCAL
)
1561 rta
= RTA_NEXT(rta
, attr_len
);
1566 static int ip_addr_get(int family
, int ifindex
, void **res
)
1568 int answer_len
, err
;
1569 struct ifaddrmsg
*ifa
;
1570 struct nl_handler nlh
;
1571 struct nlmsghdr
*msg
;
1572 int readmore
= 0, recv_len
= 0;
1573 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1575 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1580 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1584 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1588 /* Save the answer buffer length, since it will be overwritten on the
1589 * first receive (and we might need to receive more than once).
1591 answer_len
= answer
->nlmsghdr
->nlmsg_len
;
1593 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ROOT
;
1594 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETADDR
;
1596 ifa
= nlmsg_reserve(nlmsg
, sizeof(struct ifaddrmsg
));
1599 ifa
->ifa_family
= family
;
1601 /* Send the request for addresses, which returns all addresses on all
1604 err
= netlink_send(&nlh
, nlmsg
);
1609 /* Restore the answer buffer length, it might have been
1610 * overwritten by a previous receive.
1612 answer
->nlmsghdr
->nlmsg_len
= answer_len
;
1614 /* Get the (next) batch of reply messages. */
1615 err
= netlink_rcv(&nlh
, answer
);
1622 /* Satisfy the typing for the netlink macros. */
1623 msg
= answer
->nlmsghdr
;
1625 while (NLMSG_OK(msg
, recv_len
)) {
1626 /* Stop reading if we see an error message. */
1627 if (msg
->nlmsg_type
== NLMSG_ERROR
) {
1628 struct nlmsgerr
*errmsg
=
1629 (struct nlmsgerr
*)NLMSG_DATA(msg
);
1630 err
= errmsg
->error
;
1634 /* Stop reading if we see a NLMSG_DONE message. */
1635 if (msg
->nlmsg_type
== NLMSG_DONE
) {
1640 if (msg
->nlmsg_type
!= RTM_NEWADDR
) {
1645 ifa
= (struct ifaddrmsg
*)NLMSG_DATA(msg
);
1646 if (ifa
->ifa_index
== ifindex
) {
1647 if (ifa_get_local_ip(family
, msg
, res
) < 0) {
1652 /* Found a result, stop searching. */
1657 /* Keep reading more data from the socket if the last
1658 * message had the NLF_F_MULTI flag set.
1660 readmore
= (msg
->nlmsg_flags
& NLM_F_MULTI
);
1662 /* Look at the next message received in this buffer. */
1663 msg
= NLMSG_NEXT(msg
, recv_len
);
1667 /* If we end up here, we didn't find any result, so signal an
1673 netlink_close(&nlh
);
1679 int lxc_ipv6_addr_get(int ifindex
, struct in6_addr
**res
)
1681 return ip_addr_get(AF_INET6
, ifindex
, (void **)res
);
1684 int lxc_ipv4_addr_get(int ifindex
, struct in_addr
**res
)
1686 return ip_addr_get(AF_INET
, ifindex
, (void **)res
);
1689 static int ip_gateway_add(int family
, int ifindex
, void *gw
)
1692 struct nl_handler nlh
;
1694 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1696 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1697 : sizeof(struct in6_addr
);
1699 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1704 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1708 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1712 nlmsg
->nlmsghdr
->nlmsg_flags
=
1713 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1714 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWROUTE
;
1716 rt
= nlmsg_reserve(nlmsg
, sizeof(struct rtmsg
));
1719 rt
->rtm_family
= family
;
1720 rt
->rtm_table
= RT_TABLE_MAIN
;
1721 rt
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1722 rt
->rtm_protocol
= RTPROT_BOOT
;
1723 rt
->rtm_type
= RTN_UNICAST
;
1724 /* "default" destination */
1725 rt
->rtm_dst_len
= 0;
1728 if (nla_put_buffer(nlmsg
, RTA_GATEWAY
, gw
, addrlen
))
1731 /* Adding the interface index enables the use of link-local
1732 * addresses for the gateway.
1734 if (nla_put_u32(nlmsg
, RTA_OIF
, ifindex
))
1737 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1739 netlink_close(&nlh
);
1745 int lxc_ipv4_gateway_add(int ifindex
, struct in_addr
*gw
)
1747 return ip_gateway_add(AF_INET
, ifindex
, gw
);
1750 int lxc_ipv6_gateway_add(int ifindex
, struct in6_addr
*gw
)
1752 return ip_gateway_add(AF_INET6
, ifindex
, gw
);
1755 static int ip_route_dest_add(int family
, int ifindex
, void *dest
)
1758 struct nl_handler nlh
;
1760 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1762 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1763 : sizeof(struct in6_addr
);
1765 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1770 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1774 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1778 nlmsg
->nlmsghdr
->nlmsg_flags
=
1779 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1780 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWROUTE
;
1782 rt
= nlmsg_reserve(nlmsg
, sizeof(struct rtmsg
));
1785 rt
->rtm_family
= family
;
1786 rt
->rtm_table
= RT_TABLE_MAIN
;
1787 rt
->rtm_scope
= RT_SCOPE_LINK
;
1788 rt
->rtm_protocol
= RTPROT_BOOT
;
1789 rt
->rtm_type
= RTN_UNICAST
;
1790 rt
->rtm_dst_len
= addrlen
* 8;
1793 if (nla_put_buffer(nlmsg
, RTA_DST
, dest
, addrlen
))
1795 if (nla_put_u32(nlmsg
, RTA_OIF
, ifindex
))
1797 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1799 netlink_close(&nlh
);
1805 int lxc_ipv4_dest_add(int ifindex
, struct in_addr
*dest
)
1807 return ip_route_dest_add(AF_INET
, ifindex
, dest
);
1810 int lxc_ipv6_dest_add(int ifindex
, struct in6_addr
*dest
)
1812 return ip_route_dest_add(AF_INET6
, ifindex
, dest
);
1815 bool is_ovs_bridge(const char *bridge
)
1819 char brdirname
[22 + IFNAMSIZ
+ 1] = {0};
1821 ret
= snprintf(brdirname
, 22 + IFNAMSIZ
+ 1, "/sys/class/net/%s/bridge",
1823 if (ret
< 0 || (size_t)ret
>= 22 + IFNAMSIZ
+ 1)
1826 ret
= stat(brdirname
, &sb
);
1827 if (ret
< 0 && errno
== ENOENT
)
1833 struct ovs_veth_args
{
1838 /* Called from a background thread - when nic goes away, remove it from the
1841 static int lxc_ovs_delete_port_exec(void *data
)
1843 struct ovs_veth_args
*args
= data
;
1845 execlp("ovs-vsctl", "ovs-vsctl", "del-port", args
->bridge
, args
->nic
,
1850 int lxc_ovs_delete_port(const char *bridge
, const char *nic
)
1853 char cmd_output
[MAXPATHLEN
];
1854 struct ovs_veth_args args
;
1856 args
.bridge
= bridge
;
1858 ret
= run_command(cmd_output
, sizeof(cmd_output
),
1859 lxc_ovs_delete_port_exec
, (void *)&args
);
1861 ERROR("Failed to delete \"%s\" from openvswitch bridge \"%s\": "
1862 "%s", bridge
, nic
, cmd_output
);
1869 static int lxc_ovs_attach_bridge_exec(void *data
)
1871 struct ovs_veth_args
*args
= data
;
1873 execlp("ovs-vsctl", "ovs-vsctl", "add-port", args
->bridge
, args
->nic
,
1878 static int lxc_ovs_attach_bridge(const char *bridge
, const char *nic
)
1881 char cmd_output
[MAXPATHLEN
];
1882 struct ovs_veth_args args
;
1884 args
.bridge
= bridge
;
1886 ret
= run_command(cmd_output
, sizeof(cmd_output
),
1887 lxc_ovs_attach_bridge_exec
, (void *)&args
);
1889 ERROR("Failed to attach \"%s\" to openvswitch bridge \"%s\": %s",
1890 bridge
, nic
, cmd_output
);
1897 int lxc_bridge_attach(const char *bridge
, const char *ifname
)
1902 if (strlen(ifname
) >= IFNAMSIZ
)
1905 index
= if_nametoindex(ifname
);
1909 if (is_ovs_bridge(bridge
))
1910 return lxc_ovs_attach_bridge(bridge
, ifname
);
1912 fd
= socket(AF_INET
, SOCK_STREAM
, 0);
1916 strncpy(ifr
.ifr_name
, bridge
, IFNAMSIZ
- 1);
1917 ifr
.ifr_name
[IFNAMSIZ
- 1] = '\0';
1918 ifr
.ifr_ifindex
= index
;
1919 err
= ioctl(fd
, SIOCBRADDIF
, &ifr
);
1927 static const char *const lxc_network_types
[LXC_NET_MAXCONFTYPE
+ 1] = {
1928 [LXC_NET_EMPTY
] = "empty",
1929 [LXC_NET_VETH
] = "veth",
1930 [LXC_NET_MACVLAN
] = "macvlan",
1931 [LXC_NET_PHYS
] = "phys",
1932 [LXC_NET_VLAN
] = "vlan",
1933 [LXC_NET_NONE
] = "none",
1936 const char *lxc_net_type_to_str(int type
)
1938 if (type
< 0 || type
> LXC_NET_MAXCONFTYPE
)
1941 return lxc_network_types
[type
];
1944 static const char padchar
[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1946 char *lxc_mkifname(char *template)
1951 struct ifaddrs
*ifa
, *ifaddr
;
1952 char name
[IFNAMSIZ
];
1953 bool exists
= false;
1956 if (strlen(template) >= IFNAMSIZ
)
1959 /* Get all the network interfaces. */
1960 ret
= getifaddrs(&ifaddr
);
1962 ERROR("%s - Failed to get network interfaces", strerror(errno
));
1966 /* Initialize the random number generator. */
1967 urandom
= fopen("/dev/urandom", "r");
1968 if (urandom
!= NULL
) {
1969 if (fread(&seed
, sizeof(seed
), 1, urandom
) <= 0)
1980 /* Generate random names until we find one that doesn't exist. */
1983 strcpy(name
, template);
1986 for (i
= 0; i
< strlen(name
); i
++) {
1987 if (name
[i
] == 'X') {
1989 name
[i
] = padchar
[rand_r(&seed
) % (strlen(padchar
) - 1)];
1991 name
[i
] = padchar
[rand() % (strlen(padchar
) - 1)];
1996 for (ifa
= ifaddr
; ifa
!= NULL
; ifa
= ifa
->ifa_next
) {
1997 if (!strcmp(ifa
->ifa_name
, name
)) {
2007 freeifaddrs(ifaddr
);
2008 return strcpy(template, name
);
2011 int setup_private_host_hw_addr(char *veth1
)
2016 sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
2020 err
= snprintf((char *)ifr
.ifr_name
, IFNAMSIZ
, "%s", veth1
);
2021 if (err
< 0 || (size_t)err
>= IFNAMSIZ
)
2024 err
= ioctl(sockfd
, SIOCGIFHWADDR
, &ifr
);
2030 ifr
.ifr_hwaddr
.sa_data
[0] = 0xfe;
2031 err
= ioctl(sockfd
, SIOCSIFHWADDR
, &ifr
);
2039 int lxc_find_gateway_addresses(struct lxc_handler
*handler
)
2041 struct lxc_list
*network
= &handler
->conf
->network
;
2042 struct lxc_list
*iterator
;
2043 struct lxc_netdev
*netdev
;
2046 lxc_list_for_each(iterator
, network
) {
2047 netdev
= iterator
->elem
;
2049 if (!netdev
->ipv4_gateway_auto
&& !netdev
->ipv6_gateway_auto
)
2052 if (netdev
->type
!= LXC_NET_VETH
&& netdev
->type
!= LXC_NET_MACVLAN
) {
2053 ERROR("Automatic gateway detection is only supported "
2054 "for veth and macvlan");
2058 if (netdev
->link
[0] == '\0') {
2059 ERROR("Automatic gateway detection needs a link interface");
2063 link_index
= if_nametoindex(netdev
->link
);
2067 if (netdev
->ipv4_gateway_auto
) {
2068 if (lxc_ipv4_addr_get(link_index
, &netdev
->ipv4_gateway
)) {
2069 ERROR("Failed to automatically find ipv4 gateway "
2070 "address from link interface \"%s\"", netdev
->link
);
2075 if (netdev
->ipv6_gateway_auto
) {
2076 if (lxc_ipv6_addr_get(link_index
, &netdev
->ipv6_gateway
)) {
2077 ERROR("Failed to automatically find ipv6 gateway "
2078 "address from link interface \"%s\"", netdev
->link
);
2087 #define LXC_USERNIC_PATH LIBEXECDIR "/lxc/lxc-user-nic"
2088 static int lxc_create_network_unpriv_exec(const char *lxcpath
, const char *lxcname
,
2089 struct lxc_netdev
*netdev
, pid_t pid
)
2093 int bytes
, pipefd
[2];
2094 char *token
, *saveptr
= NULL
;
2095 char netdev_link
[IFNAMSIZ
+ 1];
2096 char buffer
[MAXPATHLEN
] = {0};
2098 if (netdev
->type
!= LXC_NET_VETH
) {
2099 ERROR("Network type %d not support for unprivileged use", netdev
->type
);
2105 SYSERROR("Failed to create pipe");
2111 SYSERROR("Failed to create new process");
2119 char pidstr
[LXC_NUMSTRLEN64
];
2123 ret
= dup2(pipefd
[1], STDOUT_FILENO
);
2125 ret
= dup2(pipefd
[1], STDERR_FILENO
);
2128 SYSERROR("Failed to duplicate std{err,out} file descriptor");
2132 if (netdev
->link
[0] != '\0')
2133 strncpy(netdev_link
, netdev
->link
, IFNAMSIZ
);
2135 strncpy(netdev_link
, "none", IFNAMSIZ
);
2137 ret
= snprintf(pidstr
, LXC_NUMSTRLEN64
, "%d", pid
);
2138 if (ret
< 0 || ret
>= LXC_NUMSTRLEN64
)
2140 pidstr
[LXC_NUMSTRLEN64
- 1] = '\0';
2142 INFO("Execing lxc-user-nic create %s %s %s veth %s %s", lxcpath
,
2143 lxcname
, pidstr
, netdev_link
,
2144 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)");
2145 if (netdev
->name
[0] != '\0')
2146 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "create",
2147 lxcpath
, lxcname
, pidstr
, "veth", netdev_link
,
2148 netdev
->name
, (char *)NULL
);
2150 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "create",
2151 lxcpath
, lxcname
, pidstr
, "veth", netdev_link
,
2153 SYSERROR("Failed to execute lxc-user-nic");
2157 /* close the write-end of the pipe */
2160 bytes
= read(pipefd
[0], &buffer
, MAXPATHLEN
);
2162 SYSERROR("Failed to read from pipe file descriptor");
2165 buffer
[bytes
- 1] = '\0';
2168 ret
= wait_for_pid(child
);
2170 if (ret
!= 0 || bytes
< 0) {
2171 ERROR("lxc-user-nic failed to configure requested network: %s",
2172 buffer
[0] != '\0' ? buffer
: "(null)");
2175 TRACE("Received output \"%s\" from lxc-user-nic", buffer
);
2178 token
= strtok_r(buffer
, ":", &saveptr
);
2180 ERROR("Failed to parse lxc-user-nic output");
2184 memset(netdev
->name
, 0, IFNAMSIZ
+ 1);
2185 strncpy(netdev
->name
, token
, IFNAMSIZ
);
2187 /* netdev->ifindex */
2188 token
= strtok_r(NULL
, ":", &saveptr
);
2190 ERROR("Failed to parse lxc-user-nic output");
2194 ret
= lxc_safe_int(token
, &netdev
->ifindex
);
2196 ERROR("%s - Failed to convert string \"%s\" to integer",
2197 strerror(-ret
), token
);
2201 /* netdev->priv.veth_attr.veth1 */
2202 token
= strtok_r(NULL
, ":", &saveptr
);
2204 ERROR("Failed to parse lxc-user-nic output");
2208 if (strlen(token
) >= IFNAMSIZ
) {
2209 ERROR("Host side veth device name returned by lxc-user-nic is "
2213 strcpy(netdev
->priv
.veth_attr
.veth1
, token
);
2215 /* netdev->priv.veth_attr.ifindex */
2216 token
= strtok_r(NULL
, ":", &saveptr
);
2218 ERROR("Failed to parse lxc-user-nic output");
2222 ret
= lxc_safe_int(token
, &netdev
->priv
.veth_attr
.ifindex
);
2224 ERROR("%s - Failed to convert string \"%s\" to integer",
2225 strerror(-ret
), token
);
2232 static int lxc_delete_network_unpriv_exec(const char *lxcpath
, const char *lxcname
,
2233 struct lxc_netdev
*netdev
,
2234 const char *netns_path
)
2239 char buffer
[MAXPATHLEN
] = {0};
2241 if (netdev
->type
!= LXC_NET_VETH
) {
2242 ERROR("Network type %d not support for unprivileged use", netdev
->type
);
2248 SYSERROR("Failed to create pipe");
2254 SYSERROR("Failed to create new process");
2266 ret
= dup2(pipefd
[1], STDOUT_FILENO
);
2268 ret
= dup2(pipefd
[1], STDERR_FILENO
);
2271 SYSERROR("Failed to duplicate std{err,out} file descriptor");
2275 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2276 hostveth
= netdev
->priv
.veth_attr
.pair
;
2278 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2279 if (hostveth
[0] == '\0') {
2280 SYSERROR("Host side veth device name is missing");
2284 if (netdev
->link
[0] == '\0') {
2285 SYSERROR("Network link for network device \"%s\" is "
2286 "missing", netdev
->priv
.veth_attr
.veth1
);
2290 INFO("Execing lxc-user-nic delete %s %s %s veth %s %s", lxcpath
,
2291 lxcname
, netns_path
, netdev
->link
, hostveth
);
2292 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "delete", lxcpath
,
2293 lxcname
, netns_path
, "veth", netdev
->link
, hostveth
,
2295 SYSERROR("Failed to exec lxc-user-nic.");
2301 bytes
= read(pipefd
[0], &buffer
, MAXPATHLEN
);
2303 SYSERROR("Failed to read from pipe file descriptor.");
2306 buffer
[bytes
- 1] = '\0';
2309 ret
= wait_for_pid(child
);
2311 if (ret
!= 0 || bytes
< 0) {
2312 ERROR("lxc-user-nic failed to delete requested network: %s",
2313 buffer
[0] != '\0' ? buffer
: "(null)");
2320 bool lxc_delete_network_unpriv(struct lxc_handler
*handler
)
2323 struct lxc_list
*iterator
;
2324 struct lxc_list
*network
= &handler
->conf
->network
;
2325 /* strlen("/proc/") = 6
2329 * strlen("/fd/") = 4
2335 char netns_path
[6 + LXC_NUMSTRLEN64
+ 4 + LXC_NUMSTRLEN64
+ 1];
2339 if (handler
->nsfd
[LXC_NS_NET
] < 0) {
2340 DEBUG("Cannot not guarantee safe deletion of network devices. "
2341 "Manual cleanup maybe needed");
2345 ret
= snprintf(netns_path
, sizeof(netns_path
), "/proc/%d/fd/%d",
2346 lxc_raw_getpid(), handler
->nsfd
[LXC_NS_NET
]);
2347 if (ret
< 0 || ret
>= sizeof(netns_path
))
2350 lxc_list_for_each(iterator
, network
) {
2351 char *hostveth
= NULL
;
2352 struct lxc_netdev
*netdev
= iterator
->elem
;
2354 /* We can only delete devices whose ifindex we have. If we don't
2355 * have the index it means that we didn't create it.
2357 if (!netdev
->ifindex
)
2360 if (netdev
->type
== LXC_NET_PHYS
) {
2361 ret
= lxc_netdev_rename_by_index(netdev
->ifindex
,
2364 WARN("Failed to rename interface with index %d "
2365 "to its initial name \"%s\"",
2366 netdev
->ifindex
, netdev
->link
);
2368 TRACE("Renamed interface with index %d to its "
2369 "initial name \"%s\"",
2370 netdev
->ifindex
, netdev
->link
);
2371 goto clear_ifindices
;
2374 ret
= netdev_deconf
[netdev
->type
](handler
, netdev
);
2376 WARN("Failed to deconfigure network device");
2378 if (netdev
->type
!= LXC_NET_VETH
)
2379 goto clear_ifindices
;
2381 if (netdev
->link
[0] == '\0' || !is_ovs_bridge(netdev
->link
))
2382 goto clear_ifindices
;
2384 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2385 hostveth
= netdev
->priv
.veth_attr
.pair
;
2387 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2388 if (hostveth
[0] == '\0')
2389 goto clear_ifindices
;
2391 ret
= lxc_delete_network_unpriv_exec(handler
->lxcpath
,
2392 handler
->name
, netdev
,
2395 WARN("Failed to remove port \"%s\" from openvswitch "
2396 "bridge \"%s\"", hostveth
, netdev
->link
);
2397 goto clear_ifindices
;
2399 INFO("Removed interface \"%s\" from \"%s\"", hostveth
,
2403 /* We need to clear any ifindeces we recorded so liblxc won't
2404 * have cached stale data which would cause it to fail on reboot
2405 * we're we don't re-read the on-disk config file.
2407 netdev
->ifindex
= 0;
2408 if (netdev
->type
== LXC_NET_PHYS
) {
2409 netdev
->priv
.phys_attr
.ifindex
= 0;
2410 } else if (netdev
->type
== LXC_NET_VETH
) {
2411 netdev
->priv
.veth_attr
.veth1
[0] = '\0';
2412 netdev
->priv
.veth_attr
.ifindex
= 0;
2419 int lxc_create_network_priv(struct lxc_handler
*handler
)
2421 struct lxc_list
*iterator
;
2422 struct lxc_list
*network
= &handler
->conf
->network
;
2424 if (!handler
->am_root
)
2427 lxc_list_for_each(iterator
, network
) {
2428 struct lxc_netdev
*netdev
= iterator
->elem
;
2430 if (netdev
->type
< 0 || netdev
->type
> LXC_NET_MAXCONFTYPE
) {
2431 ERROR("Invalid network configuration type %d", netdev
->type
);
2435 if (netdev_conf
[netdev
->type
](handler
, netdev
)) {
2436 ERROR("Failed to create network device");
2445 int lxc_network_move_created_netdev_priv(const char *lxcpath
, const char *lxcname
,
2446 struct lxc_list
*network
, pid_t pid
)
2449 char ifname
[IFNAMSIZ
];
2450 struct lxc_list
*iterator
;
2452 if (am_guest_unpriv())
2455 lxc_list_for_each(iterator
, network
) {
2456 struct lxc_netdev
*netdev
= iterator
->elem
;
2458 if (!netdev
->ifindex
)
2461 /* retrieve the name of the interface */
2462 if (!if_indextoname(netdev
->ifindex
, ifname
)) {
2463 ERROR("No interface corresponding to ifindex \"%d\"",
2468 ret
= lxc_netdev_move_by_name(ifname
, pid
, NULL
);
2470 ERROR("Failed to move network device \"%s\" to "
2471 "network namespace %d: %s", ifname
, pid
,
2476 DEBUG("Moved network device \"%s\"/\"%s\" to network namespace "
2478 ifname
, netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2485 int lxc_create_network_unpriv(const char *lxcpath
, const char *lxcname
,
2486 struct lxc_list
*network
, pid_t pid
)
2488 struct lxc_list
*iterator
;
2490 if (!am_guest_unpriv())
2493 lxc_list_for_each(iterator
, network
) {
2494 struct lxc_netdev
*netdev
= iterator
->elem
;
2496 if (netdev
->type
== LXC_NET_EMPTY
)
2499 if (netdev
->type
== LXC_NET_NONE
)
2502 if (netdev
->type
!= LXC_NET_VETH
) {
2503 ERROR("Networks of type %s are not supported by "
2504 "unprivileged containers",
2505 lxc_net_type_to_str(netdev
->type
));
2510 INFO("mtu ignored due to insufficient privilege");
2512 if (lxc_create_network_unpriv_exec(lxcpath
, lxcname
, netdev
, pid
))
2519 bool lxc_delete_network_priv(struct lxc_handler
*handler
)
2522 struct lxc_list
*iterator
;
2523 struct lxc_list
*network
= &handler
->conf
->network
;
2525 lxc_list_for_each(iterator
, network
) {
2526 char *hostveth
= NULL
;
2527 struct lxc_netdev
*netdev
= iterator
->elem
;
2529 /* We can only delete devices whose ifindex we have. If we don't
2530 * have the index it means that we didn't create it.
2532 if (!netdev
->ifindex
)
2535 if (netdev
->type
== LXC_NET_PHYS
) {
2536 ret
= lxc_netdev_rename_by_index(netdev
->ifindex
, netdev
->link
);
2538 WARN("Failed to rename interface with index %d "
2539 "from \"%s\" to its initial name \"%s\"",
2540 netdev
->ifindex
, netdev
->name
, netdev
->link
);
2542 TRACE("Renamed interface with index %d from "
2543 "\"%s\" to its initial name \"%s\"",
2544 netdev
->ifindex
, netdev
->name
,
2546 goto clear_ifindices
;
2549 ret
= netdev_deconf
[netdev
->type
](handler
, netdev
);
2551 WARN("Failed to deconfigure network device");
2553 /* Recent kernels remove the virtual interfaces when the network
2554 * namespace is destroyed but in case we did not move the
2555 * interface to the network namespace, we have to destroy it.
2557 ret
= lxc_netdev_delete_by_index(netdev
->ifindex
);
2558 if (-ret
== ENODEV
) {
2559 INFO("Interface \"%s\" with index %d already "
2560 "deleted or existing in different network "
2562 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2564 } else if (ret
< 0) {
2565 WARN("Failed to remove interface \"%s\" with "
2567 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2568 netdev
->ifindex
, strerror(-ret
));
2569 goto clear_ifindices
;
2571 INFO("Removed interface \"%s\" with index %d",
2572 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2575 if (netdev
->type
!= LXC_NET_VETH
)
2576 goto clear_ifindices
;
2578 /* Explicitly delete host veth device to prevent lingering
2579 * devices. We had issues in LXD around this.
2581 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2582 hostveth
= netdev
->priv
.veth_attr
.pair
;
2584 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2585 if (hostveth
[0] == '\0')
2586 goto clear_ifindices
;
2588 ret
= lxc_netdev_delete_by_name(hostveth
);
2590 WARN("Failed to remove interface \"%s\" from \"%s\": %s",
2591 hostveth
, netdev
->link
, strerror(-ret
));
2592 goto clear_ifindices
;
2594 INFO("Removed interface \"%s\" from \"%s\"", hostveth
, netdev
->link
);
2596 if (netdev
->link
[0] == '\0' || !is_ovs_bridge(netdev
->link
)) {
2597 netdev
->priv
.veth_attr
.veth1
[0] = '\0';
2598 netdev
->ifindex
= 0;
2599 netdev
->priv
.veth_attr
.ifindex
= 0;
2600 goto clear_ifindices
;
2603 /* Delete the openvswitch port. */
2604 ret
= lxc_ovs_delete_port(netdev
->link
, hostveth
);
2606 WARN("Failed to remove port \"%s\" from openvswitch "
2607 "bridge \"%s\"", hostveth
, netdev
->link
);
2609 INFO("Removed port \"%s\" from openvswitch bridge \"%s\"",
2610 hostveth
, netdev
->link
);
2613 /* We need to clear any ifindeces we recorded so liblxc won't
2614 * have cached stale data which would cause it to fail on reboot
2615 * we're we don't re-read the on-disk config file.
2617 netdev
->ifindex
= 0;
2618 if (netdev
->type
== LXC_NET_PHYS
) {
2619 netdev
->priv
.phys_attr
.ifindex
= 0;
2620 } else if (netdev
->type
== LXC_NET_VETH
) {
2621 netdev
->priv
.veth_attr
.veth1
[0] = '\0';
2622 netdev
->priv
.veth_attr
.ifindex
= 0;
2629 int lxc_requests_empty_network(struct lxc_handler
*handler
)
2631 struct lxc_list
*network
= &handler
->conf
->network
;
2632 struct lxc_list
*iterator
;
2633 bool found_none
= false, found_nic
= false;
2635 if (lxc_list_empty(network
))
2638 lxc_list_for_each(iterator
, network
) {
2639 struct lxc_netdev
*netdev
= iterator
->elem
;
2641 if (netdev
->type
== LXC_NET_NONE
)
2646 if (found_none
&& !found_nic
)
2651 /* try to move physical nics to the init netns */
2652 int lxc_restore_phys_nics_to_netns(struct lxc_handler
*handler
)
2656 char ifname
[IFNAMSIZ
];
2657 struct lxc_list
*iterator
;
2658 int netnsfd
= handler
->nsfd
[LXC_NS_NET
];
2659 struct lxc_conf
*conf
= handler
->conf
;
2661 /* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
2662 * the parent network namespace. We won't have this capability if we are
2665 if (!handler
->am_root
)
2668 TRACE("Moving physical network devices back to parent network namespace");
2670 oldfd
= lxc_preserve_ns(lxc_raw_getpid(), "net");
2672 SYSERROR("Failed to preserve network namespace");
2676 ret
= setns(netnsfd
, CLONE_NEWNET
);
2678 SYSERROR("Failed to enter network namespace");
2683 lxc_list_for_each(iterator
, &conf
->network
) {
2684 struct lxc_netdev
*netdev
= iterator
->elem
;
2686 if (netdev
->type
!= LXC_NET_PHYS
)
2689 /* Retrieve the name of the interface in the container's network
2692 if (!if_indextoname(netdev
->ifindex
, ifname
)) {
2693 WARN("No interface corresponding to ifindex %d",
2698 ret
= lxc_netdev_move_by_name(ifname
, 1, netdev
->link
);
2700 WARN("Error moving network device \"%s\" back to "
2701 "network namespace", ifname
);
2703 TRACE("Moved network device \"%s\" back to network "
2704 "namespace", ifname
);
2707 ret
= setns(oldfd
, CLONE_NEWNET
);
2710 SYSERROR("Failed to enter network namespace");
2717 static int setup_hw_addr(char *hwaddr
, const char *ifname
)
2719 struct sockaddr sockaddr
;
2721 int ret
, fd
, saved_errno
;
2723 ret
= lxc_convert_mac(hwaddr
, &sockaddr
);
2725 ERROR("Mac address \"%s\" conversion failed: %s", hwaddr
,
2730 memcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
2731 ifr
.ifr_name
[IFNAMSIZ
-1] = '\0';
2732 memcpy((char *) &ifr
.ifr_hwaddr
, (char *) &sockaddr
, sizeof(sockaddr
));
2734 fd
= socket(AF_INET
, SOCK_DGRAM
, 0);
2738 ret
= ioctl(fd
, SIOCSIFHWADDR
, &ifr
);
2739 saved_errno
= errno
;
2742 ERROR("Failed to perform ioctl: %s", strerror(saved_errno
));
2744 DEBUG("Mac address \"%s\" on \"%s\" has been setup", hwaddr
,
2750 static int setup_ipv4_addr(struct lxc_list
*ip
, int ifindex
)
2752 struct lxc_list
*iterator
;
2755 lxc_list_for_each(iterator
, ip
) {
2756 struct lxc_inetdev
*inetdev
= iterator
->elem
;
2758 err
= lxc_ipv4_addr_add(ifindex
, &inetdev
->addr
,
2759 &inetdev
->bcast
, inetdev
->prefix
);
2761 ERROR("Failed to setup ipv4 address for network device "
2762 "with eifindex %d: %s", ifindex
, strerror(-err
));
2770 static int setup_ipv6_addr(struct lxc_list
*ip
, int ifindex
)
2772 struct lxc_list
*iterator
;
2775 lxc_list_for_each(iterator
, ip
) {
2776 struct lxc_inet6dev
*inet6dev
= iterator
->elem
;
2778 err
= lxc_ipv6_addr_add(ifindex
, &inet6dev
->addr
,
2779 &inet6dev
->mcast
, &inet6dev
->acast
,
2782 ERROR("Failed to setup ipv6 address for network device "
2783 "with eifindex %d: %s", ifindex
, strerror(-err
));
2791 static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev
*netdev
)
2793 char ifname
[IFNAMSIZ
];
2795 const char *net_type_name
;
2796 char *current_ifname
= ifname
;
2798 /* empty network namespace */
2799 if (!netdev
->ifindex
) {
2800 if (netdev
->flags
& IFF_UP
) {
2801 err
= lxc_netdev_up("lo");
2803 ERROR("Failed to set the loopback network "
2810 if (netdev
->type
== LXC_NET_EMPTY
)
2813 if (netdev
->type
== LXC_NET_NONE
)
2816 if (netdev
->type
!= LXC_NET_VETH
) {
2817 net_type_name
= lxc_net_type_to_str(netdev
->type
);
2818 ERROR("%s networks are not supported for containers "
2819 "not setup up by privileged users", net_type_name
);
2823 netdev
->ifindex
= if_nametoindex(netdev
->name
);
2826 /* get the new ifindex in case of physical netdev */
2827 if (netdev
->type
== LXC_NET_PHYS
) {
2828 netdev
->ifindex
= if_nametoindex(netdev
->link
);
2829 if (!netdev
->ifindex
) {
2830 ERROR("Failed to get ifindex for network device \"%s\"",
2836 /* retrieve the name of the interface */
2837 if (!if_indextoname(netdev
->ifindex
, current_ifname
)) {
2838 ERROR("Failed get name for network device with ifindex %d",
2843 /* Default: let the system to choose one interface name.
2844 * When the IFLA_IFNAME attribute is passed something like "<prefix>%d"
2845 * netlink will replace the format specifier with an appropriate index.
2847 if (netdev
->name
[0] == '\0') {
2848 if (netdev
->type
== LXC_NET_PHYS
)
2849 strcpy(netdev
->name
, netdev
->link
);
2851 strcpy(netdev
->name
, "eth%d");
2854 /* rename the interface name */
2855 if (strcmp(ifname
, netdev
->name
) != 0) {
2856 err
= lxc_netdev_rename_by_name(ifname
, netdev
->name
);
2858 ERROR("Failed to rename network device \"%s\" to "
2859 "\"%s\": %s", ifname
, netdev
->name
, strerror(-err
));
2864 /* Re-read the name of the interface because its name has changed
2865 * and would be automatically allocated by the system
2867 if (!if_indextoname(netdev
->ifindex
, current_ifname
)) {
2868 ERROR("Failed get name for network device with ifindex %d",
2873 /* Now update the recorded name of the network device to reflect the
2874 * name of the network device in the child's network namespace. We will
2875 * later on send this information back to the parent.
2877 strcpy(netdev
->name
, current_ifname
);
2879 /* set a mac address */
2880 if (netdev
->hwaddr
) {
2881 if (setup_hw_addr(netdev
->hwaddr
, current_ifname
)) {
2882 ERROR("Failed to setup hw address for network device \"%s\"",
2888 /* setup ipv4 addresses on the interface */
2889 if (setup_ipv4_addr(&netdev
->ipv4
, netdev
->ifindex
)) {
2890 ERROR("Failed to setup ip addresses for network device \"%s\"",
2895 /* setup ipv6 addresses on the interface */
2896 if (setup_ipv6_addr(&netdev
->ipv6
, netdev
->ifindex
)) {
2897 ERROR("Failed to setup ipv6 addresses for network device \"%s\"",
2902 /* set the network device up */
2903 if (netdev
->flags
& IFF_UP
) {
2906 err
= lxc_netdev_up(current_ifname
);
2908 ERROR("Failed to set network device \"%s\" up: %s",
2909 current_ifname
, strerror(-err
));
2913 /* the network is up, make the loopback up too */
2914 err
= lxc_netdev_up("lo");
2916 ERROR("Failed to set the loopback network device up: %s",
2922 /* We can only set up the default routes after bringing
2923 * up the interface, sine bringing up the interface adds
2924 * the link-local routes and we can't add a default
2925 * route if the gateway is not reachable. */
2927 /* setup ipv4 gateway on the interface */
2928 if (netdev
->ipv4_gateway
) {
2929 if (!(netdev
->flags
& IFF_UP
)) {
2930 ERROR("Cannot add ipv4 gateway for network device "
2931 "\"%s\" when not bringing up the interface", ifname
);
2935 if (lxc_list_empty(&netdev
->ipv4
)) {
2936 ERROR("Cannot add ipv4 gateway for network device "
2937 "\"%s\" when not assigning an address", ifname
);
2941 err
= lxc_ipv4_gateway_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2943 err
= lxc_ipv4_dest_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2945 ERROR("Failed to add ipv4 dest for network "
2946 "device \"%s\": %s", ifname
, strerror(-err
));
2949 err
= lxc_ipv4_gateway_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2951 ERROR("Failed to setup ipv4 gateway for "
2952 "network device \"%s\": %s",
2953 ifname
, strerror(-err
));
2954 if (netdev
->ipv4_gateway_auto
) {
2955 char buf
[INET_ADDRSTRLEN
];
2956 inet_ntop(AF_INET
, netdev
->ipv4_gateway
, buf
, sizeof(buf
));
2957 ERROR("Fried to set autodetected ipv4 gateway \"%s\"", buf
);
2964 /* setup ipv6 gateway on the interface */
2965 if (netdev
->ipv6_gateway
) {
2966 if (!(netdev
->flags
& IFF_UP
)) {
2967 ERROR("Cannot add ipv6 gateway for network device "
2968 "\"%s\" when not bringing up the interface", ifname
);
2972 if (lxc_list_empty(&netdev
->ipv6
) && !IN6_IS_ADDR_LINKLOCAL(netdev
->ipv6_gateway
)) {
2973 ERROR("Cannot add ipv6 gateway for network device "
2974 "\"%s\" when not assigning an address", ifname
);
2978 err
= lxc_ipv6_gateway_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
2980 err
= lxc_ipv6_dest_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
2982 ERROR("Failed to add ipv6 dest for network "
2983 "device \"%s\": %s", ifname
, strerror(-err
));
2986 err
= lxc_ipv6_gateway_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
2988 ERROR("Failed to setup ipv6 gateway for "
2989 "network device \"%s\": %s", ifname
,
2991 if (netdev
->ipv6_gateway_auto
) {
2992 char buf
[INET6_ADDRSTRLEN
];
2993 inet_ntop(AF_INET6
, netdev
->ipv6_gateway
, buf
, sizeof(buf
));
2994 ERROR("Tried to set autodetected ipv6 "
2995 "gateway for network device "
3003 DEBUG("Network device \"%s\" has been setup", current_ifname
);
3008 int lxc_setup_network_in_child_namespaces(const struct lxc_conf
*conf
,
3009 struct lxc_list
*network
)
3011 struct lxc_list
*iterator
;
3012 struct lxc_netdev
*netdev
;
3014 lxc_list_for_each(iterator
, network
) {
3015 netdev
= iterator
->elem
;
3017 /* REMOVE in LXC 3.0 */
3018 if (netdev
->idx
< 0) {
3019 ERROR("WARNING: using \"lxc.network.*\" keys to define "
3020 "networks is DEPRECATED, please switch to using "
3021 "\"lxc.net.[i].* keys\"");
3024 if (lxc_setup_netdev_in_child_namespaces(netdev
)) {
3025 ERROR("failed to setup netdev");
3030 if (!lxc_list_empty(network
))
3031 INFO("network has been setup");
3036 int lxc_network_send_veth_names_to_child(struct lxc_handler
*handler
)
3038 struct lxc_list
*iterator
;
3039 struct lxc_list
*network
= &handler
->conf
->network
;
3040 int data_sock
= handler
->data_sock
[0];
3042 if (handler
->am_root
)
3045 lxc_list_for_each(iterator
, network
) {
3047 struct lxc_netdev
*netdev
= iterator
->elem
;
3049 if (netdev
->type
!= LXC_NET_VETH
)
3052 ret
= send(data_sock
, netdev
->name
, IFNAMSIZ
, 0);
3055 TRACE("Sent network device name \"%s\" to child", netdev
->name
);
3061 int lxc_network_recv_veth_names_from_parent(struct lxc_handler
*handler
)
3063 struct lxc_list
*iterator
;
3064 struct lxc_list
*network
= &handler
->conf
->network
;
3065 int data_sock
= handler
->data_sock
[1];
3067 if (handler
->am_root
)
3070 lxc_list_for_each(iterator
, network
) {
3072 struct lxc_netdev
*netdev
= iterator
->elem
;
3074 if (netdev
->type
!= LXC_NET_VETH
)
3077 ret
= recv(data_sock
, netdev
->name
, IFNAMSIZ
, 0);
3080 TRACE("Received network device name \"%s\" from parent", netdev
->name
);
3086 int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler
*handler
)
3088 struct lxc_list
*iterator
, *network
;
3089 int data_sock
= handler
->data_sock
[0];
3091 if (!handler
->am_root
)
3094 network
= &handler
->conf
->network
;
3095 lxc_list_for_each(iterator
, network
) {
3097 struct lxc_netdev
*netdev
= iterator
->elem
;
3099 /* Send network device name in the child's namespace to parent. */
3100 ret
= send(data_sock
, netdev
->name
, IFNAMSIZ
, 0);
3104 /* Send network device ifindex in the child's namespace to
3107 ret
= send(data_sock
, &netdev
->ifindex
, sizeof(netdev
->ifindex
), 0);
3112 TRACE("Sent network device names and ifindeces to parent");
3116 int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler
*handler
)
3118 struct lxc_list
*iterator
, *network
;
3119 int data_sock
= handler
->data_sock
[1];
3121 if (!handler
->am_root
)
3124 network
= &handler
->conf
->network
;
3125 lxc_list_for_each(iterator
, network
) {
3127 struct lxc_netdev
*netdev
= iterator
->elem
;
3129 /* Receive network device name in the child's namespace to
3132 ret
= recv(data_sock
, netdev
->name
, IFNAMSIZ
, 0);
3136 /* Receive network device ifindex in the child's namespace to
3139 ret
= recv(data_sock
, &netdev
->ifindex
, sizeof(netdev
->ifindex
), 0);
3147 void lxc_delete_network(struct lxc_handler
*handler
)
3151 if (handler
->am_root
)
3152 bret
= lxc_delete_network_priv(handler
);
3154 bret
= lxc_delete_network_unpriv(handler
);
3156 DEBUG("Failed to delete network devices");
3158 DEBUG("Deleted network devices");