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