]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/network.c
cb2a8c0fd787f6c73a41a1fdde68d7311096b274
[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 #define _GNU_SOURCE
24 #include <stdio.h>
25 #undef _GNU_SOURCe
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <errno.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <time.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/socket.h>
37 #include <sys/param.h>
38 #include <sys/ioctl.h>
39 #include <arpa/inet.h>
40 #include <net/if.h>
41 #include <net/if_arp.h>
42 #include <net/ethernet.h>
43 #include <netinet/in.h>
44 #include <linux/netlink.h>
45 #include <linux/rtnetlink.h>
46 #include <linux/sockios.h>
47
48 #include "nl.h"
49 #include "network.h"
50 #include "conf.h"
51 #include "utils.h"
52
53 #if HAVE_IFADDRS_H
54 #include <ifaddrs.h>
55 #else
56 #include <../include/ifaddrs.h>
57 #endif
58
59 #ifndef IFLA_LINKMODE
60 # define IFLA_LINKMODE 17
61 #endif
62
63 #ifndef IFLA_LINKINFO
64 # define IFLA_LINKINFO 18
65 #endif
66
67 #ifndef IFLA_NET_NS_PID
68 # define IFLA_NET_NS_PID 19
69 #endif
70
71 #ifndef IFLA_INFO_KIND
72 # define IFLA_INFO_KIND 1
73 #endif
74
75 #ifndef IFLA_VLAN_ID
76 # define IFLA_VLAN_ID 1
77 #endif
78
79 #ifndef IFLA_INFO_DATA
80 # define IFLA_INFO_DATA 2
81 #endif
82
83 #ifndef VETH_INFO_PEER
84 # define VETH_INFO_PEER 1
85 #endif
86
87 #ifndef IFLA_MACVLAN_MODE
88 # define IFLA_MACVLAN_MODE 1
89 #endif
90
91
92 int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname)
93 {
94 struct nl_handler nlh;
95 struct nlmsg *nlmsg = NULL;
96 struct ifinfomsg *ifi;
97 int err;
98
99 err = netlink_open(&nlh, NETLINK_ROUTE);
100 if (err)
101 return err;
102
103 err = -ENOMEM;
104 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
105 if (!nlmsg)
106 goto out;
107
108 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
109 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
110
111 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
112 ifi->ifi_family = AF_UNSPEC;
113 ifi->ifi_index = ifindex;
114
115 if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid))
116 goto out;
117
118 if (ifname != NULL) {
119 if (nla_put_string(nlmsg, IFLA_IFNAME, ifname))
120 goto out;
121 }
122
123 err = netlink_transaction(&nlh, nlmsg, nlmsg);
124 out:
125 netlink_close(&nlh);
126 nlmsg_free(nlmsg);
127 return err;
128 }
129
130 /*
131 * If we are asked to move a wireless interface, then
132 * we must actually move its phyN device. Detect
133 * that condition and return the physname here. The
134 * physname will be passed to lxc_netdev_move_wlan()
135 * which will free it when done
136 */
137 #define PHYSNAME "/sys/class/net/%s/phy80211/name"
138 static char * is_wlan(const char *ifname)
139 {
140 char *path, *physname = NULL;
141 size_t len = strlen(ifname) + strlen(PHYSNAME) - 1;
142 struct stat sb;
143 long physlen;
144 FILE *f;
145 int ret, i;
146
147 path = alloca(len+1);
148 ret = snprintf(path, len, PHYSNAME, ifname);
149 if (ret < 0 || ret >= len)
150 goto bad;
151 ret = stat(path, &sb);
152 if (ret)
153 goto bad;
154 if (!(f = fopen(path, "r")))
155 goto bad;
156 // feh - sb.st_size is always 4096
157 fseek(f, 0, SEEK_END);
158 physlen = ftell(f);
159 fseek(f, 0, SEEK_SET);
160 physname = malloc(physlen+1);
161 if (!physname)
162 goto bad;
163 memset(physname, 0, physlen+1);
164 ret = fread(physname, 1, physlen, f);
165 fclose(f);
166 if (ret < 0)
167 goto bad;
168
169 for (i = 0; i < physlen; i++) {
170 if (physname[i] == '\n')
171 physname[i] = '\0';
172 if (physname[i] == '\0')
173 break;
174 }
175
176 return physname;
177
178 bad:
179 if (physname)
180 free(physname);
181 return NULL;
182 }
183
184 static int
185 lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old, const char *new)
186 {
187 pid_t fpid = fork();
188
189 if (fpid < 0)
190 return -1;
191 if (fpid != 0)
192 return wait_for_pid(fpid);
193 if (!switch_to_ns(pid, "net"))
194 return -1;
195 exit(lxc_netdev_rename_by_name(old, new));
196 }
197
198 static int
199 lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, const char* newname)
200 {
201 int err = -1;
202 pid_t fpid;
203 char *cmd;
204
205 /* Move phyN into the container. TODO - do this using netlink.
206 * However, IIUC this involves a bit more complicated work to
207 * talk to the 80211 module, so for now just call out to iw
208 */
209 cmd = on_path("iw", NULL);
210 if (!cmd)
211 goto out1;
212 free(cmd);
213
214 fpid = fork();
215 if (fpid < 0)
216 goto out1;
217 if (fpid == 0) {
218 char pidstr[30];
219 sprintf(pidstr, "%d", pid);
220 if (execlp("iw", "iw", "phy", physname, "set", "netns", pidstr, NULL))
221 exit(1);
222 exit(0); // notreached
223 }
224 if (wait_for_pid(fpid))
225 goto out1;
226
227 err = 0;
228 if (newname)
229 err = lxc_netdev_rename_by_name_in_netns(pid, ifname, newname);
230
231 out1:
232 free(physname);
233 return err;
234 }
235
236 int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
237 {
238 int index;
239 char *physname;
240
241 if (!ifname)
242 return -EINVAL;
243
244 index = if_nametoindex(ifname);
245 if (!index)
246 return -EINVAL;
247
248 if ((physname = is_wlan(ifname)))
249 return lxc_netdev_move_wlan(physname, ifname, pid, newname);
250
251 return lxc_netdev_move_by_index(index, pid, newname);
252 }
253
254 int lxc_netdev_delete_by_index(int ifindex)
255 {
256 struct nl_handler nlh;
257 struct nlmsg *nlmsg = NULL, *answer = NULL;
258 struct ifinfomsg *ifi;
259 int err;
260
261 err = netlink_open(&nlh, NETLINK_ROUTE);
262 if (err)
263 return err;
264
265 err = -ENOMEM;
266 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
267 if (!nlmsg)
268 goto out;
269
270 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
271 if (!answer)
272 goto out;
273
274 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
275 nlmsg->nlmsghdr->nlmsg_type = RTM_DELLINK;
276
277 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
278 ifi->ifi_family = AF_UNSPEC;
279 ifi->ifi_index = ifindex;
280
281 err = netlink_transaction(&nlh, nlmsg, answer);
282 out:
283 netlink_close(&nlh);
284 nlmsg_free(answer);
285 nlmsg_free(nlmsg);
286 return err;
287 }
288
289 int lxc_netdev_delete_by_name(const char *name)
290 {
291 int index;
292
293 index = if_nametoindex(name);
294 if (!index)
295 return -EINVAL;
296
297 return lxc_netdev_delete_by_index(index);
298 }
299
300 int lxc_netdev_rename_by_index(int ifindex, const char *newname)
301 {
302 struct nl_handler nlh;
303 struct nlmsg *nlmsg = NULL, *answer = NULL;
304 struct ifinfomsg *ifi;
305 int len, err;
306
307 err = netlink_open(&nlh, NETLINK_ROUTE);
308 if (err)
309 return err;
310
311 len = strlen(newname);
312 if (len == 1 || len >= IFNAMSIZ)
313 goto out;
314
315 err = -ENOMEM;
316 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
317 if (!nlmsg)
318 goto out;
319
320 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
321 if (!answer)
322 goto out;
323
324 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
325 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
326
327 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
328 ifi->ifi_family = AF_UNSPEC;
329 ifi->ifi_index = ifindex;
330
331 if (nla_put_string(nlmsg, IFLA_IFNAME, newname))
332 goto out;
333
334 err = netlink_transaction(&nlh, nlmsg, answer);
335 out:
336 netlink_close(&nlh);
337 nlmsg_free(answer);
338 nlmsg_free(nlmsg);
339 return err;
340 }
341
342 int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
343 {
344 int len, index;
345
346 len = strlen(oldname);
347 if (len == 1 || len >= IFNAMSIZ)
348 return -EINVAL;
349
350 index = if_nametoindex(oldname);
351 if (!index)
352 return -EINVAL;
353
354 return lxc_netdev_rename_by_index(index, newname);
355 }
356
357 int netdev_set_flag(const char *name, int flag)
358 {
359 struct nl_handler nlh;
360 struct nlmsg *nlmsg = NULL, *answer = NULL;
361 struct ifinfomsg *ifi;
362 int index, len, err;
363
364 err = netlink_open(&nlh, NETLINK_ROUTE);
365 if (err)
366 return err;
367
368 err = -EINVAL;
369 len = strlen(name);
370 if (len == 1 || len >= IFNAMSIZ)
371 goto out;
372
373 err = -ENOMEM;
374 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
375 if (!nlmsg)
376 goto out;
377
378 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
379 if (!answer)
380 goto out;
381
382 err = -EINVAL;
383 index = if_nametoindex(name);
384 if (!index)
385 goto out;
386
387 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
388 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
389
390 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
391 ifi->ifi_family = AF_UNSPEC;
392 ifi->ifi_index = index;
393 ifi->ifi_change |= IFF_UP;
394 ifi->ifi_flags |= flag;
395
396 err = netlink_transaction(&nlh, nlmsg, answer);
397 out:
398 netlink_close(&nlh);
399 nlmsg_free(nlmsg);
400 nlmsg_free(answer);
401 return err;
402 }
403
404 int netdev_get_flag(const char* name, int *flag)
405 {
406 struct nl_handler nlh;
407 struct nlmsg *nlmsg = NULL, *answer = NULL;
408 struct ifinfomsg *ifi;
409 int index, len, err;
410
411 if (!name)
412 return -EINVAL;
413
414 err = netlink_open(&nlh, NETLINK_ROUTE);
415 if (err)
416 return err;
417
418 err = -EINVAL;
419 len = strlen(name);
420 if (len == 1 || len >= IFNAMSIZ)
421 goto out;
422
423 err = -ENOMEM;
424 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
425 if (!nlmsg)
426 goto out;
427
428 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
429 if (!answer)
430 goto out;
431
432 err = -EINVAL;
433 index = if_nametoindex(name);
434 if (!index)
435 goto out;
436
437 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST;
438 nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK;
439
440 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
441 ifi->ifi_family = AF_UNSPEC;
442 ifi->ifi_index = index;
443
444 nlmsg_reserve(answer, sizeof(struct ifinfomsg));
445
446 err = netlink_transaction(&nlh, nlmsg, answer);
447 if (err)
448 goto out;
449
450 ifi = NLMSG_DATA(answer);
451
452 *flag = ifi->ifi_flags;
453 out:
454 netlink_close(&nlh);
455 nlmsg_free(nlmsg);
456 nlmsg_free(answer);
457 return err;
458 }
459
460 /*
461 * \brief Check a interface is up or not.
462 *
463 * \param name: name for the interface.
464 *
465 * \return int.
466 * 0 means interface is down.
467 * 1 means interface is up.
468 * Others means error happened, and ret-value is the error number.
469 */
470 int lxc_netdev_isup(const char* name)
471 {
472 int flag;
473 int err;
474
475 err = netdev_get_flag(name, &flag);
476 if (err)
477 goto out;
478 if (flag & IFF_UP)
479 return 1;
480 return 0;
481 out:
482 return err;
483 }
484
485 int netdev_get_mtu(int ifindex)
486 {
487 struct nl_handler nlh;
488 struct nlmsg *nlmsg = NULL, *answer = NULL;
489 struct ifinfomsg *ifi;
490 struct nlmsghdr *msg;
491 int err, res;
492 int recv_len = 0, answer_len;
493 int readmore = 0;
494
495 err = netlink_open(&nlh, NETLINK_ROUTE);
496 if (err)
497 return err;
498
499 err = -ENOMEM;
500 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
501 if (!nlmsg)
502 goto out;
503
504 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
505 if (!answer)
506 goto out;
507
508 /* Save the answer buffer length, since it will be overwritten
509 * on the first receive (and we might need to receive more than
510 * once. */
511 nlmsg_reserve(answer, NLMSG_GOOD_SIZE);
512 answer_len = answer->nlmsghdr->nlmsg_len;
513
514 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
515 nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK;
516
517 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
518 ifi->ifi_family = AF_UNSPEC;
519
520 /* Send the request for addresses, which returns all addresses
521 * on all interfaces. */
522 err = netlink_send(&nlh, nlmsg);
523 if (err < 0)
524 goto out;
525
526 do {
527 /* Restore the answer buffer length, it might have been
528 * overwritten by a previous receive. */
529 answer->nlmsghdr->nlmsg_len = answer_len;
530
531 /* Get the (next) batch of reply messages */
532 err = netlink_rcv(&nlh, answer);
533 if (err < 0)
534 goto out;
535
536 recv_len = err;
537 err = 0;
538
539 /* Satisfy the typing for the netlink macros */
540 msg = answer->nlmsghdr;
541
542 while (NLMSG_OK(msg, recv_len)) {
543
544 /* Stop reading if we see an error message */
545 if (msg->nlmsg_type == NLMSG_ERROR) {
546 struct nlmsgerr *errmsg = (struct nlmsgerr*)NLMSG_DATA(msg);
547 err = errmsg->error;
548 goto out;
549 }
550
551 /* Stop reading if we see a NLMSG_DONE message */
552 if (msg->nlmsg_type == NLMSG_DONE) {
553 readmore = 0;
554 break;
555 }
556
557 ifi = NLMSG_DATA(msg);
558 if (ifi->ifi_index == ifindex) {
559 struct rtattr *rta = IFLA_RTA(ifi);
560 int attr_len = msg->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
561 res = 0;
562 while(RTA_OK(rta, attr_len)) {
563 /* Found a local address for the requested interface,
564 * return it. */
565 if (rta->rta_type == IFLA_MTU) {
566 memcpy(&res, RTA_DATA(rta), sizeof(int));
567 err = res;
568 goto out;
569 }
570 rta = RTA_NEXT(rta, attr_len);
571 }
572
573 }
574
575 /* Keep reading more data from the socket if the
576 * last message had the NLF_F_MULTI flag set */
577 readmore = (msg->nlmsg_flags & NLM_F_MULTI);
578
579 /* Look at the next message received in this buffer */
580 msg = NLMSG_NEXT(msg, recv_len);
581 }
582 } while (readmore);
583
584 /* If we end up here, we didn't find any result, so signal an
585 * error */
586 err = -1;
587
588 out:
589 netlink_close(&nlh);
590 nlmsg_free(answer);
591 nlmsg_free(nlmsg);
592 return err;
593 }
594
595 int lxc_netdev_set_mtu(const char *name, int mtu)
596 {
597 struct nl_handler nlh;
598 struct nlmsg *nlmsg = NULL, *answer = NULL;
599 struct ifinfomsg *ifi;
600 int index, len, err;
601
602 err = netlink_open(&nlh, NETLINK_ROUTE);
603 if (err)
604 return err;
605
606 err = -EINVAL;
607 len = strlen(name);
608 if (len == 1 || len >= IFNAMSIZ)
609 goto out;
610
611 err = -ENOMEM;
612 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
613 if (!nlmsg)
614 goto out;
615
616 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
617 if (!answer)
618 goto out;
619
620 err = -EINVAL;
621 index = if_nametoindex(name);
622 if (!index)
623 goto out;
624
625 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
626 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
627
628 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
629 ifi->ifi_family = AF_UNSPEC;
630 ifi->ifi_index = index;
631
632 if (nla_put_u32(nlmsg, IFLA_MTU, mtu))
633 goto out;
634
635 err = netlink_transaction(&nlh, nlmsg, answer);
636 out:
637 netlink_close(&nlh);
638 nlmsg_free(nlmsg);
639 nlmsg_free(answer);
640 return err;
641 }
642
643 int lxc_netdev_up(const char *name)
644 {
645 return netdev_set_flag(name, IFF_UP);
646 }
647
648 int lxc_netdev_down(const char *name)
649 {
650 return netdev_set_flag(name, 0);
651 }
652
653 int lxc_veth_create(const char *name1, const char *name2)
654 {
655 struct nl_handler nlh;
656 struct nlmsg *nlmsg = NULL, *answer = NULL;
657 struct ifinfomsg *ifi;
658 struct rtattr *nest1, *nest2, *nest3;
659 int len, err;
660
661 err = netlink_open(&nlh, NETLINK_ROUTE);
662 if (err)
663 return err;
664
665 err = -EINVAL;
666 len = strlen(name1);
667 if (len == 1 || len >= IFNAMSIZ)
668 goto out;
669
670 len = strlen(name2);
671 if (len == 1 || len >= IFNAMSIZ)
672 goto out;
673
674 err = -ENOMEM;
675 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
676 if (!nlmsg)
677 goto out;
678
679 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
680 if (!answer)
681 goto out;
682
683 nlmsg->nlmsghdr->nlmsg_flags =
684 NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
685 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
686
687 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
688 ifi->ifi_family = AF_UNSPEC;
689
690 err = -EINVAL;
691 nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO);
692 if (!nest1)
693 goto out;
694
695 if (nla_put_string(nlmsg, IFLA_INFO_KIND, "veth"))
696 goto out;
697
698 nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
699 if (!nest2)
700 goto out;
701
702 nest3 = nla_begin_nested(nlmsg, VETH_INFO_PEER);
703 if (!nest3)
704 goto out;
705
706 nlmsg->nlmsghdr->nlmsg_len += sizeof(struct ifinfomsg);
707
708 if (nla_put_string(nlmsg, IFLA_IFNAME, name2))
709 goto out;
710
711 nla_end_nested(nlmsg, nest3);
712
713 nla_end_nested(nlmsg, nest2);
714
715 nla_end_nested(nlmsg, nest1);
716
717 if (nla_put_string(nlmsg, IFLA_IFNAME, name1))
718 goto out;
719
720 err = netlink_transaction(&nlh, nlmsg, answer);
721 out:
722 netlink_close(&nlh);
723 nlmsg_free(answer);
724 nlmsg_free(nlmsg);
725 return err;
726 }
727
728 /* XXX: merge with lxc_macvlan_create */
729 int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
730 {
731 struct nl_handler nlh;
732 struct nlmsg *nlmsg = NULL, *answer = NULL;
733 struct ifinfomsg *ifi;
734 struct rtattr *nest, *nest2;
735 int lindex, len, err;
736
737 err = netlink_open(&nlh, NETLINK_ROUTE);
738 if (err)
739 return err;
740
741 err = -EINVAL;
742 len = strlen(master);
743 if (len == 1 || len >= IFNAMSIZ)
744 goto err3;
745
746 len = strlen(name);
747 if (len == 1 || len >= IFNAMSIZ)
748 goto err3;
749
750 err = -ENOMEM;
751 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
752 if (!nlmsg)
753 goto err3;
754
755 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
756 if (!answer)
757 goto err2;
758
759 err = -EINVAL;
760 lindex = if_nametoindex(master);
761 if (!lindex)
762 goto err1;
763
764 nlmsg->nlmsghdr->nlmsg_flags =
765 NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
766 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
767
768 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
769 ifi->ifi_family = AF_UNSPEC;
770
771 nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
772 if (!nest)
773 goto err1;
774
775 if (nla_put_string(nlmsg, IFLA_INFO_KIND, "vlan"))
776 goto err1;
777
778 nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
779 if (!nest2)
780 goto err1;
781
782 if (nla_put_u16(nlmsg, IFLA_VLAN_ID, vlanid))
783 goto err1;
784
785 nla_end_nested(nlmsg, nest2);
786
787 nla_end_nested(nlmsg, nest);
788
789 if (nla_put_u32(nlmsg, IFLA_LINK, lindex))
790 goto err1;
791
792 if (nla_put_string(nlmsg, IFLA_IFNAME, name))
793 goto err1;
794
795 err = netlink_transaction(&nlh, nlmsg, answer);
796 err1:
797 nlmsg_free(answer);
798 err2:
799 nlmsg_free(nlmsg);
800 err3:
801 netlink_close(&nlh);
802 return err;
803 }
804
805 int lxc_macvlan_create(const char *master, const char *name, int mode)
806 {
807 struct nl_handler nlh;
808 struct nlmsg *nlmsg = NULL, *answer = NULL;
809 struct ifinfomsg *ifi;
810 struct rtattr *nest, *nest2;
811 int index, len, err;
812
813 err = netlink_open(&nlh, NETLINK_ROUTE);
814 if (err)
815 return err;
816
817 err = -EINVAL;
818 len = strlen(master);
819 if (len == 1 || len >= IFNAMSIZ)
820 goto out;
821
822 len = strlen(name);
823 if (len == 1 || len >= IFNAMSIZ)
824 goto out;
825
826 err = -ENOMEM;
827 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
828 if (!nlmsg)
829 goto out;
830
831 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
832 if (!answer)
833 goto out;
834
835 err = -EINVAL;
836 index = if_nametoindex(master);
837 if (!index)
838 goto out;
839
840 nlmsg->nlmsghdr->nlmsg_flags =
841 NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
842 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
843
844 ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
845 ifi->ifi_family = AF_UNSPEC;
846
847 nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
848 if (!nest)
849 goto out;
850
851 if (nla_put_string(nlmsg, IFLA_INFO_KIND, "macvlan"))
852 goto out;
853
854 if (mode) {
855 nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
856 if (!nest2)
857 goto out;
858
859 if (nla_put_u32(nlmsg, IFLA_MACVLAN_MODE, mode))
860 goto out;
861
862 nla_end_nested(nlmsg, nest2);
863 }
864
865 nla_end_nested(nlmsg, nest);
866
867 if (nla_put_u32(nlmsg, IFLA_LINK, index))
868 goto out;
869
870 if (nla_put_string(nlmsg, IFLA_IFNAME, name))
871 goto out;
872
873 err = netlink_transaction(&nlh, nlmsg, answer);
874 out:
875 netlink_close(&nlh);
876 nlmsg_free(answer);
877 nlmsg_free(nlmsg);
878 return err;
879 }
880
881 static int proc_sys_net_write(const char *path, const char *value)
882 {
883 int fd, err = 0;
884
885 fd = open(path, O_WRONLY);
886 if (fd < 0)
887 return -errno;
888
889 if (write(fd, value, strlen(value)) < 0)
890 err = -errno;
891
892 close(fd);
893 return err;
894 }
895
896 static int ip_forward_set(const char *ifname, int family, int flag)
897 {
898 char path[MAXPATHLEN];
899 int rc;
900
901 if (family != AF_INET && family != AF_INET6)
902 return -EINVAL;
903
904 rc = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/forwarding",
905 family == AF_INET?"ipv4":"ipv6" , ifname);
906 if (rc >= MAXPATHLEN)
907 return -E2BIG;
908
909 return proc_sys_net_write(path, flag?"1":"0");
910 }
911
912 int lxc_ip_forward_on(const char *ifname, int family)
913 {
914 return ip_forward_set(ifname, family, 1);
915 }
916
917 int lxc_ip_forward_off(const char *ifname, int family)
918 {
919 return ip_forward_set(ifname, family, 0);
920 }
921
922 static int neigh_proxy_set(const char *ifname, int family, int flag)
923 {
924 char path[MAXPATHLEN];
925 int ret;
926
927 if (family != AF_INET && family != AF_INET6)
928 return -EINVAL;
929
930 ret = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/%s",
931 family == AF_INET?"ipv4":"ipv6" , ifname,
932 family == AF_INET?"proxy_arp":"proxy_ndp");
933 if (ret < 0 || ret >= MAXPATHLEN)
934 return -E2BIG;
935
936 return proc_sys_net_write(path, flag?"1":"0");
937 }
938
939 int lxc_neigh_proxy_on(const char *name, int family)
940 {
941 return neigh_proxy_set(name, family, 1);
942 }
943
944 int lxc_neigh_proxy_off(const char *name, int family)
945 {
946 return neigh_proxy_set(name, family, 0);
947 }
948
949 int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
950 {
951 unsigned char *data;
952 char c;
953 int i = 0;
954 unsigned val;
955
956 sockaddr->sa_family = ARPHRD_ETHER;
957 data = (unsigned char *)sockaddr->sa_data;
958
959 while ((*macaddr != '\0') && (i < ETH_ALEN)) {
960 val = 0;
961 c = *macaddr++;
962 if (isdigit(c))
963 val = c - '0';
964 else if (c >= 'a' && c <= 'f')
965 val = c - 'a' + 10;
966 else if (c >= 'A' && c <= 'F')
967 val = c - 'A' + 10;
968 else {
969 return -EINVAL;
970 }
971 val <<= 4;
972 c = *macaddr;
973 if (isdigit(c))
974 val |= c - '0';
975 else if (c >= 'a' && c <= 'f')
976 val |= c - 'a' + 10;
977 else if (c >= 'A' && c <= 'F')
978 val |= c - 'A' + 10;
979 else if (c == ':' || c == 0)
980 val >>= 4;
981 else {
982 return -EINVAL;
983 }
984 if (c != 0)
985 macaddr++;
986 *data++ = (unsigned char) (val & 0377);
987 i++;
988
989 if (*macaddr == ':')
990 macaddr++;
991 }
992
993 return 0;
994 }
995
996 static int ip_addr_add(int family, int ifindex,
997 void *addr, void *bcast, void *acast, int prefix)
998 {
999 struct nl_handler nlh;
1000 struct nlmsg *nlmsg = NULL, *answer = NULL;
1001 struct ifaddrmsg *ifa;
1002 int addrlen;
1003 int err;
1004
1005 addrlen = family == AF_INET ? sizeof(struct in_addr) :
1006 sizeof(struct in6_addr);
1007
1008 err = netlink_open(&nlh, NETLINK_ROUTE);
1009 if (err)
1010 return err;
1011
1012 err = -ENOMEM;
1013 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1014 if (!nlmsg)
1015 goto out;
1016
1017 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
1018 if (!answer)
1019 goto out;
1020
1021 nlmsg->nlmsghdr->nlmsg_flags =
1022 NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL;
1023 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWADDR;
1024
1025 ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg));
1026 ifa->ifa_prefixlen = prefix;
1027 ifa->ifa_index = ifindex;
1028 ifa->ifa_family = family;
1029 ifa->ifa_scope = 0;
1030
1031 err = -EINVAL;
1032 if (nla_put_buffer(nlmsg, IFA_LOCAL, addr, addrlen))
1033 goto out;
1034
1035 if (nla_put_buffer(nlmsg, IFA_ADDRESS, addr, addrlen))
1036 goto out;
1037
1038 if (nla_put_buffer(nlmsg, IFA_BROADCAST, bcast, addrlen))
1039 goto out;
1040
1041 /* TODO : multicast, anycast with ipv6 */
1042 err = -EPROTONOSUPPORT;
1043 if (family == AF_INET6 &&
1044 (memcmp(bcast, &in6addr_any, sizeof(in6addr_any)) ||
1045 memcmp(acast, &in6addr_any, sizeof(in6addr_any))))
1046 goto out;
1047
1048 err = netlink_transaction(&nlh, nlmsg, answer);
1049 out:
1050 netlink_close(&nlh);
1051 nlmsg_free(answer);
1052 nlmsg_free(nlmsg);
1053 return err;
1054 }
1055
1056 int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
1057 struct in6_addr *mcast,
1058 struct in6_addr *acast, int prefix)
1059 {
1060 return ip_addr_add(AF_INET6, ifindex, addr, mcast, acast, prefix);
1061 }
1062
1063 int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr,
1064 struct in_addr *bcast, int prefix)
1065 {
1066 return ip_addr_add(AF_INET, ifindex, addr, bcast, NULL, prefix);
1067 }
1068
1069 /* Find an IFA_LOCAL (or IFA_ADDRESS if not IFA_LOCAL is present)
1070 * address from the given RTM_NEWADDR message. Allocates memory for the
1071 * address and stores that pointer in *res (so res should be an
1072 * in_addr** or in6_addr**).
1073 */
1074 static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) {
1075 struct ifaddrmsg *ifa = NLMSG_DATA(msg);
1076 struct rtattr *rta = IFA_RTA(ifa);
1077 int attr_len = NLMSG_PAYLOAD(msg, sizeof(struct ifaddrmsg));
1078 int addrlen;
1079
1080 if (ifa->ifa_family != family)
1081 return 0;
1082
1083 addrlen = family == AF_INET ? sizeof(struct in_addr) :
1084 sizeof(struct in6_addr);
1085
1086 /* Loop over the rtattr's in this message */
1087 while(RTA_OK(rta, attr_len)) {
1088 /* Found a local address for the requested interface,
1089 * return it. */
1090 if (rta->rta_type == IFA_LOCAL || rta->rta_type == IFA_ADDRESS) {
1091 /* Sanity check. The family check above should
1092 * make sure the address length is correct, but
1093 * check here just in case */
1094 if (RTA_PAYLOAD(rta) != addrlen)
1095 return -1;
1096
1097 /* We might have found an IFA_ADDRESS before,
1098 * which we now overwrite with an IFA_LOCAL. */
1099 if (!*res) {
1100 *res = malloc(addrlen);
1101 if (!*res)
1102 return -1;
1103 }
1104
1105 memcpy(*res, RTA_DATA(rta), addrlen);
1106
1107 if (rta->rta_type == IFA_LOCAL)
1108 break;
1109 }
1110 rta = RTA_NEXT(rta, attr_len);
1111 }
1112 return 0;
1113 }
1114
1115 static int ip_addr_get(int family, int ifindex, void **res)
1116 {
1117 struct nl_handler nlh;
1118 struct nlmsg *nlmsg = NULL, *answer = NULL;
1119 struct ifaddrmsg *ifa;
1120 struct nlmsghdr *msg;
1121 int err;
1122 int recv_len = 0, answer_len;
1123 int readmore = 0;
1124
1125 err = netlink_open(&nlh, NETLINK_ROUTE);
1126 if (err)
1127 return err;
1128
1129 err = -ENOMEM;
1130 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1131 if (!nlmsg)
1132 goto out;
1133
1134 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
1135 if (!answer)
1136 goto out;
1137
1138 /* Save the answer buffer length, since it will be overwritten
1139 * on the first receive (and we might need to receive more than
1140 * once. */
1141 nlmsg_reserve(answer, NLMSG_GOOD_SIZE);
1142 answer_len = answer->nlmsghdr->nlmsg_len;
1143
1144 nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ROOT;
1145 nlmsg->nlmsghdr->nlmsg_type = RTM_GETADDR;
1146
1147 ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg));
1148 ifa->ifa_family = family;
1149
1150 /* Send the request for addresses, which returns all addresses
1151 * on all interfaces. */
1152 err = netlink_send(&nlh, nlmsg);
1153 if (err < 0)
1154 goto out;
1155
1156 do {
1157 /* Restore the answer buffer length, it might have been
1158 * overwritten by a previous receive. */
1159 answer->nlmsghdr->nlmsg_len = answer_len;
1160
1161 /* Get the (next) batch of reply messages */
1162 err = netlink_rcv(&nlh, answer);
1163 if (err < 0)
1164 goto out;
1165
1166 recv_len = err;
1167 err = 0;
1168
1169 /* Satisfy the typing for the netlink macros */
1170 msg = answer->nlmsghdr;
1171
1172 while (NLMSG_OK(msg, recv_len)) {
1173 /* Stop reading if we see an error message */
1174 if (msg->nlmsg_type == NLMSG_ERROR) {
1175 struct nlmsgerr *errmsg = (struct nlmsgerr*)NLMSG_DATA(msg);
1176 err = errmsg->error;
1177 goto out;
1178 }
1179
1180 /* Stop reading if we see a NLMSG_DONE message */
1181 if (msg->nlmsg_type == NLMSG_DONE) {
1182 readmore = 0;
1183 break;
1184 }
1185
1186 if (msg->nlmsg_type != RTM_NEWADDR) {
1187 err = -1;
1188 goto out;
1189 }
1190
1191 ifa = (struct ifaddrmsg *)NLMSG_DATA(msg);
1192 if (ifa->ifa_index == ifindex) {
1193 if (ifa_get_local_ip(family, msg, res) < 0) {
1194 err = -1;
1195 goto out;
1196 }
1197
1198 /* Found a result, stop searching */
1199 if (*res)
1200 goto out;
1201 }
1202
1203 /* Keep reading more data from the socket if the
1204 * last message had the NLF_F_MULTI flag set */
1205 readmore = (msg->nlmsg_flags & NLM_F_MULTI);
1206
1207 /* Look at the next message received in this buffer */
1208 msg = NLMSG_NEXT(msg, recv_len);
1209 }
1210 } while (readmore);
1211
1212 /* If we end up here, we didn't find any result, so signal an
1213 * error */
1214 err = -1;
1215
1216 out:
1217 netlink_close(&nlh);
1218 nlmsg_free(answer);
1219 nlmsg_free(nlmsg);
1220 return err;
1221 }
1222
1223 int lxc_ipv6_addr_get(int ifindex, struct in6_addr **res)
1224 {
1225 return ip_addr_get(AF_INET6, ifindex, (void**)res);
1226 }
1227
1228 int lxc_ipv4_addr_get(int ifindex, struct in_addr** res)
1229 {
1230 return ip_addr_get(AF_INET, ifindex, (void**)res);
1231 }
1232
1233 static int ip_gateway_add(int family, int ifindex, void *gw)
1234 {
1235 struct nl_handler nlh;
1236 struct nlmsg *nlmsg = NULL, *answer = NULL;
1237 struct rtmsg *rt;
1238 int addrlen;
1239 int err;
1240
1241 addrlen = family == AF_INET ? sizeof(struct in_addr) :
1242 sizeof(struct in6_addr);
1243
1244 err = netlink_open(&nlh, NETLINK_ROUTE);
1245 if (err)
1246 return err;
1247
1248 err = -ENOMEM;
1249 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1250 if (!nlmsg)
1251 goto out;
1252
1253 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
1254 if (!answer)
1255 goto out;
1256
1257 nlmsg->nlmsghdr->nlmsg_flags =
1258 NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL;
1259 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWROUTE;
1260
1261 rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
1262 rt->rtm_family = family;
1263 rt->rtm_table = RT_TABLE_MAIN;
1264 rt->rtm_scope = RT_SCOPE_UNIVERSE;
1265 rt->rtm_protocol = RTPROT_BOOT;
1266 rt->rtm_type = RTN_UNICAST;
1267 /* "default" destination */
1268 rt->rtm_dst_len = 0;
1269
1270 err = -EINVAL;
1271 if (nla_put_buffer(nlmsg, RTA_GATEWAY, gw, addrlen))
1272 goto out;
1273
1274 /* Adding the interface index enables the use of link-local
1275 * addresses for the gateway */
1276 if (nla_put_u32(nlmsg, RTA_OIF, ifindex))
1277 goto out;
1278
1279 err = netlink_transaction(&nlh, nlmsg, answer);
1280 out:
1281 netlink_close(&nlh);
1282 nlmsg_free(answer);
1283 nlmsg_free(nlmsg);
1284 return err;
1285 }
1286
1287 int lxc_ipv4_gateway_add(int ifindex, struct in_addr *gw)
1288 {
1289 return ip_gateway_add(AF_INET, ifindex, gw);
1290 }
1291
1292 int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw)
1293 {
1294 return ip_gateway_add(AF_INET6, ifindex, gw);
1295 }
1296
1297 static int ip_route_dest_add(int family, int ifindex, void *dest)
1298 {
1299 struct nl_handler nlh;
1300 struct nlmsg *nlmsg = NULL, *answer = NULL;
1301 struct rtmsg *rt;
1302 int addrlen;
1303 int err;
1304
1305 addrlen = family == AF_INET ? sizeof(struct in_addr) :
1306 sizeof(struct in6_addr);
1307
1308 err = netlink_open(&nlh, NETLINK_ROUTE);
1309 if (err)
1310 return err;
1311
1312 err = -ENOMEM;
1313 nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
1314 if (!nlmsg)
1315 goto out;
1316
1317 answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
1318 if (!answer)
1319 goto out;
1320
1321 nlmsg->nlmsghdr->nlmsg_flags =
1322 NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL;
1323 nlmsg->nlmsghdr->nlmsg_type = RTM_NEWROUTE;
1324
1325 rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
1326 rt->rtm_family = family;
1327 rt->rtm_table = RT_TABLE_MAIN;
1328 rt->rtm_scope = RT_SCOPE_LINK;
1329 rt->rtm_protocol = RTPROT_BOOT;
1330 rt->rtm_type = RTN_UNICAST;
1331 rt->rtm_dst_len = addrlen*8;
1332
1333 err = -EINVAL;
1334 if (nla_put_buffer(nlmsg, RTA_DST, dest, addrlen))
1335 goto out;
1336 if (nla_put_u32(nlmsg, RTA_OIF, ifindex))
1337 goto out;
1338 err = netlink_transaction(&nlh, nlmsg, answer);
1339 out:
1340 netlink_close(&nlh);
1341 nlmsg_free(answer);
1342 nlmsg_free(nlmsg);
1343 return err;
1344 }
1345
1346 int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest)
1347 {
1348 return ip_route_dest_add(AF_INET, ifindex, dest);
1349 }
1350
1351 int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
1352 {
1353 return ip_route_dest_add(AF_INET6, ifindex, dest);
1354 }
1355
1356 static bool is_ovs_bridge(const char *bridge)
1357 {
1358 char brdirname[22 + IFNAMSIZ + 1] = {0};
1359 struct stat sb;
1360
1361 snprintf(brdirname, 22 +IFNAMSIZ + 1, "/sys/class/net/%s/bridge", bridge);
1362 if (stat(brdirname, &sb) == -1 && errno == ENOENT)
1363 return true;
1364 return false;
1365 }
1366
1367 static int attach_to_ovs_bridge(const char *bridge, const char *nic)
1368 {
1369 pid_t pid;
1370 char *cmd;
1371
1372 cmd = on_path("ovs-vsctl", NULL);
1373 if (!cmd)
1374 return -1;
1375 free(cmd);
1376
1377 pid = fork();
1378 if (pid < 0)
1379 return -1;
1380 if (pid > 0)
1381 return wait_for_pid(pid);
1382
1383 if (execlp("ovs-vsctl", "ovs-vsctl", "add-port", bridge, nic, NULL))
1384 exit(1);
1385 // not reached
1386 exit(1);
1387 }
1388
1389 /*
1390 * There is a lxc_bridge_attach, but no need of a bridge detach
1391 * as automatically done by kernel when a netdev is deleted.
1392 */
1393 int lxc_bridge_attach(const char *bridge, const char *ifname)
1394 {
1395 int fd, index, err;
1396 struct ifreq ifr;
1397
1398 if (strlen(ifname) >= IFNAMSIZ)
1399 return -EINVAL;
1400
1401 index = if_nametoindex(ifname);
1402 if (!index)
1403 return -EINVAL;
1404
1405 if (is_ovs_bridge(bridge))
1406 return attach_to_ovs_bridge(bridge, ifname);
1407
1408 fd = socket(AF_INET, SOCK_STREAM, 0);
1409 if (fd < 0)
1410 return -errno;
1411
1412 strncpy(ifr.ifr_name, bridge, IFNAMSIZ-1);
1413 ifr.ifr_name[IFNAMSIZ-1] = '\0';
1414 ifr.ifr_ifindex = index;
1415 err = ioctl(fd, SIOCBRADDIF, &ifr);
1416 close(fd);
1417 if (err)
1418 err = -errno;
1419
1420 return err;
1421 }
1422
1423 static const char* const lxc_network_types[LXC_NET_MAXCONFTYPE + 1] = {
1424 [LXC_NET_EMPTY] = "empty",
1425 [LXC_NET_VETH] = "veth",
1426 [LXC_NET_MACVLAN] = "macvlan",
1427 [LXC_NET_PHYS] = "phys",
1428 [LXC_NET_VLAN] = "vlan",
1429 [LXC_NET_NONE] = "none",
1430 };
1431
1432 const char *lxc_net_type_to_str(int type)
1433 {
1434 if (type < 0 || type > LXC_NET_MAXCONFTYPE)
1435 return NULL;
1436 return lxc_network_types[type];
1437 }
1438
1439 static const char padchar[] =
1440 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1441
1442 char *lxc_mkifname(char *template)
1443 {
1444 char *name = NULL;
1445 int i = 0;
1446 FILE *urandom;
1447 unsigned int seed;
1448 struct ifaddrs *ifaddr, *ifa;
1449 int ifexists = 0;
1450
1451 /* Get all the network interfaces */
1452 getifaddrs(&ifaddr);
1453
1454 /* Initialize the random number generator */
1455 urandom = fopen ("/dev/urandom", "r");
1456 if (urandom != NULL) {
1457 if (fread (&seed, sizeof(seed), 1, urandom) <= 0)
1458 seed = time(0);
1459 fclose(urandom);
1460 }
1461 else
1462 seed = time(0);
1463
1464 #ifndef HAVE_RAND_R
1465 srand(seed);
1466 #endif
1467
1468 /* Generate random names until we find one that doesn't exist */
1469 while(1) {
1470 ifexists = 0;
1471 name = strdup(template);
1472
1473 if (name == NULL)
1474 return NULL;
1475
1476 for (i = 0; i < strlen(name); i++) {
1477 if (name[i] == 'X') {
1478 #ifdef HAVE_RAND_R
1479 name[i] = padchar[rand_r(&seed) % (strlen(padchar) - 1)];
1480 #else
1481 name[i] = padchar[rand() % (strlen(padchar) - 1)];
1482 #endif
1483 }
1484 }
1485
1486 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
1487 if (strcmp(ifa->ifa_name, name) == 0) {
1488 ifexists = 1;
1489 break;
1490 }
1491 }
1492
1493 if (ifexists == 0)
1494 break;
1495
1496 free(name);
1497 }
1498
1499 freeifaddrs(ifaddr);
1500 return name;
1501 }
1502
1503 int setup_private_host_hw_addr(char *veth1)
1504 {
1505 struct ifreq ifr;
1506 int err;
1507 int sockfd;
1508
1509 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
1510 if (sockfd < 0)
1511 return -errno;
1512
1513 snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
1514 err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
1515 if (err < 0) {
1516 close(sockfd);
1517 return -errno;
1518 }
1519
1520 ifr.ifr_hwaddr.sa_data[0] = 0xfe;
1521 err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
1522 close(sockfd);
1523 if (err < 0)
1524 return -errno;
1525
1526 return 0;
1527 }