2 * netifd - network interface daemon
3 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
4 * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
5 * Copyright (C) 2013 Steven Barth <steven@midlink.org>
6 * Copyright (C) 2014 Gioacchino Mazzurco <gio@eigenlab.org>
7 * Copyright (C) 2017 Matthias Schiffer <mschiffer@universe-factory.net>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2
11 * as published by the Free Software Foundation
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
20 #include <sys/socket.h>
21 #include <sys/ioctl.h>
23 #include <sys/syscall.h>
26 #include <net/if_arp.h>
28 #include <arpa/inet.h>
29 #include <netinet/ether.h>
30 #include <netinet/in.h>
32 #include <linux/rtnetlink.h>
33 #include <linux/sockios.h>
35 #include <linux/if_addr.h>
36 #include <linux/if_link.h>
37 #include <linux/if_vlan.h>
38 #include <linux/if_bridge.h>
39 #include <linux/if_tunnel.h>
40 #include <linux/ip6_tunnel.h>
41 #include <linux/ethtool.h>
42 #include <linux/fib_rules.h>
43 #include <linux/veth.h>
44 #include <linux/version.h>
46 #ifndef RTN_FAILED_POLICY
47 #define RTN_FAILED_POLICY 12
50 #ifndef IFA_F_NOPREFIXROUTE
51 #define IFA_F_NOPREFIXROUTE 0x200
55 #define IFA_FLAGS (IFA_MULTICAST + 1)
64 #include <netlink/msg.h>
65 #include <netlink/attr.h>
66 #include <netlink/socket.h>
67 #include <libubox/uloop.h>
74 struct uloop_fd uloop;
79 static int sock_ioctl = -1;
80 static struct nl_sock *sock_rtnl = NULL;
82 static int cb_rtnl_event(struct nl_msg *msg, void *arg);
83 static void handle_hotplug_event(struct uloop_fd *u, unsigned int events);
84 static int system_add_proto_tunnel(const char *name, const uint8_t proto,
85 const unsigned int link, struct blob_attr **tb);
86 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb);
88 static char dev_buf[256];
91 handler_nl_event(struct uloop_fd *u, unsigned int events)
93 struct event_socket *ev = container_of(u, struct event_socket, uloop);
95 socklen_t errlen = sizeof(err);
98 nl_recvmsgs_default(ev->sock);
102 if (getsockopt(u->fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen))
107 // Increase rx buffer size on netlink socket
109 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
112 // Request full dump since some info got dropped
113 struct rtgenmsg msg = { .rtgen_family = AF_UNSPEC };
114 nl_send_simple(ev->sock, RTM_GETLINK, NLM_F_DUMP, &msg, sizeof(msg));
124 uloop_fd_delete(&ev->uloop);
128 static struct nl_sock *
129 create_socket(int protocol, int groups)
131 struct nl_sock *sock;
133 sock = nl_socket_alloc();
138 nl_join_groups(sock, groups);
140 if (nl_connect(sock, protocol))
147 create_raw_event_socket(struct event_socket *ev, int protocol, int groups,
148 uloop_fd_handler cb, int flags)
150 ev->sock = create_socket(protocol, groups);
154 ev->uloop.fd = nl_socket_get_fd(ev->sock);
156 if (uloop_fd_add(&ev->uloop, ULOOP_READ|flags))
163 create_event_socket(struct event_socket *ev, int protocol,
164 int (*cb)(struct nl_msg *msg, void *arg))
166 if (!create_raw_event_socket(ev, protocol, 0, handler_nl_event, ULOOP_ERROR_CB))
169 // Install the valid custom callback handler
170 nl_socket_modify_cb(ev->sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL);
172 // Disable sequence number checking on event sockets
173 nl_socket_disable_seq_check(ev->sock);
175 // Increase rx buffer size to 65K on event sockets
177 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
184 system_rtn_aton(const char *src, unsigned int *dst)
189 if (!strcmp(src, "local"))
191 else if (!strcmp(src, "nat"))
193 else if (!strcmp(src, "broadcast"))
195 else if (!strcmp(src, "anycast"))
197 else if (!strcmp(src, "multicast"))
199 else if (!strcmp(src, "prohibit"))
201 else if (!strcmp(src, "unreachable"))
203 else if (!strcmp(src, "blackhole"))
205 else if (!strcmp(src, "xresolve"))
207 else if (!strcmp(src, "unicast"))
209 else if (!strcmp(src, "throw"))
211 else if (!strcmp(src, "failed_policy"))
212 n = RTN_FAILED_POLICY;
214 n = strtoul(src, &e, 0);
215 if (!e || *e || e == src || n > 255)
224 system_tos_aton(const char *src, unsigned *dst)
228 *dst = strtoul(src, &e, 16);
229 if (e == src || *e || *dst > 255)
235 int system_init(void)
237 static struct event_socket rtnl_event;
238 static struct event_socket hotplug_event;
240 sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0);
241 system_fd_set_cloexec(sock_ioctl);
243 // Prepare socket for routing / address control
244 sock_rtnl = create_socket(NETLINK_ROUTE, 0);
248 if (!create_event_socket(&rtnl_event, NETLINK_ROUTE, cb_rtnl_event))
251 if (!create_raw_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT, 1,
252 handle_hotplug_event, 0))
255 // Receive network link events form kernel
256 nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK);
261 static void system_set_sysctl(const char *path, const char *val)
265 fd = open(path, O_WRONLY);
269 if (write(fd, val, strlen(val))) {}
273 static void system_set_dev_sysctl(const char *path, const char *device, const char *val)
275 snprintf(dev_buf, sizeof(dev_buf), path, device);
276 system_set_sysctl(dev_buf, val);
279 static void system_set_disable_ipv6(struct device *dev, const char *val)
281 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6", dev->ifname, val);
284 static void system_set_rpfilter(struct device *dev, const char *val)
286 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter", dev->ifname, val);
289 static void system_set_acceptlocal(struct device *dev, const char *val)
291 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local", dev->ifname, val);
294 static void system_set_igmpversion(struct device *dev, const char *val)
296 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version", dev->ifname, val);
299 static void system_set_mldversion(struct device *dev, const char *val)
301 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version", dev->ifname, val);
304 static void system_set_neigh4reachabletime(struct device *dev, const char *val)
306 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms", dev->ifname, val);
309 static void system_set_neigh6reachabletime(struct device *dev, const char *val)
311 system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", dev->ifname, val);
314 static void system_set_neigh4gcstaletime(struct device *dev, const char *val)
316 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/gc_stale_time", dev->ifname, val);
319 static void system_set_neigh6gcstaletime(struct device *dev, const char *val)
321 system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time", dev->ifname, val);
324 static void system_set_neigh4locktime(struct device *dev, const char *val)
326 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/locktime", dev->ifname, val);
329 static void system_set_dadtransmits(struct device *dev, const char *val)
331 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits", dev->ifname, val);
334 static void system_bridge_set_multicast_to_unicast(struct device *dev, const char *val)
336 system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_to_unicast", dev->ifname, val);
339 static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val)
341 system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_fast_leave", dev->ifname, val);
344 static void system_bridge_set_hairpin_mode(struct device *dev, const char *val)
346 system_set_dev_sysctl("/sys/class/net/%s/brport/hairpin_mode", dev->ifname, val);
349 static void system_bridge_set_isolate_mode(struct device *dev, const char *val)
351 system_set_dev_sysctl("/sys/class/net/%s/brport/isolate_mode", dev->ifname, val);
354 static void system_bridge_set_multicast_router(struct device *dev, const char *val, bool bridge)
356 system_set_dev_sysctl(bridge ? "/sys/class/net/%s/bridge/multicast_router" :
357 "/sys/class/net/%s/brport/multicast_router",
361 static void system_bridge_set_robustness(struct device *dev, const char *val)
363 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_startup_query_count",
365 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_last_member_count",
369 static void system_bridge_set_query_interval(struct device *dev, const char *val)
371 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_query_interval",
375 static void system_bridge_set_query_response_interval(struct device *dev, const char *val)
377 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_query_response_interval",
381 static void system_bridge_set_last_member_interval(struct device *dev, const char *val)
383 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_last_member_interval",
387 static void system_bridge_set_membership_interval(struct device *dev, const char *val)
389 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_membership_interval",
393 static void system_bridge_set_other_querier_timeout(struct device *dev, const char *val)
395 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_querier_interval",
399 static void system_bridge_set_startup_query_interval(struct device *dev, const char *val)
401 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_startup_query_interval",
405 static void system_bridge_set_learning(struct device *dev, const char *val)
407 system_set_dev_sysctl("/sys/class/net/%s/brport/learning", dev->ifname, val);
410 static void system_bridge_set_unicast_flood(struct device *dev, const char *val)
412 system_set_dev_sysctl("/sys/class/net/%s/brport/unicast_flood", dev->ifname, val);
415 static void system_set_sendredirects(struct device *dev, const char *val)
417 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects", dev->ifname, val);
420 static int system_get_sysctl(const char *path, char *buf, const size_t buf_sz)
422 int fd = -1, ret = -1;
424 fd = open(path, O_RDONLY);
428 ssize_t len = read(fd, buf, buf_sz - 1);
442 system_get_dev_sysctl(const char *path, const char *device, char *buf, const size_t buf_sz)
444 snprintf(dev_buf, sizeof(dev_buf), path, device);
445 return system_get_sysctl(dev_buf, buf, buf_sz);
448 static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t buf_sz)
450 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6",
451 dev->ifname, buf, buf_sz);
454 static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz)
456 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter",
457 dev->ifname, buf, buf_sz);
460 static int system_get_acceptlocal(struct device *dev, char *buf, const size_t buf_sz)
462 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local",
463 dev->ifname, buf, buf_sz);
466 static int system_get_igmpversion(struct device *dev, char *buf, const size_t buf_sz)
468 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version",
469 dev->ifname, buf, buf_sz);
472 static int system_get_mldversion(struct device *dev, char *buf, const size_t buf_sz)
474 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version",
475 dev->ifname, buf, buf_sz);
478 static int system_get_neigh4reachabletime(struct device *dev, char *buf, const size_t buf_sz)
480 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms",
481 dev->ifname, buf, buf_sz);
484 static int system_get_neigh6reachabletime(struct device *dev, char *buf, const size_t buf_sz)
486 return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms",
487 dev->ifname, buf, buf_sz);
490 static int system_get_neigh4gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
492 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/gc_stale_time",
493 dev->ifname, buf, buf_sz);
496 static int system_get_neigh6gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
498 return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time",
499 dev->ifname, buf, buf_sz);
502 static int system_get_neigh4locktime(struct device *dev, char *buf, const size_t buf_sz)
504 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/locktime",
505 dev->ifname, buf, buf_sz);
508 static int system_get_dadtransmits(struct device *dev, char *buf, const size_t buf_sz)
510 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits",
511 dev->ifname, buf, buf_sz);
514 static int system_get_sendredirects(struct device *dev, char *buf, const size_t buf_sz)
516 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects",
517 dev->ifname, buf, buf_sz);
520 // Evaluate netlink messages
521 static int cb_rtnl_event(struct nl_msg *msg, void *arg)
523 struct nlmsghdr *nh = nlmsg_hdr(msg);
524 struct nlattr *nla[__IFLA_MAX];
528 if (nh->nlmsg_type != RTM_NEWLINK)
531 nlmsg_parse(nh, sizeof(struct ifinfomsg), nla, __IFLA_MAX - 1, NULL);
532 if (!nla[IFLA_IFNAME])
535 struct device *dev = device_find(nla_data(nla[IFLA_IFNAME]));
539 if (!system_get_dev_sysctl("/sys/class/net/%s/carrier", dev->ifname, buf, sizeof(buf)))
540 link_state = strtoul(buf, NULL, 0);
542 device_set_link(dev, link_state ? true : false);
549 handle_hotplug_msg(char *data, int size)
551 const char *subsystem = NULL, *interface = NULL, *interface_old = NULL;
552 char *cur, *end, *sep;
555 bool add, move = false;
557 if (!strncmp(data, "add@", 4))
559 else if (!strncmp(data, "remove@", 7))
561 else if (!strncmp(data, "move@", 5)) {
568 skip = strlen(data) + 1;
571 for (cur = data + skip; cur < end; cur += skip) {
572 skip = strlen(cur) + 1;
574 sep = strchr(cur, '=');
579 if (!strcmp(cur, "INTERFACE"))
581 else if (!strcmp(cur, "SUBSYSTEM")) {
583 if (strcmp(subsystem, "net") != 0)
585 } else if (!strcmp(cur, "DEVPATH_OLD")) {
586 interface_old = strrchr(sep + 1, '/');
592 if (subsystem && interface) {
593 if (move && interface_old)
602 dev = device_find(interface_old);
606 if (dev->type != &simple_device_type)
609 device_set_present(dev, false);
612 dev = device_find(interface);
616 if (dev->type != &simple_device_type)
619 if (add && system_if_force_external(dev->ifname))
622 device_set_present(dev, add);
626 handle_hotplug_event(struct uloop_fd *u, unsigned int events)
628 struct event_socket *ev = container_of(u, struct event_socket, uloop);
629 struct sockaddr_nl nla;
630 unsigned char *buf = NULL;
633 while ((size = nl_recv(ev->sock, &nla, &buf, NULL)) > 0) {
635 handle_hotplug_msg((char *) buf, size);
641 static int system_rtnl_call(struct nl_msg *msg)
645 ret = nl_send_auto_complete(sock_rtnl, msg);
651 return nl_wait_for_ack(sock_rtnl);
654 int system_bridge_delbr(struct device *bridge)
656 return ioctl(sock_ioctl, SIOCBRDELBR, bridge->ifname);
659 static int system_bridge_if(const char *bridge, struct device *dev, int cmd, void *data)
663 memset(&ifr, 0, sizeof(ifr));
665 ifr.ifr_ifindex = dev->ifindex;
668 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name));
669 return ioctl(sock_ioctl, cmd, &ifr);
672 static bool system_is_bridge(const char *name, char *buf, int buflen)
676 snprintf(buf, buflen, "/sys/devices/virtual/net/%s/bridge", name);
677 if (stat(buf, &st) < 0)
683 static char *system_get_bridge(const char *name, char *buf, int buflen)
689 snprintf(buf, buflen, "/sys/devices/virtual/net/*/brif/%s/bridge", name);
690 if (glob(buf, GLOB_NOSORT, NULL, &gl) < 0)
694 len = readlink(gl.gl_pathv[0], buf, buflen);
702 path = strrchr(buf, '/');
710 system_bridge_set_wireless(struct device *bridge, struct device *dev)
712 bool mcast_to_ucast = dev->wireless_ap;
715 if (bridge->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST &&
716 !bridge->settings.multicast_to_unicast)
717 mcast_to_ucast = false;
719 if (!mcast_to_ucast || dev->wireless_isolate)
722 system_bridge_set_multicast_to_unicast(dev, mcast_to_ucast ? "1" : "0");
723 system_bridge_set_hairpin_mode(dev, hairpin ? "1" : "0");
726 int system_bridge_addif(struct device *bridge, struct device *dev)
732 oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
733 if (!oldbr || strcmp(oldbr, bridge->ifname) != 0)
734 ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
737 system_bridge_set_wireless(bridge, dev);
739 if (dev->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
740 snprintf(buf, sizeof(buf), "%u", dev->settings.multicast_router);
741 system_bridge_set_multicast_router(dev, buf, false);
744 if (dev->settings.flags & DEV_OPT_MULTICAST_FAST_LEAVE &&
745 dev->settings.multicast_fast_leave)
746 system_bridge_set_multicast_fast_leave(dev, "1");
748 if (dev->settings.flags & DEV_OPT_LEARNING &&
749 !dev->settings.learning)
750 system_bridge_set_learning(dev, "0");
752 if (dev->settings.flags & DEV_OPT_UNICAST_FLOOD &&
753 !dev->settings.unicast_flood)
754 system_bridge_set_unicast_flood(dev, "0");
756 if (dev->settings.flags & DEV_OPT_ISOLATE &&
757 dev->settings.isolate)
758 system_bridge_set_isolate_mode(dev, "1");
763 int system_bridge_delif(struct device *bridge, struct device *dev)
765 return system_bridge_if(bridge->ifname, dev, SIOCBRDELIF, NULL);
768 int system_if_resolve(struct device *dev)
771 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
772 if (!ioctl(sock_ioctl, SIOCGIFINDEX, &ifr))
773 return ifr.ifr_ifindex;
778 static int system_if_flags(const char *ifname, unsigned add, unsigned rem)
782 memset(&ifr, 0, sizeof(ifr));
783 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
784 ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr);
785 ifr.ifr_flags |= add;
786 ifr.ifr_flags &= ~rem;
787 return ioctl(sock_ioctl, SIOCSIFFLAGS, &ifr);
799 static bool check_ifaddr(struct nlmsghdr *hdr, int ifindex)
801 struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
803 return ifa->ifa_index == ifindex;
806 static bool check_route(struct nlmsghdr *hdr, int ifindex)
808 struct rtmsg *r = NLMSG_DATA(hdr);
809 struct nlattr *tb[__RTA_MAX];
811 if (r->rtm_protocol == RTPROT_KERNEL &&
812 r->rtm_family == AF_INET6)
815 nlmsg_parse(hdr, sizeof(struct rtmsg), tb, __RTA_MAX - 1, NULL);
819 return *(int *)RTA_DATA(tb[RTA_OIF]) == ifindex;
822 static bool check_rule(struct nlmsghdr *hdr, int ifindex)
827 static int cb_clear_event(struct nl_msg *msg, void *arg)
829 struct clear_data *clr = arg;
830 struct nlmsghdr *hdr = nlmsg_hdr(msg);
831 bool (*cb)(struct nlmsghdr *, int ifindex);
837 if (hdr->nlmsg_type != RTM_NEWADDR)
844 if (hdr->nlmsg_type != RTM_NEWROUTE)
851 if (hdr->nlmsg_type != RTM_NEWRULE)
860 if (!cb(hdr, clr->dev ? clr->dev->ifindex : 0))
863 if (type == RTM_DELRULE)
864 D(SYSTEM, "Remove a rule\n");
866 D(SYSTEM, "Remove %s from device %s\n",
867 type == RTM_DELADDR ? "an address" : "a route",
869 memcpy(nlmsg_hdr(clr->msg), hdr, hdr->nlmsg_len);
870 hdr = nlmsg_hdr(clr->msg);
871 hdr->nlmsg_type = type;
872 hdr->nlmsg_flags = NLM_F_REQUEST;
874 nl_socket_disable_auto_ack(sock_rtnl);
875 nl_send_auto_complete(sock_rtnl, clr->msg);
876 nl_socket_enable_auto_ack(sock_rtnl);
882 cb_finish_event(struct nl_msg *msg, void *arg)
890 error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
893 *pending = err->error;
898 system_if_clear_entries(struct device *dev, int type, int af)
900 struct clear_data clr;
901 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
904 .rtm_flags = RTM_F_CLONED,
906 int flags = NLM_F_DUMP;
915 clr.size = sizeof(struct rtgenmsg);
918 clr.size = sizeof(struct rtmsg);
927 clr.msg = nlmsg_alloc_simple(type, flags);
931 nlmsg_append(clr.msg, &rtm, clr.size, 0);
932 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_clear_event, &clr);
933 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_finish_event, &pending);
934 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &pending);
936 nl_send_auto_complete(sock_rtnl, clr.msg);
938 nl_recvmsgs(sock_rtnl, cb);
946 * Clear bridge (membership) state and bring down device
948 void system_if_clear_state(struct device *dev)
950 static char buf[256];
953 device_set_ifindex(dev, system_if_resolve(dev));
954 if (dev->external || !dev->ifindex)
957 system_if_flags(dev->ifname, 0, IFF_UP);
959 if (system_is_bridge(dev->ifname, buf, sizeof(buf))) {
960 D(SYSTEM, "Delete existing bridge named '%s'\n", dev->ifname);
961 system_bridge_delbr(dev);
965 bridge = system_get_bridge(dev->ifname, buf, sizeof(buf));
967 D(SYSTEM, "Remove device '%s' from bridge '%s'\n", dev->ifname, bridge);
968 system_bridge_if(bridge, dev, SIOCBRDELIF, NULL);
971 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET);
972 system_if_clear_entries(dev, RTM_GETADDR, AF_INET);
973 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET6);
974 system_if_clear_entries(dev, RTM_GETADDR, AF_INET6);
975 system_set_disable_ipv6(dev, "0");
978 static inline unsigned long
979 sec_to_jiffies(int val)
981 return (unsigned long) val * 100;
984 static void system_bridge_conf_multicast_deps(struct device *bridge,
985 struct bridge_config *cfg,
991 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS ||
992 cfg->flags & BRIDGE_OPT_QUERY_INTERVAL ||
993 cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
994 val = cfg->robustness * cfg->query_interval +
995 cfg->query_response_interval;
997 snprintf(buf, buf_len, "%i", val);
998 system_bridge_set_membership_interval(bridge, buf);
1000 val = cfg->robustness * cfg->query_interval +
1001 cfg->query_response_interval / 2;
1003 snprintf(buf, buf_len, "%i", val);
1004 system_bridge_set_other_querier_timeout(bridge, buf);
1007 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
1008 val = cfg->query_interval / 4;
1010 snprintf(buf, buf_len, "%i", val);
1011 system_bridge_set_startup_query_interval(bridge, buf);
1015 static void system_bridge_conf_multicast(struct device *bridge,
1016 struct bridge_config *cfg,
1020 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_snooping",
1021 bridge->ifname, cfg->igmp_snoop ? "1" : "0");
1023 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_querier",
1024 bridge->ifname, cfg->multicast_querier ? "1" : "0");
1026 snprintf(buf, buf_len, "%i", cfg->hash_max);
1027 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/hash_max",
1028 bridge->ifname, buf);
1030 if (bridge->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
1031 snprintf(buf, buf_len, "%u", bridge->settings.multicast_router);
1032 system_bridge_set_multicast_router(bridge, buf, true);
1035 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS) {
1036 snprintf(buf, buf_len, "%i", cfg->robustness);
1037 system_bridge_set_robustness(bridge, buf);
1040 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
1041 snprintf(buf, buf_len, "%i", cfg->query_interval);
1042 system_bridge_set_query_interval(bridge, buf);
1045 if (cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
1046 snprintf(buf, buf_len, "%i", cfg->query_response_interval);
1047 system_bridge_set_query_response_interval(bridge, buf);
1050 if (cfg->flags & BRIDGE_OPT_LAST_MEMBER_INTERVAL) {
1051 snprintf(buf, buf_len, "%i", cfg->last_member_interval);
1052 system_bridge_set_last_member_interval(bridge, buf);
1055 system_bridge_conf_multicast_deps(bridge, cfg, buf, buf_len);
1058 int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg)
1061 unsigned long args[4] = {};
1063 if (ioctl(sock_ioctl, SIOCBRADDBR, bridge->ifname) < 0)
1066 args[0] = BRCTL_SET_BRIDGE_STP_STATE;
1067 args[1] = !!cfg->stp;
1068 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1070 args[0] = BRCTL_SET_BRIDGE_FORWARD_DELAY;
1071 args[1] = sec_to_jiffies(cfg->forward_delay);
1072 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1074 system_bridge_conf_multicast(bridge, cfg, buf, sizeof(buf));
1076 args[0] = BRCTL_SET_BRIDGE_PRIORITY;
1077 args[1] = cfg->priority;
1078 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1080 if (cfg->flags & BRIDGE_OPT_AGEING_TIME) {
1081 args[0] = BRCTL_SET_AGEING_TIME;
1082 args[1] = sec_to_jiffies(cfg->ageing_time);
1083 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1086 if (cfg->flags & BRIDGE_OPT_HELLO_TIME) {
1087 args[0] = BRCTL_SET_BRIDGE_HELLO_TIME;
1088 args[1] = sec_to_jiffies(cfg->hello_time);
1089 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1092 if (cfg->flags & BRIDGE_OPT_MAX_AGE) {
1093 args[0] = BRCTL_SET_BRIDGE_MAX_AGE;
1094 args[1] = sec_to_jiffies(cfg->max_age);
1095 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1101 int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvlan_config *cfg)
1104 struct nlattr *linkinfo, *data;
1105 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
1107 static const struct {
1109 enum macvlan_mode val;
1111 { "private", MACVLAN_MODE_PRIVATE },
1112 { "vepa", MACVLAN_MODE_VEPA },
1113 { "bridge", MACVLAN_MODE_BRIDGE },
1114 { "passthru", MACVLAN_MODE_PASSTHRU },
1117 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1122 nlmsg_append(msg, &iim, sizeof(iim), 0);
1124 if (cfg->flags & MACVLAN_OPT_MACADDR)
1125 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1126 nla_put_string(msg, IFLA_IFNAME, macvlan->ifname);
1127 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1129 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1130 goto nla_put_failure;
1132 nla_put_string(msg, IFLA_INFO_KIND, "macvlan");
1134 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1135 goto nla_put_failure;
1138 for (i = 0; i < ARRAY_SIZE(modes); i++) {
1139 if (strcmp(cfg->mode, modes[i].name) != 0)
1142 nla_put_u32(msg, IFLA_MACVLAN_MODE, modes[i].val);
1147 nla_nest_end(msg, data);
1148 nla_nest_end(msg, linkinfo);
1150 rv = system_rtnl_call(msg);
1152 D(SYSTEM, "Error adding macvlan '%s' over '%s': %d\n", macvlan->ifname, dev->ifname, rv);
1161 static int system_link_del(const char *ifname)
1164 struct ifinfomsg iim = {
1165 .ifi_family = AF_UNSPEC,
1169 msg = nlmsg_alloc_simple(RTM_DELLINK, NLM_F_REQUEST);
1174 nlmsg_append(msg, &iim, sizeof(iim), 0);
1175 nla_put_string(msg, IFLA_IFNAME, ifname);
1176 return system_rtnl_call(msg);
1179 int system_macvlan_del(struct device *macvlan)
1181 return system_link_del(macvlan->ifname);
1184 int system_veth_add(struct device *veth, struct veth_config *cfg)
1187 struct ifinfomsg empty_iim = {};
1188 struct nlattr *linkinfo, *data, *veth_info;
1191 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1196 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
1198 if (cfg->flags & VETH_OPT_MACADDR)
1199 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1200 nla_put_string(msg, IFLA_IFNAME, veth->ifname);
1202 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1203 goto nla_put_failure;
1205 nla_put_string(msg, IFLA_INFO_KIND, "veth");
1207 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1208 goto nla_put_failure;
1210 if (!(veth_info = nla_nest_start(msg, VETH_INFO_PEER)))
1211 goto nla_put_failure;
1213 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
1215 if (cfg->flags & VETH_OPT_PEER_NAME)
1216 nla_put_string(msg, IFLA_IFNAME, cfg->peer_name);
1217 if (cfg->flags & VETH_OPT_PEER_MACADDR)
1218 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->peer_macaddr), cfg->peer_macaddr);
1220 nla_nest_end(msg, veth_info);
1221 nla_nest_end(msg, data);
1222 nla_nest_end(msg, linkinfo);
1224 rv = system_rtnl_call(msg);
1226 if (cfg->flags & VETH_OPT_PEER_NAME)
1227 D(SYSTEM, "Error adding veth '%s' with peer '%s': %d\n", veth->ifname, cfg->peer_name, rv);
1229 D(SYSTEM, "Error adding veth '%s': %d\n", veth->ifname, rv);
1239 int system_veth_del(struct device *veth)
1241 return system_link_del(veth->ifname);
1244 static int system_vlan(struct device *dev, int id)
1246 struct vlan_ioctl_args ifr = {
1247 .cmd = SET_VLAN_NAME_TYPE_CMD,
1248 .u.name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD,
1251 ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);
1254 ifr.cmd = DEL_VLAN_CMD;
1257 ifr.cmd = ADD_VLAN_CMD;
1260 strncpy(ifr.device1, dev->ifname, sizeof(ifr.device1));
1261 return ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);
1264 int system_vlan_add(struct device *dev, int id)
1266 return system_vlan(dev, id);
1269 int system_vlan_del(struct device *dev)
1271 return system_vlan(dev, -1);
1274 int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlandev_config *cfg)
1277 struct nlattr *linkinfo, *data;
1278 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC };
1281 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1286 nlmsg_append(msg, &iim, sizeof(iim), 0);
1287 nla_put_string(msg, IFLA_IFNAME, vlandev->ifname);
1288 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1290 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1291 goto nla_put_failure;
1293 nla_put_string(msg, IFLA_INFO_KIND, "vlan");
1295 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1296 goto nla_put_failure;
1298 nla_put_u16(msg, IFLA_VLAN_ID, cfg->vid);
1300 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
1301 nla_put_u16(msg, IFLA_VLAN_PROTOCOL, htons(cfg->proto));
1303 if(cfg->proto == VLAN_PROTO_8021AD)
1304 netifd_log_message(L_WARNING, "%s Your kernel is older than linux 3.10.0, 802.1ad is not supported defaulting to 802.1q", vlandev->type->name);
1307 nla_nest_end(msg, data);
1308 nla_nest_end(msg, linkinfo);
1310 rv = system_rtnl_call(msg);
1312 D(SYSTEM, "Error adding vlandev '%s' over '%s': %d\n", vlandev->ifname, dev->ifname, rv);
1321 int system_vlandev_del(struct device *vlandev)
1323 return system_link_del(vlandev->ifname);
1327 system_if_get_settings(struct device *dev, struct device_settings *s)
1332 memset(&ifr, 0, sizeof(ifr));
1333 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
1335 if (ioctl(sock_ioctl, SIOCGIFMTU, &ifr) == 0) {
1336 s->mtu = ifr.ifr_mtu;
1337 s->flags |= DEV_OPT_MTU;
1340 s->mtu6 = system_update_ipv6_mtu(dev, 0);
1342 s->flags |= DEV_OPT_MTU6;
1344 if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) {
1345 s->txqueuelen = ifr.ifr_qlen;
1346 s->flags |= DEV_OPT_TXQUEUELEN;
1349 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) {
1350 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr));
1351 s->flags |= DEV_OPT_MACADDR;
1354 if (!system_get_disable_ipv6(dev, buf, sizeof(buf))) {
1355 s->ipv6 = !strtoul(buf, NULL, 0);
1356 s->flags |= DEV_OPT_IPV6;
1359 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) == 0) {
1360 s->promisc = ifr.ifr_flags & IFF_PROMISC;
1361 s->flags |= DEV_OPT_PROMISC;
1363 s->multicast = ifr.ifr_flags & IFF_MULTICAST;
1364 s->flags |= DEV_OPT_MULTICAST;
1367 if (!system_get_rpfilter(dev, buf, sizeof(buf))) {
1368 s->rpfilter = strtoul(buf, NULL, 0);
1369 s->flags |= DEV_OPT_RPFILTER;
1372 if (!system_get_acceptlocal(dev, buf, sizeof(buf))) {
1373 s->acceptlocal = strtoul(buf, NULL, 0);
1374 s->flags |= DEV_OPT_ACCEPTLOCAL;
1377 if (!system_get_igmpversion(dev, buf, sizeof(buf))) {
1378 s->igmpversion = strtoul(buf, NULL, 0);
1379 s->flags |= DEV_OPT_IGMPVERSION;
1382 if (!system_get_mldversion(dev, buf, sizeof(buf))) {
1383 s->mldversion = strtoul(buf, NULL, 0);
1384 s->flags |= DEV_OPT_MLDVERSION;
1387 if (!system_get_neigh4reachabletime(dev, buf, sizeof(buf))) {
1388 s->neigh4reachabletime = strtoul(buf, NULL, 0);
1389 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
1392 if (!system_get_neigh6reachabletime(dev, buf, sizeof(buf))) {
1393 s->neigh6reachabletime = strtoul(buf, NULL, 0);
1394 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
1397 if (!system_get_neigh4locktime(dev, buf, sizeof(buf))) {
1398 s->neigh4locktime = strtol(buf, NULL, 0);
1399 s->flags |= DEV_OPT_NEIGHLOCKTIME;
1402 if (!system_get_neigh4gcstaletime(dev, buf, sizeof(buf))) {
1403 s->neigh4gcstaletime = strtoul(buf, NULL, 0);
1404 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
1407 if (!system_get_neigh6gcstaletime(dev, buf, sizeof(buf))) {
1408 s->neigh6gcstaletime = strtoul(buf, NULL, 0);
1409 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
1412 if (!system_get_dadtransmits(dev, buf, sizeof(buf))) {
1413 s->dadtransmits = strtoul(buf, NULL, 0);
1414 s->flags |= DEV_OPT_DADTRANSMITS;
1417 if (!system_get_sendredirects(dev, buf, sizeof(buf))) {
1418 s->sendredirects = strtoul(buf, NULL, 0);
1419 s->flags |= DEV_OPT_SENDREDIRECTS;
1424 system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned int apply_mask)
1429 memset(&ifr, 0, sizeof(ifr));
1430 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
1431 if (s->flags & DEV_OPT_MTU & apply_mask) {
1432 ifr.ifr_mtu = s->mtu;
1433 if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0)
1434 s->flags &= ~DEV_OPT_MTU;
1436 if (s->flags & DEV_OPT_MTU6 & apply_mask) {
1437 system_update_ipv6_mtu(dev, s->mtu6);
1439 if (s->flags & DEV_OPT_TXQUEUELEN & apply_mask) {
1440 ifr.ifr_qlen = s->txqueuelen;
1441 if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0)
1442 s->flags &= ~DEV_OPT_TXQUEUELEN;
1444 if ((s->flags & DEV_OPT_MACADDR & apply_mask) && !dev->external) {
1445 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
1446 memcpy(&ifr.ifr_hwaddr.sa_data, s->macaddr, sizeof(s->macaddr));
1447 if (ioctl(sock_ioctl, SIOCSIFHWADDR, &ifr) < 0)
1448 s->flags &= ~DEV_OPT_MACADDR;
1450 if (s->flags & DEV_OPT_IPV6 & apply_mask)
1451 system_set_disable_ipv6(dev, s->ipv6 ? "0" : "1");
1452 if (s->flags & DEV_OPT_PROMISC & apply_mask) {
1453 if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0,
1454 !s->promisc ? IFF_PROMISC : 0) < 0)
1455 s->flags &= ~DEV_OPT_PROMISC;
1457 if (s->flags & DEV_OPT_RPFILTER & apply_mask) {
1458 snprintf(buf, sizeof(buf), "%u", s->rpfilter);
1459 system_set_rpfilter(dev, buf);
1461 if (s->flags & DEV_OPT_ACCEPTLOCAL & apply_mask)
1462 system_set_acceptlocal(dev, s->acceptlocal ? "1" : "0");
1463 if (s->flags & DEV_OPT_IGMPVERSION & apply_mask) {
1464 snprintf(buf, sizeof(buf), "%u", s->igmpversion);
1465 system_set_igmpversion(dev, buf);
1467 if (s->flags & DEV_OPT_MLDVERSION & apply_mask) {
1468 snprintf(buf, sizeof(buf), "%u", s->mldversion);
1469 system_set_mldversion(dev, buf);
1471 if (s->flags & DEV_OPT_NEIGHREACHABLETIME & apply_mask) {
1472 snprintf(buf, sizeof(buf), "%u", s->neigh4reachabletime);
1473 system_set_neigh4reachabletime(dev, buf);
1474 snprintf(buf, sizeof(buf), "%u", s->neigh6reachabletime);
1475 system_set_neigh6reachabletime(dev, buf);
1477 if (s->flags & DEV_OPT_NEIGHLOCKTIME & apply_mask) {
1478 snprintf(buf, sizeof(buf), "%d", s->neigh4locktime);
1479 system_set_neigh4locktime(dev, buf);
1481 if (s->flags & DEV_OPT_NEIGHGCSTALETIME & apply_mask) {
1482 snprintf(buf, sizeof(buf), "%u", s->neigh4gcstaletime);
1483 system_set_neigh4gcstaletime(dev, buf);
1484 snprintf(buf, sizeof(buf), "%u", s->neigh6gcstaletime);
1485 system_set_neigh6gcstaletime(dev, buf);
1487 if (s->flags & DEV_OPT_DADTRANSMITS & apply_mask) {
1488 snprintf(buf, sizeof(buf), "%u", s->dadtransmits);
1489 system_set_dadtransmits(dev, buf);
1491 if (s->flags & DEV_OPT_MULTICAST & apply_mask) {
1492 if (system_if_flags(dev->ifname, s->multicast ? IFF_MULTICAST : 0,
1493 !s->multicast ? IFF_MULTICAST : 0) < 0)
1494 s->flags &= ~DEV_OPT_MULTICAST;
1496 if (s->flags & DEV_OPT_SENDREDIRECTS & apply_mask)
1497 system_set_sendredirects(dev, s->sendredirects ? "1" : "0");
1500 int system_if_up(struct device *dev)
1502 system_if_get_settings(dev, &dev->orig_settings);
1503 /* Only keep orig settings based on what needs to be set */
1504 dev->orig_settings.valid_flags = dev->orig_settings.flags;
1505 dev->orig_settings.flags &= dev->settings.flags;
1506 system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
1507 return system_if_flags(dev->ifname, IFF_UP, 0);
1510 int system_if_down(struct device *dev)
1512 int ret = system_if_flags(dev->ifname, 0, IFF_UP);
1513 system_if_apply_settings(dev, &dev->orig_settings, dev->orig_settings.flags);
1517 struct if_check_data {
1523 #ifndef IFF_LOWER_UP
1524 #define IFF_LOWER_UP 0x10000
1527 static int cb_if_check_valid(struct nl_msg *msg, void *arg)
1529 struct nlmsghdr *nh = nlmsg_hdr(msg);
1530 struct ifinfomsg *ifi = NLMSG_DATA(nh);
1531 struct if_check_data *chk = (struct if_check_data *)arg;
1533 if (nh->nlmsg_type != RTM_NEWLINK)
1536 device_set_present(chk->dev, ifi->ifi_index > 0 ? true : false);
1537 device_set_link(chk->dev, ifi->ifi_flags & IFF_LOWER_UP ? true : false);
1542 static int cb_if_check_ack(struct nl_msg *msg, void *arg)
1544 struct if_check_data *chk = (struct if_check_data *)arg;
1549 static int cb_if_check_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1551 struct if_check_data *chk = (struct if_check_data *)arg;
1553 device_set_present(chk->dev, false);
1554 device_set_link(chk->dev, false);
1555 chk->pending = err->error;
1560 int system_if_check(struct device *dev)
1562 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1564 struct ifinfomsg ifi = {
1565 .ifi_family = AF_UNSPEC,
1568 struct if_check_data chk = {
1574 msg = nlmsg_alloc_simple(RTM_GETLINK, 0);
1578 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) ||
1579 nla_put_string(msg, IFLA_IFNAME, dev->ifname))
1582 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_check_valid, &chk);
1583 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_check_ack, &chk);
1584 nl_cb_err(cb, NL_CB_CUSTOM, cb_if_check_error, &chk);
1586 nl_send_auto_complete(sock_rtnl, msg);
1587 while (chk.pending > 0)
1588 nl_recvmsgs(sock_rtnl, cb);
1600 system_if_get_parent(struct device *dev)
1602 char buf[64], *devname;
1603 int ifindex, iflink, len;
1606 snprintf(buf, sizeof(buf), "/sys/class/net/%s/iflink", dev->ifname);
1607 f = fopen(buf, "r");
1611 len = fread(buf, 1, sizeof(buf) - 1, f);
1618 iflink = strtoul(buf, NULL, 0);
1619 ifindex = system_if_resolve(dev);
1620 if (!iflink || iflink == ifindex)
1623 devname = if_indextoname(iflink, buf);
1627 return device_get(devname, true);
1631 read_string_file(int dir_fd, const char *file, char *buf, int len)
1637 fd = openat(dir_fd, file, O_RDONLY);
1642 len = read(fd, buf, len - 1);
1646 } else if (len > 0) {
1649 c = strchr(buf, '\n');
1662 read_uint64_file(int dir_fd, const char *file, uint64_t *val)
1667 ret = read_string_file(dir_fd, file, buf, sizeof(buf));
1669 *val = strtoull(buf, NULL, 0);
1674 /* Assume advertised flags == supported flags */
1675 static const struct {
1678 } ethtool_link_modes[] = {
1679 { ADVERTISED_10baseT_Half, "10H" },
1680 { ADVERTISED_10baseT_Full, "10F" },
1681 { ADVERTISED_100baseT_Half, "100H" },
1682 { ADVERTISED_100baseT_Full, "100F" },
1683 { ADVERTISED_1000baseT_Half, "1000H" },
1684 { ADVERTISED_1000baseT_Full, "1000F" },
1687 static void system_add_link_modes(struct blob_buf *b, __u32 mask)
1690 for (i = 0; i < ARRAY_SIZE(ethtool_link_modes); i++) {
1691 if (mask & ethtool_link_modes[i].mask)
1692 blobmsg_add_string(b, NULL, ethtool_link_modes[i].name);
1697 system_if_force_external(const char *ifname)
1702 snprintf(buf, sizeof(buf), "/sys/class/net/%s/phy80211", ifname);
1703 return stat(buf, &s) == 0;
1707 system_if_dump_info(struct device *dev, struct blob_buf *b)
1709 struct ethtool_cmd ecmd;
1715 snprintf(buf, sizeof(buf), "/sys/class/net/%s", dev->ifname);
1716 dir_fd = open(buf, O_DIRECTORY);
1718 memset(&ecmd, 0, sizeof(ecmd));
1719 memset(&ifr, 0, sizeof(ifr));
1720 strcpy(ifr.ifr_name, dev->ifname);
1721 ifr.ifr_data = (caddr_t) &ecmd;
1722 ecmd.cmd = ETHTOOL_GSET;
1724 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == 0) {
1725 c = blobmsg_open_array(b, "link-advertising");
1726 system_add_link_modes(b, ecmd.advertising);
1727 blobmsg_close_array(b, c);
1729 c = blobmsg_open_array(b, "link-supported");
1730 system_add_link_modes(b, ecmd.supported);
1731 blobmsg_close_array(b, c);
1733 s = blobmsg_alloc_string_buffer(b, "speed", 8);
1734 snprintf(s, 8, "%d%c", ethtool_cmd_speed(&ecmd),
1735 ecmd.duplex == DUPLEX_HALF ? 'H' : 'F');
1736 blobmsg_add_string_buffer(b);
1744 system_if_dump_stats(struct device *dev, struct blob_buf *b)
1746 const char *const counters[] = {
1747 "collisions", "rx_frame_errors", "tx_compressed",
1748 "multicast", "rx_length_errors", "tx_dropped",
1749 "rx_bytes", "rx_missed_errors", "tx_errors",
1750 "rx_compressed", "rx_over_errors", "tx_fifo_errors",
1751 "rx_crc_errors", "rx_packets", "tx_heartbeat_errors",
1752 "rx_dropped", "tx_aborted_errors", "tx_packets",
1753 "rx_errors", "tx_bytes", "tx_window_errors",
1754 "rx_fifo_errors", "tx_carrier_errors",
1761 snprintf(buf, sizeof(buf), "/sys/class/net/%s/statistics", dev->ifname);
1762 stats_dir = open(buf, O_DIRECTORY);
1766 for (i = 0; i < ARRAY_SIZE(counters); i++)
1767 if (read_uint64_file(stats_dir, counters[i], &val))
1768 blobmsg_add_u64(b, counters[i], val);
1774 static int system_addr(struct device *dev, struct device_addr *addr, int cmd)
1776 bool v4 = ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4);
1777 int alen = v4 ? 4 : 16;
1778 unsigned int flags = 0;
1779 struct ifaddrmsg ifa = {
1780 .ifa_family = (alen == 4) ? AF_INET : AF_INET6,
1781 .ifa_prefixlen = addr->mask,
1782 .ifa_index = dev->ifindex,
1786 if (cmd == RTM_NEWADDR)
1787 flags |= NLM_F_CREATE | NLM_F_REPLACE;
1789 msg = nlmsg_alloc_simple(cmd, flags);
1793 nlmsg_append(msg, &ifa, sizeof(ifa), 0);
1794 nla_put(msg, IFA_LOCAL, alen, &addr->addr);
1796 if (addr->broadcast)
1797 nla_put_u32(msg, IFA_BROADCAST, addr->broadcast);
1798 if (addr->point_to_point)
1799 nla_put_u32(msg, IFA_ADDRESS, addr->point_to_point);
1801 time_t now = system_get_rtime();
1802 struct ifa_cacheinfo cinfo = {0xffffffffU, 0xffffffffU, 0, 0};
1804 if (addr->preferred_until) {
1805 int64_t preferred = addr->preferred_until - now;
1808 else if (preferred > UINT32_MAX)
1809 preferred = UINT32_MAX;
1811 cinfo.ifa_prefered = preferred;
1814 if (addr->valid_until) {
1815 int64_t valid = addr->valid_until - now;
1820 else if (valid > UINT32_MAX)
1823 cinfo.ifa_valid = valid;
1826 nla_put(msg, IFA_CACHEINFO, sizeof(cinfo), &cinfo);
1828 if (cmd == RTM_NEWADDR && (addr->flags & DEVADDR_OFFLINK))
1829 nla_put_u32(msg, IFA_FLAGS, IFA_F_NOPREFIXROUTE);
1832 return system_rtnl_call(msg);
1835 int system_add_address(struct device *dev, struct device_addr *addr)
1837 return system_addr(dev, addr, RTM_NEWADDR);
1840 int system_del_address(struct device *dev, struct device_addr *addr)
1842 return system_addr(dev, addr, RTM_DELADDR);
1845 static int system_rt(struct device *dev, struct device_route *route, int cmd)
1847 int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
1849 unsigned int flags = 0;
1852 have_gw = !!route->nexthop.in.s_addr;
1854 have_gw = route->nexthop.in6.s6_addr32[0] ||
1855 route->nexthop.in6.s6_addr32[1] ||
1856 route->nexthop.in6.s6_addr32[2] ||
1857 route->nexthop.in6.s6_addr32[3];
1859 unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))
1860 ? route->table : RT_TABLE_MAIN;
1862 struct rtmsg rtm = {
1863 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
1864 .rtm_dst_len = route->mask,
1865 .rtm_src_len = route->sourcemask,
1866 .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC,
1867 .rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC,
1868 .rtm_scope = RT_SCOPE_NOWHERE,
1869 .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST,
1870 .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0,
1874 if (cmd == RTM_NEWROUTE) {
1875 flags |= NLM_F_CREATE | NLM_F_REPLACE;
1877 if (!dev) { // Add null-route
1878 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
1879 rtm.rtm_type = RTN_UNREACHABLE;
1882 rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
1885 if (route->flags & DEVROUTE_TYPE) {
1886 rtm.rtm_type = route->type;
1887 if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) {
1888 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST ||
1889 rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST)
1890 rtm.rtm_table = RT_TABLE_LOCAL;
1893 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) {
1894 rtm.rtm_scope = RT_SCOPE_HOST;
1895 } else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
1896 rtm.rtm_type == RTN_ANYCAST) {
1897 rtm.rtm_scope = RT_SCOPE_LINK;
1898 } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE ||
1899 rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY ||
1900 rtm.rtm_type == RTN_THROW) {
1901 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
1906 msg = nlmsg_alloc_simple(cmd, flags);
1910 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1913 nla_put(msg, RTA_DST, alen, &route->addr);
1915 if (route->sourcemask) {
1916 if (rtm.rtm_family == AF_INET)
1917 nla_put(msg, RTA_PREFSRC, alen, &route->source);
1919 nla_put(msg, RTA_SRC, alen, &route->source);
1922 if (route->metric > 0)
1923 nla_put_u32(msg, RTA_PRIORITY, route->metric);
1926 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop);
1929 nla_put_u32(msg, RTA_OIF, dev->ifindex);
1932 nla_put_u32(msg, RTA_TABLE, table);
1934 if (route->flags & DEVROUTE_MTU) {
1935 struct nlattr *metrics;
1937 if (!(metrics = nla_nest_start(msg, RTA_METRICS)))
1938 goto nla_put_failure;
1940 nla_put_u32(msg, RTAX_MTU, route->mtu);
1942 nla_nest_end(msg, metrics);
1945 return system_rtnl_call(msg);
1952 int system_add_route(struct device *dev, struct device_route *route)
1954 return system_rt(dev, route, RTM_NEWROUTE);
1957 int system_del_route(struct device *dev, struct device_route *route)
1959 return system_rt(dev, route, RTM_DELROUTE);
1962 int system_flush_routes(void)
1964 const char *names[] = {
1965 "/proc/sys/net/ipv4/route/flush",
1966 "/proc/sys/net/ipv6/route/flush"
1970 for (i = 0; i < ARRAY_SIZE(names); i++) {
1971 fd = open(names[i], O_WRONLY);
1975 if (write(fd, "-1", 2)) {}
1981 bool system_resolve_rt_type(const char *type, unsigned int *id)
1983 return system_rtn_aton(type, id);
1986 bool system_resolve_rt_proto(const char *type, unsigned int *id)
1990 unsigned int n, proto = 256;
1991 n = strtoul(type, &e, 0);
1992 if (!*e && e != type)
1994 else if (!strcmp(type, "unspec"))
1995 proto = RTPROT_UNSPEC;
1996 else if (!strcmp(type, "kernel"))
1997 proto = RTPROT_KERNEL;
1998 else if (!strcmp(type, "boot"))
1999 proto = RTPROT_BOOT;
2000 else if (!strcmp(type, "static"))
2001 proto = RTPROT_STATIC;
2002 else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) {
2003 while (fgets(buf, sizeof(buf) - 1, f) != NULL) {
2004 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2007 n = strtoul(e, NULL, 10);
2008 e = strtok(NULL, " \t\n");
2010 if (e && !strcmp(e, type)) {
2025 bool system_resolve_rt_table(const char *name, unsigned int *id)
2029 unsigned int n, table = RT_TABLE_UNSPEC;
2031 /* first try to parse table as number */
2032 if ((n = strtoul(name, &e, 0)) > 0 && !*e)
2035 /* handle well known aliases */
2036 else if (!strcmp(name, "default"))
2037 table = RT_TABLE_DEFAULT;
2038 else if (!strcmp(name, "main"))
2039 table = RT_TABLE_MAIN;
2040 else if (!strcmp(name, "local"))
2041 table = RT_TABLE_LOCAL;
2043 /* try to look up name in /etc/iproute2/rt_tables */
2044 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL)
2046 while (fgets(buf, sizeof(buf) - 1, f) != NULL)
2048 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2051 n = strtoul(e, NULL, 10);
2052 e = strtok(NULL, " \t\n");
2054 if (e && !strcmp(e, name))
2064 if (table == RT_TABLE_UNSPEC)
2071 bool system_is_default_rt_table(unsigned int id)
2073 return (id == RT_TABLE_MAIN);
2076 bool system_resolve_rpfilter(const char *filter, unsigned int *id)
2081 if (!strcmp(filter, "strict"))
2083 else if (!strcmp(filter, "loose"))
2086 n = strtoul(filter, &e, 0);
2087 if (*e || e == filter || n > 2)
2095 static int system_iprule(struct iprule *rule, int cmd)
2097 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16;
2100 struct rtmsg rtm = {
2101 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
2102 .rtm_protocol = RTPROT_STATIC,
2103 .rtm_scope = RT_SCOPE_UNIVERSE,
2104 .rtm_table = RT_TABLE_UNSPEC,
2105 .rtm_type = RTN_UNSPEC,
2109 if (cmd == RTM_NEWRULE)
2110 rtm.rtm_type = RTN_UNICAST;
2113 rtm.rtm_flags |= FIB_RULE_INVERT;
2115 if (rule->flags & IPRULE_SRC)
2116 rtm.rtm_src_len = rule->src_mask;
2118 if (rule->flags & IPRULE_DEST)
2119 rtm.rtm_dst_len = rule->dest_mask;
2121 if (rule->flags & IPRULE_TOS)
2122 rtm.rtm_tos = rule->tos;
2124 if (rule->flags & IPRULE_LOOKUP) {
2125 if (rule->lookup < 256)
2126 rtm.rtm_table = rule->lookup;
2129 if (rule->flags & IPRULE_ACTION)
2130 rtm.rtm_type = rule->action;
2131 else if (rule->flags & IPRULE_GOTO)
2132 rtm.rtm_type = FR_ACT_GOTO;
2133 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO)))
2134 rtm.rtm_type = FR_ACT_NOP;
2136 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST);
2141 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
2143 if (rule->flags & IPRULE_IN)
2144 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev);
2146 if (rule->flags & IPRULE_OUT)
2147 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev);
2149 if (rule->flags & IPRULE_SRC)
2150 nla_put(msg, FRA_SRC, alen, &rule->src_addr);
2152 if (rule->flags & IPRULE_DEST)
2153 nla_put(msg, FRA_DST, alen, &rule->dest_addr);
2155 if (rule->flags & IPRULE_PRIORITY)
2156 nla_put_u32(msg, FRA_PRIORITY, rule->priority);
2157 else if (cmd == RTM_NEWRULE)
2158 nla_put_u32(msg, FRA_PRIORITY, rule->order);
2160 if (rule->flags & IPRULE_FWMARK)
2161 nla_put_u32(msg, FRA_FWMARK, rule->fwmark);
2163 if (rule->flags & IPRULE_FWMASK)
2164 nla_put_u32(msg, FRA_FWMASK, rule->fwmask);
2166 if (rule->flags & IPRULE_LOOKUP) {
2167 if (rule->lookup >= 256)
2168 nla_put_u32(msg, FRA_TABLE, rule->lookup);
2171 if (rule->flags & IPRULE_SUP_PREFIXLEN)
2172 nla_put_u32(msg, FRA_SUPPRESS_PREFIXLEN, rule->sup_prefixlen);
2174 if (rule->flags & IPRULE_GOTO)
2175 nla_put_u32(msg, FRA_GOTO, rule->gotoid);
2177 return system_rtnl_call(msg);
2180 int system_add_iprule(struct iprule *rule)
2182 return system_iprule(rule, RTM_NEWRULE);
2185 int system_del_iprule(struct iprule *rule)
2187 return system_iprule(rule, RTM_DELRULE);
2190 int system_flush_iprules(void)
2195 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET);
2196 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6);
2198 memset(&rule, 0, sizeof(rule));
2201 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2204 rule.lookup = RT_TABLE_LOCAL;
2205 rv |= system_iprule(&rule, RTM_NEWRULE);
2207 rule.priority = 32766;
2208 rule.lookup = RT_TABLE_MAIN;
2209 rv |= system_iprule(&rule, RTM_NEWRULE);
2211 rule.priority = 32767;
2212 rule.lookup = RT_TABLE_DEFAULT;
2213 rv |= system_iprule(&rule, RTM_NEWRULE);
2216 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2219 rule.lookup = RT_TABLE_LOCAL;
2220 rv |= system_iprule(&rule, RTM_NEWRULE);
2222 rule.priority = 32766;
2223 rule.lookup = RT_TABLE_MAIN;
2224 rv |= system_iprule(&rule, RTM_NEWRULE);
2229 bool system_resolve_iprule_action(const char *action, unsigned int *id)
2231 return system_rtn_aton(action, id);
2234 time_t system_get_rtime(void)
2239 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts) == 0)
2242 if (gettimeofday(&tv, NULL) == 0)
2249 #define IP_DF 0x4000
2252 static int tunnel_ioctl(const char *name, int cmd, void *p)
2256 memset(&ifr, 0, sizeof(ifr));
2257 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
2258 ifr.ifr_ifru.ifru_data = p;
2259 return ioctl(sock_ioctl, cmd, &ifr);
2262 #ifdef IFLA_IPTUN_MAX
2263 static int system_add_ip6_tunnel(const char *name, const unsigned int link,
2264 struct blob_attr **tb)
2266 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK,
2267 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2268 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC };
2269 struct blob_attr *cur;
2270 int ret = 0, ttl = 0;
2275 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2276 nla_put_string(nlm, IFLA_IFNAME, name);
2279 nla_put_u32(nlm, IFLA_LINK, link);
2281 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2287 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl");
2288 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2295 nla_put_u32(nlm, IFLA_IPTUN_LINK, link);
2297 if ((cur = tb[TUNNEL_ATTR_TTL]))
2298 ttl = blobmsg_get_u32(cur);
2300 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP);
2301 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64);
2302 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, 4);
2304 struct in6_addr in6buf;
2305 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2306 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2310 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf);
2313 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2314 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2318 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf);
2321 #ifdef IFLA_IPTUN_FMR_MAX
2322 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2323 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS);
2324 struct blob_attr *dcur;
2325 unsigned drem, fmrcnt = 0;
2327 blobmsg_for_each_attr(dcur, cur, drem) {
2328 if (blobmsg_type(dcur) != BLOBMSG_TYPE_ARRAY ||
2329 strcmp(blobmsg_name(dcur), "fmrs") ||
2330 blobmsg_check_array(dcur, BLOBMSG_TYPE_UNSPEC) <= 0)
2333 struct blob_attr *rcur;
2335 blobmsg_for_each_attr(rcur, dcur, rrem) {
2336 struct blob_attr *tb_fmr[__FMR_DATA_ATTR_MAX], *tb_cur;
2337 struct in6_addr ip6prefix;
2338 struct in_addr ip4prefix;
2339 unsigned ip4len, ip6len, ealen, offset;
2341 blobmsg_parse(fmr_data_attr_list.params, __FMR_DATA_ATTR_MAX, tb_fmr,
2342 blobmsg_data(rcur), blobmsg_len(rcur));
2344 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX6]) ||
2345 !parse_ip_and_netmask(AF_INET6,
2346 blobmsg_data(tb_cur), &ip6prefix,
2352 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX4]) ||
2353 !parse_ip_and_netmask(AF_INET,
2354 blobmsg_data(tb_cur), &ip4prefix,
2360 if (!(tb_cur = tb_fmr[FMR_DATA_EALEN])) {
2364 ealen = blobmsg_get_u32(tb_cur);
2366 if (!(tb_cur = tb_fmr[FMR_DATA_OFFSET])) {
2370 offset = blobmsg_get_u32(tb_cur);
2372 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt);
2374 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix);
2375 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix);
2376 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len);
2377 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len);
2378 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen);
2379 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset);
2381 nla_nest_end(nlm, rule);
2384 nla_nest_end(nlm, fmrs);
2388 nla_nest_end(nlm, infodata);
2389 nla_nest_end(nlm, linkinfo);
2391 return system_rtnl_call(nlm);
2399 #ifdef IFLA_IPTUN_MAX
2400 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000)
2401 static int system_add_gre_tunnel(const char *name, const char *kind,
2402 const unsigned int link, struct blob_attr **tb, bool v6)
2405 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
2406 struct blob_attr *cur;
2407 uint32_t ikey = 0, okey = 0, flags = 0, flowinfo = 0;
2408 uint16_t iflags = 0, oflags = 0;
2410 int ret = 0, ttl = 0;
2412 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2416 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2417 nla_put_string(nlm, IFLA_IFNAME, name);
2419 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2425 nla_put_string(nlm, IFLA_INFO_KIND, kind);
2426 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2433 nla_put_u32(nlm, IFLA_GRE_LINK, link);
2435 if ((cur = tb[TUNNEL_ATTR_TTL]))
2436 ttl = blobmsg_get_u32(cur);
2438 if ((cur = tb[TUNNEL_ATTR_TOS])) {
2439 char *str = blobmsg_get_string(cur);
2440 if (strcmp(str, "inherit")) {
2443 if (!system_tos_aton(str, &uval)) {
2449 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS;
2454 flags |= IP6_TNL_F_USE_ORIG_TCLASS;
2460 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2461 struct blob_attr *tb_data[__GRE_DATA_ATTR_MAX];
2463 blobmsg_parse(gre_data_attr_list.params, __GRE_DATA_ATTR_MAX, tb_data,
2464 blobmsg_data(cur), blobmsg_len(cur));
2466 if ((cur = tb_data[GRE_DATA_IKEY])) {
2467 if ((ikey = blobmsg_get_u32(cur)))
2471 if ((cur = tb_data[GRE_DATA_OKEY])) {
2472 if ((okey = blobmsg_get_u32(cur)))
2476 if ((cur = tb_data[GRE_DATA_ICSUM])) {
2477 if (blobmsg_get_bool(cur))
2481 if ((cur = tb_data[GRE_DATA_OCSUM])) {
2482 if (blobmsg_get_bool(cur))
2486 if ((cur = tb_data[GRE_DATA_ISEQNO])) {
2487 if (blobmsg_get_bool(cur))
2491 if ((cur = tb[GRE_DATA_OSEQNO])) {
2492 if (blobmsg_get_bool(cur))
2498 struct in6_addr in6buf;
2499 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2500 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2504 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf);
2507 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2508 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2512 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf);
2514 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, 4);
2517 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo);
2520 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags);
2525 struct in_addr inbuf;
2528 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2529 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2533 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf);
2536 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2537 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2541 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf);
2543 if (IN_MULTICAST(ntohl(inbuf.s_addr))) {
2545 okey = inbuf.s_addr;
2550 ikey = inbuf.s_addr;
2556 if ((cur = tb[TUNNEL_ATTR_DF]))
2557 set_df = blobmsg_get_bool(cur);
2560 /* ttl != 0 and nopmtudisc are incompatible */
2568 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0);
2570 nla_put_u8(nlm, IFLA_GRE_TOS, tos);
2574 nla_put_u8(nlm, IFLA_GRE_TTL, ttl);
2577 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags);
2580 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags);
2583 nla_put_u32(nlm, IFLA_GRE_OKEY, htonl(okey));
2586 nla_put_u32(nlm, IFLA_GRE_IKEY, htonl(ikey));
2588 nla_nest_end(nlm, infodata);
2589 nla_nest_end(nlm, linkinfo);
2591 return system_rtnl_call(nlm);
2600 static int system_add_vti_tunnel(const char *name, const char *kind,
2601 const unsigned int link, struct blob_attr **tb, bool v6)
2604 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
2605 struct blob_attr *cur;
2608 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2612 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2613 nla_put_string(nlm, IFLA_IFNAME, name);
2615 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2621 nla_put_string(nlm, IFLA_INFO_KIND, kind);
2622 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2629 nla_put_u32(nlm, IFLA_VTI_LINK, link);
2632 struct in6_addr in6buf;
2633 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2634 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2638 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(in6buf), &in6buf);
2641 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2642 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2646 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(in6buf), &in6buf);
2650 struct in_addr inbuf;
2652 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2653 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2657 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(inbuf), &inbuf);
2660 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2661 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2665 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(inbuf), &inbuf);
2670 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2671 struct blob_attr *tb_data[__VTI_DATA_ATTR_MAX];
2672 uint32_t ikey = 0, okey = 0;
2674 blobmsg_parse(vti_data_attr_list.params, __VTI_DATA_ATTR_MAX, tb_data,
2675 blobmsg_data(cur), blobmsg_len(cur));
2677 if ((cur = tb_data[VTI_DATA_IKEY])) {
2678 if ((ikey = blobmsg_get_u32(cur)))
2679 nla_put_u32(nlm, IFLA_VTI_IKEY, htonl(ikey));
2682 if ((cur = tb_data[VTI_DATA_OKEY])) {
2683 if ((okey = blobmsg_get_u32(cur)))
2684 nla_put_u32(nlm, IFLA_VTI_OKEY, htonl(okey));
2688 nla_nest_end(nlm, infodata);
2689 nla_nest_end(nlm, linkinfo);
2691 return system_rtnl_call(nlm);
2699 #ifdef IFLA_VXLAN_MAX
2700 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6)
2702 struct blob_attr *tb_data[__VXLAN_DATA_ATTR_MAX];
2704 struct nlattr *linkinfo, *data;
2705 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
2706 struct blob_attr *cur;
2709 if ((cur = tb[TUNNEL_ATTR_DATA]))
2710 blobmsg_parse(vxlan_data_attr_list.params, __VXLAN_DATA_ATTR_MAX, tb_data,
2711 blobmsg_data(cur), blobmsg_len(cur));
2715 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
2720 nlmsg_append(msg, &iim, sizeof(iim), 0);
2722 nla_put_string(msg, IFLA_IFNAME, name);
2724 if ((cur = tb_data[VXLAN_DATA_ATTR_MACADDR])) {
2725 struct ether_addr *ea = ether_aton(blobmsg_get_string(cur));
2731 nla_put(msg, IFLA_ADDRESS, ETH_ALEN, ea);
2734 if ((cur = tb[TUNNEL_ATTR_MTU])) {
2735 uint32_t mtu = blobmsg_get_u32(cur);
2736 nla_put_u32(msg, IFLA_MTU, mtu);
2739 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) {
2744 nla_put_string(msg, IFLA_INFO_KIND, "vxlan");
2746 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) {
2752 nla_put_u32(msg, IFLA_VXLAN_LINK, link);
2754 if ((cur = tb_data[VXLAN_DATA_ATTR_ID])) {
2755 uint32_t id = blobmsg_get_u32(cur);
2756 if (id >= (1u << 24) - 1) {
2761 nla_put_u32(msg, IFLA_VXLAN_ID, id);
2765 struct in6_addr in6buf;
2766 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2767 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2771 nla_put(msg, IFLA_VXLAN_LOCAL6, sizeof(in6buf), &in6buf);
2774 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2775 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2779 nla_put(msg, IFLA_VXLAN_GROUP6, sizeof(in6buf), &in6buf);
2782 struct in_addr inbuf;
2784 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2785 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2789 nla_put(msg, IFLA_VXLAN_LOCAL, sizeof(inbuf), &inbuf);
2792 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2793 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2797 nla_put(msg, IFLA_VXLAN_GROUP, sizeof(inbuf), &inbuf);
2801 uint32_t port = 4789;
2802 if ((cur = tb_data[VXLAN_DATA_ATTR_PORT])) {
2803 port = blobmsg_get_u32(cur);
2804 if (port < 1 || port > 65535) {
2809 nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port));
2811 if ((cur = tb_data[VXLAN_DATA_ATTR_RXCSUM])) {
2812 bool rxcsum = blobmsg_get_bool(cur);
2813 nla_put_u8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, !rxcsum);
2816 if ((cur = tb_data[VXLAN_DATA_ATTR_TXCSUM])) {
2817 bool txcsum = blobmsg_get_bool(cur);
2818 nla_put_u8(msg, IFLA_VXLAN_UDP_CSUM, txcsum);
2819 nla_put_u8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, !txcsum);
2822 if ((cur = tb[TUNNEL_ATTR_TOS])) {
2823 char *str = blobmsg_get_string(cur);
2826 if (strcmp(str, "inherit")) {
2827 if (!system_tos_aton(str, &tos))
2831 nla_put_u8(msg, IFLA_VXLAN_TOS, tos);
2834 if ((cur = tb[TUNNEL_ATTR_TTL])) {
2835 uint32_t ttl = blobmsg_get_u32(cur);
2836 if (ttl < 1 || ttl > 255) {
2841 nla_put_u8(msg, IFLA_VXLAN_TTL, ttl);
2844 nla_nest_end(msg, data);
2845 nla_nest_end(msg, linkinfo);
2847 ret = system_rtnl_call(msg);
2849 D(SYSTEM, "Error adding vxlan '%s': %d\n", name, ret);
2859 static int system_add_sit_tunnel(const char *name, const unsigned int link, struct blob_attr **tb)
2861 struct blob_attr *cur;
2864 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
2868 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2869 struct blob_attr *tb_data[__SIXRD_DATA_ATTR_MAX];
2871 struct ip_tunnel_6rd p6;
2873 blobmsg_parse(sixrd_data_attr_list.params, __SIXRD_DATA_ATTR_MAX, tb_data,
2874 blobmsg_data(cur), blobmsg_len(cur));
2876 memset(&p6, 0, sizeof(p6));
2878 if ((cur = tb_data[SIXRD_DATA_PREFIX])) {
2879 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur),
2880 &p6.prefix, &mask) || mask > 128) {
2885 p6.prefixlen = mask;
2888 if ((cur = tb_data[SIXRD_DATA_RELAY_PREFIX])) {
2889 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur),
2890 &p6.relay_prefix, &mask) || mask > 32) {
2895 p6.relay_prefixlen = mask;
2898 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) {
2908 __system_del_ip_tunnel(name, tb);
2912 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb)
2914 struct blob_attr *cur;
2916 struct ip_tunnel_parm p = {
2925 if ((cur = tb[TUNNEL_ATTR_LOCAL]) &&
2926 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1)
2929 if ((cur = tb[TUNNEL_ATTR_REMOTE]) &&
2930 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1)
2933 if ((cur = tb[TUNNEL_ATTR_DF]))
2934 set_df = blobmsg_get_bool(cur);
2936 if ((cur = tb[TUNNEL_ATTR_TTL]))
2937 p.iph.ttl = blobmsg_get_u32(cur);
2939 if ((cur = tb[TUNNEL_ATTR_TOS])) {
2940 char *str = blobmsg_get_string(cur);
2941 if (strcmp(str, "inherit")) {
2944 if (!system_tos_aton(str, &uval))
2952 p.iph.frag_off = set_df ? htons(IP_DF) : 0;
2953 /* ttl !=0 and nopmtudisc are incompatible */
2954 if (p.iph.ttl && p.iph.frag_off == 0)
2957 strncpy(p.name, name, sizeof(p.name));
2959 switch (p.iph.protocol) {
2961 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p);
2963 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p);
2970 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb)
2972 struct blob_attr *cur;
2975 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
2977 str = blobmsg_data(cur);
2979 if (!strcmp(str, "greip") || !strcmp(str, "gretapip") ||
2980 !strcmp(str, "greip6") || !strcmp(str, "gretapip6") ||
2981 !strcmp(str, "vtiip") || !strcmp(str, "vtiip6") ||
2982 !strcmp(str, "vxlan") || !strcmp(str, "vxlan6"))
2983 return system_link_del(name);
2985 return tunnel_ioctl(name, SIOCDELTUNNEL, NULL);
2988 int system_del_ip_tunnel(const char *name, struct blob_attr *attr)
2990 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
2992 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
2993 blob_data(attr), blob_len(attr));
2995 return __system_del_ip_tunnel(name, tb);
2998 int system_update_ipv6_mtu(struct device *dev, int mtu)
3004 snprintf(buf, sizeof(buf), "/proc/sys/net/ipv6/conf/%s/mtu",
3007 fd = open(buf, O_RDWR);
3012 ssize_t len = read(fd, buf, sizeof(buf) - 1);
3019 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0)
3028 int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
3030 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
3031 struct blob_attr *cur;
3034 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
3035 blob_data(attr), blob_len(attr));
3037 __system_del_ip_tunnel(name, tb);
3039 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
3041 str = blobmsg_data(cur);
3043 unsigned int ttl = 0;
3044 if ((cur = tb[TUNNEL_ATTR_TTL])) {
3045 ttl = blobmsg_get_u32(cur);
3050 unsigned int link = 0;
3051 if ((cur = tb[TUNNEL_ATTR_LINK])) {
3052 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
3056 if (iface->l3_dev.dev)
3057 link = iface->l3_dev.dev->ifindex;
3060 if (!strcmp(str, "sit"))
3061 return system_add_sit_tunnel(name, link, tb);
3062 #ifdef IFLA_IPTUN_MAX
3063 else if (!strcmp(str, "ipip6")) {
3064 return system_add_ip6_tunnel(name, link, tb);
3065 } else if (!strcmp(str, "greip")) {
3066 return system_add_gre_tunnel(name, "gre", link, tb, false);
3067 } else if (!strcmp(str, "gretapip")) {
3068 return system_add_gre_tunnel(name, "gretap", link, tb, false);
3069 } else if (!strcmp(str, "greip6")) {
3070 return system_add_gre_tunnel(name, "ip6gre", link, tb, true);
3071 } else if (!strcmp(str, "gretapip6")) {
3072 return system_add_gre_tunnel(name, "ip6gretap", link, tb, true);
3074 } else if (!strcmp(str, "vtiip")) {
3075 return system_add_vti_tunnel(name, "vti", link, tb, false);
3076 } else if (!strcmp(str, "vtiip6")) {
3077 return system_add_vti_tunnel(name, "vti6", link, tb, true);
3079 #ifdef IFLA_VXLAN_MAX
3080 } else if(!strcmp(str, "vxlan")) {
3081 return system_add_vxlan(name, link, tb, false);
3082 } else if(!strcmp(str, "vxlan6")) {
3083 return system_add_vxlan(name, link, tb, true);
3086 } else if (!strcmp(str, "ipip")) {
3087 return system_add_proto_tunnel(name, IPPROTO_IPIP, link, tb);