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