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>
58 #include <../include/ifaddrs.h>
62 #define IFLA_LINKMODE 17
66 #define IFLA_LINKINFO 18
69 #ifndef IFLA_NET_NS_PID
70 #define IFLA_NET_NS_PID 19
73 #ifndef IFLA_INFO_KIND
74 #define IFLA_INFO_KIND 1
78 #define IFLA_VLAN_ID 1
81 #ifndef IFLA_INFO_DATA
82 #define IFLA_INFO_DATA 2
85 #ifndef VETH_INFO_PEER
86 #define VETH_INFO_PEER 1
89 #ifndef IFLA_MACVLAN_MODE
90 #define IFLA_MACVLAN_MODE 1
93 lxc_log_define(lxc_network
, lxc
);
95 typedef int (*instantiate_cb
)(struct lxc_handler
*, struct lxc_netdev
*);
97 static int instantiate_veth(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
99 int bridge_index
, err
;
101 char veth1buf
[IFNAMSIZ
], veth2buf
[IFNAMSIZ
];
102 unsigned int mtu
= 0;
104 if (netdev
->priv
.veth_attr
.pair
[0] != '\0') {
105 veth1
= netdev
->priv
.veth_attr
.pair
;
106 if (handler
->conf
->reboot
)
107 lxc_netdev_delete_by_name(veth1
);
109 err
= snprintf(veth1buf
, sizeof(veth1buf
), "vethXXXXXX");
110 if (err
< 0 || (size_t)err
>= sizeof(veth1buf
))
113 veth1
= lxc_mkifname(veth1buf
);
117 /* store away for deconf */
118 memcpy(netdev
->priv
.veth_attr
.veth1
, veth1
, IFNAMSIZ
);
121 snprintf(veth2buf
, sizeof(veth2buf
), "vethXXXXXX");
122 veth2
= lxc_mkifname(veth2buf
);
126 err
= lxc_veth_create(veth1
, veth2
);
128 ERROR("Failed to create veth pair \"%s\" and \"%s\": %s", veth1
,
129 veth2
, strerror(-err
));
133 /* changing the high byte of the mac address to 0xfe, the bridge interface
134 * will always keep the host's mac address and not take the mac address
136 err
= setup_private_host_hw_addr(veth1
);
138 ERROR("Failed to change mac address of host interface \"%s\": %s",
139 veth1
, strerror(-err
));
143 /* Retrieve ifindex of the host's veth device. */
144 netdev
->priv
.veth_attr
.ifindex
= if_nametoindex(veth1
);
145 if (!netdev
->priv
.veth_attr
.ifindex
) {
146 ERROR("Failed to retrieve ifindex for \"%s\"", veth1
);
150 /* Note that we're retrieving the container's ifindex in the host's
151 * network namespace because we need it to move the device from the
152 * host's network namespace to the container's network namespace later
155 netdev
->ifindex
= if_nametoindex(veth2
);
156 if (!netdev
->ifindex
) {
157 ERROR("Failed to retrieve ifindex for \"%s\"", veth2
);
162 if (lxc_safe_uint(netdev
->mtu
, &mtu
) < 0)
163 WARN("Failed to parse mtu");
165 INFO("Retrieved mtu %d", mtu
);
166 } else if (netdev
->link
[0] != '\0') {
167 bridge_index
= if_nametoindex(netdev
->link
);
169 mtu
= netdev_get_mtu(bridge_index
);
170 INFO("Retrieved mtu %d from %s", mtu
, netdev
->link
);
172 mtu
= netdev_get_mtu(netdev
->ifindex
);
173 INFO("Retrieved mtu %d from %s", mtu
, veth2
);
178 err
= lxc_netdev_set_mtu(veth1
, mtu
);
180 err
= lxc_netdev_set_mtu(veth2
, mtu
);
182 ERROR("Failed to set mtu \"%d\" for veth pair \"%s\" "
184 mtu
, veth1
, veth2
, strerror(-err
));
189 if (netdev
->link
[0] != '\0') {
190 err
= lxc_bridge_attach(netdev
->link
, veth1
);
192 ERROR("Failed to attach \"%s\" to bridge \"%s\": %s",
193 veth1
, netdev
->link
, strerror(-err
));
196 INFO("Attached \"%s\" to bridge \"%s\"", veth1
, netdev
->link
);
199 err
= lxc_netdev_up(veth1
);
201 ERROR("Failed to set \"%s\" up: %s", veth1
, strerror(-err
));
205 if (netdev
->upscript
) {
206 err
= run_script(handler
->name
, "net", netdev
->upscript
, "up",
207 "veth", veth1
, (char*) NULL
);
212 DEBUG("Instantiated veth \"%s/%s\", index is \"%d\"", veth1
, veth2
,
218 if (netdev
->ifindex
!= 0)
219 lxc_netdev_delete_by_name(veth1
);
220 if (netdev
->priv
.veth_attr
.pair
!= veth1
)
226 static int instantiate_macvlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
228 char peerbuf
[IFNAMSIZ
], *peer
;
231 if (netdev
->link
[0] == '\0') {
232 ERROR("No link for macvlan network device specified");
236 err
= snprintf(peerbuf
, sizeof(peerbuf
), "mcXXXXXX");
237 if (err
< 0 || (size_t)err
>= sizeof(peerbuf
))
240 peer
= lxc_mkifname(peerbuf
);
244 err
= lxc_macvlan_create(netdev
->link
, peer
,
245 netdev
->priv
.macvlan_attr
.mode
);
247 ERROR("Failed to create macvlan interface \"%s\" on \"%s\": %s",
248 peer
, netdev
->link
, strerror(-err
));
252 netdev
->ifindex
= if_nametoindex(peer
);
253 if (!netdev
->ifindex
) {
254 ERROR("Failed to retrieve ifindex for \"%s\"", peer
);
258 if (netdev
->upscript
) {
259 err
= run_script(handler
->name
, "net", netdev
->upscript
, "up",
260 "macvlan", netdev
->link
, (char*) NULL
);
265 DEBUG("Instantiated macvlan \"%s\" with ifindex is %d and mode %d",
266 peer
, netdev
->ifindex
, netdev
->priv
.macvlan_attr
.mode
);
270 lxc_netdev_delete_by_name(peer
);
275 static int instantiate_vlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
279 static uint16_t vlan_cntr
= 0;
280 unsigned int mtu
= 0;
282 if (netdev
->link
[0] == '\0') {
283 ERROR("No link for vlan network device specified");
287 err
= snprintf(peer
, sizeof(peer
), "vlan%d-%d", netdev
->priv
.vlan_attr
.vid
, vlan_cntr
++);
288 if (err
< 0 || (size_t)err
>= sizeof(peer
))
291 err
= lxc_vlan_create(netdev
->link
, peer
, netdev
->priv
.vlan_attr
.vid
);
293 ERROR("Failed to create vlan interface \"%s\" on \"%s\": %s",
294 peer
, netdev
->link
, strerror(-err
));
298 netdev
->ifindex
= if_nametoindex(peer
);
299 if (!netdev
->ifindex
) {
300 ERROR("Failed to retrieve ifindex for \"%s\"", peer
);
301 lxc_netdev_delete_by_name(peer
);
305 DEBUG("Instantiated vlan \"%s\" with ifindex is \"%d\" (vlan1000)",
306 peer
, netdev
->ifindex
);
308 if (lxc_safe_uint(netdev
->mtu
, &mtu
) < 0) {
309 ERROR("Failed to retrieve mtu from \"%d\"/\"%s\".",
311 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)");
314 err
= lxc_netdev_set_mtu(peer
, mtu
);
316 ERROR("Failed to set mtu \"%s\" for \"%s\": %s",
317 netdev
->mtu
, peer
, strerror(-err
));
318 lxc_netdev_delete_by_name(peer
);
326 static int instantiate_phys(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
328 if (netdev
->link
[0] == '\0') {
329 ERROR("No link for physical interface specified");
333 /* Note that we're retrieving the container's ifindex in the host's
334 * network namespace because we need it to move the device from the
335 * host's network namespace to the container's network namespace later
337 * Note that netdev->link will contain the name of the physical network
338 * device in the host's namespace.
340 netdev
->ifindex
= if_nametoindex(netdev
->link
);
341 if (!netdev
->ifindex
) {
342 ERROR("Failed to retrieve ifindex for \"%s\"", netdev
->link
);
346 /* Store the ifindex of the host's network device in the host's
349 netdev
->priv
.phys_attr
.ifindex
= netdev
->ifindex
;
351 if (netdev
->upscript
) {
353 err
= run_script(handler
->name
, "net", netdev
->upscript
,
354 "up", "phys", netdev
->link
, (char*) NULL
);
362 static int instantiate_empty(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
365 if (netdev
->upscript
) {
367 err
= run_script(handler
->name
, "net", netdev
->upscript
,
368 "up", "empty", (char*) NULL
);
375 static int instantiate_none(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
381 static instantiate_cb netdev_conf
[LXC_NET_MAXCONFTYPE
+ 1] = {
382 [LXC_NET_VETH
] = instantiate_veth
,
383 [LXC_NET_MACVLAN
] = instantiate_macvlan
,
384 [LXC_NET_VLAN
] = instantiate_vlan
,
385 [LXC_NET_PHYS
] = instantiate_phys
,
386 [LXC_NET_EMPTY
] = instantiate_empty
,
387 [LXC_NET_NONE
] = instantiate_none
,
390 static int shutdown_veth(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
395 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
396 veth1
= netdev
->priv
.veth_attr
.pair
;
398 veth1
= netdev
->priv
.veth_attr
.veth1
;
400 if (netdev
->downscript
) {
401 err
= run_script(handler
->name
, "net", netdev
->downscript
,
402 "down", "veth", veth1
, (char*) NULL
);
409 static int shutdown_macvlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
413 if (netdev
->downscript
) {
414 err
= run_script(handler
->name
, "net", netdev
->downscript
,
415 "down", "macvlan", netdev
->link
,
423 static int shutdown_vlan(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
428 static int shutdown_phys(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
432 if (netdev
->downscript
) {
433 err
= run_script(handler
->name
, "net", netdev
->downscript
,
434 "down", "phys", netdev
->link
, (char*) NULL
);
441 static int shutdown_empty(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
445 if (netdev
->downscript
) {
446 err
= run_script(handler
->name
, "net", netdev
->downscript
,
447 "down", "empty", (char*) NULL
);
454 static int shutdown_none(struct lxc_handler
*handler
, struct lxc_netdev
*netdev
)
459 static instantiate_cb netdev_deconf
[LXC_NET_MAXCONFTYPE
+ 1] = {
460 [LXC_NET_VETH
] = shutdown_veth
,
461 [LXC_NET_MACVLAN
] = shutdown_macvlan
,
462 [LXC_NET_VLAN
] = shutdown_vlan
,
463 [LXC_NET_PHYS
] = shutdown_phys
,
464 [LXC_NET_EMPTY
] = shutdown_empty
,
465 [LXC_NET_NONE
] = shutdown_none
,
468 int lxc_netdev_move_by_index(int ifindex
, pid_t pid
, const char *ifname
)
471 struct nl_handler nlh
;
472 struct ifinfomsg
*ifi
;
473 struct nlmsg
*nlmsg
= NULL
;
475 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
480 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
484 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
485 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
487 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
490 ifi
->ifi_family
= AF_UNSPEC
;
491 ifi
->ifi_index
= ifindex
;
493 if (nla_put_u32(nlmsg
, IFLA_NET_NS_PID
, pid
))
496 if (ifname
!= NULL
) {
497 if (nla_put_string(nlmsg
, IFLA_IFNAME
, ifname
))
501 err
= netlink_transaction(&nlh
, nlmsg
, nlmsg
);
508 /* If we are asked to move a wireless interface, then we must actually move its
509 * phyN device. Detect that condition and return the physname here. The physname
510 * will be passed to lxc_netdev_move_wlan() which will free it when done.
512 #define PHYSNAME "/sys/class/net/%s/phy80211/name"
513 static char *is_wlan(const char *ifname
)
521 char *physname
= NULL
;
523 len
= strlen(ifname
) + strlen(PHYSNAME
) - 1;
524 path
= alloca(len
+ 1);
525 ret
= snprintf(path
, len
, PHYSNAME
, ifname
);
526 if (ret
< 0 || (size_t)ret
>= len
)
529 ret
= stat(path
, &sb
);
533 f
= fopen(path
, "r");
537 /* Feh - sb.st_size is always 4096. */
538 fseek(f
, 0, SEEK_END
);
540 fseek(f
, 0, SEEK_SET
);
542 physname
= malloc(physlen
+ 1);
548 memset(physname
, 0, physlen
+ 1);
549 ret
= fread(physname
, 1, physlen
, f
);
554 for (i
= 0; i
< physlen
; i
++) {
555 if (physname
[i
] == '\n')
558 if (physname
[i
] == '\0')
569 static int lxc_netdev_rename_by_name_in_netns(pid_t pid
, const char *old
,
579 return wait_for_pid(fpid
);
581 if (!switch_to_ns(pid
, "net"))
584 exit(lxc_netdev_rename_by_name(old
, new));
587 static int lxc_netdev_move_wlan(char *physname
, const char *ifname
, pid_t pid
,
594 /* Move phyN into the container. TODO - do this using netlink.
595 * However, IIUC this involves a bit more complicated work to talk to
596 * the 80211 module, so for now just call out to iw.
598 cmd
= on_path("iw", NULL
);
609 sprintf(pidstr
, "%d", pid
);
610 execlp("iw", "iw", "phy", physname
, "set", "netns", pidstr
,
615 if (wait_for_pid(fpid
))
620 err
= lxc_netdev_rename_by_name_in_netns(pid
, ifname
, newname
);
627 int lxc_netdev_move_by_name(const char *ifname
, pid_t pid
, const char* newname
)
635 index
= if_nametoindex(ifname
);
639 physname
= is_wlan(ifname
);
641 return lxc_netdev_move_wlan(physname
, ifname
, pid
, newname
);
643 return lxc_netdev_move_by_index(index
, pid
, newname
);
646 int lxc_netdev_delete_by_index(int ifindex
)
649 struct ifinfomsg
*ifi
;
650 struct nl_handler nlh
;
651 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
653 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
658 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
662 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
666 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_ACK
| NLM_F_REQUEST
;
667 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_DELLINK
;
669 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
672 ifi
->ifi_family
= AF_UNSPEC
;
673 ifi
->ifi_index
= ifindex
;
675 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
683 int lxc_netdev_delete_by_name(const char *name
)
687 index
= if_nametoindex(name
);
691 return lxc_netdev_delete_by_index(index
);
694 int lxc_netdev_rename_by_index(int ifindex
, const char *newname
)
697 struct ifinfomsg
*ifi
;
698 struct nl_handler nlh
;
699 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
701 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
705 len
= strlen(newname
);
706 if (len
== 1 || len
>= IFNAMSIZ
)
710 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
714 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
718 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_ACK
| NLM_F_REQUEST
;
719 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
721 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
724 ifi
->ifi_family
= AF_UNSPEC
;
725 ifi
->ifi_index
= ifindex
;
727 if (nla_put_string(nlmsg
, IFLA_IFNAME
, newname
))
730 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
738 int lxc_netdev_rename_by_name(const char *oldname
, const char *newname
)
742 len
= strlen(oldname
);
743 if (len
== 1 || len
>= IFNAMSIZ
)
746 index
= if_nametoindex(oldname
);
750 return lxc_netdev_rename_by_index(index
, newname
);
753 int netdev_set_flag(const char *name
, int flag
)
756 struct ifinfomsg
*ifi
;
757 struct nl_handler nlh
;
758 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
760 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
766 if (len
== 1 || len
>= IFNAMSIZ
)
770 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
774 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
779 index
= if_nametoindex(name
);
783 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
784 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
786 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
791 ifi
->ifi_family
= AF_UNSPEC
;
792 ifi
->ifi_index
= index
;
793 ifi
->ifi_change
|= IFF_UP
;
794 ifi
->ifi_flags
|= flag
;
796 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
804 int netdev_get_flag(const char *name
, int *flag
)
807 struct ifinfomsg
*ifi
;
808 struct nl_handler nlh
;
809 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
;
838 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETLINK
;
840 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
845 ifi
->ifi_family
= AF_UNSPEC
;
846 ifi
->ifi_index
= index
;
848 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
852 ifi
= NLMSG_DATA(answer
->nlmsghdr
);
854 *flag
= ifi
->ifi_flags
;
863 * \brief Check a interface is up or not.
865 * \param name: name for the interface.
868 * 0 means interface is down.
869 * 1 means interface is up.
870 * Others means error happened, and ret-value is the error number.
872 int lxc_netdev_isup(const char *name
)
876 err
= netdev_get_flag(name
, &flag
);
886 int netdev_get_mtu(int ifindex
)
888 int answer_len
, err
, res
;
889 struct nl_handler nlh
;
890 struct ifinfomsg
*ifi
;
891 struct nlmsghdr
*msg
;
892 int readmore
= 0, recv_len
= 0;
893 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
895 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
900 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
904 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
908 /* Save the answer buffer length, since it will be overwritten
909 * on the first receive (and we might need to receive more than
912 answer_len
= answer
->nlmsghdr
->nlmsg_len
;
914 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_DUMP
;
915 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETLINK
;
917 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
920 ifi
->ifi_family
= AF_UNSPEC
;
922 /* Send the request for addresses, which returns all addresses
923 * on all interfaces. */
924 err
= netlink_send(&nlh
, nlmsg
);
929 /* Restore the answer buffer length, it might have been
930 * overwritten by a previous receive.
932 answer
->nlmsghdr
->nlmsg_len
= answer_len
;
934 /* Get the (next) batch of reply messages */
935 err
= netlink_rcv(&nlh
, answer
);
942 /* Satisfy the typing for the netlink macros */
943 msg
= answer
->nlmsghdr
;
945 while (NLMSG_OK(msg
, recv_len
)) {
947 /* Stop reading if we see an error message */
948 if (msg
->nlmsg_type
== NLMSG_ERROR
) {
949 struct nlmsgerr
*errmsg
=
950 (struct nlmsgerr
*)NLMSG_DATA(msg
);
955 /* Stop reading if we see a NLMSG_DONE message */
956 if (msg
->nlmsg_type
== NLMSG_DONE
) {
961 ifi
= NLMSG_DATA(msg
);
962 if (ifi
->ifi_index
== ifindex
) {
963 struct rtattr
*rta
= IFLA_RTA(ifi
);
965 msg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
967 while (RTA_OK(rta
, attr_len
)) {
968 /* Found a local address for the
969 * requested interface, return it.
971 if (rta
->rta_type
== IFLA_MTU
) {
972 memcpy(&res
, RTA_DATA(rta
),
977 rta
= RTA_NEXT(rta
, attr_len
);
981 /* Keep reading more data from the socket if the last
982 * message had the NLF_F_MULTI flag set.
984 readmore
= (msg
->nlmsg_flags
& NLM_F_MULTI
);
986 /* Look at the next message received in this buffer. */
987 msg
= NLMSG_NEXT(msg
, recv_len
);
991 /* If we end up here, we didn't find any result, so signal an error. */
1001 int lxc_netdev_set_mtu(const char *name
, int mtu
)
1003 int err
, index
, len
;
1004 struct ifinfomsg
*ifi
;
1005 struct nl_handler nlh
;
1006 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1008 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1014 if (len
== 1 || len
>= IFNAMSIZ
)
1018 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1022 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1027 index
= if_nametoindex(name
);
1031 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1032 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1034 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1039 ifi
->ifi_family
= AF_UNSPEC
;
1040 ifi
->ifi_index
= index
;
1042 if (nla_put_u32(nlmsg
, IFLA_MTU
, mtu
))
1045 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1047 netlink_close(&nlh
);
1053 int lxc_netdev_up(const char *name
)
1055 return netdev_set_flag(name
, IFF_UP
);
1058 int lxc_netdev_down(const char *name
)
1060 return netdev_set_flag(name
, 0);
1063 int lxc_veth_create(const char *name1
, const char *name2
)
1066 struct ifinfomsg
*ifi
;
1067 struct nl_handler nlh
;
1068 struct rtattr
*nest1
, *nest2
, *nest3
;
1069 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1071 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1076 len
= strlen(name1
);
1077 if (len
== 1 || len
>= IFNAMSIZ
)
1080 len
= strlen(name2
);
1081 if (len
== 1 || len
>= IFNAMSIZ
)
1085 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1089 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1093 nlmsg
->nlmsghdr
->nlmsg_flags
=
1094 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1095 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1097 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1100 ifi
->ifi_family
= AF_UNSPEC
;
1103 nest1
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1107 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "veth"))
1110 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1114 nest3
= nla_begin_nested(nlmsg
, VETH_INFO_PEER
);
1118 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1124 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name2
))
1127 nla_end_nested(nlmsg
, nest3
);
1128 nla_end_nested(nlmsg
, nest2
);
1129 nla_end_nested(nlmsg
, nest1
);
1131 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name1
))
1134 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1136 netlink_close(&nlh
);
1142 /* TODO: merge with lxc_macvlan_create */
1143 int lxc_vlan_create(const char *master
, const char *name
, unsigned short vlanid
)
1145 int err
, len
, lindex
;
1146 struct ifinfomsg
*ifi
;
1147 struct nl_handler nlh
;
1148 struct rtattr
*nest
, *nest2
;
1149 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1151 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1156 len
= strlen(master
);
1157 if (len
== 1 || len
>= IFNAMSIZ
)
1161 if (len
== 1 || len
>= IFNAMSIZ
)
1165 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1169 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1174 lindex
= if_nametoindex(master
);
1178 nlmsg
->nlmsghdr
->nlmsg_flags
=
1179 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1180 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1182 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1187 ifi
->ifi_family
= AF_UNSPEC
;
1189 nest
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1193 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "vlan"))
1196 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1200 if (nla_put_u16(nlmsg
, IFLA_VLAN_ID
, vlanid
))
1203 nla_end_nested(nlmsg
, nest2
);
1204 nla_end_nested(nlmsg
, nest
);
1206 if (nla_put_u32(nlmsg
, IFLA_LINK
, lindex
))
1209 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name
))
1212 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1218 netlink_close(&nlh
);
1222 int lxc_macvlan_create(const char *master
, const char *name
, int mode
)
1224 int err
, index
, len
;
1225 struct ifinfomsg
*ifi
;
1226 struct nl_handler nlh
;
1227 struct rtattr
*nest
, *nest2
;
1228 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1230 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1235 len
= strlen(master
);
1236 if (len
== 1 || len
>= IFNAMSIZ
)
1240 if (len
== 1 || len
>= IFNAMSIZ
)
1244 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1248 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1253 index
= if_nametoindex(master
);
1257 nlmsg
->nlmsghdr
->nlmsg_flags
=
1258 NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_ACK
;
1259 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
1261 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
1266 ifi
->ifi_family
= AF_UNSPEC
;
1268 nest
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
1272 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "macvlan"))
1276 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
1280 if (nla_put_u32(nlmsg
, IFLA_MACVLAN_MODE
, mode
))
1283 nla_end_nested(nlmsg
, nest2
);
1286 nla_end_nested(nlmsg
, nest
);
1288 if (nla_put_u32(nlmsg
, IFLA_LINK
, index
))
1291 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name
))
1294 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1296 netlink_close(&nlh
);
1302 static int proc_sys_net_write(const char *path
, const char *value
)
1307 fd
= open(path
, O_WRONLY
);
1311 if (write(fd
, value
, strlen(value
)) < 0)
1318 static int ip_forward_set(const char *ifname
, int family
, int flag
)
1321 char path
[MAXPATHLEN
];
1323 if (family
!= AF_INET
&& family
!= AF_INET6
)
1326 rc
= snprintf(path
, MAXPATHLEN
, "/proc/sys/net/%s/conf/%s/forwarding",
1327 family
== AF_INET
? "ipv4" : "ipv6", ifname
);
1328 if (rc
< 0 || (size_t)rc
>= MAXPATHLEN
)
1331 return proc_sys_net_write(path
, flag
? "1" : "0");
1334 int lxc_ip_forward_on(const char *ifname
, int family
)
1336 return ip_forward_set(ifname
, family
, 1);
1339 int lxc_ip_forward_off(const char *ifname
, int family
)
1341 return ip_forward_set(ifname
, family
, 0);
1344 static int neigh_proxy_set(const char *ifname
, int family
, int flag
)
1347 char path
[MAXPATHLEN
];
1349 if (family
!= AF_INET
&& family
!= AF_INET6
)
1352 ret
= snprintf(path
, MAXPATHLEN
, "/proc/sys/net/%s/conf/%s/%s",
1353 family
== AF_INET
? "ipv4" : "ipv6", ifname
,
1354 family
== AF_INET
? "proxy_arp" : "proxy_ndp");
1355 if (ret
< 0 || (size_t)ret
>= MAXPATHLEN
)
1358 return proc_sys_net_write(path
, flag
? "1" : "0");
1361 int lxc_neigh_proxy_on(const char *name
, int family
)
1363 return neigh_proxy_set(name
, family
, 1);
1366 int lxc_neigh_proxy_off(const char *name
, int family
)
1368 return neigh_proxy_set(name
, family
, 0);
1371 int lxc_convert_mac(char *macaddr
, struct sockaddr
*sockaddr
)
1376 unsigned char *data
;
1378 sockaddr
->sa_family
= ARPHRD_ETHER
;
1379 data
= (unsigned char *)sockaddr
->sa_data
;
1381 while ((*macaddr
!= '\0') && (i
< ETH_ALEN
)) {
1386 else if (c
>= 'a' && c
<= 'f')
1388 else if (c
>= 'A' && c
<= 'F')
1397 else if (c
>= 'a' && c
<= 'f')
1398 val
|= c
- 'a' + 10;
1399 else if (c
>= 'A' && c
<= 'F')
1400 val
|= c
- 'A' + 10;
1401 else if (c
== ':' || c
== 0)
1407 *data
++ = (unsigned char)(val
& 0377);
1410 if (*macaddr
== ':')
1417 static int ip_addr_add(int family
, int ifindex
, void *addr
, void *bcast
,
1418 void *acast
, int prefix
)
1421 struct ifaddrmsg
*ifa
;
1422 struct nl_handler nlh
;
1423 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1425 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1426 : sizeof(struct in6_addr
);
1428 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1433 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1437 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1441 nlmsg
->nlmsghdr
->nlmsg_flags
=
1442 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1443 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWADDR
;
1445 ifa
= nlmsg_reserve(nlmsg
, sizeof(struct ifaddrmsg
));
1448 ifa
->ifa_prefixlen
= prefix
;
1449 ifa
->ifa_index
= ifindex
;
1450 ifa
->ifa_family
= family
;
1454 if (nla_put_buffer(nlmsg
, IFA_LOCAL
, addr
, addrlen
))
1457 if (nla_put_buffer(nlmsg
, IFA_ADDRESS
, addr
, addrlen
))
1460 if (nla_put_buffer(nlmsg
, IFA_BROADCAST
, bcast
, addrlen
))
1463 /* TODO: multicast, anycast with ipv6 */
1464 err
= -EPROTONOSUPPORT
;
1465 if (family
== AF_INET6
&&
1466 (memcmp(bcast
, &in6addr_any
, sizeof(in6addr_any
)) ||
1467 memcmp(acast
, &in6addr_any
, sizeof(in6addr_any
))))
1470 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1472 netlink_close(&nlh
);
1478 int lxc_ipv6_addr_add(int ifindex
, struct in6_addr
*addr
,
1479 struct in6_addr
*mcast
, struct in6_addr
*acast
,
1482 return ip_addr_add(AF_INET6
, ifindex
, addr
, mcast
, acast
, prefix
);
1485 int lxc_ipv4_addr_add(int ifindex
, struct in_addr
*addr
, struct in_addr
*bcast
,
1488 return ip_addr_add(AF_INET
, ifindex
, addr
, bcast
, NULL
, prefix
);
1491 /* Find an IFA_LOCAL (or IFA_ADDRESS if not IFA_LOCAL is present) address from
1492 * the given RTM_NEWADDR message. Allocates memory for the address and stores
1493 * that pointer in *res (so res should be an in_addr** or in6_addr**).
1495 static int ifa_get_local_ip(int family
, struct nlmsghdr
*msg
, void **res
)
1498 struct ifaddrmsg
*ifa
= NLMSG_DATA(msg
);
1499 struct rtattr
*rta
= IFA_RTA(ifa
);
1500 int attr_len
= NLMSG_PAYLOAD(msg
, sizeof(struct ifaddrmsg
));
1502 if (ifa
->ifa_family
!= family
)
1505 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1506 : sizeof(struct in6_addr
);
1508 /* Loop over the rtattr's in this message */
1509 while (RTA_OK(rta
, attr_len
)) {
1510 /* Found a local address for the requested interface,
1513 if (rta
->rta_type
== IFA_LOCAL
||
1514 rta
->rta_type
== IFA_ADDRESS
) {
1515 /* Sanity check. The family check above should make sure
1516 * the address length is correct, but check here just in
1519 if (RTA_PAYLOAD(rta
) != addrlen
)
1522 /* We might have found an IFA_ADDRESS before, which we
1523 * now overwrite with an IFA_LOCAL.
1526 *res
= malloc(addrlen
);
1531 memcpy(*res
, RTA_DATA(rta
), addrlen
);
1532 if (rta
->rta_type
== IFA_LOCAL
)
1535 rta
= RTA_NEXT(rta
, attr_len
);
1540 static int ip_addr_get(int family
, int ifindex
, void **res
)
1542 int answer_len
, err
;
1543 struct ifaddrmsg
*ifa
;
1544 struct nl_handler nlh
;
1545 struct nlmsghdr
*msg
;
1546 int readmore
= 0, recv_len
= 0;
1547 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1549 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1554 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1558 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1562 /* Save the answer buffer length, since it will be overwritten on the
1563 * first receive (and we might need to receive more than once).
1565 answer_len
= answer
->nlmsghdr
->nlmsg_len
;
1567 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ROOT
;
1568 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETADDR
;
1570 ifa
= nlmsg_reserve(nlmsg
, sizeof(struct ifaddrmsg
));
1573 ifa
->ifa_family
= family
;
1575 /* Send the request for addresses, which returns all addresses on all
1578 err
= netlink_send(&nlh
, nlmsg
);
1583 /* Restore the answer buffer length, it might have been
1584 * overwritten by a previous receive.
1586 answer
->nlmsghdr
->nlmsg_len
= answer_len
;
1588 /* Get the (next) batch of reply messages. */
1589 err
= netlink_rcv(&nlh
, answer
);
1596 /* Satisfy the typing for the netlink macros. */
1597 msg
= answer
->nlmsghdr
;
1599 while (NLMSG_OK(msg
, recv_len
)) {
1600 /* Stop reading if we see an error message. */
1601 if (msg
->nlmsg_type
== NLMSG_ERROR
) {
1602 struct nlmsgerr
*errmsg
=
1603 (struct nlmsgerr
*)NLMSG_DATA(msg
);
1604 err
= errmsg
->error
;
1608 /* Stop reading if we see a NLMSG_DONE message. */
1609 if (msg
->nlmsg_type
== NLMSG_DONE
) {
1614 if (msg
->nlmsg_type
!= RTM_NEWADDR
) {
1619 ifa
= (struct ifaddrmsg
*)NLMSG_DATA(msg
);
1620 if (ifa
->ifa_index
== ifindex
) {
1621 if (ifa_get_local_ip(family
, msg
, res
) < 0) {
1626 /* Found a result, stop searching. */
1631 /* Keep reading more data from the socket if the last
1632 * message had the NLF_F_MULTI flag set.
1634 readmore
= (msg
->nlmsg_flags
& NLM_F_MULTI
);
1636 /* Look at the next message received in this buffer. */
1637 msg
= NLMSG_NEXT(msg
, recv_len
);
1641 /* If we end up here, we didn't find any result, so signal an
1647 netlink_close(&nlh
);
1653 int lxc_ipv6_addr_get(int ifindex
, struct in6_addr
**res
)
1655 return ip_addr_get(AF_INET6
, ifindex
, (void **)res
);
1658 int lxc_ipv4_addr_get(int ifindex
, struct in_addr
**res
)
1660 return ip_addr_get(AF_INET
, ifindex
, (void **)res
);
1663 static int ip_gateway_add(int family
, int ifindex
, void *gw
)
1666 struct nl_handler nlh
;
1668 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1670 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1671 : sizeof(struct in6_addr
);
1673 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1678 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1682 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1686 nlmsg
->nlmsghdr
->nlmsg_flags
=
1687 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1688 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWROUTE
;
1690 rt
= nlmsg_reserve(nlmsg
, sizeof(struct rtmsg
));
1693 rt
->rtm_family
= family
;
1694 rt
->rtm_table
= RT_TABLE_MAIN
;
1695 rt
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1696 rt
->rtm_protocol
= RTPROT_BOOT
;
1697 rt
->rtm_type
= RTN_UNICAST
;
1698 /* "default" destination */
1699 rt
->rtm_dst_len
= 0;
1702 if (nla_put_buffer(nlmsg
, RTA_GATEWAY
, gw
, addrlen
))
1705 /* Adding the interface index enables the use of link-local
1706 * addresses for the gateway.
1708 if (nla_put_u32(nlmsg
, RTA_OIF
, ifindex
))
1711 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1713 netlink_close(&nlh
);
1719 int lxc_ipv4_gateway_add(int ifindex
, struct in_addr
*gw
)
1721 return ip_gateway_add(AF_INET
, ifindex
, gw
);
1724 int lxc_ipv6_gateway_add(int ifindex
, struct in6_addr
*gw
)
1726 return ip_gateway_add(AF_INET6
, ifindex
, gw
);
1729 static int ip_route_dest_add(int family
, int ifindex
, void *dest
)
1732 struct nl_handler nlh
;
1734 struct nlmsg
*answer
= NULL
, *nlmsg
= NULL
;
1736 addrlen
= family
== AF_INET
? sizeof(struct in_addr
)
1737 : sizeof(struct in6_addr
);
1739 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1744 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1748 answer
= nlmsg_alloc_reserve(NLMSG_GOOD_SIZE
);
1752 nlmsg
->nlmsghdr
->nlmsg_flags
=
1753 NLM_F_ACK
| NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_EXCL
;
1754 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWROUTE
;
1756 rt
= nlmsg_reserve(nlmsg
, sizeof(struct rtmsg
));
1759 rt
->rtm_family
= family
;
1760 rt
->rtm_table
= RT_TABLE_MAIN
;
1761 rt
->rtm_scope
= RT_SCOPE_LINK
;
1762 rt
->rtm_protocol
= RTPROT_BOOT
;
1763 rt
->rtm_type
= RTN_UNICAST
;
1764 rt
->rtm_dst_len
= addrlen
* 8;
1767 if (nla_put_buffer(nlmsg
, RTA_DST
, dest
, addrlen
))
1769 if (nla_put_u32(nlmsg
, RTA_OIF
, ifindex
))
1771 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1773 netlink_close(&nlh
);
1779 int lxc_ipv4_dest_add(int ifindex
, struct in_addr
*dest
)
1781 return ip_route_dest_add(AF_INET
, ifindex
, dest
);
1784 int lxc_ipv6_dest_add(int ifindex
, struct in6_addr
*dest
)
1786 return ip_route_dest_add(AF_INET6
, ifindex
, dest
);
1789 bool is_ovs_bridge(const char *bridge
)
1793 char brdirname
[22 + IFNAMSIZ
+ 1] = {0};
1795 ret
= snprintf(brdirname
, 22 + IFNAMSIZ
+ 1, "/sys/class/net/%s/bridge",
1797 if (ret
< 0 || (size_t)ret
>= 22 + IFNAMSIZ
+ 1)
1800 ret
= stat(brdirname
, &sb
);
1801 if (ret
< 0 && errno
== ENOENT
)
1807 struct ovs_veth_args
{
1812 /* Called from a background thread - when nic goes away, remove it from the
1815 static int lxc_ovs_delete_port_exec(void *data
)
1817 struct ovs_veth_args
*args
= data
;
1819 execlp("ovs-vsctl", "ovs-vsctl", "del-port", args
->bridge
, args
->nic
,
1824 int lxc_ovs_delete_port(const char *bridge
, const char *nic
)
1827 char cmd_output
[MAXPATHLEN
];
1828 struct ovs_veth_args args
;
1830 args
.bridge
= bridge
;
1832 ret
= run_command(cmd_output
, sizeof(cmd_output
),
1833 lxc_ovs_delete_port_exec
, (void *)&args
);
1835 ERROR("Failed to delete \"%s\" from openvswitch bridge \"%s\": "
1836 "%s", bridge
, nic
, cmd_output
);
1843 static int lxc_ovs_attach_bridge_exec(void *data
)
1845 struct ovs_veth_args
*args
= data
;
1847 execlp("ovs-vsctl", "ovs-vsctl", "add-port", args
->bridge
, args
->nic
,
1852 static int lxc_ovs_attach_bridge(const char *bridge
, const char *nic
)
1855 char cmd_output
[MAXPATHLEN
];
1856 struct ovs_veth_args args
;
1858 args
.bridge
= bridge
;
1860 ret
= run_command(cmd_output
, sizeof(cmd_output
),
1861 lxc_ovs_attach_bridge_exec
, (void *)&args
);
1863 ERROR("Failed to attach \"%s\" to openvswitch bridge \"%s\": %s",
1864 bridge
, nic
, cmd_output
);
1871 int lxc_bridge_attach(const char *bridge
, const char *ifname
)
1876 if (strlen(ifname
) >= IFNAMSIZ
)
1879 index
= if_nametoindex(ifname
);
1883 if (is_ovs_bridge(bridge
))
1884 return lxc_ovs_attach_bridge(bridge
, ifname
);
1886 fd
= socket(AF_INET
, SOCK_STREAM
, 0);
1890 strncpy(ifr
.ifr_name
, bridge
, IFNAMSIZ
- 1);
1891 ifr
.ifr_name
[IFNAMSIZ
- 1] = '\0';
1892 ifr
.ifr_ifindex
= index
;
1893 err
= ioctl(fd
, SIOCBRADDIF
, &ifr
);
1901 static const char *const lxc_network_types
[LXC_NET_MAXCONFTYPE
+ 1] = {
1902 [LXC_NET_EMPTY
] = "empty",
1903 [LXC_NET_VETH
] = "veth",
1904 [LXC_NET_MACVLAN
] = "macvlan",
1905 [LXC_NET_PHYS
] = "phys",
1906 [LXC_NET_VLAN
] = "vlan",
1907 [LXC_NET_NONE
] = "none",
1910 const char *lxc_net_type_to_str(int type
)
1912 if (type
< 0 || type
> LXC_NET_MAXCONFTYPE
)
1915 return lxc_network_types
[type
];
1918 static const char padchar
[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1920 char *lxc_mkifname(const char *template)
1927 struct ifaddrs
*ifa
, *ifaddr
;
1929 if (strlen(template) >= IFNAMSIZ
)
1932 /* Get all the network interfaces. */
1933 getifaddrs(&ifaddr
);
1935 /* Initialize the random number generator. */
1936 urandom
= fopen("/dev/urandom", "r");
1937 if (urandom
!= NULL
) {
1938 if (fread(&seed
, sizeof(seed
), 1, urandom
) <= 0)
1949 /* Generate random names until we find one that doesn't exist. */
1952 name
= strdup(template);
1957 for (i
= 0; i
< strlen(name
); i
++) {
1958 if (name
[i
] == 'X') {
1960 name
[i
] = padchar
[rand_r(&seed
) %
1961 (strlen(padchar
) - 1)];
1963 name
[i
] = padchar
[rand() % (strlen(padchar
) - 1)];
1968 for (ifa
= ifaddr
; ifa
!= NULL
; ifa
= ifa
->ifa_next
) {
1969 if (strcmp(ifa
->ifa_name
, name
) == 0) {
1981 freeifaddrs(ifaddr
);
1985 int setup_private_host_hw_addr(char *veth1
)
1990 sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
1994 err
= snprintf((char *)ifr
.ifr_name
, IFNAMSIZ
, "%s", veth1
);
1995 if (err
< 0 || (size_t)err
>= IFNAMSIZ
)
1998 err
= ioctl(sockfd
, SIOCGIFHWADDR
, &ifr
);
2004 ifr
.ifr_hwaddr
.sa_data
[0] = 0xfe;
2005 err
= ioctl(sockfd
, SIOCSIFHWADDR
, &ifr
);
2013 int lxc_find_gateway_addresses(struct lxc_handler
*handler
)
2015 struct lxc_list
*network
= &handler
->conf
->network
;
2016 struct lxc_list
*iterator
;
2017 struct lxc_netdev
*netdev
;
2020 lxc_list_for_each(iterator
, network
) {
2021 netdev
= iterator
->elem
;
2023 if (!netdev
->ipv4_gateway_auto
&& !netdev
->ipv6_gateway_auto
)
2026 if (netdev
->type
!= LXC_NET_VETH
&& netdev
->type
!= LXC_NET_MACVLAN
) {
2027 ERROR("Automatic gateway detection is only supported "
2028 "for veth and macvlan");
2032 if (netdev
->link
[0] == '\0') {
2033 ERROR("Automatic gateway detection needs a link interface");
2037 link_index
= if_nametoindex(netdev
->link
);
2041 if (netdev
->ipv4_gateway_auto
) {
2042 if (lxc_ipv4_addr_get(link_index
, &netdev
->ipv4_gateway
)) {
2043 ERROR("Failed to automatically find ipv4 gateway "
2044 "address from link interface \"%s\"", netdev
->link
);
2049 if (netdev
->ipv6_gateway_auto
) {
2050 if (lxc_ipv6_addr_get(link_index
, &netdev
->ipv6_gateway
)) {
2051 ERROR("Failed to automatically find ipv6 gateway "
2052 "address from link interface \"%s\"", netdev
->link
);
2061 #define LXC_USERNIC_PATH LIBEXECDIR "/lxc/lxc-user-nic"
2062 static int lxc_create_network_unpriv_exec(const char *lxcpath
, char *lxcname
,
2063 struct lxc_netdev
*netdev
, pid_t pid
)
2067 int bytes
, pipefd
[2];
2068 char *token
, *saveptr
= NULL
;
2069 char netdev_link
[IFNAMSIZ
+ 1];
2070 char buffer
[MAXPATHLEN
] = {0};
2072 if (netdev
->type
!= LXC_NET_VETH
) {
2073 ERROR("Network type %d not support for unprivileged use", netdev
->type
);
2079 SYSERROR("Failed to create pipe");
2085 SYSERROR("Failed to create new process");
2093 char pidstr
[LXC_NUMSTRLEN64
];
2097 ret
= dup2(pipefd
[1], STDOUT_FILENO
);
2099 ret
= dup2(pipefd
[1], STDERR_FILENO
);
2102 SYSERROR("Failed to duplicate std{err,out} file descriptor");
2106 if (netdev
->link
[0] != '\0')
2107 strncpy(netdev_link
, netdev
->link
, IFNAMSIZ
);
2109 strncpy(netdev_link
, "none", IFNAMSIZ
);
2111 ret
= snprintf(pidstr
, LXC_NUMSTRLEN64
, "%d", pid
);
2112 if (ret
< 0 || ret
>= LXC_NUMSTRLEN64
)
2114 pidstr
[LXC_NUMSTRLEN64
- 1] = '\0';
2116 INFO("Execing lxc-user-nic create %s %s %s veth %s %s", lxcpath
,
2117 lxcname
, pidstr
, netdev_link
,
2118 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)");
2119 if (netdev
->name
[0] != '\0')
2120 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "create",
2121 lxcpath
, lxcname
, pidstr
, "veth", netdev_link
,
2122 netdev
->name
, (char *)NULL
);
2124 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "create",
2125 lxcpath
, lxcname
, pidstr
, "veth", netdev_link
,
2127 SYSERROR("Failed to execute lxc-user-nic");
2131 /* close the write-end of the pipe */
2134 bytes
= read(pipefd
[0], &buffer
, MAXPATHLEN
);
2136 SYSERROR("Failed to read from pipe file descriptor");
2140 buffer
[bytes
- 1] = '\0';
2142 ret
= wait_for_pid(child
);
2145 ERROR("lxc-user-nic failed to configure requested network: %s",
2146 buffer
[0] != '\0' ? buffer
: "(null)");
2149 TRACE("Received output \"%s\" from lxc-user-nic", buffer
);
2152 token
= strtok_r(buffer
, ":", &saveptr
);
2154 ERROR("Failed to parse lxc-user-nic output");
2158 memset(netdev
->name
, 0, IFNAMSIZ
+ 1);
2159 strncpy(netdev
->name
, token
, IFNAMSIZ
);
2161 /* netdev->ifindex */
2162 token
= strtok_r(NULL
, ":", &saveptr
);
2164 ERROR("Failed to parse lxc-user-nic output");
2168 ret
= lxc_safe_int(token
, &netdev
->ifindex
);
2170 ERROR("%s - Failed to convert string \"%s\" to integer",
2171 strerror(-ret
), token
);
2175 /* netdev->priv.veth_attr.veth1 */
2176 token
= strtok_r(NULL
, ":", &saveptr
);
2178 ERROR("Failed to parse lxc-user-nic output");
2182 if (strlen(token
) >= IFNAMSIZ
) {
2183 ERROR("Host side veth device name returned by lxc-user-nic is "
2187 strcpy(netdev
->priv
.veth_attr
.veth1
, token
);
2189 /* netdev->priv.veth_attr.ifindex */
2190 token
= strtok_r(NULL
, ":", &saveptr
);
2192 ERROR("Failed to parse lxc-user-nic output");
2196 ret
= lxc_safe_int(token
, &netdev
->priv
.veth_attr
.ifindex
);
2198 ERROR("%s - Failed to convert string \"%s\" to integer",
2199 strerror(-ret
), token
);
2206 static int lxc_delete_network_unpriv_exec(const char *lxcpath
, char *lxcname
,
2207 struct lxc_netdev
*netdev
,
2208 const char *netns_path
)
2213 char buffer
[MAXPATHLEN
] = {0};
2215 if (netdev
->type
!= LXC_NET_VETH
) {
2216 ERROR("Network type %d not support for unprivileged use", netdev
->type
);
2222 SYSERROR("Failed to create pipe");
2228 SYSERROR("Failed to create new process");
2240 ret
= dup2(pipefd
[1], STDOUT_FILENO
);
2242 ret
= dup2(pipefd
[1], STDERR_FILENO
);
2245 SYSERROR("Failed to duplicate std{err,out} file descriptor");
2249 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2250 hostveth
= netdev
->priv
.veth_attr
.pair
;
2252 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2253 if (hostveth
[0] == '\0') {
2254 SYSERROR("Host side veth device name is missing");
2258 if (netdev
->link
[0] == '\0') {
2259 SYSERROR("Network link for network device \"%s\" is "
2260 "missing", netdev
->priv
.veth_attr
.veth1
);
2264 INFO("Execing lxc-user-nic delete %s %s %s veth %s %s", lxcpath
,
2265 lxcname
, netns_path
, netdev
->link
, hostveth
);
2266 execlp(LXC_USERNIC_PATH
, LXC_USERNIC_PATH
, "delete", lxcpath
,
2267 lxcname
, netns_path
, "veth", netdev
->link
, hostveth
,
2269 SYSERROR("Failed to exec lxc-user-nic.");
2275 bytes
= read(pipefd
[0], &buffer
, MAXPATHLEN
);
2277 SYSERROR("Failed to read from pipe file descriptor.");
2281 buffer
[bytes
- 1] = '\0';
2283 if (wait_for_pid(child
) != 0) {
2284 ERROR("lxc-user-nic failed to delete requested network: %s",
2285 buffer
[0] != '\0' ? buffer
: "(null)");
2295 bool lxc_delete_network_unpriv(struct lxc_handler
*handler
)
2298 struct lxc_list
*iterator
;
2299 struct lxc_list
*network
= &handler
->conf
->network
;
2300 /* strlen("/proc/") = 6
2304 * strlen("/fd/") = 4
2310 char netns_path
[6 + LXC_NUMSTRLEN64
+ 4 + LXC_NUMSTRLEN64
+ 1];
2311 bool deleted_all
= true;
2318 if (handler
->netnsfd
< 0) {
2319 DEBUG("Cannot not guarantee safe deletion of network devices. "
2320 "Manual cleanup maybe needed");
2324 ret
= snprintf(netns_path
, sizeof(netns_path
), "/proc/%d/fd/%d",
2325 getpid(), handler
->netnsfd
);
2326 if (ret
< 0 || ret
>= sizeof(netns_path
))
2329 lxc_list_for_each(iterator
, network
) {
2330 char *hostveth
= NULL
;
2331 struct lxc_netdev
*netdev
= iterator
->elem
;
2333 /* We can only delete devices whose ifindex we have. If we don't
2334 * have the index it means that we didn't create it.
2336 if (!netdev
->ifindex
)
2339 if (netdev
->type
== LXC_NET_PHYS
) {
2340 ret
= lxc_netdev_rename_by_index(netdev
->ifindex
,
2343 WARN("Failed to rename interface with index %d "
2344 "to its initial name \"%s\"",
2345 netdev
->ifindex
, netdev
->link
);
2347 TRACE("Renamed interface with index %d to its "
2348 "initial name \"%s\"",
2349 netdev
->ifindex
, netdev
->link
);
2353 ret
= netdev_deconf
[netdev
->type
](handler
, netdev
);
2355 WARN("Failed to deconfigure network device");
2357 if (netdev
->type
!= LXC_NET_VETH
)
2360 if (!is_ovs_bridge(netdev
->link
))
2363 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2364 hostveth
= netdev
->priv
.veth_attr
.pair
;
2366 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2367 if (hostveth
[0] == '\0')
2370 ret
= lxc_delete_network_unpriv_exec(handler
->lxcpath
,
2371 handler
->name
, netdev
,
2374 deleted_all
= false;
2375 WARN("Failed to remove port \"%s\" from openvswitch "
2376 "bridge \"%s\"", hostveth
, netdev
->link
);
2379 INFO("Removed interface \"%s\" from \"%s\"", hostveth
,
2386 int lxc_create_network_priv(struct lxc_handler
*handler
)
2388 struct lxc_list
*iterator
;
2389 struct lxc_list
*network
= &handler
->conf
->network
;
2394 lxc_list_for_each(iterator
, network
) {
2395 struct lxc_netdev
*netdev
= iterator
->elem
;
2397 if (netdev
->type
< 0 || netdev
->type
> LXC_NET_MAXCONFTYPE
) {
2398 ERROR("Invalid network configuration type %d", netdev
->type
);
2402 if (netdev_conf
[netdev
->type
](handler
, netdev
)) {
2403 ERROR("Failed to create network device");
2412 int lxc_network_move_created_netdev_priv(const char *lxcpath
, char *lxcname
,
2413 struct lxc_list
*network
, pid_t pid
)
2416 char ifname
[IFNAMSIZ
];
2417 struct lxc_list
*iterator
;
2422 lxc_list_for_each(iterator
, network
) {
2423 struct lxc_netdev
*netdev
= iterator
->elem
;
2425 if (!netdev
->ifindex
)
2428 /* retrieve the name of the interface */
2429 if (!if_indextoname(netdev
->ifindex
, ifname
)) {
2430 ERROR("No interface corresponding to ifindex \"%d\"",
2435 ret
= lxc_netdev_move_by_name(ifname
, pid
, NULL
);
2437 ERROR("Failed to move network device \"%s\" to "
2438 "network namespace %d: %s", ifname
, pid
,
2443 DEBUG("Moved network device \"%s\"/\"%s\" to network namespace "
2445 ifname
, netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2452 int lxc_create_network_unpriv(const char *lxcpath
, char *lxcname
,
2453 struct lxc_list
*network
, pid_t pid
)
2455 struct lxc_list
*iterator
;
2460 lxc_list_for_each(iterator
, network
) {
2461 struct lxc_netdev
*netdev
= iterator
->elem
;
2463 if (netdev
->type
== LXC_NET_EMPTY
)
2466 if (netdev
->type
== LXC_NET_NONE
)
2469 if (netdev
->type
!= LXC_NET_VETH
) {
2470 ERROR("Networks of type %s are not supported by "
2471 "unprivileged containers",
2472 lxc_net_type_to_str(netdev
->type
));
2477 INFO("mtu ignored due to insufficient privilege");
2479 if (lxc_create_network_unpriv_exec(lxcpath
, lxcname
, netdev
, pid
))
2486 bool lxc_delete_network_priv(struct lxc_handler
*handler
)
2489 struct lxc_list
*iterator
;
2490 struct lxc_list
*network
= &handler
->conf
->network
;
2491 bool deleted_all
= true;
2496 lxc_list_for_each(iterator
, network
) {
2497 char *hostveth
= NULL
;
2498 struct lxc_netdev
*netdev
= iterator
->elem
;
2500 /* We can only delete devices whose ifindex we have. If we don't
2501 * have the index it means that we didn't create it.
2503 if (!netdev
->ifindex
)
2506 if (netdev
->type
== LXC_NET_PHYS
) {
2507 ret
= lxc_netdev_rename_by_index(netdev
->ifindex
, netdev
->link
);
2509 WARN("Failed to rename interface with index %d "
2510 "from \"%s\" to its initial name \"%s\"",
2511 netdev
->ifindex
, netdev
->name
, netdev
->link
);
2513 TRACE("Renamed interface with index %d to its "
2514 "from \"%s\" to its initial name \"%s\"",
2515 netdev
->ifindex
, netdev
->name
, netdev
->link
);
2519 ret
= netdev_deconf
[netdev
->type
](handler
, netdev
);
2521 WARN("Failed to deconfigure network device");
2523 /* Recent kernels remove the virtual interfaces when the network
2524 * namespace is destroyed but in case we did not move the
2525 * interface to the network namespace, we have to destroy it.
2527 ret
= lxc_netdev_delete_by_index(netdev
->ifindex
);
2528 if (-ret
== ENODEV
) {
2529 INFO("Interface \"%s\" with index %d already "
2530 "deleted or existing in different network "
2532 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2534 } else if (ret
< 0) {
2535 deleted_all
= false;
2536 WARN("Failed to remove interface \"%s\" with "
2538 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2539 netdev
->ifindex
, strerror(-ret
));
2542 INFO("Removed interface \"%s\" with index %d",
2543 netdev
->name
[0] != '\0' ? netdev
->name
: "(null)",
2546 if (netdev
->type
!= LXC_NET_VETH
)
2549 /* Explicitly delete host veth device to prevent lingering
2550 * devices. We had issues in LXD around this.
2552 if (netdev
->priv
.veth_attr
.pair
[0] != '\0')
2553 hostveth
= netdev
->priv
.veth_attr
.pair
;
2555 hostveth
= netdev
->priv
.veth_attr
.veth1
;
2556 if (hostveth
[0] == '\0')
2559 ret
= lxc_netdev_delete_by_name(hostveth
);
2561 deleted_all
= false;
2562 WARN("Failed to remove interface \"%s\" from \"%s\": %s",
2563 hostveth
, netdev
->link
, strerror(-ret
));
2566 INFO("Removed interface \"%s\" from \"%s\"", hostveth
, netdev
->link
);
2568 if (!is_ovs_bridge(netdev
->link
)) {
2569 netdev
->priv
.veth_attr
.veth1
[0] = '\0';
2573 /* Delete the openvswitch port. */
2574 ret
= lxc_ovs_delete_port(netdev
->link
, hostveth
);
2576 WARN("Failed to remove port \"%s\" from openvswitch "
2577 "bridge \"%s\"", hostveth
, netdev
->link
);
2579 INFO("Removed port \"%s\" from openvswitch bridge \"%s\"",
2580 hostveth
, netdev
->link
);
2582 netdev
->priv
.veth_attr
.veth1
[0] = '\0';
2588 int lxc_requests_empty_network(struct lxc_handler
*handler
)
2590 struct lxc_list
*network
= &handler
->conf
->network
;
2591 struct lxc_list
*iterator
;
2592 bool found_none
= false, found_nic
= false;
2594 if (lxc_list_empty(network
))
2597 lxc_list_for_each(iterator
, network
) {
2598 struct lxc_netdev
*netdev
= iterator
->elem
;
2600 if (netdev
->type
== LXC_NET_NONE
)
2605 if (found_none
&& !found_nic
)
2610 /* try to move physical nics to the init netns */
2611 int lxc_restore_phys_nics_to_netns(struct lxc_handler
*handler
)
2615 char ifname
[IFNAMSIZ
];
2616 struct lxc_list
*iterator
;
2617 int netnsfd
= handler
->netnsfd
;
2618 struct lxc_conf
*conf
= handler
->conf
;
2620 /* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
2621 * the parent network namespace. We won't have this capability if we are
2627 TRACE("Moving physical network devices back to parent network namespace");
2629 oldfd
= lxc_preserve_ns(getpid(), "net");
2631 SYSERROR("Failed to preserve network namespace");
2635 ret
= setns(netnsfd
, CLONE_NEWNET
);
2637 SYSERROR("Failed to enter network namespace");
2642 lxc_list_for_each(iterator
, &conf
->network
) {
2643 struct lxc_netdev
*netdev
= iterator
->elem
;
2645 if (netdev
->type
!= LXC_NET_PHYS
)
2648 /* Retrieve the name of the interface in the container's network
2651 if (!if_indextoname(netdev
->ifindex
, ifname
)) {
2652 WARN("No interface corresponding to ifindex %d",
2657 ret
= lxc_netdev_move_by_name(ifname
, 1, netdev
->link
);
2659 WARN("Error moving network device \"%s\" back to "
2660 "network namespace", ifname
);
2662 TRACE("Moved network device \"%s\" back to network "
2663 "namespace", ifname
);
2666 ret
= setns(oldfd
, CLONE_NEWNET
);
2669 SYSERROR("Failed to enter network namespace");
2676 static int setup_hw_addr(char *hwaddr
, const char *ifname
)
2678 struct sockaddr sockaddr
;
2680 int ret
, fd
, saved_errno
;
2682 ret
= lxc_convert_mac(hwaddr
, &sockaddr
);
2684 ERROR("Mac address \"%s\" conversion failed: %s", hwaddr
,
2689 memcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
2690 ifr
.ifr_name
[IFNAMSIZ
-1] = '\0';
2691 memcpy((char *) &ifr
.ifr_hwaddr
, (char *) &sockaddr
, sizeof(sockaddr
));
2693 fd
= socket(AF_INET
, SOCK_DGRAM
, 0);
2697 ret
= ioctl(fd
, SIOCSIFHWADDR
, &ifr
);
2698 saved_errno
= errno
;
2701 ERROR("Failed to perform ioctl: %s", strerror(saved_errno
));
2703 DEBUG("Mac address \"%s\" on \"%s\" has been setup", hwaddr
,
2709 static int setup_ipv4_addr(struct lxc_list
*ip
, int ifindex
)
2711 struct lxc_list
*iterator
;
2714 lxc_list_for_each(iterator
, ip
) {
2715 struct lxc_inetdev
*inetdev
= iterator
->elem
;
2717 err
= lxc_ipv4_addr_add(ifindex
, &inetdev
->addr
,
2718 &inetdev
->bcast
, inetdev
->prefix
);
2720 ERROR("Failed to setup ipv4 address for network device "
2721 "with eifindex %d: %s", ifindex
, strerror(-err
));
2729 static int setup_ipv6_addr(struct lxc_list
*ip
, int ifindex
)
2731 struct lxc_list
*iterator
;
2734 lxc_list_for_each(iterator
, ip
) {
2735 struct lxc_inet6dev
*inet6dev
= iterator
->elem
;
2737 err
= lxc_ipv6_addr_add(ifindex
, &inet6dev
->addr
,
2738 &inet6dev
->mcast
, &inet6dev
->acast
,
2741 ERROR("Failed to setup ipv6 address for network device "
2742 "with eifindex %d: %s", ifindex
, strerror(-err
));
2750 static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev
*netdev
)
2752 char ifname
[IFNAMSIZ
];
2754 const char *net_type_name
;
2755 char *current_ifname
= ifname
;
2757 /* empty network namespace */
2758 if (!netdev
->ifindex
) {
2759 if (netdev
->flags
& IFF_UP
) {
2760 err
= lxc_netdev_up("lo");
2762 ERROR("Failed to set the loopback network "
2769 if (netdev
->type
== LXC_NET_EMPTY
)
2772 if (netdev
->type
== LXC_NET_NONE
)
2775 if (netdev
->type
!= LXC_NET_VETH
) {
2776 net_type_name
= lxc_net_type_to_str(netdev
->type
);
2777 ERROR("%s networks are not supported for containers "
2778 "not setup up by privileged users", net_type_name
);
2782 netdev
->ifindex
= if_nametoindex(netdev
->name
);
2785 /* get the new ifindex in case of physical netdev */
2786 if (netdev
->type
== LXC_NET_PHYS
) {
2787 netdev
->ifindex
= if_nametoindex(netdev
->link
);
2788 if (!netdev
->ifindex
) {
2789 ERROR("Failed to get ifindex for network device \"%s\"",
2795 /* retrieve the name of the interface */
2796 if (!if_indextoname(netdev
->ifindex
, current_ifname
)) {
2797 ERROR("Failed get name for network device with ifindex %d",
2802 /* Default: let the system to choose one interface name.
2803 * When the IFLA_IFNAME attribute is passed something like "<prefix>%d"
2804 * netlink will replace the format specifier with an appropriate index.
2806 if (netdev
->name
[0] == '\0') {
2807 if (netdev
->type
== LXC_NET_PHYS
)
2808 strcpy(netdev
->name
, netdev
->link
);
2810 strcpy(netdev
->name
, "eth%d");
2813 /* rename the interface name */
2814 if (strcmp(ifname
, netdev
->name
) != 0) {
2815 err
= lxc_netdev_rename_by_name(ifname
, netdev
->name
);
2817 ERROR("Failed to rename network device \"%s\" to "
2818 "\"%s\": %s", ifname
, netdev
->name
, strerror(-err
));
2823 /* Re-read the name of the interface because its name has changed
2824 * and would be automatically allocated by the system
2826 if (!if_indextoname(netdev
->ifindex
, current_ifname
)) {
2827 ERROR("Failed get name for network device with ifindex %d",
2832 /* Now update the recorded name of the network device to reflect the
2833 * name of the network device in the child's network namespace. We will
2834 * later on send this information back to the parent.
2836 strcpy(netdev
->name
, current_ifname
);
2838 /* set a mac address */
2839 if (netdev
->hwaddr
) {
2840 if (setup_hw_addr(netdev
->hwaddr
, current_ifname
)) {
2841 ERROR("Failed to setup hw address for network device \"%s\"",
2847 /* setup ipv4 addresses on the interface */
2848 if (setup_ipv4_addr(&netdev
->ipv4
, netdev
->ifindex
)) {
2849 ERROR("Failed to setup ip addresses for network device \"%s\"",
2854 /* setup ipv6 addresses on the interface */
2855 if (setup_ipv6_addr(&netdev
->ipv6
, netdev
->ifindex
)) {
2856 ERROR("Failed to setup ipv6 addresses for network device \"%s\"",
2861 /* set the network device up */
2862 if (netdev
->flags
& IFF_UP
) {
2865 err
= lxc_netdev_up(current_ifname
);
2867 ERROR("Failed to set network device \"%s\" up: %s",
2868 current_ifname
, strerror(-err
));
2872 /* the network is up, make the loopback up too */
2873 err
= lxc_netdev_up("lo");
2875 ERROR("Failed to set the loopback network device up: %s",
2881 /* We can only set up the default routes after bringing
2882 * up the interface, sine bringing up the interface adds
2883 * the link-local routes and we can't add a default
2884 * route if the gateway is not reachable. */
2886 /* setup ipv4 gateway on the interface */
2887 if (netdev
->ipv4_gateway
) {
2888 if (!(netdev
->flags
& IFF_UP
)) {
2889 ERROR("Cannot add ipv4 gateway for network device "
2890 "\"%s\" when not bringing up the interface", ifname
);
2894 if (lxc_list_empty(&netdev
->ipv4
)) {
2895 ERROR("Cannot add ipv4 gateway for network device "
2896 "\"%s\" when not assigning an address", ifname
);
2900 err
= lxc_ipv4_gateway_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2902 err
= lxc_ipv4_dest_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2904 ERROR("Failed to add ipv4 dest for network "
2905 "device \"%s\": %s", ifname
, strerror(-err
));
2908 err
= lxc_ipv4_gateway_add(netdev
->ifindex
, netdev
->ipv4_gateway
);
2910 ERROR("Failed to setup ipv4 gateway for "
2911 "network device \"%s\": %s",
2912 ifname
, strerror(-err
));
2913 if (netdev
->ipv4_gateway_auto
) {
2914 char buf
[INET_ADDRSTRLEN
];
2915 inet_ntop(AF_INET
, netdev
->ipv4_gateway
, buf
, sizeof(buf
));
2916 ERROR("Fried to set autodetected ipv4 gateway \"%s\"", buf
);
2923 /* setup ipv6 gateway on the interface */
2924 if (netdev
->ipv6_gateway
) {
2925 if (!(netdev
->flags
& IFF_UP
)) {
2926 ERROR("Cannot add ipv6 gateway for network device "
2927 "\"%s\" when not bringing up the interface", ifname
);
2931 if (lxc_list_empty(&netdev
->ipv6
) && !IN6_IS_ADDR_LINKLOCAL(netdev
->ipv6_gateway
)) {
2932 ERROR("Cannot add ipv6 gateway for network device "
2933 "\"%s\" when not assigning an address", ifname
);
2937 err
= lxc_ipv6_gateway_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
2939 err
= lxc_ipv6_dest_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
2941 ERROR("Failed to add ipv6 dest for network "
2942 "device \"%s\": %s", ifname
, strerror(-err
));
2945 err
= lxc_ipv6_gateway_add(netdev
->ifindex
, netdev
->ipv6_gateway
);
2947 ERROR("Failed to setup ipv6 gateway for "
2948 "network device \"%s\": %s", ifname
,
2950 if (netdev
->ipv6_gateway_auto
) {
2951 char buf
[INET6_ADDRSTRLEN
];
2952 inet_ntop(AF_INET6
, netdev
->ipv6_gateway
, buf
, sizeof(buf
));
2953 ERROR("Tried to set autodetected ipv6 "
2954 "gateway for network device "
2962 DEBUG("Network device \"%s\" has been setup", current_ifname
);
2967 int lxc_setup_network_in_child_namespaces(const struct lxc_conf
*conf
,
2968 struct lxc_list
*network
)
2970 struct lxc_list
*iterator
;
2971 struct lxc_netdev
*netdev
;
2973 lxc_list_for_each(iterator
, network
) {
2974 netdev
= iterator
->elem
;
2976 /* REMOVE in LXC 3.0 */
2977 if (netdev
->idx
< 0) {
2978 ERROR("WARNING: using \"lxc.network.*\" keys to define "
2979 "networks is DEPRECATED, please switch to using "
2980 "\"lxc.net.[i].* keys\"");
2983 if (lxc_setup_netdev_in_child_namespaces(netdev
)) {
2984 ERROR("failed to setup netdev");
2989 if (!lxc_list_empty(network
))
2990 INFO("network has been setup");