]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/network.c
cb2a8c0fd787f6c73a41a1fdde68d7311096b274
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
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.
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.
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
34 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/param.h>
38 #include <sys/ioctl.h>
39 #include <arpa/inet.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>
56 #include <../include/ifaddrs.h>
60 # define IFLA_LINKMODE 17
64 # define IFLA_LINKINFO 18
67 #ifndef IFLA_NET_NS_PID
68 # define IFLA_NET_NS_PID 19
71 #ifndef IFLA_INFO_KIND
72 # define IFLA_INFO_KIND 1
76 # define IFLA_VLAN_ID 1
79 #ifndef IFLA_INFO_DATA
80 # define IFLA_INFO_DATA 2
83 #ifndef VETH_INFO_PEER
84 # define VETH_INFO_PEER 1
87 #ifndef IFLA_MACVLAN_MODE
88 # define IFLA_MACVLAN_MODE 1
92 int lxc_netdev_move_by_index(int ifindex
, pid_t pid
, const char* ifname
)
94 struct nl_handler nlh
;
95 struct nlmsg
*nlmsg
= NULL
;
96 struct ifinfomsg
*ifi
;
99 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
104 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
108 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
|NLM_F_ACK
;
109 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
111 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
112 ifi
->ifi_family
= AF_UNSPEC
;
113 ifi
->ifi_index
= ifindex
;
115 if (nla_put_u32(nlmsg
, IFLA_NET_NS_PID
, pid
))
118 if (ifname
!= NULL
) {
119 if (nla_put_string(nlmsg
, IFLA_IFNAME
, ifname
))
123 err
= netlink_transaction(&nlh
, nlmsg
, nlmsg
);
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
137 #define PHYSNAME "/sys/class/net/%s/phy80211/name"
138 static char * is_wlan(const char *ifname
)
140 char *path
, *physname
= NULL
;
141 size_t len
= strlen(ifname
) + strlen(PHYSNAME
) - 1;
147 path
= alloca(len
+1);
148 ret
= snprintf(path
, len
, PHYSNAME
, ifname
);
149 if (ret
< 0 || ret
>= len
)
151 ret
= stat(path
, &sb
);
154 if (!(f
= fopen(path
, "r")))
156 // feh - sb.st_size is always 4096
157 fseek(f
, 0, SEEK_END
);
159 fseek(f
, 0, SEEK_SET
);
160 physname
= malloc(physlen
+1);
163 memset(physname
, 0, physlen
+1);
164 ret
= fread(physname
, 1, physlen
, f
);
169 for (i
= 0; i
< physlen
; i
++) {
170 if (physname
[i
] == '\n')
172 if (physname
[i
] == '\0')
185 lxc_netdev_rename_by_name_in_netns(pid_t pid
, const char *old
, const char *new)
192 return wait_for_pid(fpid
);
193 if (!switch_to_ns(pid
, "net"))
195 exit(lxc_netdev_rename_by_name(old
, new));
199 lxc_netdev_move_wlan(char *physname
, const char *ifname
, pid_t pid
, const char* newname
)
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
209 cmd
= on_path("iw", NULL
);
219 sprintf(pidstr
, "%d", pid
);
220 if (execlp("iw", "iw", "phy", physname
, "set", "netns", pidstr
, NULL
))
222 exit(0); // notreached
224 if (wait_for_pid(fpid
))
229 err
= lxc_netdev_rename_by_name_in_netns(pid
, ifname
, newname
);
236 int lxc_netdev_move_by_name(const char *ifname
, pid_t pid
, const char* newname
)
244 index
= if_nametoindex(ifname
);
248 if ((physname
= is_wlan(ifname
)))
249 return lxc_netdev_move_wlan(physname
, ifname
, pid
, newname
);
251 return lxc_netdev_move_by_index(index
, pid
, newname
);
254 int lxc_netdev_delete_by_index(int ifindex
)
256 struct nl_handler nlh
;
257 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
258 struct ifinfomsg
*ifi
;
261 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
266 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
270 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
274 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_ACK
|NLM_F_REQUEST
;
275 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_DELLINK
;
277 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
278 ifi
->ifi_family
= AF_UNSPEC
;
279 ifi
->ifi_index
= ifindex
;
281 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
289 int lxc_netdev_delete_by_name(const char *name
)
293 index
= if_nametoindex(name
);
297 return lxc_netdev_delete_by_index(index
);
300 int lxc_netdev_rename_by_index(int ifindex
, const char *newname
)
302 struct nl_handler nlh
;
303 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
304 struct ifinfomsg
*ifi
;
307 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
311 len
= strlen(newname
);
312 if (len
== 1 || len
>= IFNAMSIZ
)
316 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
320 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
324 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_ACK
|NLM_F_REQUEST
;
325 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
327 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
328 ifi
->ifi_family
= AF_UNSPEC
;
329 ifi
->ifi_index
= ifindex
;
331 if (nla_put_string(nlmsg
, IFLA_IFNAME
, newname
))
334 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
342 int lxc_netdev_rename_by_name(const char *oldname
, const char *newname
)
346 len
= strlen(oldname
);
347 if (len
== 1 || len
>= IFNAMSIZ
)
350 index
= if_nametoindex(oldname
);
354 return lxc_netdev_rename_by_index(index
, newname
);
357 int netdev_set_flag(const char *name
, int flag
)
359 struct nl_handler nlh
;
360 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
361 struct ifinfomsg
*ifi
;
364 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
370 if (len
== 1 || len
>= IFNAMSIZ
)
374 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
378 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
383 index
= if_nametoindex(name
);
387 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
|NLM_F_ACK
;
388 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
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
;
396 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
404 int netdev_get_flag(const char* name
, int *flag
)
406 struct nl_handler nlh
;
407 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
408 struct ifinfomsg
*ifi
;
414 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
420 if (len
== 1 || len
>= IFNAMSIZ
)
424 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
428 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
433 index
= if_nametoindex(name
);
437 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
;
438 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETLINK
;
440 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
441 ifi
->ifi_family
= AF_UNSPEC
;
442 ifi
->ifi_index
= index
;
444 nlmsg_reserve(answer
, sizeof(struct ifinfomsg
));
446 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
450 ifi
= NLMSG_DATA(answer
);
452 *flag
= ifi
->ifi_flags
;
461 * \brief Check a interface is up or not.
463 * \param name: name for the interface.
466 * 0 means interface is down.
467 * 1 means interface is up.
468 * Others means error happened, and ret-value is the error number.
470 int lxc_netdev_isup(const char* name
)
475 err
= netdev_get_flag(name
, &flag
);
485 int netdev_get_mtu(int ifindex
)
487 struct nl_handler nlh
;
488 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
489 struct ifinfomsg
*ifi
;
490 struct nlmsghdr
*msg
;
492 int recv_len
= 0, answer_len
;
495 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
500 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
504 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
508 /* Save the answer buffer length, since it will be overwritten
509 * on the first receive (and we might need to receive more than
511 nlmsg_reserve(answer
, NLMSG_GOOD_SIZE
);
512 answer_len
= answer
->nlmsghdr
->nlmsg_len
;
514 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
|NLM_F_DUMP
;
515 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETLINK
;
517 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
518 ifi
->ifi_family
= AF_UNSPEC
;
520 /* Send the request for addresses, which returns all addresses
521 * on all interfaces. */
522 err
= netlink_send(&nlh
, nlmsg
);
527 /* Restore the answer buffer length, it might have been
528 * overwritten by a previous receive. */
529 answer
->nlmsghdr
->nlmsg_len
= answer_len
;
531 /* Get the (next) batch of reply messages */
532 err
= netlink_rcv(&nlh
, answer
);
539 /* Satisfy the typing for the netlink macros */
540 msg
= answer
->nlmsghdr
;
542 while (NLMSG_OK(msg
, recv_len
)) {
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
);
551 /* Stop reading if we see a NLMSG_DONE message */
552 if (msg
->nlmsg_type
== NLMSG_DONE
) {
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
));
562 while(RTA_OK(rta
, attr_len
)) {
563 /* Found a local address for the requested interface,
565 if (rta
->rta_type
== IFLA_MTU
) {
566 memcpy(&res
, RTA_DATA(rta
), sizeof(int));
570 rta
= RTA_NEXT(rta
, attr_len
);
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
);
579 /* Look at the next message received in this buffer */
580 msg
= NLMSG_NEXT(msg
, recv_len
);
584 /* If we end up here, we didn't find any result, so signal an
595 int lxc_netdev_set_mtu(const char *name
, int mtu
)
597 struct nl_handler nlh
;
598 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
599 struct ifinfomsg
*ifi
;
602 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
608 if (len
== 1 || len
>= IFNAMSIZ
)
612 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
616 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
621 index
= if_nametoindex(name
);
625 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
|NLM_F_ACK
;
626 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_NEWLINK
;
628 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
629 ifi
->ifi_family
= AF_UNSPEC
;
630 ifi
->ifi_index
= index
;
632 if (nla_put_u32(nlmsg
, IFLA_MTU
, mtu
))
635 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
643 int lxc_netdev_up(const char *name
)
645 return netdev_set_flag(name
, IFF_UP
);
648 int lxc_netdev_down(const char *name
)
650 return netdev_set_flag(name
, 0);
653 int lxc_veth_create(const char *name1
, const char *name2
)
655 struct nl_handler nlh
;
656 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
657 struct ifinfomsg
*ifi
;
658 struct rtattr
*nest1
, *nest2
, *nest3
;
661 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
667 if (len
== 1 || len
>= IFNAMSIZ
)
671 if (len
== 1 || len
>= IFNAMSIZ
)
675 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
679 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
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
;
687 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
688 ifi
->ifi_family
= AF_UNSPEC
;
691 nest1
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
695 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "veth"))
698 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
702 nest3
= nla_begin_nested(nlmsg
, VETH_INFO_PEER
);
706 nlmsg
->nlmsghdr
->nlmsg_len
+= sizeof(struct ifinfomsg
);
708 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name2
))
711 nla_end_nested(nlmsg
, nest3
);
713 nla_end_nested(nlmsg
, nest2
);
715 nla_end_nested(nlmsg
, nest1
);
717 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name1
))
720 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
728 /* XXX: merge with lxc_macvlan_create */
729 int lxc_vlan_create(const char *master
, const char *name
, unsigned short vlanid
)
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
;
737 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
742 len
= strlen(master
);
743 if (len
== 1 || len
>= IFNAMSIZ
)
747 if (len
== 1 || len
>= IFNAMSIZ
)
751 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
755 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
760 lindex
= if_nametoindex(master
);
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
;
768 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
769 ifi
->ifi_family
= AF_UNSPEC
;
771 nest
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
775 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "vlan"))
778 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
782 if (nla_put_u16(nlmsg
, IFLA_VLAN_ID
, vlanid
))
785 nla_end_nested(nlmsg
, nest2
);
787 nla_end_nested(nlmsg
, nest
);
789 if (nla_put_u32(nlmsg
, IFLA_LINK
, lindex
))
792 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name
))
795 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
805 int lxc_macvlan_create(const char *master
, const char *name
, int mode
)
807 struct nl_handler nlh
;
808 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
809 struct ifinfomsg
*ifi
;
810 struct rtattr
*nest
, *nest2
;
813 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
818 len
= strlen(master
);
819 if (len
== 1 || len
>= IFNAMSIZ
)
823 if (len
== 1 || len
>= IFNAMSIZ
)
827 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
831 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
836 index
= if_nametoindex(master
);
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
;
844 ifi
= nlmsg_reserve(nlmsg
, sizeof(struct ifinfomsg
));
845 ifi
->ifi_family
= AF_UNSPEC
;
847 nest
= nla_begin_nested(nlmsg
, IFLA_LINKINFO
);
851 if (nla_put_string(nlmsg
, IFLA_INFO_KIND
, "macvlan"))
855 nest2
= nla_begin_nested(nlmsg
, IFLA_INFO_DATA
);
859 if (nla_put_u32(nlmsg
, IFLA_MACVLAN_MODE
, mode
))
862 nla_end_nested(nlmsg
, nest2
);
865 nla_end_nested(nlmsg
, nest
);
867 if (nla_put_u32(nlmsg
, IFLA_LINK
, index
))
870 if (nla_put_string(nlmsg
, IFLA_IFNAME
, name
))
873 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
881 static int proc_sys_net_write(const char *path
, const char *value
)
885 fd
= open(path
, O_WRONLY
);
889 if (write(fd
, value
, strlen(value
)) < 0)
896 static int ip_forward_set(const char *ifname
, int family
, int flag
)
898 char path
[MAXPATHLEN
];
901 if (family
!= AF_INET
&& family
!= AF_INET6
)
904 rc
= snprintf(path
, MAXPATHLEN
, "/proc/sys/net/%s/conf/%s/forwarding",
905 family
== AF_INET
?"ipv4":"ipv6" , ifname
);
906 if (rc
>= MAXPATHLEN
)
909 return proc_sys_net_write(path
, flag
?"1":"0");
912 int lxc_ip_forward_on(const char *ifname
, int family
)
914 return ip_forward_set(ifname
, family
, 1);
917 int lxc_ip_forward_off(const char *ifname
, int family
)
919 return ip_forward_set(ifname
, family
, 0);
922 static int neigh_proxy_set(const char *ifname
, int family
, int flag
)
924 char path
[MAXPATHLEN
];
927 if (family
!= AF_INET
&& family
!= AF_INET6
)
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
)
936 return proc_sys_net_write(path
, flag
?"1":"0");
939 int lxc_neigh_proxy_on(const char *name
, int family
)
941 return neigh_proxy_set(name
, family
, 1);
944 int lxc_neigh_proxy_off(const char *name
, int family
)
946 return neigh_proxy_set(name
, family
, 0);
949 int lxc_convert_mac(char *macaddr
, struct sockaddr
*sockaddr
)
956 sockaddr
->sa_family
= ARPHRD_ETHER
;
957 data
= (unsigned char *)sockaddr
->sa_data
;
959 while ((*macaddr
!= '\0') && (i
< ETH_ALEN
)) {
964 else if (c
>= 'a' && c
<= 'f')
966 else if (c
>= 'A' && c
<= 'F')
975 else if (c
>= 'a' && c
<= 'f')
977 else if (c
>= 'A' && c
<= 'F')
979 else if (c
== ':' || c
== 0)
986 *data
++ = (unsigned char) (val
& 0377);
996 static int ip_addr_add(int family
, int ifindex
,
997 void *addr
, void *bcast
, void *acast
, int prefix
)
999 struct nl_handler nlh
;
1000 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
1001 struct ifaddrmsg
*ifa
;
1005 addrlen
= family
== AF_INET
? sizeof(struct in_addr
) :
1006 sizeof(struct in6_addr
);
1008 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1013 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1017 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
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
;
1025 ifa
= nlmsg_reserve(nlmsg
, sizeof(struct ifaddrmsg
));
1026 ifa
->ifa_prefixlen
= prefix
;
1027 ifa
->ifa_index
= ifindex
;
1028 ifa
->ifa_family
= family
;
1032 if (nla_put_buffer(nlmsg
, IFA_LOCAL
, addr
, addrlen
))
1035 if (nla_put_buffer(nlmsg
, IFA_ADDRESS
, addr
, addrlen
))
1038 if (nla_put_buffer(nlmsg
, IFA_BROADCAST
, bcast
, addrlen
))
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
))))
1048 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1050 netlink_close(&nlh
);
1056 int lxc_ipv6_addr_add(int ifindex
, struct in6_addr
*addr
,
1057 struct in6_addr
*mcast
,
1058 struct in6_addr
*acast
, int prefix
)
1060 return ip_addr_add(AF_INET6
, ifindex
, addr
, mcast
, acast
, prefix
);
1063 int lxc_ipv4_addr_add(int ifindex
, struct in_addr
*addr
,
1064 struct in_addr
*bcast
, int prefix
)
1066 return ip_addr_add(AF_INET
, ifindex
, addr
, bcast
, NULL
, prefix
);
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**).
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
));
1080 if (ifa
->ifa_family
!= family
)
1083 addrlen
= family
== AF_INET
? sizeof(struct in_addr
) :
1084 sizeof(struct in6_addr
);
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,
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
)
1097 /* We might have found an IFA_ADDRESS before,
1098 * which we now overwrite with an IFA_LOCAL. */
1100 *res
= malloc(addrlen
);
1105 memcpy(*res
, RTA_DATA(rta
), addrlen
);
1107 if (rta
->rta_type
== IFA_LOCAL
)
1110 rta
= RTA_NEXT(rta
, attr_len
);
1115 static int ip_addr_get(int family
, int ifindex
, void **res
)
1117 struct nl_handler nlh
;
1118 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
1119 struct ifaddrmsg
*ifa
;
1120 struct nlmsghdr
*msg
;
1122 int recv_len
= 0, answer_len
;
1125 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1130 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1134 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1138 /* Save the answer buffer length, since it will be overwritten
1139 * on the first receive (and we might need to receive more than
1141 nlmsg_reserve(answer
, NLMSG_GOOD_SIZE
);
1142 answer_len
= answer
->nlmsghdr
->nlmsg_len
;
1144 nlmsg
->nlmsghdr
->nlmsg_flags
= NLM_F_REQUEST
|NLM_F_ROOT
;
1145 nlmsg
->nlmsghdr
->nlmsg_type
= RTM_GETADDR
;
1147 ifa
= nlmsg_reserve(nlmsg
, sizeof(struct ifaddrmsg
));
1148 ifa
->ifa_family
= family
;
1150 /* Send the request for addresses, which returns all addresses
1151 * on all interfaces. */
1152 err
= netlink_send(&nlh
, nlmsg
);
1157 /* Restore the answer buffer length, it might have been
1158 * overwritten by a previous receive. */
1159 answer
->nlmsghdr
->nlmsg_len
= answer_len
;
1161 /* Get the (next) batch of reply messages */
1162 err
= netlink_rcv(&nlh
, answer
);
1169 /* Satisfy the typing for the netlink macros */
1170 msg
= answer
->nlmsghdr
;
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
;
1180 /* Stop reading if we see a NLMSG_DONE message */
1181 if (msg
->nlmsg_type
== NLMSG_DONE
) {
1186 if (msg
->nlmsg_type
!= RTM_NEWADDR
) {
1191 ifa
= (struct ifaddrmsg
*)NLMSG_DATA(msg
);
1192 if (ifa
->ifa_index
== ifindex
) {
1193 if (ifa_get_local_ip(family
, msg
, res
) < 0) {
1198 /* Found a result, stop searching */
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
);
1207 /* Look at the next message received in this buffer */
1208 msg
= NLMSG_NEXT(msg
, recv_len
);
1212 /* If we end up here, we didn't find any result, so signal an
1217 netlink_close(&nlh
);
1223 int lxc_ipv6_addr_get(int ifindex
, struct in6_addr
**res
)
1225 return ip_addr_get(AF_INET6
, ifindex
, (void**)res
);
1228 int lxc_ipv4_addr_get(int ifindex
, struct in_addr
** res
)
1230 return ip_addr_get(AF_INET
, ifindex
, (void**)res
);
1233 static int ip_gateway_add(int family
, int ifindex
, void *gw
)
1235 struct nl_handler nlh
;
1236 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
1241 addrlen
= family
== AF_INET
? sizeof(struct in_addr
) :
1242 sizeof(struct in6_addr
);
1244 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1249 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1253 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
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
;
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;
1271 if (nla_put_buffer(nlmsg
, RTA_GATEWAY
, gw
, addrlen
))
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
))
1279 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1281 netlink_close(&nlh
);
1287 int lxc_ipv4_gateway_add(int ifindex
, struct in_addr
*gw
)
1289 return ip_gateway_add(AF_INET
, ifindex
, gw
);
1292 int lxc_ipv6_gateway_add(int ifindex
, struct in6_addr
*gw
)
1294 return ip_gateway_add(AF_INET6
, ifindex
, gw
);
1297 static int ip_route_dest_add(int family
, int ifindex
, void *dest
)
1299 struct nl_handler nlh
;
1300 struct nlmsg
*nlmsg
= NULL
, *answer
= NULL
;
1305 addrlen
= family
== AF_INET
? sizeof(struct in_addr
) :
1306 sizeof(struct in6_addr
);
1308 err
= netlink_open(&nlh
, NETLINK_ROUTE
);
1313 nlmsg
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
1317 answer
= nlmsg_alloc(NLMSG_GOOD_SIZE
);
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
;
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;
1334 if (nla_put_buffer(nlmsg
, RTA_DST
, dest
, addrlen
))
1336 if (nla_put_u32(nlmsg
, RTA_OIF
, ifindex
))
1338 err
= netlink_transaction(&nlh
, nlmsg
, answer
);
1340 netlink_close(&nlh
);
1346 int lxc_ipv4_dest_add(int ifindex
, struct in_addr
*dest
)
1348 return ip_route_dest_add(AF_INET
, ifindex
, dest
);
1351 int lxc_ipv6_dest_add(int ifindex
, struct in6_addr
*dest
)
1353 return ip_route_dest_add(AF_INET6
, ifindex
, dest
);
1356 static bool is_ovs_bridge(const char *bridge
)
1358 char brdirname
[22 + IFNAMSIZ
+ 1] = {0};
1361 snprintf(brdirname
, 22 +IFNAMSIZ
+ 1, "/sys/class/net/%s/bridge", bridge
);
1362 if (stat(brdirname
, &sb
) == -1 && errno
== ENOENT
)
1367 static int attach_to_ovs_bridge(const char *bridge
, const char *nic
)
1372 cmd
= on_path("ovs-vsctl", NULL
);
1381 return wait_for_pid(pid
);
1383 if (execlp("ovs-vsctl", "ovs-vsctl", "add-port", bridge
, nic
, NULL
))
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.
1393 int lxc_bridge_attach(const char *bridge
, const char *ifname
)
1398 if (strlen(ifname
) >= IFNAMSIZ
)
1401 index
= if_nametoindex(ifname
);
1405 if (is_ovs_bridge(bridge
))
1406 return attach_to_ovs_bridge(bridge
, ifname
);
1408 fd
= socket(AF_INET
, SOCK_STREAM
, 0);
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
);
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",
1432 const char *lxc_net_type_to_str(int type
)
1434 if (type
< 0 || type
> LXC_NET_MAXCONFTYPE
)
1436 return lxc_network_types
[type
];
1439 static const char padchar
[] =
1440 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1442 char *lxc_mkifname(char *template)
1448 struct ifaddrs
*ifaddr
, *ifa
;
1451 /* Get all the network interfaces */
1452 getifaddrs(&ifaddr
);
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)
1468 /* Generate random names until we find one that doesn't exist */
1471 name
= strdup(template);
1476 for (i
= 0; i
< strlen(name
); i
++) {
1477 if (name
[i
] == 'X') {
1479 name
[i
] = padchar
[rand_r(&seed
) % (strlen(padchar
) - 1)];
1481 name
[i
] = padchar
[rand() % (strlen(padchar
) - 1)];
1486 for (ifa
= ifaddr
; ifa
!= NULL
; ifa
= ifa
->ifa_next
) {
1487 if (strcmp(ifa
->ifa_name
, name
) == 0) {
1499 freeifaddrs(ifaddr
);
1503 int setup_private_host_hw_addr(char *veth1
)
1509 sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
1513 snprintf((char *)ifr
.ifr_name
, IFNAMSIZ
, "%s", veth1
);
1514 err
= ioctl(sockfd
, SIOCGIFHWADDR
, &ifr
);
1520 ifr
.ifr_hwaddr
.sa_data
[0] = 0xfe;
1521 err
= ioctl(sockfd
, SIOCSIFHWADDR
, &ifr
);