]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/network.c
network: use correct network device name
[mirror_lxc.git] / src / lxc / network.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 *
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.
13 *
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.
18 *
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
22 */
23
24 #define _GNU_SOURCE
25 #include <ctype.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.h>
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>
38 #include <net/if.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>
45 #include <sys/stat.h>
46 #include <sys/types.h>
47
48 #include "conf.h"
49 #include "config.h"
50 #include "log.h"
51 #include "network.h"
52 #include "nl.h"
53 #include "utils.h"
54
55 #if HAVE_IFADDRS_H
56 #include <ifaddrs.h>
57 #else
58 #include <../include/ifaddrs.h>
59 #endif
60
61 #ifndef IFLA_LINKMODE
62 #define IFLA_LINKMODE 17
63 #endif
64
65 #ifndef IFLA_LINKINFO
66 #define IFLA_LINKINFO 18
67 #endif
68
69 #ifndef IFLA_NET_NS_PID
70 #define IFLA_NET_NS_PID 19
71 #endif
72
73 #ifndef IFLA_INFO_KIND
74 #define IFLA_INFO_KIND 1
75 #endif
76
77 #ifndef IFLA_VLAN_ID
78 #define IFLA_VLAN_ID 1
79 #endif
80
81 #ifndef IFLA_INFO_DATA
82 #define IFLA_INFO_DATA 2
83 #endif
84
85 #ifndef VETH_INFO_PEER
86 #define VETH_INFO_PEER 1
87 #endif
88
89 #ifndef IFLA_MACVLAN_MODE
90 #define IFLA_MACVLAN_MODE 1
91 #endif
92
93 lxc_log_define(lxc_network, lxc);
94
95 typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *);
96
97 static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
98 {
99 int bridge_index, err;
100 char *veth1, *veth2;
101 char veth1buf[IFNAMSIZ], veth2buf[IFNAMSIZ];
102 unsigned int mtu = 0;
103
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);
108 } else {
109 err = snprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX");
110 if (err < 0 || (size_t)err >= sizeof(veth1buf))
111 return -1;
112
113 veth1 = lxc_mkifname(veth1buf);
114 if (!veth1)
115 return -1;
116
117 /* store away for deconf */
118 memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ);
119 }
120
121 snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
122 veth2 = lxc_mkifname(veth2buf);
123 if (!veth2)
124 goto out_delete;
125
126 err = lxc_veth_create(veth1, veth2);
127 if (err) {
128 ERROR("Failed to create veth pair \"%s\" and \"%s\": %s", veth1,
129 veth2, strerror(-err));
130 goto out_delete;
131 }
132
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
135 * of a container */
136 err = setup_private_host_hw_addr(veth1);
137 if (err) {
138 ERROR("Failed to change mac address of host interface \"%s\": %s",
139 veth1, strerror(-err));
140 goto out_delete;
141 }
142
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);
147 goto out_delete;
148 }
149
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
153 * on.
154 */
155 netdev->ifindex = if_nametoindex(veth2);
156 if (!netdev->ifindex) {
157 ERROR("Failed to retrieve ifindex for \"%s\"", veth2);
158 goto out_delete;
159 }
160
161 if (netdev->mtu) {
162 if (lxc_safe_uint(netdev->mtu, &mtu) < 0)
163 WARN("Failed to parse mtu");
164 else
165 INFO("Retrieved mtu %d", mtu);
166 } else if (netdev->link[0] != '\0') {
167 bridge_index = if_nametoindex(netdev->link);
168 if (bridge_index) {
169 mtu = netdev_get_mtu(bridge_index);
170 INFO("Retrieved mtu %d from %s", mtu, netdev->link);
171 } else {
172 mtu = netdev_get_mtu(netdev->ifindex);
173 INFO("Retrieved mtu %d from %s", mtu, veth2);
174 }
175 }
176
177 if (mtu) {
178 err = lxc_netdev_set_mtu(veth1, mtu);
179 if (!err)
180 err = lxc_netdev_set_mtu(veth2, mtu);
181 if (err) {
182 ERROR("Failed to set mtu \"%d\" for veth pair \"%s\" "
183 "and \"%s\": %s",
184 mtu, veth1, veth2, strerror(-err));
185 goto out_delete;
186 }
187 }
188
189 if (netdev->link[0] != '\0') {
190 err = lxc_bridge_attach(netdev->link, veth1);
191 if (err) {
192 ERROR("Failed to attach \"%s\" to bridge \"%s\": %s",
193 veth1, netdev->link, strerror(-err));
194 goto out_delete;
195 }
196 INFO("Attached \"%s\" to bridge \"%s\"", veth1, netdev->link);
197 }
198
199 err = lxc_netdev_up(veth1);
200 if (err) {
201 ERROR("Failed to set \"%s\" up: %s", veth1, strerror(-err));
202 goto out_delete;
203 }
204
205 if (netdev->upscript) {
206 err = run_script(handler->name, "net", netdev->upscript, "up",
207 "veth", veth1, (char*) NULL);
208 if (err)
209 goto out_delete;
210 }
211
212 DEBUG("Instantiated veth \"%s/%s\", index is \"%d\"", veth1, veth2,
213 netdev->ifindex);
214
215 return 0;
216
217 out_delete:
218 if (netdev->ifindex != 0)
219 lxc_netdev_delete_by_name(veth1);
220 if (netdev->priv.veth_attr.pair != veth1)
221 free(veth1);
222 free(veth2);
223 return -1;
224 }
225
226 static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
227 {
228 char peerbuf[IFNAMSIZ], *peer;
229 int err;
230
231 if (netdev->link[0] == '\0') {
232 ERROR("No link for macvlan network device specified");
233 return -1;
234 }
235
236 err = snprintf(peerbuf, sizeof(peerbuf), "mcXXXXXX");
237 if (err < 0 || (size_t)err >= sizeof(peerbuf))
238 return -1;
239
240 peer = lxc_mkifname(peerbuf);
241 if (!peer)
242 return -1;
243
244 err = lxc_macvlan_create(netdev->link, peer,
245 netdev->priv.macvlan_attr.mode);
246 if (err) {
247 ERROR("Failed to create macvlan interface \"%s\" on \"%s\": %s",
248 peer, netdev->link, strerror(-err));
249 goto out;
250 }
251
252 netdev->ifindex = if_nametoindex(peer);
253 if (!netdev->ifindex) {
254 ERROR("Failed to retrieve ifindex for \"%s\"", peer);
255 goto out;
256 }
257
258 if (netdev->upscript) {
259 err = run_script(handler->name, "net", netdev->upscript, "up",
260 "macvlan", netdev->link, (char*) NULL);
261 if (err)
262 goto out;
263 }
264
265 DEBUG("Instantiated macvlan \"%s\" with ifindex is %d and mode %d",
266 peer, netdev->ifindex, netdev->priv.macvlan_attr.mode);
267
268 return 0;
269 out:
270 lxc_netdev_delete_by_name(peer);
271 free(peer);
272 return -1;
273 }
274
275 static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
276 {
277 char peer[IFNAMSIZ];
278 int err;
279 static uint16_t vlan_cntr = 0;
280 unsigned int mtu = 0;
281
282 if (netdev->link[0] == '\0') {
283 ERROR("No link for vlan network device specified");
284 return -1;
285 }
286
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))
289 return -1;
290
291 err = lxc_vlan_create(netdev->link, peer, netdev->priv.vlan_attr.vid);
292 if (err) {
293 ERROR("Failed to create vlan interface \"%s\" on \"%s\": %s",
294 peer, netdev->link, strerror(-err));
295 return -1;
296 }
297
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);
302 return -1;
303 }
304
305 DEBUG("Instantiated vlan \"%s\" with ifindex is \"%d\" (vlan1000)",
306 peer, netdev->ifindex);
307 if (netdev->mtu) {
308 if (lxc_safe_uint(netdev->mtu, &mtu) < 0) {
309 ERROR("Failed to retrieve mtu from \"%d\"/\"%s\".",
310 netdev->ifindex,
311 netdev->name[0] != '\0' ? netdev->name : "(null)");
312 return -1;
313 }
314 err = lxc_netdev_set_mtu(peer, mtu);
315 if (err) {
316 ERROR("Failed to set mtu \"%s\" for \"%s\": %s",
317 netdev->mtu, peer, strerror(-err));
318 lxc_netdev_delete_by_name(peer);
319 return -1;
320 }
321 }
322
323 return 0;
324 }
325
326 static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
327 {
328 if (netdev->link[0] == '\0') {
329 ERROR("No link for physical interface specified");
330 return -1;
331 }
332
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
336 * on.
337 * Note that netdev->link will contain the name of the physical network
338 * device in the host's namespace.
339 */
340 netdev->ifindex = if_nametoindex(netdev->link);
341 if (!netdev->ifindex) {
342 ERROR("Failed to retrieve ifindex for \"%s\"", netdev->link);
343 return -1;
344 }
345
346 /* Store the ifindex of the host's network device in the host's
347 * namespace.
348 */
349 netdev->priv.phys_attr.ifindex = netdev->ifindex;
350
351 if (netdev->upscript) {
352 int err;
353 err = run_script(handler->name, "net", netdev->upscript,
354 "up", "phys", netdev->link, (char*) NULL);
355 if (err)
356 return -1;
357 }
358
359 return 0;
360 }
361
362 static int instantiate_empty(struct lxc_handler *handler, struct lxc_netdev *netdev)
363 {
364 netdev->ifindex = 0;
365 if (netdev->upscript) {
366 int err;
367 err = run_script(handler->name, "net", netdev->upscript,
368 "up", "empty", (char*) NULL);
369 if (err)
370 return -1;
371 }
372 return 0;
373 }
374
375 static int instantiate_none(struct lxc_handler *handler, struct lxc_netdev *netdev)
376 {
377 netdev->ifindex = 0;
378 return 0;
379 }
380
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,
388 };
389
390 static int shutdown_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
391 {
392 char *veth1;
393 int err;
394
395 if (netdev->priv.veth_attr.pair[0] != '\0')
396 veth1 = netdev->priv.veth_attr.pair;
397 else
398 veth1 = netdev->priv.veth_attr.veth1;
399
400 if (netdev->downscript) {
401 err = run_script(handler->name, "net", netdev->downscript,
402 "down", "veth", veth1, (char*) NULL);
403 if (err)
404 return -1;
405 }
406 return 0;
407 }
408
409 static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
410 {
411 int err;
412
413 if (netdev->downscript) {
414 err = run_script(handler->name, "net", netdev->downscript,
415 "down", "macvlan", netdev->link,
416 (char*) NULL);
417 if (err)
418 return -1;
419 }
420 return 0;
421 }
422
423 static int shutdown_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
424 {
425 return 0;
426 }
427
428 static int shutdown_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
429 {
430 int err;
431
432 if (netdev->downscript) {
433 err = run_script(handler->name, "net", netdev->downscript,
434 "down", "phys", netdev->link, (char*) NULL);
435 if (err)
436 return -1;
437 }
438 return 0;
439 }
440
441 static int shutdown_empty(struct lxc_handler *handler, struct lxc_netdev *netdev)
442 {
443 int err;
444
445 if (netdev->downscript) {
446 err = run_script(handler->name, "net", netdev->downscript,
447 "down", "empty", (char*) NULL);
448 if (err)
449 return -1;
450 }
451 return 0;
452 }
453
454 static int shutdown_none(struct lxc_handler *handler, struct lxc_netdev *netdev)
455 {
456 return 0;
457 }
458
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,
466 };
467
468 int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char *ifname)
469 {
470 int err;
471 struct nl_handler nlh;
472 struct ifinfomsg *ifi;
473 struct nlmsg *nlmsg = NULL;
474
475 err = netlink_open(&nlh, NETLINK_ROUTE);
476 if (err)
477 return err;
478
479 err = -ENOMEM;
480 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
481 if (!nlmsg)
482 goto out;
483
484 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
485 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
486
487 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
488 if (!ifi)
489 goto out;
490 ifi->ifi_family = AF_UNSPEC;
491 ifi->ifi_index = ifindex;
492
493 if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid))
494 goto out;
495
496 if (ifname != NULL) {
497 if (nla_put_string(nlmsg, IFLA_IFNAME, ifname))
498 goto out;
499 }
500
501 err = netlink_transaction(&nlh, nlmsg, nlmsg);
502 out:
503 netlink_close(&nlh);
504 nlmsg_free(nlmsg);
505 return err;
506 }
507
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.
511 */
512 #define PHYSNAME "/sys/class/net/%s/phy80211/name"
513 static char *is_wlan(const char *ifname)
514 {
515 int i, ret;
516 long physlen;
517 size_t len;
518 char *path;
519 FILE *f;
520 struct stat sb;
521 char *physname = NULL;
522
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)
527 goto bad;
528
529 ret = stat(path, &sb);
530 if (ret)
531 goto bad;
532
533 f = fopen(path, "r");
534 if (!f)
535 goto bad;
536
537 /* Feh - sb.st_size is always 4096. */
538 fseek(f, 0, SEEK_END);
539 physlen = ftell(f);
540 fseek(f, 0, SEEK_SET);
541
542 physname = malloc(physlen + 1);
543 if (!physname) {
544 fclose(f);
545 goto bad;
546 }
547
548 memset(physname, 0, physlen + 1);
549 ret = fread(physname, 1, physlen, f);
550 fclose(f);
551 if (ret < 0)
552 goto bad;
553
554 for (i = 0; i < physlen; i++) {
555 if (physname[i] == '\n')
556 physname[i] = '\0';
557
558 if (physname[i] == '\0')
559 break;
560 }
561
562 return physname;
563
564 bad:
565 free(physname);
566 return NULL;
567 }
568
569 static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old,
570 const char *new)
571 {
572 pid_t fpid;
573
574 fpid = fork();
575 if (fpid < 0)
576 return -1;
577
578 if (fpid != 0)
579 return wait_for_pid(fpid);
580
581 if (!switch_to_ns(pid, "net"))
582 return -1;
583
584 exit(lxc_netdev_rename_by_name(old, new));
585 }
586
587 static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
588 const char *newname)
589 {
590 char *cmd;
591 pid_t fpid;
592 int err = -1;
593
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.
597 */
598 cmd = on_path("iw", NULL);
599 if (!cmd)
600 goto out1;
601 free(cmd);
602
603 fpid = fork();
604 if (fpid < 0)
605 goto out1;
606
607 if (fpid == 0) {
608 char pidstr[30];
609 sprintf(pidstr, "%d", pid);
610 execlp("iw", "iw", "phy", physname, "set", "netns", pidstr,
611 (char *)NULL);
612 exit(EXIT_FAILURE);
613 }
614
615 if (wait_for_pid(fpid))
616 goto out1;
617
618 err = 0;
619 if (newname)
620 err = lxc_netdev_rename_by_name_in_netns(pid, ifname, newname);
621
622 out1:
623 free(physname);
624 return err;
625 }
626
627 int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
628 {
629 int index;
630 char *physname;
631
632 if (!ifname)
633 return -EINVAL;
634
635 index = if_nametoindex(ifname);
636 if (!index)
637 return -EINVAL;
638
639 physname = is_wlan(ifname);
640 if (physname)
641 return lxc_netdev_move_wlan(physname, ifname, pid, newname);
642
643 return lxc_netdev_move_by_index(index, pid, newname);
644 }
645
646 int lxc_netdev_delete_by_index(int ifindex)
647 {
648 int err;
649 struct ifinfomsg *ifi;
650 struct nl_handler nlh;
651 struct nlmsg *answer = NULL, *nlmsg = NULL;
652
653 err = netlink_open(&nlh, NETLINK_ROUTE);
654 if (err)
655 return err;
656
657 err = -ENOMEM;
658 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
659 if (!nlmsg)
660 goto out;
661
662 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
663 if (!answer)
664 goto out;
665
666 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST;
667 nlmsg->nlmsghdr->nlmsg_type = RTM_DELLINK;
668
669 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
670 if (!ifi)
671 goto out;
672 ifi->ifi_family = AF_UNSPEC;
673 ifi->ifi_index = ifindex;
674
675 err = netlink_transaction(&nlh, nlmsg, answer);
676 out:
677 netlink_close(&nlh);
678 nlmsg_free(answer);
679 nlmsg_free(nlmsg);
680 return err;
681 }
682
683 int lxc_netdev_delete_by_name(const char *name)
684 {
685 int index;
686
687 index = if_nametoindex(name);
688 if (!index)
689 return -EINVAL;
690
691 return lxc_netdev_delete_by_index(index);
692 }
693
694 int lxc_netdev_rename_by_index(int ifindex, const char *newname)
695 {
696 int err, len;
697 struct ifinfomsg *ifi;
698 struct nl_handler nlh;
699 struct nlmsg *answer = NULL, *nlmsg = NULL;
700
701 err = netlink_open(&nlh, NETLINK_ROUTE);
702 if (err)
703 return err;
704
705 len = strlen(newname);
706 if (len == 1 || len >= IFNAMSIZ)
707 goto out;
708
709 err = -ENOMEM;
710 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
711 if (!nlmsg)
712 goto out;
713
714 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
715 if (!answer)
716 goto out;
717
718 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST;
719 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
720
721 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
722 if (!ifi)
723 goto out;
724 ifi->ifi_family = AF_UNSPEC;
725 ifi->ifi_index = ifindex;
726
727 if (nla_put_string(nlmsg, IFLA_IFNAME, newname))
728 goto out;
729
730 err = netlink_transaction(&nlh, nlmsg, answer);
731 out:
732 netlink_close(&nlh);
733 nlmsg_free(answer);
734 nlmsg_free(nlmsg);
735 return err;
736 }
737
738 int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
739 {
740 int len, index;
741
742 len = strlen(oldname);
743 if (len == 1 || len >= IFNAMSIZ)
744 return -EINVAL;
745
746 index = if_nametoindex(oldname);
747 if (!index)
748 return -EINVAL;
749
750 return lxc_netdev_rename_by_index(index, newname);
751 }
752
753 int netdev_set_flag(const char *name, int flag)
754 {
755 int err, index, len;
756 struct ifinfomsg *ifi;
757 struct nl_handler nlh;
758 struct nlmsg *answer = NULL, *nlmsg = NULL;
759
760 err = netlink_open(&nlh, NETLINK_ROUTE);
761 if (err)
762 return err;
763
764 err = -EINVAL;
765 len = strlen(name);
766 if (len == 1 || len >= IFNAMSIZ)
767 goto out;
768
769 err = -ENOMEM;
770 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
771 if (!nlmsg)
772 goto out;
773
774 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
775 if (!answer)
776 goto out;
777
778 err = -EINVAL;
779 index = if_nametoindex(name);
780 if (!index)
781 goto out;
782
783 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
784 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
785
786 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
787 if (!ifi) {
788 err = -ENOMEM;
789 goto out;
790 }
791 ifi->ifi_family = AF_UNSPEC;
792 ifi->ifi_index = index;
793 ifi->ifi_change |= IFF_UP;
794 ifi->ifi_flags |= flag;
795
796 err = netlink_transaction(&nlh, nlmsg, answer);
797 out:
798 netlink_close(&nlh);
799 nlmsg_free(nlmsg);
800 nlmsg_free(answer);
801 return err;
802 }
803
804 int netdev_get_flag(const char *name, int *flag)
805 {
806 int err, index, len;
807 struct ifinfomsg *ifi;
808 struct nl_handler nlh;
809 struct nlmsg *answer = NULL, *nlmsg = NULL;
810
811 if (!name)
812 return -EINVAL;
813
814 err = netlink_open(&nlh, NETLINK_ROUTE);
815 if (err)
816 return err;
817
818 err = -EINVAL;
819 len = strlen(name);
820 if (len == 1 || len >= IFNAMSIZ)
821 goto out;
822
823 err = -ENOMEM;
824 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
825 if (!nlmsg)
826 goto out;
827
828 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
829 if (!answer)
830 goto out;
831
832 err = -EINVAL;
833 index = if_nametoindex(name);
834 if (!index)
835 goto out;
836
837 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST;
838 nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK;
839
840 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
841 if (!ifi) {
842 err = -ENOMEM;
843 goto out;
844 }
845 ifi->ifi_family = AF_UNSPEC;
846 ifi->ifi_index = index;
847
848 err = netlink_transaction(&nlh, nlmsg, answer);
849 if (err)
850 goto out;
851
852 ifi = NLMSG_DATA(answer->nlmsghdr);
853
854 *flag = ifi->ifi_flags;
855 out:
856 netlink_close(&nlh);
857 nlmsg_free(nlmsg);
858 nlmsg_free(answer);
859 return err;
860 }
861
862 /*
863 * \brief Check a interface is up or not.
864 *
865 * \param name: name for the interface.
866 *
867 * \return int.
868 * 0 means interface is down.
869 * 1 means interface is up.
870 * Others means error happened, and ret-value is the error number.
871 */
872 int lxc_netdev_isup(const char *name)
873 {
874 int err, flag;
875
876 err = netdev_get_flag(name, &flag);
877 if (err)
878 return err;
879
880 if (flag & IFF_UP)
881 return 1;
882
883 return 0;
884 }
885
886 int netdev_get_mtu(int ifindex)
887 {
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;
894
895 err = netlink_open(&nlh, NETLINK_ROUTE);
896 if (err)
897 return err;
898
899 err = -ENOMEM;
900 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
901 if (!nlmsg)
902 goto out;
903
904 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
905 if (!answer)
906 goto out;
907
908 /* Save the answer buffer length, since it will be overwritten
909 * on the first receive (and we might need to receive more than
910 * once.
911 */
912 answer_len = answer->nlmsghdr->nlmsg_len;
913
914 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
915 nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK;
916
917 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
918 if (!ifi)
919 goto out;
920 ifi->ifi_family = AF_UNSPEC;
921
922 /* Send the request for addresses, which returns all addresses
923 * on all interfaces. */
924 err = netlink_send(&nlh, nlmsg);
925 if (err < 0)
926 goto out;
927
928 do {
929 /* Restore the answer buffer length, it might have been
930 * overwritten by a previous receive.
931 */
932 answer->nlmsghdr->nlmsg_len = answer_len;
933
934 /* Get the (next) batch of reply messages */
935 err = netlink_rcv(&nlh, answer);
936 if (err < 0)
937 goto out;
938
939 recv_len = err;
940 err = 0;
941
942 /* Satisfy the typing for the netlink macros */
943 msg = answer->nlmsghdr;
944
945 while (NLMSG_OK(msg, recv_len)) {
946
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);
951 err = errmsg->error;
952 goto out;
953 }
954
955 /* Stop reading if we see a NLMSG_DONE message */
956 if (msg->nlmsg_type == NLMSG_DONE) {
957 readmore = 0;
958 break;
959 }
960
961 ifi = NLMSG_DATA(msg);
962 if (ifi->ifi_index == ifindex) {
963 struct rtattr *rta = IFLA_RTA(ifi);
964 int attr_len =
965 msg->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
966 res = 0;
967 while (RTA_OK(rta, attr_len)) {
968 /* Found a local address for the
969 * requested interface, return it.
970 */
971 if (rta->rta_type == IFLA_MTU) {
972 memcpy(&res, RTA_DATA(rta),
973 sizeof(int));
974 err = res;
975 goto out;
976 }
977 rta = RTA_NEXT(rta, attr_len);
978 }
979 }
980
981 /* Keep reading more data from the socket if the last
982 * message had the NLF_F_MULTI flag set.
983 */
984 readmore = (msg->nlmsg_flags & NLM_F_MULTI);
985
986 /* Look at the next message received in this buffer. */
987 msg = NLMSG_NEXT(msg, recv_len);
988 }
989 } while (readmore);
990
991 /* If we end up here, we didn't find any result, so signal an error. */
992 err = -1;
993
994 out:
995 netlink_close(&nlh);
996 nlmsg_free(answer);
997 nlmsg_free(nlmsg);
998 return err;
999 }
1000
1001 int lxc_netdev_set_mtu(const char *name, int mtu)
1002 {
1003 int err, index, len;
1004 struct ifinfomsg *ifi;
1005 struct nl_handler nlh;
1006 struct nlmsg *answer = NULL, *nlmsg = NULL;
1007
1008 err = netlink_open(&nlh, NETLINK_ROUTE);
1009 if (err)
1010 return err;
1011
1012 err = -EINVAL;
1013 len = strlen(name);
1014 if (len == 1 || len >= IFNAMSIZ)
1015 goto out;
1016
1017 err = -ENOMEM;
1018 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1019 if (!nlmsg)
1020 goto out;
1021
1022 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
1023 if (!answer)
1024 goto out;
1025
1026 err = -EINVAL;
1027 index = if_nametoindex(name);
1028 if (!index)
1029 goto out;
1030
1031 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
1032 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
1033
1034 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
1035 if (!ifi) {
1036 err = -ENOMEM;
1037 goto out;
1038 }
1039 ifi->ifi_family = AF_UNSPEC;
1040 ifi->ifi_index = index;
1041
1042 if (nla_put_u32(nlmsg, IFLA_MTU, mtu))
1043 goto out;
1044
1045 err = netlink_transaction(&nlh, nlmsg, answer);
1046 out:
1047 netlink_close(&nlh);
1048 nlmsg_free(nlmsg);
1049 nlmsg_free(answer);
1050 return err;
1051 }
1052
1053 int lxc_netdev_up(const char *name)
1054 {
1055 return netdev_set_flag(name, IFF_UP);
1056 }
1057
1058 int lxc_netdev_down(const char *name)
1059 {
1060 return netdev_set_flag(name, 0);
1061 }
1062
1063 int lxc_veth_create(const char *name1, const char *name2)
1064 {
1065 int err, len;
1066 struct ifinfomsg *ifi;
1067 struct nl_handler nlh;
1068 struct rtattr *nest1, *nest2, *nest3;
1069 struct nlmsg *answer = NULL, *nlmsg = NULL;
1070
1071 err = netlink_open(&nlh, NETLINK_ROUTE);
1072 if (err)
1073 return err;
1074
1075 err = -EINVAL;
1076 len = strlen(name1);
1077 if (len == 1 || len >= IFNAMSIZ)
1078 goto out;
1079
1080 len = strlen(name2);
1081 if (len == 1 || len >= IFNAMSIZ)
1082 goto out;
1083
1084 err = -ENOMEM;
1085 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1086 if (!nlmsg)
1087 goto out;
1088
1089 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
1090 if (!answer)
1091 goto out;
1092
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;
1096
1097 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
1098 if (!ifi)
1099 goto out;
1100 ifi->ifi_family = AF_UNSPEC;
1101
1102 err = -EINVAL;
1103 nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO);
1104 if (!nest1)
1105 goto out;
1106
1107 if (nla_put_string(nlmsg, IFLA_INFO_KIND, "veth"))
1108 goto out;
1109
1110 nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
1111 if (!nest2)
1112 goto out;
1113
1114 nest3 = nla_begin_nested(nlmsg, VETH_INFO_PEER);
1115 if (!nest3)
1116 goto out;
1117
1118 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
1119 if (!ifi) {
1120 err = -ENOMEM;
1121 goto out;
1122 }
1123
1124 if (nla_put_string(nlmsg, IFLA_IFNAME, name2))
1125 goto out;
1126
1127 nla_end_nested(nlmsg, nest3);
1128 nla_end_nested(nlmsg, nest2);
1129 nla_end_nested(nlmsg, nest1);
1130
1131 if (nla_put_string(nlmsg, IFLA_IFNAME, name1))
1132 goto out;
1133
1134 err = netlink_transaction(&nlh, nlmsg, answer);
1135 out:
1136 netlink_close(&nlh);
1137 nlmsg_free(answer);
1138 nlmsg_free(nlmsg);
1139 return err;
1140 }
1141
1142 /* TODO: merge with lxc_macvlan_create */
1143 int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
1144 {
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;
1150
1151 err = netlink_open(&nlh, NETLINK_ROUTE);
1152 if (err)
1153 return err;
1154
1155 err = -EINVAL;
1156 len = strlen(master);
1157 if (len == 1 || len >= IFNAMSIZ)
1158 goto err3;
1159
1160 len = strlen(name);
1161 if (len == 1 || len >= IFNAMSIZ)
1162 goto err3;
1163
1164 err = -ENOMEM;
1165 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1166 if (!nlmsg)
1167 goto err3;
1168
1169 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
1170 if (!answer)
1171 goto err2;
1172
1173 err = -EINVAL;
1174 lindex = if_nametoindex(master);
1175 if (!lindex)
1176 goto err1;
1177
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;
1181
1182 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
1183 if (!ifi) {
1184 err = -ENOMEM;
1185 goto err1;
1186 }
1187 ifi->ifi_family = AF_UNSPEC;
1188
1189 nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
1190 if (!nest)
1191 goto err1;
1192
1193 if (nla_put_string(nlmsg, IFLA_INFO_KIND, "vlan"))
1194 goto err1;
1195
1196 nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
1197 if (!nest2)
1198 goto err1;
1199
1200 if (nla_put_u16(nlmsg, IFLA_VLAN_ID, vlanid))
1201 goto err1;
1202
1203 nla_end_nested(nlmsg, nest2);
1204 nla_end_nested(nlmsg, nest);
1205
1206 if (nla_put_u32(nlmsg, IFLA_LINK, lindex))
1207 goto err1;
1208
1209 if (nla_put_string(nlmsg, IFLA_IFNAME, name))
1210 goto err1;
1211
1212 err = netlink_transaction(&nlh, nlmsg, answer);
1213 err1:
1214 nlmsg_free(answer);
1215 err2:
1216 nlmsg_free(nlmsg);
1217 err3:
1218 netlink_close(&nlh);
1219 return err;
1220 }
1221
1222 int lxc_macvlan_create(const char *master, const char *name, int mode)
1223 {
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;
1229
1230 err = netlink_open(&nlh, NETLINK_ROUTE);
1231 if (err)
1232 return err;
1233
1234 err = -EINVAL;
1235 len = strlen(master);
1236 if (len == 1 || len >= IFNAMSIZ)
1237 goto out;
1238
1239 len = strlen(name);
1240 if (len == 1 || len >= IFNAMSIZ)
1241 goto out;
1242
1243 err = -ENOMEM;
1244 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1245 if (!nlmsg)
1246 goto out;
1247
1248 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
1249 if (!answer)
1250 goto out;
1251
1252 err = -EINVAL;
1253 index = if_nametoindex(master);
1254 if (!index)
1255 goto out;
1256
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;
1260
1261 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
1262 if (!ifi) {
1263 err = -ENOMEM;
1264 goto out;
1265 }
1266 ifi->ifi_family = AF_UNSPEC;
1267
1268 nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
1269 if (!nest)
1270 goto out;
1271
1272 if (nla_put_string(nlmsg, IFLA_INFO_KIND, "macvlan"))
1273 goto out;
1274
1275 if (mode) {
1276 nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
1277 if (!nest2)
1278 goto out;
1279
1280 if (nla_put_u32(nlmsg, IFLA_MACVLAN_MODE, mode))
1281 goto out;
1282
1283 nla_end_nested(nlmsg, nest2);
1284 }
1285
1286 nla_end_nested(nlmsg, nest);
1287
1288 if (nla_put_u32(nlmsg, IFLA_LINK, index))
1289 goto out;
1290
1291 if (nla_put_string(nlmsg, IFLA_IFNAME, name))
1292 goto out;
1293
1294 err = netlink_transaction(&nlh, nlmsg, answer);
1295 out:
1296 netlink_close(&nlh);
1297 nlmsg_free(answer);
1298 nlmsg_free(nlmsg);
1299 return err;
1300 }
1301
1302 static int proc_sys_net_write(const char *path, const char *value)
1303 {
1304 int fd;
1305 int err = 0;
1306
1307 fd = open(path, O_WRONLY);
1308 if (fd < 0)
1309 return -errno;
1310
1311 if (write(fd, value, strlen(value)) < 0)
1312 err = -errno;
1313
1314 close(fd);
1315 return err;
1316 }
1317
1318 static int ip_forward_set(const char *ifname, int family, int flag)
1319 {
1320 int rc;
1321 char path[MAXPATHLEN];
1322
1323 if (family != AF_INET && family != AF_INET6)
1324 return -EINVAL;
1325
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)
1329 return -E2BIG;
1330
1331 return proc_sys_net_write(path, flag ? "1" : "0");
1332 }
1333
1334 int lxc_ip_forward_on(const char *ifname, int family)
1335 {
1336 return ip_forward_set(ifname, family, 1);
1337 }
1338
1339 int lxc_ip_forward_off(const char *ifname, int family)
1340 {
1341 return ip_forward_set(ifname, family, 0);
1342 }
1343
1344 static int neigh_proxy_set(const char *ifname, int family, int flag)
1345 {
1346 int ret;
1347 char path[MAXPATHLEN];
1348
1349 if (family != AF_INET && family != AF_INET6)
1350 return -EINVAL;
1351
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)
1356 return -E2BIG;
1357
1358 return proc_sys_net_write(path, flag ? "1" : "0");
1359 }
1360
1361 int lxc_neigh_proxy_on(const char *name, int family)
1362 {
1363 return neigh_proxy_set(name, family, 1);
1364 }
1365
1366 int lxc_neigh_proxy_off(const char *name, int family)
1367 {
1368 return neigh_proxy_set(name, family, 0);
1369 }
1370
1371 int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
1372 {
1373 int i = 0;
1374 unsigned val;
1375 char c;
1376 unsigned char *data;
1377
1378 sockaddr->sa_family = ARPHRD_ETHER;
1379 data = (unsigned char *)sockaddr->sa_data;
1380
1381 while ((*macaddr != '\0') && (i < ETH_ALEN)) {
1382 val = 0;
1383 c = *macaddr++;
1384 if (isdigit(c))
1385 val = c - '0';
1386 else if (c >= 'a' && c <= 'f')
1387 val = c - 'a' + 10;
1388 else if (c >= 'A' && c <= 'F')
1389 val = c - 'A' + 10;
1390 else
1391 return -EINVAL;
1392
1393 val <<= 4;
1394 c = *macaddr;
1395 if (isdigit(c))
1396 val |= c - '0';
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)
1402 val >>= 4;
1403 else
1404 return -EINVAL;
1405 if (c != 0)
1406 macaddr++;
1407 *data++ = (unsigned char)(val & 0377);
1408 i++;
1409
1410 if (*macaddr == ':')
1411 macaddr++;
1412 }
1413
1414 return 0;
1415 }
1416
1417 static int ip_addr_add(int family, int ifindex, void *addr, void *bcast,
1418 void *acast, int prefix)
1419 {
1420 int addrlen, err;
1421 struct ifaddrmsg *ifa;
1422 struct nl_handler nlh;
1423 struct nlmsg *answer = NULL, *nlmsg = NULL;
1424
1425 addrlen = family == AF_INET ? sizeof(struct in_addr)
1426 : sizeof(struct in6_addr);
1427
1428 err = netlink_open(&nlh, NETLINK_ROUTE);
1429 if (err)
1430 return err;
1431
1432 err = -ENOMEM;
1433 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1434 if (!nlmsg)
1435 goto out;
1436
1437 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
1438 if (!answer)
1439 goto out;
1440
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;
1444
1445 ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg));
1446 if (!ifa)
1447 goto out;
1448 ifa->ifa_prefixlen = prefix;
1449 ifa->ifa_index = ifindex;
1450 ifa->ifa_family = family;
1451 ifa->ifa_scope = 0;
1452
1453 err = -EINVAL;
1454 if (nla_put_buffer(nlmsg, IFA_LOCAL, addr, addrlen))
1455 goto out;
1456
1457 if (nla_put_buffer(nlmsg, IFA_ADDRESS, addr, addrlen))
1458 goto out;
1459
1460 if (nla_put_buffer(nlmsg, IFA_BROADCAST, bcast, addrlen))
1461 goto out;
1462
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))))
1468 goto out;
1469
1470 err = netlink_transaction(&nlh, nlmsg, answer);
1471 out:
1472 netlink_close(&nlh);
1473 nlmsg_free(answer);
1474 nlmsg_free(nlmsg);
1475 return err;
1476 }
1477
1478 int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
1479 struct in6_addr *mcast, struct in6_addr *acast,
1480 int prefix)
1481 {
1482 return ip_addr_add(AF_INET6, ifindex, addr, mcast, acast, prefix);
1483 }
1484
1485 int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr, struct in_addr *bcast,
1486 int prefix)
1487 {
1488 return ip_addr_add(AF_INET, ifindex, addr, bcast, NULL, prefix);
1489 }
1490
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**).
1494 */
1495 static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void **res)
1496 {
1497 int addrlen;
1498 struct ifaddrmsg *ifa = NLMSG_DATA(msg);
1499 struct rtattr *rta = IFA_RTA(ifa);
1500 int attr_len = NLMSG_PAYLOAD(msg, sizeof(struct ifaddrmsg));
1501
1502 if (ifa->ifa_family != family)
1503 return 0;
1504
1505 addrlen = family == AF_INET ? sizeof(struct in_addr)
1506 : sizeof(struct in6_addr);
1507
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,
1511 * return it.
1512 */
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
1517 * case.
1518 */
1519 if (RTA_PAYLOAD(rta) != addrlen)
1520 return -1;
1521
1522 /* We might have found an IFA_ADDRESS before, which we
1523 * now overwrite with an IFA_LOCAL.
1524 */
1525 if (!*res) {
1526 *res = malloc(addrlen);
1527 if (!*res)
1528 return -1;
1529 }
1530
1531 memcpy(*res, RTA_DATA(rta), addrlen);
1532 if (rta->rta_type == IFA_LOCAL)
1533 break;
1534 }
1535 rta = RTA_NEXT(rta, attr_len);
1536 }
1537 return 0;
1538 }
1539
1540 static int ip_addr_get(int family, int ifindex, void **res)
1541 {
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;
1548
1549 err = netlink_open(&nlh, NETLINK_ROUTE);
1550 if (err)
1551 return err;
1552
1553 err = -ENOMEM;
1554 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1555 if (!nlmsg)
1556 goto out;
1557
1558 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
1559 if (!answer)
1560 goto out;
1561
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).
1564 */
1565 answer_len = answer->nlmsghdr->nlmsg_len;
1566
1567 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
1568 nlmsg->nlmsghdr->nlmsg_type = RTM_GETADDR;
1569
1570 ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg));
1571 if (!ifa)
1572 goto out;
1573 ifa->ifa_family = family;
1574
1575 /* Send the request for addresses, which returns all addresses on all
1576 * interfaces.
1577 */
1578 err = netlink_send(&nlh, nlmsg);
1579 if (err < 0)
1580 goto out;
1581
1582 do {
1583 /* Restore the answer buffer length, it might have been
1584 * overwritten by a previous receive.
1585 */
1586 answer->nlmsghdr->nlmsg_len = answer_len;
1587
1588 /* Get the (next) batch of reply messages. */
1589 err = netlink_rcv(&nlh, answer);
1590 if (err < 0)
1591 goto out;
1592
1593 recv_len = err;
1594 err = 0;
1595
1596 /* Satisfy the typing for the netlink macros. */
1597 msg = answer->nlmsghdr;
1598
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;
1605 goto out;
1606 }
1607
1608 /* Stop reading if we see a NLMSG_DONE message. */
1609 if (msg->nlmsg_type == NLMSG_DONE) {
1610 readmore = 0;
1611 break;
1612 }
1613
1614 if (msg->nlmsg_type != RTM_NEWADDR) {
1615 err = -1;
1616 goto out;
1617 }
1618
1619 ifa = (struct ifaddrmsg *)NLMSG_DATA(msg);
1620 if (ifa->ifa_index == ifindex) {
1621 if (ifa_get_local_ip(family, msg, res) < 0) {
1622 err = -1;
1623 goto out;
1624 }
1625
1626 /* Found a result, stop searching. */
1627 if (*res)
1628 goto out;
1629 }
1630
1631 /* Keep reading more data from the socket if the last
1632 * message had the NLF_F_MULTI flag set.
1633 */
1634 readmore = (msg->nlmsg_flags & NLM_F_MULTI);
1635
1636 /* Look at the next message received in this buffer. */
1637 msg = NLMSG_NEXT(msg, recv_len);
1638 }
1639 } while (readmore);
1640
1641 /* If we end up here, we didn't find any result, so signal an
1642 * error.
1643 */
1644 err = -1;
1645
1646 out:
1647 netlink_close(&nlh);
1648 nlmsg_free(answer);
1649 nlmsg_free(nlmsg);
1650 return err;
1651 }
1652
1653 int lxc_ipv6_addr_get(int ifindex, struct in6_addr **res)
1654 {
1655 return ip_addr_get(AF_INET6, ifindex, (void **)res);
1656 }
1657
1658 int lxc_ipv4_addr_get(int ifindex, struct in_addr **res)
1659 {
1660 return ip_addr_get(AF_INET, ifindex, (void **)res);
1661 }
1662
1663 static int ip_gateway_add(int family, int ifindex, void *gw)
1664 {
1665 int addrlen, err;
1666 struct nl_handler nlh;
1667 struct rtmsg *rt;
1668 struct nlmsg *answer = NULL, *nlmsg = NULL;
1669
1670 addrlen = family == AF_INET ? sizeof(struct in_addr)
1671 : sizeof(struct in6_addr);
1672
1673 err = netlink_open(&nlh, NETLINK_ROUTE);
1674 if (err)
1675 return err;
1676
1677 err = -ENOMEM;
1678 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1679 if (!nlmsg)
1680 goto out;
1681
1682 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
1683 if (!answer)
1684 goto out;
1685
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;
1689
1690 rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
1691 if (!rt)
1692 goto out;
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;
1700
1701 err = -EINVAL;
1702 if (nla_put_buffer(nlmsg, RTA_GATEWAY, gw, addrlen))
1703 goto out;
1704
1705 /* Adding the interface index enables the use of link-local
1706 * addresses for the gateway.
1707 */
1708 if (nla_put_u32(nlmsg, RTA_OIF, ifindex))
1709 goto out;
1710
1711 err = netlink_transaction(&nlh, nlmsg, answer);
1712 out:
1713 netlink_close(&nlh);
1714 nlmsg_free(answer);
1715 nlmsg_free(nlmsg);
1716 return err;
1717 }
1718
1719 int lxc_ipv4_gateway_add(int ifindex, struct in_addr *gw)
1720 {
1721 return ip_gateway_add(AF_INET, ifindex, gw);
1722 }
1723
1724 int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw)
1725 {
1726 return ip_gateway_add(AF_INET6, ifindex, gw);
1727 }
1728
1729 static int ip_route_dest_add(int family, int ifindex, void *dest)
1730 {
1731 int addrlen, err;
1732 struct nl_handler nlh;
1733 struct rtmsg *rt;
1734 struct nlmsg *answer = NULL, *nlmsg = NULL;
1735
1736 addrlen = family == AF_INET ? sizeof(struct in_addr)
1737 : sizeof(struct in6_addr);
1738
1739 err = netlink_open(&nlh, NETLINK_ROUTE);
1740 if (err)
1741 return err;
1742
1743 err = -ENOMEM;
1744 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1745 if (!nlmsg)
1746 goto out;
1747
1748 answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
1749 if (!answer)
1750 goto out;
1751
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;
1755
1756 rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
1757 if (!rt)
1758 goto out;
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;
1765
1766 err = -EINVAL;
1767 if (nla_put_buffer(nlmsg, RTA_DST, dest, addrlen))
1768 goto out;
1769 if (nla_put_u32(nlmsg, RTA_OIF, ifindex))
1770 goto out;
1771 err = netlink_transaction(&nlh, nlmsg, answer);
1772 out:
1773 netlink_close(&nlh);
1774 nlmsg_free(answer);
1775 nlmsg_free(nlmsg);
1776 return err;
1777 }
1778
1779 int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest)
1780 {
1781 return ip_route_dest_add(AF_INET, ifindex, dest);
1782 }
1783
1784 int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
1785 {
1786 return ip_route_dest_add(AF_INET6, ifindex, dest);
1787 }
1788
1789 bool is_ovs_bridge(const char *bridge)
1790 {
1791 int ret;
1792 struct stat sb;
1793 char brdirname[22 + IFNAMSIZ + 1] = {0};
1794
1795 ret = snprintf(brdirname, 22 + IFNAMSIZ + 1, "/sys/class/net/%s/bridge",
1796 bridge);
1797 if (ret < 0 || (size_t)ret >= 22 + IFNAMSIZ + 1)
1798 return false;
1799
1800 ret = stat(brdirname, &sb);
1801 if (ret < 0 && errno == ENOENT)
1802 return true;
1803
1804 return false;
1805 }
1806
1807 struct ovs_veth_args {
1808 const char *bridge;
1809 const char *nic;
1810 };
1811
1812 /* Called from a background thread - when nic goes away, remove it from the
1813 * bridge.
1814 */
1815 static int lxc_ovs_delete_port_exec(void *data)
1816 {
1817 struct ovs_veth_args *args = data;
1818
1819 execlp("ovs-vsctl", "ovs-vsctl", "del-port", args->bridge, args->nic,
1820 (char *)NULL);
1821 return -1;
1822 }
1823
1824 int lxc_ovs_delete_port(const char *bridge, const char *nic)
1825 {
1826 int ret;
1827 char cmd_output[MAXPATHLEN];
1828 struct ovs_veth_args args;
1829
1830 args.bridge = bridge;
1831 args.nic = nic;
1832 ret = run_command(cmd_output, sizeof(cmd_output),
1833 lxc_ovs_delete_port_exec, (void *)&args);
1834 if (ret < 0) {
1835 ERROR("Failed to delete \"%s\" from openvswitch bridge \"%s\": "
1836 "%s", bridge, nic, cmd_output);
1837 return -1;
1838 }
1839
1840 return 0;
1841 }
1842
1843 static int lxc_ovs_attach_bridge_exec(void *data)
1844 {
1845 struct ovs_veth_args *args = data;
1846
1847 execlp("ovs-vsctl", "ovs-vsctl", "add-port", args->bridge, args->nic,
1848 (char *)NULL);
1849 return -1;
1850 }
1851
1852 static int lxc_ovs_attach_bridge(const char *bridge, const char *nic)
1853 {
1854 int ret;
1855 char cmd_output[MAXPATHLEN];
1856 struct ovs_veth_args args;
1857
1858 args.bridge = bridge;
1859 args.nic = nic;
1860 ret = run_command(cmd_output, sizeof(cmd_output),
1861 lxc_ovs_attach_bridge_exec, (void *)&args);
1862 if (ret < 0) {
1863 ERROR("Failed to attach \"%s\" to openvswitch bridge \"%s\": %s",
1864 bridge, nic, cmd_output);
1865 return -1;
1866 }
1867
1868 return 0;
1869 }
1870
1871 int lxc_bridge_attach(const char *bridge, const char *ifname)
1872 {
1873 int err, fd, index;
1874 struct ifreq ifr;
1875
1876 if (strlen(ifname) >= IFNAMSIZ)
1877 return -EINVAL;
1878
1879 index = if_nametoindex(ifname);
1880 if (!index)
1881 return -EINVAL;
1882
1883 if (is_ovs_bridge(bridge))
1884 return lxc_ovs_attach_bridge(bridge, ifname);
1885
1886 fd = socket(AF_INET, SOCK_STREAM, 0);
1887 if (fd < 0)
1888 return -errno;
1889
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);
1894 close(fd);
1895 if (err)
1896 err = -errno;
1897
1898 return err;
1899 }
1900
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",
1908 };
1909
1910 const char *lxc_net_type_to_str(int type)
1911 {
1912 if (type < 0 || type > LXC_NET_MAXCONFTYPE)
1913 return NULL;
1914
1915 return lxc_network_types[type];
1916 }
1917
1918 static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1919
1920 char *lxc_mkifname(const char *template)
1921 {
1922 int ifexists = 0;
1923 size_t i = 0;
1924 char *name = NULL;
1925 unsigned int seed;
1926 FILE *urandom;
1927 struct ifaddrs *ifa, *ifaddr;
1928
1929 if (strlen(template) >= IFNAMSIZ)
1930 return NULL;
1931
1932 /* Get all the network interfaces. */
1933 getifaddrs(&ifaddr);
1934
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)
1939 seed = time(0);
1940 fclose(urandom);
1941 } else {
1942 seed = time(0);
1943 }
1944
1945 #ifndef HAVE_RAND_R
1946 srand(seed);
1947 #endif
1948
1949 /* Generate random names until we find one that doesn't exist. */
1950 while (true) {
1951 ifexists = 0;
1952 name = strdup(template);
1953
1954 if (name == NULL)
1955 return NULL;
1956
1957 for (i = 0; i < strlen(name); i++) {
1958 if (name[i] == 'X') {
1959 #ifdef HAVE_RAND_R
1960 name[i] = padchar[rand_r(&seed) %
1961 (strlen(padchar) - 1)];
1962 #else
1963 name[i] = padchar[rand() % (strlen(padchar) - 1)];
1964 #endif
1965 }
1966 }
1967
1968 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
1969 if (strcmp(ifa->ifa_name, name) == 0) {
1970 ifexists = 1;
1971 break;
1972 }
1973 }
1974
1975 if (ifexists == 0)
1976 break;
1977
1978 free(name);
1979 }
1980
1981 freeifaddrs(ifaddr);
1982 return name;
1983 }
1984
1985 int setup_private_host_hw_addr(char *veth1)
1986 {
1987 int err, sockfd;
1988 struct ifreq ifr;
1989
1990 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
1991 if (sockfd < 0)
1992 return -errno;
1993
1994 err = snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
1995 if (err < 0 || (size_t)err >= IFNAMSIZ)
1996 return -E2BIG;
1997
1998 err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
1999 if (err < 0) {
2000 close(sockfd);
2001 return -errno;
2002 }
2003
2004 ifr.ifr_hwaddr.sa_data[0] = 0xfe;
2005 err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
2006 close(sockfd);
2007 if (err < 0)
2008 return -errno;
2009
2010 return 0;
2011 }
2012
2013 int lxc_find_gateway_addresses(struct lxc_handler *handler)
2014 {
2015 struct lxc_list *network = &handler->conf->network;
2016 struct lxc_list *iterator;
2017 struct lxc_netdev *netdev;
2018 int link_index;
2019
2020 lxc_list_for_each(iterator, network) {
2021 netdev = iterator->elem;
2022
2023 if (!netdev->ipv4_gateway_auto && !netdev->ipv6_gateway_auto)
2024 continue;
2025
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");
2029 return -1;
2030 }
2031
2032 if (netdev->link[0] == '\0') {
2033 ERROR("Automatic gateway detection needs a link interface");
2034 return -1;
2035 }
2036
2037 link_index = if_nametoindex(netdev->link);
2038 if (!link_index)
2039 return -EINVAL;
2040
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);
2045 return -1;
2046 }
2047 }
2048
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);
2053 return -1;
2054 }
2055 }
2056 }
2057
2058 return 0;
2059 }
2060
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)
2064 {
2065 int ret;
2066 pid_t child;
2067 int bytes, pipefd[2];
2068 char *token, *saveptr = NULL;
2069 char netdev_link[IFNAMSIZ + 1];
2070 char buffer[MAXPATHLEN] = {0};
2071
2072 if (netdev->type != LXC_NET_VETH) {
2073 ERROR("Network type %d not support for unprivileged use", netdev->type);
2074 return -1;
2075 }
2076
2077 ret = pipe(pipefd);
2078 if (ret < 0) {
2079 SYSERROR("Failed to create pipe");
2080 return -1;
2081 }
2082
2083 child = fork();
2084 if (child < 0) {
2085 SYSERROR("Failed to create new process");
2086 close(pipefd[0]);
2087 close(pipefd[1]);
2088 return -1;
2089 }
2090
2091 if (child == 0) {
2092 int ret;
2093 char pidstr[LXC_NUMSTRLEN64];
2094
2095 close(pipefd[0]);
2096
2097 ret = dup2(pipefd[1], STDOUT_FILENO);
2098 if (ret >= 0)
2099 ret = dup2(pipefd[1], STDERR_FILENO);
2100 close(pipefd[1]);
2101 if (ret < 0) {
2102 SYSERROR("Failed to duplicate std{err,out} file descriptor");
2103 exit(EXIT_FAILURE);
2104 }
2105
2106 if (netdev->link[0] != '\0')
2107 strncpy(netdev_link, netdev->link, IFNAMSIZ);
2108 else
2109 strncpy(netdev_link, "none", IFNAMSIZ);
2110
2111 ret = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", pid);
2112 if (ret < 0 || ret >= LXC_NUMSTRLEN64)
2113 exit(EXIT_FAILURE);
2114 pidstr[LXC_NUMSTRLEN64 - 1] = '\0';
2115
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);
2123 else
2124 execlp(LXC_USERNIC_PATH, LXC_USERNIC_PATH, "create",
2125 lxcpath, lxcname, pidstr, "veth", netdev_link,
2126 (char *)NULL);
2127 SYSERROR("Failed to execute lxc-user-nic");
2128 exit(EXIT_FAILURE);
2129 }
2130
2131 /* close the write-end of the pipe */
2132 close(pipefd[1]);
2133
2134 bytes = read(pipefd[0], &buffer, MAXPATHLEN);
2135 if (bytes < 0) {
2136 SYSERROR("Failed to read from pipe file descriptor");
2137 close(pipefd[0]);
2138 return -1;
2139 }
2140 buffer[bytes - 1] = '\0';
2141
2142 ret = wait_for_pid(child);
2143 close(pipefd[0]);
2144 if (ret != 0) {
2145 ERROR("lxc-user-nic failed to configure requested network: %s",
2146 buffer[0] != '\0' ? buffer : "(null)");
2147 return -1;
2148 }
2149 TRACE("Received output \"%s\" from lxc-user-nic", buffer);
2150
2151 /* netdev->name */
2152 token = strtok_r(buffer, ":", &saveptr);
2153 if (!token) {
2154 ERROR("Failed to parse lxc-user-nic output");
2155 return -1;
2156 }
2157
2158 memset(netdev->name, 0, IFNAMSIZ + 1);
2159 strncpy(netdev->name, token, IFNAMSIZ);
2160
2161 /* netdev->ifindex */
2162 token = strtok_r(NULL, ":", &saveptr);
2163 if (!token) {
2164 ERROR("Failed to parse lxc-user-nic output");
2165 return -1;
2166 }
2167
2168 ret = lxc_safe_int(token, &netdev->ifindex);
2169 if (ret < 0) {
2170 ERROR("%s - Failed to convert string \"%s\" to integer",
2171 strerror(-ret), token);
2172 return -1;
2173 }
2174
2175 /* netdev->priv.veth_attr.veth1 */
2176 token = strtok_r(NULL, ":", &saveptr);
2177 if (!token) {
2178 ERROR("Failed to parse lxc-user-nic output");
2179 return -1;
2180 }
2181
2182 if (strlen(token) >= IFNAMSIZ) {
2183 ERROR("Host side veth device name returned by lxc-user-nic is "
2184 "too long");
2185 return -E2BIG;
2186 }
2187 strcpy(netdev->priv.veth_attr.veth1, token);
2188
2189 /* netdev->priv.veth_attr.ifindex */
2190 token = strtok_r(NULL, ":", &saveptr);
2191 if (!token) {
2192 ERROR("Failed to parse lxc-user-nic output");
2193 return -1;
2194 }
2195
2196 ret = lxc_safe_int(token, &netdev->priv.veth_attr.ifindex);
2197 if (ret < 0) {
2198 ERROR("%s - Failed to convert string \"%s\" to integer",
2199 strerror(-ret), token);
2200 return -1;
2201 }
2202
2203 return 0;
2204 }
2205
2206 static int lxc_delete_network_unpriv_exec(const char *lxcpath, char *lxcname,
2207 struct lxc_netdev *netdev,
2208 const char *netns_path)
2209 {
2210 int bytes, ret;
2211 pid_t child;
2212 int pipefd[2];
2213 char buffer[MAXPATHLEN] = {0};
2214
2215 if (netdev->type != LXC_NET_VETH) {
2216 ERROR("Network type %d not support for unprivileged use", netdev->type);
2217 return -1;
2218 }
2219
2220 ret = pipe(pipefd);
2221 if (ret < 0) {
2222 SYSERROR("Failed to create pipe");
2223 return -1;
2224 }
2225
2226 child = fork();
2227 if (child < 0) {
2228 SYSERROR("Failed to create new process");
2229 close(pipefd[0]);
2230 close(pipefd[1]);
2231 return -1;
2232 }
2233
2234 if (child == 0) {
2235 char *hostveth;
2236 int ret;
2237
2238 close(pipefd[0]);
2239
2240 ret = dup2(pipefd[1], STDOUT_FILENO);
2241 if (ret >= 0)
2242 ret = dup2(pipefd[1], STDERR_FILENO);
2243 close(pipefd[1]);
2244 if (ret < 0) {
2245 SYSERROR("Failed to duplicate std{err,out} file descriptor");
2246 exit(EXIT_FAILURE);
2247 }
2248
2249 if (netdev->priv.veth_attr.pair[0] != '\0')
2250 hostveth = netdev->priv.veth_attr.pair;
2251 else
2252 hostveth = netdev->priv.veth_attr.veth1;
2253 if (hostveth[0] == '\0') {
2254 SYSERROR("Host side veth device name is missing");
2255 exit(EXIT_FAILURE);
2256 }
2257
2258 if (netdev->link[0] == '\0') {
2259 SYSERROR("Network link for network device \"%s\" is "
2260 "missing", netdev->priv.veth_attr.veth1);
2261 exit(EXIT_FAILURE);
2262 }
2263
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,
2268 (char *)NULL);
2269 SYSERROR("Failed to exec lxc-user-nic.");
2270 exit(EXIT_FAILURE);
2271 }
2272
2273 close(pipefd[1]);
2274
2275 bytes = read(pipefd[0], &buffer, MAXPATHLEN);
2276 if (bytes < 0) {
2277 SYSERROR("Failed to read from pipe file descriptor.");
2278 close(pipefd[0]);
2279 return -1;
2280 }
2281 buffer[bytes - 1] = '\0';
2282
2283 if (wait_for_pid(child) != 0) {
2284 ERROR("lxc-user-nic failed to delete requested network: %s",
2285 buffer[0] != '\0' ? buffer : "(null)");
2286 close(pipefd[0]);
2287 return -1;
2288 }
2289
2290 close(pipefd[0]);
2291
2292 return 0;
2293 }
2294
2295 bool lxc_delete_network_unpriv(struct lxc_handler *handler)
2296 {
2297 int ret;
2298 struct lxc_list *iterator;
2299 struct lxc_list *network = &handler->conf->network;
2300 /* strlen("/proc/") = 6
2301 * +
2302 * LXC_NUMSTRLEN64
2303 * +
2304 * strlen("/fd/") = 4
2305 * +
2306 * LXC_NUMSTRLEN64
2307 * +
2308 * \0
2309 */
2310 char netns_path[6 + LXC_NUMSTRLEN64 + 4 + LXC_NUMSTRLEN64 + 1];
2311 bool deleted_all = true;
2312
2313 if (handler->root)
2314 return true;
2315
2316 *netns_path = '\0';
2317
2318 if (handler->netnsfd < 0) {
2319 DEBUG("Cannot not guarantee safe deletion of network devices. "
2320 "Manual cleanup maybe needed");
2321 return false;
2322 }
2323
2324 ret = snprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d",
2325 getpid(), handler->netnsfd);
2326 if (ret < 0 || ret >= sizeof(netns_path))
2327 return false;
2328
2329 lxc_list_for_each(iterator, network) {
2330 char *hostveth = NULL;
2331 struct lxc_netdev *netdev = iterator->elem;
2332
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.
2335 */
2336 if (!netdev->ifindex)
2337 continue;
2338
2339 if (netdev->type == LXC_NET_PHYS) {
2340 ret = lxc_netdev_rename_by_index(netdev->ifindex,
2341 netdev->link);
2342 if (ret < 0)
2343 WARN("Failed to rename interface with index %d "
2344 "to its initial name \"%s\"",
2345 netdev->ifindex, netdev->link);
2346 else
2347 TRACE("Renamed interface with index %d to its "
2348 "initial name \"%s\"",
2349 netdev->ifindex, netdev->link);
2350 continue;
2351 }
2352
2353 ret = netdev_deconf[netdev->type](handler, netdev);
2354 if (ret < 0)
2355 WARN("Failed to deconfigure network device");
2356
2357 if (netdev->type != LXC_NET_VETH)
2358 continue;
2359
2360 if (!is_ovs_bridge(netdev->link))
2361 continue;
2362
2363 if (netdev->priv.veth_attr.pair[0] != '\0')
2364 hostveth = netdev->priv.veth_attr.pair;
2365 else
2366 hostveth = netdev->priv.veth_attr.veth1;
2367 if (hostveth[0] == '\0')
2368 continue;
2369
2370 ret = lxc_delete_network_unpriv_exec(handler->lxcpath,
2371 handler->name, netdev,
2372 netns_path);
2373 if (ret < 0) {
2374 deleted_all = false;
2375 WARN("Failed to remove port \"%s\" from openvswitch "
2376 "bridge \"%s\"", hostveth, netdev->link);
2377 continue;
2378 }
2379 INFO("Removed interface \"%s\" from \"%s\"", hostveth,
2380 netdev->link);
2381 }
2382
2383 return deleted_all;
2384 }
2385
2386 int lxc_create_network_priv(struct lxc_handler *handler)
2387 {
2388 struct lxc_list *iterator;
2389 struct lxc_list *network = &handler->conf->network;
2390
2391 if (!handler->root)
2392 return 0;
2393
2394 lxc_list_for_each(iterator, network) {
2395 struct lxc_netdev *netdev = iterator->elem;
2396
2397 if (netdev->type < 0 || netdev->type > LXC_NET_MAXCONFTYPE) {
2398 ERROR("Invalid network configuration type %d", netdev->type);
2399 return -1;
2400 }
2401
2402 if (netdev_conf[netdev->type](handler, netdev)) {
2403 ERROR("Failed to create network device");
2404 return -1;
2405 }
2406
2407 }
2408
2409 return 0;
2410 }
2411
2412 int lxc_network_move_created_netdev_priv(const char *lxcpath, char *lxcname,
2413 struct lxc_list *network, pid_t pid)
2414 {
2415 int ret;
2416 char ifname[IFNAMSIZ];
2417 struct lxc_list *iterator;
2418
2419 if (am_unpriv())
2420 return 0;
2421
2422 lxc_list_for_each(iterator, network) {
2423 struct lxc_netdev *netdev = iterator->elem;
2424
2425 if (!netdev->ifindex)
2426 continue;
2427
2428 /* retrieve the name of the interface */
2429 if (!if_indextoname(netdev->ifindex, ifname)) {
2430 ERROR("No interface corresponding to ifindex \"%d\"",
2431 netdev->ifindex);
2432 return -1;
2433 }
2434
2435 ret = lxc_netdev_move_by_name(ifname, pid, NULL);
2436 if (ret) {
2437 ERROR("Failed to move network device \"%s\" to "
2438 "network namespace %d: %s", ifname, pid,
2439 strerror(-ret));
2440 return -1;
2441 }
2442
2443 DEBUG("Moved network device \"%s\"/\"%s\" to network namespace "
2444 "of %d",
2445 ifname, netdev->name[0] != '\0' ? netdev->name : "(null)",
2446 pid);
2447 }
2448
2449 return 0;
2450 }
2451
2452 int lxc_create_network_unpriv(const char *lxcpath, char *lxcname,
2453 struct lxc_list *network, pid_t pid)
2454 {
2455 struct lxc_list *iterator;
2456
2457 if (!am_unpriv())
2458 return 0;
2459
2460 lxc_list_for_each(iterator, network) {
2461 struct lxc_netdev *netdev = iterator->elem;
2462
2463 if (netdev->type == LXC_NET_EMPTY)
2464 continue;
2465
2466 if (netdev->type == LXC_NET_NONE)
2467 continue;
2468
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));
2473 return -1;
2474 }
2475
2476 if (netdev->mtu)
2477 INFO("mtu ignored due to insufficient privilege");
2478
2479 if (lxc_create_network_unpriv_exec(lxcpath, lxcname, netdev, pid))
2480 return -1;
2481 }
2482
2483 return 0;
2484 }
2485
2486 bool lxc_delete_network_priv(struct lxc_handler *handler)
2487 {
2488 int ret;
2489 struct lxc_list *iterator;
2490 struct lxc_list *network = &handler->conf->network;
2491 bool deleted_all = true;
2492
2493 if (!handler->root)
2494 return true;
2495
2496 lxc_list_for_each(iterator, network) {
2497 char *hostveth = NULL;
2498 struct lxc_netdev *netdev = iterator->elem;
2499
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.
2502 */
2503 if (!netdev->ifindex)
2504 continue;
2505
2506 if (netdev->type == LXC_NET_PHYS) {
2507 ret = lxc_netdev_rename_by_index(netdev->ifindex, netdev->link);
2508 if (ret < 0)
2509 WARN("Failed to rename interface with index %d "
2510 "from \"%s\" to its initial name \"%s\"",
2511 netdev->ifindex, netdev->name, netdev->link);
2512 else
2513 TRACE("Renamed interface with index %d to its "
2514 "from \"%s\" to its initial name \"%s\"",
2515 netdev->ifindex, netdev->name, netdev->link);
2516 continue;
2517 }
2518
2519 ret = netdev_deconf[netdev->type](handler, netdev);
2520 if (ret < 0)
2521 WARN("Failed to deconfigure network device");
2522
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.
2526 */
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 "
2531 "namespace",
2532 netdev->name[0] != '\0' ? netdev->name : "(null)",
2533 netdev->ifindex);
2534 } else if (ret < 0) {
2535 deleted_all = false;
2536 WARN("Failed to remove interface \"%s\" with "
2537 "index %d: %s",
2538 netdev->name[0] != '\0' ? netdev->name : "(null)",
2539 netdev->ifindex, strerror(-ret));
2540 continue;
2541 }
2542 INFO("Removed interface \"%s\" with index %d",
2543 netdev->name[0] != '\0' ? netdev->name : "(null)",
2544 netdev->ifindex);
2545
2546 if (netdev->type != LXC_NET_VETH)
2547 continue;
2548
2549 /* Explicitly delete host veth device to prevent lingering
2550 * devices. We had issues in LXD around this.
2551 */
2552 if (netdev->priv.veth_attr.pair[0] != '\0')
2553 hostveth = netdev->priv.veth_attr.pair;
2554 else
2555 hostveth = netdev->priv.veth_attr.veth1;
2556 if (hostveth[0] == '\0')
2557 continue;
2558
2559 ret = lxc_netdev_delete_by_name(hostveth);
2560 if (ret < 0) {
2561 deleted_all = false;
2562 WARN("Failed to remove interface \"%s\" from \"%s\": %s",
2563 hostveth, netdev->link, strerror(-ret));
2564 continue;
2565 }
2566 INFO("Removed interface \"%s\" from \"%s\"", hostveth, netdev->link);
2567
2568 if (!is_ovs_bridge(netdev->link)) {
2569 netdev->priv.veth_attr.veth1[0] = '\0';
2570 continue;
2571 }
2572
2573 /* Delete the openvswitch port. */
2574 ret = lxc_ovs_delete_port(netdev->link, hostveth);
2575 if (ret < 0)
2576 WARN("Failed to remove port \"%s\" from openvswitch "
2577 "bridge \"%s\"", hostveth, netdev->link);
2578 else
2579 INFO("Removed port \"%s\" from openvswitch bridge \"%s\"",
2580 hostveth, netdev->link);
2581
2582 netdev->priv.veth_attr.veth1[0] = '\0';
2583 }
2584
2585 return deleted_all;
2586 }
2587
2588 int lxc_requests_empty_network(struct lxc_handler *handler)
2589 {
2590 struct lxc_list *network = &handler->conf->network;
2591 struct lxc_list *iterator;
2592 bool found_none = false, found_nic = false;
2593
2594 if (lxc_list_empty(network))
2595 return 0;
2596
2597 lxc_list_for_each(iterator, network) {
2598 struct lxc_netdev *netdev = iterator->elem;
2599
2600 if (netdev->type == LXC_NET_NONE)
2601 found_none = true;
2602 else
2603 found_nic = true;
2604 }
2605 if (found_none && !found_nic)
2606 return 1;
2607 return 0;
2608 }
2609
2610 /* try to move physical nics to the init netns */
2611 int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
2612 {
2613 int ret;
2614 int oldfd;
2615 char ifname[IFNAMSIZ];
2616 struct lxc_list *iterator;
2617 int netnsfd = handler->netnsfd;
2618 struct lxc_conf *conf = handler->conf;
2619
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
2622 * unprivileged.
2623 */
2624 if (!handler->root)
2625 return 0;
2626
2627 TRACE("Moving physical network devices back to parent network namespace");
2628
2629 oldfd = lxc_preserve_ns(getpid(), "net");
2630 if (oldfd < 0) {
2631 SYSERROR("Failed to preserve network namespace");
2632 return -1;
2633 }
2634
2635 ret = setns(netnsfd, CLONE_NEWNET);
2636 if (ret < 0) {
2637 SYSERROR("Failed to enter network namespace");
2638 close(oldfd);
2639 return -1;
2640 }
2641
2642 lxc_list_for_each(iterator, &conf->network) {
2643 struct lxc_netdev *netdev = iterator->elem;
2644
2645 if (netdev->type != LXC_NET_PHYS)
2646 continue;
2647
2648 /* Retrieve the name of the interface in the container's network
2649 * namespace.
2650 */
2651 if (!if_indextoname(netdev->ifindex, ifname)) {
2652 WARN("No interface corresponding to ifindex %d",
2653 netdev->ifindex);
2654 continue;
2655 }
2656
2657 ret = lxc_netdev_move_by_name(ifname, 1, netdev->link);
2658 if (ret < 0)
2659 WARN("Error moving network device \"%s\" back to "
2660 "network namespace", ifname);
2661 else
2662 TRACE("Moved network device \"%s\" back to network "
2663 "namespace", ifname);
2664 }
2665
2666 ret = setns(oldfd, CLONE_NEWNET);
2667 close(oldfd);
2668 if (ret < 0) {
2669 SYSERROR("Failed to enter network namespace");
2670 return -1;
2671 }
2672
2673 return 0;
2674 }
2675
2676 static int setup_hw_addr(char *hwaddr, const char *ifname)
2677 {
2678 struct sockaddr sockaddr;
2679 struct ifreq ifr;
2680 int ret, fd, saved_errno;
2681
2682 ret = lxc_convert_mac(hwaddr, &sockaddr);
2683 if (ret) {
2684 ERROR("Mac address \"%s\" conversion failed: %s", hwaddr,
2685 strerror(-ret));
2686 return -1;
2687 }
2688
2689 memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
2690 ifr.ifr_name[IFNAMSIZ-1] = '\0';
2691 memcpy((char *) &ifr.ifr_hwaddr, (char *) &sockaddr, sizeof(sockaddr));
2692
2693 fd = socket(AF_INET, SOCK_DGRAM, 0);
2694 if (fd < 0)
2695 return -1;
2696
2697 ret = ioctl(fd, SIOCSIFHWADDR, &ifr);
2698 saved_errno = errno;
2699 close(fd);
2700 if (ret)
2701 ERROR("Failed to perform ioctl: %s", strerror(saved_errno));
2702
2703 DEBUG("Mac address \"%s\" on \"%s\" has been setup", hwaddr,
2704 ifr.ifr_name);
2705
2706 return ret;
2707 }
2708
2709 static int setup_ipv4_addr(struct lxc_list *ip, int ifindex)
2710 {
2711 struct lxc_list *iterator;
2712 int err;
2713
2714 lxc_list_for_each(iterator, ip) {
2715 struct lxc_inetdev *inetdev = iterator->elem;
2716
2717 err = lxc_ipv4_addr_add(ifindex, &inetdev->addr,
2718 &inetdev->bcast, inetdev->prefix);
2719 if (err) {
2720 ERROR("Failed to setup ipv4 address for network device "
2721 "with eifindex %d: %s", ifindex, strerror(-err));
2722 return -1;
2723 }
2724 }
2725
2726 return 0;
2727 }
2728
2729 static int setup_ipv6_addr(struct lxc_list *ip, int ifindex)
2730 {
2731 struct lxc_list *iterator;
2732 int err;
2733
2734 lxc_list_for_each(iterator, ip) {
2735 struct lxc_inet6dev *inet6dev = iterator->elem;
2736
2737 err = lxc_ipv6_addr_add(ifindex, &inet6dev->addr,
2738 &inet6dev->mcast, &inet6dev->acast,
2739 inet6dev->prefix);
2740 if (err) {
2741 ERROR("Failed to setup ipv6 address for network device "
2742 "with eifindex %d: %s", ifindex, strerror(-err));
2743 return -1;
2744 }
2745 }
2746
2747 return 0;
2748 }
2749
2750 static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev *netdev)
2751 {
2752 char ifname[IFNAMSIZ];
2753 int err;
2754 const char *net_type_name;
2755 char *current_ifname = ifname;
2756
2757 /* empty network namespace */
2758 if (!netdev->ifindex) {
2759 if (netdev->flags & IFF_UP) {
2760 err = lxc_netdev_up("lo");
2761 if (err) {
2762 ERROR("Failed to set the loopback network "
2763 "device up: %s",
2764 strerror(-err));
2765 return -1;
2766 }
2767 }
2768
2769 if (netdev->type == LXC_NET_EMPTY)
2770 return 0;
2771
2772 if (netdev->type == LXC_NET_NONE)
2773 return 0;
2774
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);
2779 return -1;
2780 }
2781
2782 netdev->ifindex = if_nametoindex(netdev->name);
2783 }
2784
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\"",
2790 netdev->link);
2791 return -1;
2792 }
2793 }
2794
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",
2798 netdev->ifindex);
2799 return -1;
2800 }
2801
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.
2805 */
2806 if (netdev->name[0] == '\0') {
2807 if (netdev->type == LXC_NET_PHYS)
2808 strcpy(netdev->name, netdev->link);
2809 else
2810 strcpy(netdev->name, "eth%d");
2811 }
2812
2813 /* rename the interface name */
2814 if (strcmp(ifname, netdev->name) != 0) {
2815 err = lxc_netdev_rename_by_name(ifname, netdev->name);
2816 if (err) {
2817 ERROR("Failed to rename network device \"%s\" to "
2818 "\"%s\": %s", ifname, netdev->name, strerror(-err));
2819 return -1;
2820 }
2821 }
2822
2823 /* Re-read the name of the interface because its name has changed
2824 * and would be automatically allocated by the system
2825 */
2826 if (!if_indextoname(netdev->ifindex, current_ifname)) {
2827 ERROR("Failed get name for network device with ifindex %d",
2828 netdev->ifindex);
2829 return -1;
2830 }
2831
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.
2835 */
2836 strcpy(netdev->name, current_ifname);
2837
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\"",
2842 current_ifname);
2843 return -1;
2844 }
2845 }
2846
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\"",
2850 ifname);
2851 return -1;
2852 }
2853
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\"",
2857 ifname);
2858 return -1;
2859 }
2860
2861 /* set the network device up */
2862 if (netdev->flags & IFF_UP) {
2863 int err;
2864
2865 err = lxc_netdev_up(current_ifname);
2866 if (err) {
2867 ERROR("Failed to set network device \"%s\" up: %s",
2868 current_ifname, strerror(-err));
2869 return -1;
2870 }
2871
2872 /* the network is up, make the loopback up too */
2873 err = lxc_netdev_up("lo");
2874 if (err) {
2875 ERROR("Failed to set the loopback network device up: %s",
2876 strerror(-err));
2877 return -1;
2878 }
2879 }
2880
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. */
2885
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);
2891 return -1;
2892 }
2893
2894 if (lxc_list_empty(&netdev->ipv4)) {
2895 ERROR("Cannot add ipv4 gateway for network device "
2896 "\"%s\" when not assigning an address", ifname);
2897 return -1;
2898 }
2899
2900 err = lxc_ipv4_gateway_add(netdev->ifindex, netdev->ipv4_gateway);
2901 if (err) {
2902 err = lxc_ipv4_dest_add(netdev->ifindex, netdev->ipv4_gateway);
2903 if (err) {
2904 ERROR("Failed to add ipv4 dest for network "
2905 "device \"%s\": %s", ifname, strerror(-err));
2906 }
2907
2908 err = lxc_ipv4_gateway_add(netdev->ifindex, netdev->ipv4_gateway);
2909 if (err) {
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);
2917 }
2918 return -1;
2919 }
2920 }
2921 }
2922
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);
2928 return -1;
2929 }
2930
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);
2934 return -1;
2935 }
2936
2937 err = lxc_ipv6_gateway_add(netdev->ifindex, netdev->ipv6_gateway);
2938 if (err) {
2939 err = lxc_ipv6_dest_add(netdev->ifindex, netdev->ipv6_gateway);
2940 if (err) {
2941 ERROR("Failed to add ipv6 dest for network "
2942 "device \"%s\": %s", ifname, strerror(-err));
2943 }
2944
2945 err = lxc_ipv6_gateway_add(netdev->ifindex, netdev->ipv6_gateway);
2946 if (err) {
2947 ERROR("Failed to setup ipv6 gateway for "
2948 "network device \"%s\": %s", ifname,
2949 strerror(-err));
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 "
2955 "\"%s\"", buf);
2956 }
2957 return -1;
2958 }
2959 }
2960 }
2961
2962 DEBUG("Network device \"%s\" has been setup", current_ifname);
2963
2964 return 0;
2965 }
2966
2967 int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
2968 struct lxc_list *network)
2969 {
2970 struct lxc_list *iterator;
2971 struct lxc_netdev *netdev;
2972
2973 lxc_list_for_each(iterator, network) {
2974 netdev = iterator->elem;
2975
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\"");
2981 }
2982
2983 if (lxc_setup_netdev_in_child_namespaces(netdev)) {
2984 ERROR("failed to setup netdev");
2985 return -1;
2986 }
2987 }
2988
2989 if (!lxc_list_empty(network))
2990 INFO("network has been setup");
2991
2992 return 0;
2993 }