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