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);
85 static char dev_buf[256];
88 handler_nl_event(struct uloop_fd *u, unsigned int events)
90 struct event_socket *ev = container_of(u, struct event_socket, uloop);
92 socklen_t errlen = sizeof(err);
95 nl_recvmsgs_default(ev->sock);
99 if (getsockopt(u->fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen))
104 // Increase rx buffer size on netlink socket
106 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
109 // Request full dump since some info got dropped
110 struct rtgenmsg msg = { .rtgen_family = AF_UNSPEC };
111 nl_send_simple(ev->sock, RTM_GETLINK, NLM_F_DUMP, &msg, sizeof(msg));
121 uloop_fd_delete(&ev->uloop);
125 static struct nl_sock *
126 create_socket(int protocol, int groups)
128 struct nl_sock *sock;
130 sock = nl_socket_alloc();
135 nl_join_groups(sock, groups);
137 if (nl_connect(sock, protocol))
144 create_raw_event_socket(struct event_socket *ev, int protocol, int groups,
145 uloop_fd_handler cb, int flags)
147 ev->sock = create_socket(protocol, groups);
151 ev->uloop.fd = nl_socket_get_fd(ev->sock);
153 if (uloop_fd_add(&ev->uloop, ULOOP_READ|flags))
160 create_event_socket(struct event_socket *ev, int protocol,
161 int (*cb)(struct nl_msg *msg, void *arg))
163 if (!create_raw_event_socket(ev, protocol, 0, handler_nl_event, ULOOP_ERROR_CB))
166 // Install the valid custom callback handler
167 nl_socket_modify_cb(ev->sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL);
169 // Disable sequence number checking on event sockets
170 nl_socket_disable_seq_check(ev->sock);
172 // Increase rx buffer size to 65K on event sockets
174 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
181 system_rtn_aton(const char *src, unsigned int *dst)
186 if (!strcmp(src, "local"))
188 else if (!strcmp(src, "nat"))
190 else if (!strcmp(src, "broadcast"))
192 else if (!strcmp(src, "anycast"))
194 else if (!strcmp(src, "multicast"))
196 else if (!strcmp(src, "prohibit"))
198 else if (!strcmp(src, "unreachable"))
200 else if (!strcmp(src, "blackhole"))
202 else if (!strcmp(src, "xresolve"))
204 else if (!strcmp(src, "unicast"))
206 else if (!strcmp(src, "throw"))
208 else if (!strcmp(src, "failed_policy"))
209 n = RTN_FAILED_POLICY;
211 n = strtoul(src, &e, 0);
212 if (!e || *e || e == src || n > 255)
221 system_tos_aton(const char *src, unsigned *dst)
225 *dst = strtoul(src, &e, 16);
226 if (e == src || *e || *dst > 255)
232 int system_init(void)
234 static struct event_socket rtnl_event;
235 static struct event_socket hotplug_event;
237 sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0);
238 system_fd_set_cloexec(sock_ioctl);
240 // Prepare socket for routing / address control
241 sock_rtnl = create_socket(NETLINK_ROUTE, 0);
245 if (!create_event_socket(&rtnl_event, NETLINK_ROUTE, cb_rtnl_event))
248 if (!create_raw_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT, 1,
249 handle_hotplug_event, 0))
252 // Receive network link events form kernel
253 nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK);
258 static void system_set_sysctl(const char *path, const char *val)
262 fd = open(path, O_WRONLY);
266 if (write(fd, val, strlen(val))) {}
270 static void system_set_dev_sysctl(const char *path, const char *device, const char *val)
272 snprintf(dev_buf, sizeof(dev_buf), path, device);
273 system_set_sysctl(dev_buf, val);
276 static void system_set_disable_ipv6(struct device *dev, const char *val)
278 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6", dev->ifname, val);
281 static void system_set_rpfilter(struct device *dev, const char *val)
283 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter", dev->ifname, val);
286 static void system_set_acceptlocal(struct device *dev, const char *val)
288 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local", dev->ifname, val);
291 static void system_set_igmpversion(struct device *dev, const char *val)
293 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version", dev->ifname, val);
296 static void system_set_mldversion(struct device *dev, const char *val)
298 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version", dev->ifname, val);
301 static void system_set_neigh4reachabletime(struct device *dev, const char *val)
303 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms", dev->ifname, val);
306 static void system_set_neigh6reachabletime(struct device *dev, const char *val)
308 system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", dev->ifname, val);
311 static void system_set_neigh4gcstaletime(struct device *dev, const char *val)
313 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/gc_stale_time", dev->ifname, val);
316 static void system_set_neigh6gcstaletime(struct device *dev, const char *val)
318 system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time", dev->ifname, val);
321 static void system_set_neigh4locktime(struct device *dev, const char *val)
323 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/locktime", dev->ifname, val);
326 static void system_set_dadtransmits(struct device *dev, const char *val)
328 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits", dev->ifname, val);
331 static void system_bridge_set_multicast_to_unicast(struct device *dev, const char *val)
333 system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_to_unicast", dev->ifname, val);
336 static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val)
338 system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_fast_leave", dev->ifname, val);
341 static void system_bridge_set_hairpin_mode(struct device *dev, const char *val)
343 system_set_dev_sysctl("/sys/class/net/%s/brport/hairpin_mode", dev->ifname, val);
346 static void system_bridge_set_multicast_router(struct device *dev, const char *val, bool bridge)
348 system_set_dev_sysctl(bridge ? "/sys/class/net/%s/bridge/multicast_router" :
349 "/sys/class/net/%s/brport/multicast_router",
353 static void system_bridge_set_robustness(struct device *dev, const char *val)
355 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_startup_query_count",
357 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_last_member_count",
361 static void system_bridge_set_query_interval(struct device *dev, const char *val)
363 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_query_interval",
367 static void system_bridge_set_query_response_interval(struct device *dev, const char *val)
369 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_query_response_interval",
373 static void system_bridge_set_last_member_interval(struct device *dev, const char *val)
375 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_last_member_interval",
379 static void system_bridge_set_membership_interval(struct device *dev, const char *val)
381 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_membership_interval",
385 static void system_bridge_set_other_querier_timeout(struct device *dev, const char *val)
387 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_querier_interval",
391 static void system_bridge_set_startup_query_interval(struct device *dev, const char *val)
393 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_startup_query_interval",
397 static void system_bridge_set_learning(struct device *dev, const char *val)
399 system_set_dev_sysctl("/sys/class/net/%s/brport/learning", dev->ifname, val);
402 static void system_bridge_set_unicast_flood(struct device *dev, const char *val)
404 system_set_dev_sysctl("/sys/class/net/%s/brport/unicast_flood", dev->ifname, val);
407 static void system_set_sendredirects(struct device *dev, const char *val)
409 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects", dev->ifname, val);
412 static int system_get_sysctl(const char *path, char *buf, const size_t buf_sz)
414 int fd = -1, ret = -1;
416 fd = open(path, O_RDONLY);
420 ssize_t len = read(fd, buf, buf_sz - 1);
434 system_get_dev_sysctl(const char *path, const char *device, char *buf, const size_t buf_sz)
436 snprintf(dev_buf, sizeof(dev_buf), path, device);
437 return system_get_sysctl(dev_buf, buf, buf_sz);
440 static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t buf_sz)
442 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6",
443 dev->ifname, buf, buf_sz);
446 static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz)
448 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter",
449 dev->ifname, buf, buf_sz);
452 static int system_get_acceptlocal(struct device *dev, char *buf, const size_t buf_sz)
454 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local",
455 dev->ifname, buf, buf_sz);
458 static int system_get_igmpversion(struct device *dev, char *buf, const size_t buf_sz)
460 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version",
461 dev->ifname, buf, buf_sz);
464 static int system_get_mldversion(struct device *dev, char *buf, const size_t buf_sz)
466 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version",
467 dev->ifname, buf, buf_sz);
470 static int system_get_neigh4reachabletime(struct device *dev, char *buf, const size_t buf_sz)
472 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms",
473 dev->ifname, buf, buf_sz);
476 static int system_get_neigh6reachabletime(struct device *dev, char *buf, const size_t buf_sz)
478 return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms",
479 dev->ifname, buf, buf_sz);
482 static int system_get_neigh4gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
484 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/gc_stale_time",
485 dev->ifname, buf, buf_sz);
488 static int system_get_neigh6gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
490 return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time",
491 dev->ifname, buf, buf_sz);
494 static int system_get_neigh4locktime(struct device *dev, char *buf, const size_t buf_sz)
496 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/locktime",
497 dev->ifname, buf, buf_sz);
500 static int system_get_dadtransmits(struct device *dev, char *buf, const size_t buf_sz)
502 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits",
503 dev->ifname, buf, buf_sz);
506 static int system_get_sendredirects(struct device *dev, char *buf, const size_t buf_sz)
508 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects",
509 dev->ifname, buf, buf_sz);
512 // Evaluate netlink messages
513 static int cb_rtnl_event(struct nl_msg *msg, void *arg)
515 struct nlmsghdr *nh = nlmsg_hdr(msg);
516 struct nlattr *nla[__IFLA_MAX];
520 if (nh->nlmsg_type != RTM_NEWLINK)
523 nlmsg_parse(nh, sizeof(struct ifinfomsg), nla, __IFLA_MAX - 1, NULL);
524 if (!nla[IFLA_IFNAME])
527 struct device *dev = device_find(nla_data(nla[IFLA_IFNAME]));
531 if (!system_get_dev_sysctl("/sys/class/net/%s/carrier", dev->ifname, buf, sizeof(buf)))
532 link_state = strtoul(buf, NULL, 0);
534 device_set_link(dev, link_state ? true : false);
541 handle_hotplug_msg(char *data, int size)
543 const char *subsystem = NULL, *interface = NULL;
544 char *cur, *end, *sep;
549 if (!strncmp(data, "add@", 4))
551 else if (!strncmp(data, "remove@", 7))
556 skip = strlen(data) + 1;
559 for (cur = data + skip; cur < end; cur += skip) {
560 skip = strlen(cur) + 1;
562 sep = strchr(cur, '=');
567 if (!strcmp(cur, "INTERFACE"))
569 else if (!strcmp(cur, "SUBSYSTEM")) {
571 if (strcmp(subsystem, "net") != 0)
574 if (subsystem && interface)
580 dev = device_find(interface);
584 if (dev->type != &simple_device_type)
587 if (add && system_if_force_external(dev->ifname))
590 device_set_present(dev, add);
594 handle_hotplug_event(struct uloop_fd *u, unsigned int events)
596 struct event_socket *ev = container_of(u, struct event_socket, uloop);
597 struct sockaddr_nl nla;
598 unsigned char *buf = NULL;
601 while ((size = nl_recv(ev->sock, &nla, &buf, NULL)) > 0) {
603 handle_hotplug_msg((char *) buf, size);
609 static int system_rtnl_call(struct nl_msg *msg)
613 ret = nl_send_auto_complete(sock_rtnl, msg);
619 return nl_wait_for_ack(sock_rtnl);
622 int system_bridge_delbr(struct device *bridge)
624 return ioctl(sock_ioctl, SIOCBRDELBR, bridge->ifname);
627 static int system_bridge_if(const char *bridge, struct device *dev, int cmd, void *data)
631 memset(&ifr, 0, sizeof(ifr));
633 ifr.ifr_ifindex = dev->ifindex;
636 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name));
637 return ioctl(sock_ioctl, cmd, &ifr);
640 static bool system_is_bridge(const char *name, char *buf, int buflen)
644 snprintf(buf, buflen, "/sys/devices/virtual/net/%s/bridge", name);
645 if (stat(buf, &st) < 0)
651 static char *system_get_bridge(const char *name, char *buf, int buflen)
657 snprintf(buf, buflen, "/sys/devices/virtual/net/*/brif/%s/bridge", name);
658 if (glob(buf, GLOB_NOSORT, NULL, &gl) < 0)
662 len = readlink(gl.gl_pathv[0], buf, buflen);
670 path = strrchr(buf, '/');
678 system_bridge_set_wireless(struct device *bridge, struct device *dev)
680 bool mcast_to_ucast = dev->wireless_ap;
683 if (bridge->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST &&
684 !bridge->settings.multicast_to_unicast)
685 mcast_to_ucast = false;
687 if (!mcast_to_ucast || dev->wireless_isolate)
690 system_bridge_set_multicast_to_unicast(dev, mcast_to_ucast ? "1" : "0");
691 system_bridge_set_hairpin_mode(dev, hairpin ? "1" : "0");
694 int system_bridge_addif(struct device *bridge, struct device *dev)
700 oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
701 if (!oldbr || strcmp(oldbr, bridge->ifname) != 0)
702 ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
705 system_bridge_set_wireless(bridge, dev);
707 if (dev->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
708 snprintf(buf, sizeof(buf), "%i", dev->settings.multicast_router);
709 system_bridge_set_multicast_router(dev, buf, false);
712 if (dev->settings.flags & DEV_OPT_MULTICAST_FAST_LEAVE &&
713 dev->settings.multicast_fast_leave)
714 system_bridge_set_multicast_fast_leave(dev, "1");
716 if (dev->settings.flags & DEV_OPT_LEARNING &&
717 !dev->settings.learning)
718 system_bridge_set_learning(dev, "0");
720 if (dev->settings.flags & DEV_OPT_UNICAST_FLOOD &&
721 !dev->settings.unicast_flood)
722 system_bridge_set_unicast_flood(dev, "0");
727 int system_bridge_delif(struct device *bridge, struct device *dev)
729 return system_bridge_if(bridge->ifname, dev, SIOCBRDELIF, NULL);
732 int system_if_resolve(struct device *dev)
735 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
736 if (!ioctl(sock_ioctl, SIOCGIFINDEX, &ifr))
737 return ifr.ifr_ifindex;
742 static int system_if_flags(const char *ifname, unsigned add, unsigned rem)
746 memset(&ifr, 0, sizeof(ifr));
747 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
748 ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr);
749 ifr.ifr_flags |= add;
750 ifr.ifr_flags &= ~rem;
751 return ioctl(sock_ioctl, SIOCSIFFLAGS, &ifr);
763 static bool check_ifaddr(struct nlmsghdr *hdr, int ifindex)
765 struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
767 return ifa->ifa_index == ifindex;
770 static bool check_route(struct nlmsghdr *hdr, int ifindex)
772 struct rtmsg *r = NLMSG_DATA(hdr);
773 struct nlattr *tb[__RTA_MAX];
775 if (r->rtm_protocol == RTPROT_KERNEL &&
776 r->rtm_family == AF_INET6)
779 nlmsg_parse(hdr, sizeof(struct rtmsg), tb, __RTA_MAX - 1, NULL);
783 return *(int *)RTA_DATA(tb[RTA_OIF]) == ifindex;
786 static bool check_rule(struct nlmsghdr *hdr, int ifindex)
791 static int cb_clear_event(struct nl_msg *msg, void *arg)
793 struct clear_data *clr = arg;
794 struct nlmsghdr *hdr = nlmsg_hdr(msg);
795 bool (*cb)(struct nlmsghdr *, int ifindex);
801 if (hdr->nlmsg_type != RTM_NEWADDR)
808 if (hdr->nlmsg_type != RTM_NEWROUTE)
815 if (hdr->nlmsg_type != RTM_NEWRULE)
824 if (!cb(hdr, clr->dev ? clr->dev->ifindex : 0))
827 if (type == RTM_DELRULE)
828 D(SYSTEM, "Remove a rule\n");
830 D(SYSTEM, "Remove %s from device %s\n",
831 type == RTM_DELADDR ? "an address" : "a route",
833 memcpy(nlmsg_hdr(clr->msg), hdr, hdr->nlmsg_len);
834 hdr = nlmsg_hdr(clr->msg);
835 hdr->nlmsg_type = type;
836 hdr->nlmsg_flags = NLM_F_REQUEST;
838 nl_socket_disable_auto_ack(sock_rtnl);
839 nl_send_auto_complete(sock_rtnl, clr->msg);
840 nl_socket_enable_auto_ack(sock_rtnl);
846 cb_finish_event(struct nl_msg *msg, void *arg)
854 error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
857 *pending = err->error;
862 system_if_clear_entries(struct device *dev, int type, int af)
864 struct clear_data clr;
865 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
868 .rtm_flags = RTM_F_CLONED,
870 int flags = NLM_F_DUMP;
879 clr.size = sizeof(struct rtgenmsg);
882 clr.size = sizeof(struct rtmsg);
891 clr.msg = nlmsg_alloc_simple(type, flags);
895 nlmsg_append(clr.msg, &rtm, clr.size, 0);
896 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_clear_event, &clr);
897 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_finish_event, &pending);
898 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &pending);
900 nl_send_auto_complete(sock_rtnl, clr.msg);
902 nl_recvmsgs(sock_rtnl, cb);
910 * Clear bridge (membership) state and bring down device
912 void system_if_clear_state(struct device *dev)
914 static char buf[256];
917 device_set_ifindex(dev, system_if_resolve(dev));
918 if (dev->external || !dev->ifindex)
921 system_if_flags(dev->ifname, 0, IFF_UP);
923 if (system_is_bridge(dev->ifname, buf, sizeof(buf))) {
924 D(SYSTEM, "Delete existing bridge named '%s'\n", dev->ifname);
925 system_bridge_delbr(dev);
929 bridge = system_get_bridge(dev->ifname, buf, sizeof(buf));
931 D(SYSTEM, "Remove device '%s' from bridge '%s'\n", dev->ifname, bridge);
932 system_bridge_if(bridge, dev, SIOCBRDELIF, NULL);
935 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET);
936 system_if_clear_entries(dev, RTM_GETADDR, AF_INET);
937 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET6);
938 system_if_clear_entries(dev, RTM_GETADDR, AF_INET6);
939 system_set_disable_ipv6(dev, "0");
942 static inline unsigned long
943 sec_to_jiffies(int val)
945 return (unsigned long) val * 100;
948 static void system_bridge_conf_multicast_deps(struct device *bridge,
949 struct bridge_config *cfg,
955 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS ||
956 cfg->flags & BRIDGE_OPT_QUERY_INTERVAL ||
957 cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
958 val = cfg->robustness * cfg->query_interval +
959 cfg->query_response_interval;
961 snprintf(buf, buf_len, "%i", val);
962 system_bridge_set_membership_interval(bridge, buf);
964 val = cfg->robustness * cfg->query_interval +
965 cfg->query_response_interval / 2;
967 snprintf(buf, buf_len, "%i", val);
968 system_bridge_set_other_querier_timeout(bridge, buf);
971 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
972 val = cfg->query_interval / 4;
974 snprintf(buf, buf_len, "%i", val);
975 system_bridge_set_startup_query_interval(bridge, buf);
979 static void system_bridge_conf_multicast(struct device *bridge,
980 struct bridge_config *cfg,
984 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_snooping",
985 bridge->ifname, cfg->igmp_snoop ? "1" : "0");
987 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_querier",
988 bridge->ifname, cfg->multicast_querier ? "1" : "0");
990 snprintf(buf, buf_len, "%i", cfg->hash_max);
991 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/hash_max",
992 bridge->ifname, buf);
994 if (bridge->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
995 snprintf(buf, buf_len, "%i", bridge->settings.multicast_router);
996 system_bridge_set_multicast_router(bridge, buf, true);
999 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS) {
1000 snprintf(buf, buf_len, "%i", cfg->robustness);
1001 system_bridge_set_robustness(bridge, buf);
1004 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
1005 snprintf(buf, buf_len, "%i", cfg->query_interval);
1006 system_bridge_set_query_interval(bridge, buf);
1009 if (cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
1010 snprintf(buf, buf_len, "%i", cfg->query_response_interval);
1011 system_bridge_set_query_response_interval(bridge, buf);
1014 if (cfg->flags & BRIDGE_OPT_LAST_MEMBER_INTERVAL) {
1015 snprintf(buf, buf_len, "%i", cfg->last_member_interval);
1016 system_bridge_set_last_member_interval(bridge, buf);
1019 system_bridge_conf_multicast_deps(bridge, cfg, buf, buf_len);
1022 int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg)
1025 unsigned long args[4] = {};
1027 if (ioctl(sock_ioctl, SIOCBRADDBR, bridge->ifname) < 0)
1030 args[0] = BRCTL_SET_BRIDGE_STP_STATE;
1031 args[1] = !!cfg->stp;
1032 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1034 args[0] = BRCTL_SET_BRIDGE_FORWARD_DELAY;
1035 args[1] = sec_to_jiffies(cfg->forward_delay);
1036 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1038 system_bridge_conf_multicast(bridge, cfg, buf, sizeof(buf));
1040 args[0] = BRCTL_SET_BRIDGE_PRIORITY;
1041 args[1] = cfg->priority;
1042 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1044 if (cfg->flags & BRIDGE_OPT_AGEING_TIME) {
1045 args[0] = BRCTL_SET_AGEING_TIME;
1046 args[1] = sec_to_jiffies(cfg->ageing_time);
1047 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1050 if (cfg->flags & BRIDGE_OPT_HELLO_TIME) {
1051 args[0] = BRCTL_SET_BRIDGE_HELLO_TIME;
1052 args[1] = sec_to_jiffies(cfg->hello_time);
1053 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1056 if (cfg->flags & BRIDGE_OPT_MAX_AGE) {
1057 args[0] = BRCTL_SET_BRIDGE_MAX_AGE;
1058 args[1] = sec_to_jiffies(cfg->max_age);
1059 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
1065 int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvlan_config *cfg)
1068 struct nlattr *linkinfo, *data;
1069 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
1071 static const struct {
1073 enum macvlan_mode val;
1075 { "private", MACVLAN_MODE_PRIVATE },
1076 { "vepa", MACVLAN_MODE_VEPA },
1077 { "bridge", MACVLAN_MODE_BRIDGE },
1078 { "passthru", MACVLAN_MODE_PASSTHRU },
1081 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1086 nlmsg_append(msg, &iim, sizeof(iim), 0);
1088 if (cfg->flags & MACVLAN_OPT_MACADDR)
1089 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1090 nla_put_string(msg, IFLA_IFNAME, macvlan->ifname);
1091 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1093 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1094 goto nla_put_failure;
1096 nla_put_string(msg, IFLA_INFO_KIND, "macvlan");
1098 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1099 goto nla_put_failure;
1102 for (i = 0; i < ARRAY_SIZE(modes); i++) {
1103 if (strcmp(cfg->mode, modes[i].name) != 0)
1106 nla_put_u32(msg, IFLA_MACVLAN_MODE, modes[i].val);
1111 nla_nest_end(msg, data);
1112 nla_nest_end(msg, linkinfo);
1114 rv = system_rtnl_call(msg);
1116 D(SYSTEM, "Error adding macvlan '%s' over '%s': %d\n", macvlan->ifname, dev->ifname, rv);
1125 static int system_link_del(const char *ifname)
1128 struct ifinfomsg iim = {
1129 .ifi_family = AF_UNSPEC,
1133 msg = nlmsg_alloc_simple(RTM_DELLINK, NLM_F_REQUEST);
1138 nlmsg_append(msg, &iim, sizeof(iim), 0);
1139 nla_put_string(msg, IFLA_IFNAME, ifname);
1140 return system_rtnl_call(msg);
1143 int system_macvlan_del(struct device *macvlan)
1145 return system_link_del(macvlan->ifname);
1148 int system_veth_add(struct device *veth, struct veth_config *cfg)
1151 struct ifinfomsg empty_iim = {};
1152 struct nlattr *linkinfo, *data, *veth_info;
1155 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1160 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
1162 if (cfg->flags & VETH_OPT_MACADDR)
1163 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1164 nla_put_string(msg, IFLA_IFNAME, veth->ifname);
1166 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1167 goto nla_put_failure;
1169 nla_put_string(msg, IFLA_INFO_KIND, "veth");
1171 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1172 goto nla_put_failure;
1174 if (!(veth_info = nla_nest_start(msg, VETH_INFO_PEER)))
1175 goto nla_put_failure;
1177 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
1179 if (cfg->flags & VETH_OPT_PEER_NAME)
1180 nla_put_string(msg, IFLA_IFNAME, cfg->peer_name);
1181 if (cfg->flags & VETH_OPT_PEER_MACADDR)
1182 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->peer_macaddr), cfg->peer_macaddr);
1184 nla_nest_end(msg, veth_info);
1185 nla_nest_end(msg, data);
1186 nla_nest_end(msg, linkinfo);
1188 rv = system_rtnl_call(msg);
1190 if (cfg->flags & VETH_OPT_PEER_NAME)
1191 D(SYSTEM, "Error adding veth '%s' with peer '%s': %d\n", veth->ifname, cfg->peer_name, rv);
1193 D(SYSTEM, "Error adding veth '%s': %d\n", veth->ifname, rv);
1203 int system_veth_del(struct device *veth)
1205 return system_link_del(veth->ifname);
1208 static int system_vlan(struct device *dev, int id)
1210 struct vlan_ioctl_args ifr = {
1211 .cmd = SET_VLAN_NAME_TYPE_CMD,
1212 .u.name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD,
1215 ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);
1218 ifr.cmd = DEL_VLAN_CMD;
1221 ifr.cmd = ADD_VLAN_CMD;
1224 strncpy(ifr.device1, dev->ifname, sizeof(ifr.device1));
1225 return ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);
1228 int system_vlan_add(struct device *dev, int id)
1230 return system_vlan(dev, id);
1233 int system_vlan_del(struct device *dev)
1235 return system_vlan(dev, -1);
1238 int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlandev_config *cfg)
1241 struct nlattr *linkinfo, *data;
1242 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC };
1245 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1250 nlmsg_append(msg, &iim, sizeof(iim), 0);
1251 nla_put_string(msg, IFLA_IFNAME, vlandev->ifname);
1252 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1254 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1255 goto nla_put_failure;
1257 nla_put_string(msg, IFLA_INFO_KIND, "vlan");
1259 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1260 goto nla_put_failure;
1262 nla_put_u16(msg, IFLA_VLAN_ID, cfg->vid);
1264 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
1265 nla_put_u16(msg, IFLA_VLAN_PROTOCOL, htons(cfg->proto));
1267 if(cfg->proto == VLAN_PROTO_8021AD)
1268 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);
1271 nla_nest_end(msg, data);
1272 nla_nest_end(msg, linkinfo);
1274 rv = system_rtnl_call(msg);
1276 D(SYSTEM, "Error adding vlandev '%s' over '%s': %d\n", vlandev->ifname, dev->ifname, rv);
1285 int system_vlandev_del(struct device *vlandev)
1287 return system_link_del(vlandev->ifname);
1291 system_if_get_settings(struct device *dev, struct device_settings *s)
1296 memset(&ifr, 0, sizeof(ifr));
1297 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
1299 if (ioctl(sock_ioctl, SIOCGIFMTU, &ifr) == 0) {
1300 s->mtu = ifr.ifr_mtu;
1301 s->flags |= DEV_OPT_MTU;
1304 s->mtu6 = system_update_ipv6_mtu(dev, 0);
1306 s->flags |= DEV_OPT_MTU6;
1308 if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) {
1309 s->txqueuelen = ifr.ifr_qlen;
1310 s->flags |= DEV_OPT_TXQUEUELEN;
1313 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) {
1314 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr));
1315 s->flags |= DEV_OPT_MACADDR;
1318 if (!system_get_disable_ipv6(dev, buf, sizeof(buf))) {
1319 s->ipv6 = !strtoul(buf, NULL, 0);
1320 s->flags |= DEV_OPT_IPV6;
1323 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) == 0) {
1324 s->promisc = ifr.ifr_flags & IFF_PROMISC;
1325 s->flags |= DEV_OPT_PROMISC;
1327 s->multicast = ifr.ifr_flags & IFF_MULTICAST;
1328 s->flags |= DEV_OPT_MULTICAST;
1331 if (!system_get_rpfilter(dev, buf, sizeof(buf))) {
1332 s->rpfilter = strtoul(buf, NULL, 0);
1333 s->flags |= DEV_OPT_RPFILTER;
1336 if (!system_get_acceptlocal(dev, buf, sizeof(buf))) {
1337 s->acceptlocal = strtoul(buf, NULL, 0);
1338 s->flags |= DEV_OPT_ACCEPTLOCAL;
1341 if (!system_get_igmpversion(dev, buf, sizeof(buf))) {
1342 s->igmpversion = strtoul(buf, NULL, 0);
1343 s->flags |= DEV_OPT_IGMPVERSION;
1346 if (!system_get_mldversion(dev, buf, sizeof(buf))) {
1347 s->mldversion = strtoul(buf, NULL, 0);
1348 s->flags |= DEV_OPT_MLDVERSION;
1351 if (!system_get_neigh4reachabletime(dev, buf, sizeof(buf))) {
1352 s->neigh4reachabletime = strtoul(buf, NULL, 0);
1353 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
1356 if (!system_get_neigh6reachabletime(dev, buf, sizeof(buf))) {
1357 s->neigh6reachabletime = strtoul(buf, NULL, 0);
1358 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
1361 if (!system_get_neigh4locktime(dev, buf, sizeof(buf))) {
1362 s->neigh4locktime = strtoul(buf, NULL, 0);
1363 s->flags |= DEV_OPT_NEIGHLOCKTIME;
1366 if (!system_get_neigh4gcstaletime(dev, buf, sizeof(buf))) {
1367 s->neigh4gcstaletime = strtoul(buf, NULL, 0);
1368 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
1371 if (!system_get_neigh6gcstaletime(dev, buf, sizeof(buf))) {
1372 s->neigh6gcstaletime = strtoul(buf, NULL, 0);
1373 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
1376 if (!system_get_dadtransmits(dev, buf, sizeof(buf))) {
1377 s->dadtransmits = strtoul(buf, NULL, 0);
1378 s->flags |= DEV_OPT_DADTRANSMITS;
1381 if (!system_get_sendredirects(dev, buf, sizeof(buf))) {
1382 s->sendredirects = strtoul(buf, NULL, 0);
1383 s->flags |= DEV_OPT_SENDREDIRECTS;
1388 system_if_set_rps_xps_val(const char *path, int val)
1394 if (glob(path, 0, NULL, &gl))
1397 snprintf(val_buf, sizeof(val_buf), "%x", val);
1398 for (i = 0; i < gl.gl_pathc; i++)
1399 system_set_sysctl(gl.gl_pathv[i], val_buf);
1405 system_if_apply_rps_xps(struct device *dev, struct device_settings *s)
1407 long n_cpus = sysconf(_SC_NPROCESSORS_ONLN);
1413 val = (1 << n_cpus) - 1;
1414 snprintf(dev_buf, sizeof(dev_buf), "/sys/class/net/%s/queues/*/rps_cpus", dev->ifname);
1415 system_if_set_rps_xps_val(dev_buf, s->rps ? val : 0);
1417 snprintf(dev_buf, sizeof(dev_buf), "/sys/class/net/%s/queues/*/xps_cpus", dev->ifname);
1418 system_if_set_rps_xps_val(dev_buf, s->xps ? val : 0);
1422 system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned int apply_mask)
1427 memset(&ifr, 0, sizeof(ifr));
1428 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
1429 if (s->flags & DEV_OPT_MTU & apply_mask) {
1430 ifr.ifr_mtu = s->mtu;
1431 if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0)
1432 s->flags &= ~DEV_OPT_MTU;
1434 if (s->flags & DEV_OPT_MTU6 & apply_mask) {
1435 system_update_ipv6_mtu(dev, s->mtu6);
1437 if (s->flags & DEV_OPT_TXQUEUELEN & apply_mask) {
1438 ifr.ifr_qlen = s->txqueuelen;
1439 if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0)
1440 s->flags &= ~DEV_OPT_TXQUEUELEN;
1442 if ((s->flags & DEV_OPT_MACADDR & apply_mask) && !dev->external) {
1443 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
1444 memcpy(&ifr.ifr_hwaddr.sa_data, s->macaddr, sizeof(s->macaddr));
1445 if (ioctl(sock_ioctl, SIOCSIFHWADDR, &ifr) < 0)
1446 s->flags &= ~DEV_OPT_MACADDR;
1448 if (s->flags & DEV_OPT_IPV6 & apply_mask)
1449 system_set_disable_ipv6(dev, s->ipv6 ? "0" : "1");
1450 if (s->flags & DEV_OPT_PROMISC & apply_mask) {
1451 if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0,
1452 !s->promisc ? IFF_PROMISC : 0) < 0)
1453 s->flags &= ~DEV_OPT_PROMISC;
1455 if (s->flags & DEV_OPT_RPFILTER & apply_mask) {
1456 snprintf(buf, sizeof(buf), "%d", s->rpfilter);
1457 system_set_rpfilter(dev, buf);
1459 if (s->flags & DEV_OPT_ACCEPTLOCAL & apply_mask)
1460 system_set_acceptlocal(dev, s->acceptlocal ? "1" : "0");
1461 if (s->flags & DEV_OPT_IGMPVERSION & apply_mask) {
1462 snprintf(buf, sizeof(buf), "%d", s->igmpversion);
1463 system_set_igmpversion(dev, buf);
1465 if (s->flags & DEV_OPT_MLDVERSION & apply_mask) {
1466 snprintf(buf, sizeof(buf), "%d", s->mldversion);
1467 system_set_mldversion(dev, buf);
1469 if (s->flags & DEV_OPT_NEIGHREACHABLETIME & apply_mask) {
1470 snprintf(buf, sizeof(buf), "%d", s->neigh4reachabletime);
1471 system_set_neigh4reachabletime(dev, buf);
1472 snprintf(buf, sizeof(buf), "%d", s->neigh6reachabletime);
1473 system_set_neigh6reachabletime(dev, buf);
1475 if (s->flags & DEV_OPT_NEIGHLOCKTIME & apply_mask) {
1476 snprintf(buf, sizeof(buf), "%d", s->neigh4locktime);
1477 system_set_neigh4locktime(dev, buf);
1479 if (s->flags & DEV_OPT_NEIGHGCSTALETIME & apply_mask) {
1480 snprintf(buf, sizeof(buf), "%d", s->neigh4gcstaletime);
1481 system_set_neigh4gcstaletime(dev, buf);
1482 snprintf(buf, sizeof(buf), "%d", s->neigh6gcstaletime);
1483 system_set_neigh6gcstaletime(dev, buf);
1485 if (s->flags & DEV_OPT_DADTRANSMITS & apply_mask) {
1486 snprintf(buf, sizeof(buf), "%d", s->dadtransmits);
1487 system_set_dadtransmits(dev, buf);
1489 if (s->flags & DEV_OPT_MULTICAST & apply_mask) {
1490 if (system_if_flags(dev->ifname, s->multicast ? IFF_MULTICAST : 0,
1491 !s->multicast ? IFF_MULTICAST : 0) < 0)
1492 s->flags &= ~DEV_OPT_MULTICAST;
1494 if (s->flags & DEV_OPT_SENDREDIRECTS & apply_mask)
1495 system_set_sendredirects(dev, s->sendredirects ? "1" : "0");
1497 system_if_apply_rps_xps(dev, s);
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_scope = RT_SCOPE_UNIVERSE;
1905 msg = nlmsg_alloc_simple(cmd, flags);
1909 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1912 nla_put(msg, RTA_DST, alen, &route->addr);
1914 if (route->sourcemask) {
1915 if (rtm.rtm_family == AF_INET)
1916 nla_put(msg, RTA_PREFSRC, alen, &route->source);
1918 nla_put(msg, RTA_SRC, alen, &route->source);
1921 if (route->metric > 0)
1922 nla_put_u32(msg, RTA_PRIORITY, route->metric);
1925 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop);
1928 nla_put_u32(msg, RTA_OIF, dev->ifindex);
1931 nla_put_u32(msg, RTA_TABLE, table);
1933 if (route->flags & DEVROUTE_MTU) {
1934 struct nlattr *metrics;
1936 if (!(metrics = nla_nest_start(msg, RTA_METRICS)))
1937 goto nla_put_failure;
1939 nla_put_u32(msg, RTAX_MTU, route->mtu);
1941 nla_nest_end(msg, metrics);
1944 return system_rtnl_call(msg);
1951 int system_add_route(struct device *dev, struct device_route *route)
1953 return system_rt(dev, route, RTM_NEWROUTE);
1956 int system_del_route(struct device *dev, struct device_route *route)
1958 return system_rt(dev, route, RTM_DELROUTE);
1961 int system_flush_routes(void)
1963 const char *names[] = {
1964 "/proc/sys/net/ipv4/route/flush",
1965 "/proc/sys/net/ipv6/route/flush"
1969 for (i = 0; i < ARRAY_SIZE(names); i++) {
1970 fd = open(names[i], O_WRONLY);
1974 if (write(fd, "-1", 2)) {}
1980 bool system_resolve_rt_type(const char *type, unsigned int *id)
1982 return system_rtn_aton(type, id);
1985 bool system_resolve_rt_proto(const char *type, unsigned int *id)
1989 unsigned int n, proto = 256;
1991 if ((n = strtoul(type, &e, 0)) >= 0 && !*e && e != type)
1993 else if (!strcmp(type, "unspec"))
1994 proto = RTPROT_UNSPEC;
1995 else if (!strcmp(type, "kernel"))
1996 proto = RTPROT_KERNEL;
1997 else if (!strcmp(type, "boot"))
1998 proto = RTPROT_BOOT;
1999 else if (!strcmp(type, "static"))
2000 proto = RTPROT_STATIC;
2001 else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) {
2002 while (fgets(buf, sizeof(buf) - 1, f) != NULL) {
2003 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2006 n = strtoul(e, NULL, 10);
2007 e = strtok(NULL, " \t\n");
2009 if (e && !strcmp(e, type)) {
2024 bool system_resolve_rt_table(const char *name, unsigned int *id)
2028 unsigned int n, table = RT_TABLE_UNSPEC;
2030 /* first try to parse table as number */
2031 if ((n = strtoul(name, &e, 0)) > 0 && !*e)
2034 /* handle well known aliases */
2035 else if (!strcmp(name, "default"))
2036 table = RT_TABLE_DEFAULT;
2037 else if (!strcmp(name, "main"))
2038 table = RT_TABLE_MAIN;
2039 else if (!strcmp(name, "local"))
2040 table = RT_TABLE_LOCAL;
2042 /* try to look up name in /etc/iproute2/rt_tables */
2043 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL)
2045 while (fgets(buf, sizeof(buf) - 1, f) != NULL)
2047 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2050 n = strtoul(e, NULL, 10);
2051 e = strtok(NULL, " \t\n");
2053 if (e && !strcmp(e, name))
2063 if (table == RT_TABLE_UNSPEC)
2070 bool system_is_default_rt_table(unsigned int id)
2072 return (id == RT_TABLE_MAIN);
2075 bool system_resolve_rpfilter(const char *filter, unsigned int *id)
2080 if (!strcmp(filter, "strict"))
2082 else if (!strcmp(filter, "loose"))
2085 n = strtoul(filter, &e, 0);
2086 if (*e || e == filter || n > 2)
2094 static int system_iprule(struct iprule *rule, int cmd)
2096 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16;
2099 struct rtmsg rtm = {
2100 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
2101 .rtm_protocol = RTPROT_STATIC,
2102 .rtm_scope = RT_SCOPE_UNIVERSE,
2103 .rtm_table = RT_TABLE_UNSPEC,
2104 .rtm_type = RTN_UNSPEC,
2108 if (cmd == RTM_NEWRULE)
2109 rtm.rtm_type = RTN_UNICAST;
2112 rtm.rtm_flags |= FIB_RULE_INVERT;
2114 if (rule->flags & IPRULE_SRC)
2115 rtm.rtm_src_len = rule->src_mask;
2117 if (rule->flags & IPRULE_DEST)
2118 rtm.rtm_dst_len = rule->dest_mask;
2120 if (rule->flags & IPRULE_TOS)
2121 rtm.rtm_tos = rule->tos;
2123 if (rule->flags & IPRULE_LOOKUP) {
2124 if (rule->lookup < 256)
2125 rtm.rtm_table = rule->lookup;
2128 if (rule->flags & IPRULE_ACTION)
2129 rtm.rtm_type = rule->action;
2130 else if (rule->flags & IPRULE_GOTO)
2131 rtm.rtm_type = FR_ACT_GOTO;
2132 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO)))
2133 rtm.rtm_type = FR_ACT_NOP;
2135 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST);
2140 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
2142 if (rule->flags & IPRULE_IN)
2143 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev);
2145 if (rule->flags & IPRULE_OUT)
2146 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev);
2148 if (rule->flags & IPRULE_SRC)
2149 nla_put(msg, FRA_SRC, alen, &rule->src_addr);
2151 if (rule->flags & IPRULE_DEST)
2152 nla_put(msg, FRA_DST, alen, &rule->dest_addr);
2154 if (rule->flags & IPRULE_PRIORITY)
2155 nla_put_u32(msg, FRA_PRIORITY, rule->priority);
2156 else if (cmd == RTM_NEWRULE)
2157 nla_put_u32(msg, FRA_PRIORITY, rule->order);
2159 if (rule->flags & IPRULE_FWMARK)
2160 nla_put_u32(msg, FRA_FWMARK, rule->fwmark);
2162 if (rule->flags & IPRULE_FWMASK)
2163 nla_put_u32(msg, FRA_FWMASK, rule->fwmask);
2165 if (rule->flags & IPRULE_LOOKUP) {
2166 if (rule->lookup >= 256)
2167 nla_put_u32(msg, FRA_TABLE, rule->lookup);
2170 if (rule->flags & IPRULE_GOTO)
2171 nla_put_u32(msg, FRA_GOTO, rule->gotoid);
2173 return system_rtnl_call(msg);
2176 int system_add_iprule(struct iprule *rule)
2178 return system_iprule(rule, RTM_NEWRULE);
2181 int system_del_iprule(struct iprule *rule)
2183 return system_iprule(rule, RTM_DELRULE);
2186 int system_flush_iprules(void)
2191 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET);
2192 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6);
2194 memset(&rule, 0, sizeof(rule));
2197 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2200 rule.lookup = RT_TABLE_LOCAL;
2201 rv |= system_iprule(&rule, RTM_NEWRULE);
2203 rule.priority = 32766;
2204 rule.lookup = RT_TABLE_MAIN;
2205 rv |= system_iprule(&rule, RTM_NEWRULE);
2207 rule.priority = 32767;
2208 rule.lookup = RT_TABLE_DEFAULT;
2209 rv |= system_iprule(&rule, RTM_NEWRULE);
2212 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2215 rule.lookup = RT_TABLE_LOCAL;
2216 rv |= system_iprule(&rule, RTM_NEWRULE);
2218 rule.priority = 32766;
2219 rule.lookup = RT_TABLE_MAIN;
2220 rv |= system_iprule(&rule, RTM_NEWRULE);
2225 bool system_resolve_iprule_action(const char *action, unsigned int *id)
2227 return system_rtn_aton(action, id);
2230 time_t system_get_rtime(void)
2235 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts) == 0)
2238 if (gettimeofday(&tv, NULL) == 0)
2245 #define IP_DF 0x4000
2248 static int tunnel_ioctl(const char *name, int cmd, void *p)
2252 memset(&ifr, 0, sizeof(ifr));
2253 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
2254 ifr.ifr_ifru.ifru_data = p;
2255 return ioctl(sock_ioctl, cmd, &ifr);
2258 #ifdef IFLA_IPTUN_MAX
2259 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000)
2260 static int system_add_gre_tunnel(const char *name, const char *kind,
2261 const unsigned int link, struct blob_attr **tb, bool v6)
2264 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
2265 struct blob_attr *cur;
2266 uint32_t ikey = 0, okey = 0, flags = 0, flowinfo = 0;
2267 uint16_t iflags = 0, oflags = 0;
2269 int ret = 0, ttl = 0;
2271 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2275 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2276 nla_put_string(nlm, IFLA_IFNAME, name);
2278 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2284 nla_put_string(nlm, IFLA_INFO_KIND, kind);
2285 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2292 nla_put_u32(nlm, IFLA_GRE_LINK, link);
2294 if ((cur = tb[TUNNEL_ATTR_TTL]))
2295 ttl = blobmsg_get_u32(cur);
2297 if ((cur = tb[TUNNEL_ATTR_TOS])) {
2298 char *str = blobmsg_get_string(cur);
2299 if (strcmp(str, "inherit")) {
2302 if (!system_tos_aton(str, &uval)) {
2308 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS;
2313 flags |= IP6_TNL_F_USE_ORIG_TCLASS;
2319 if ((cur = tb[TUNNEL_ATTR_INFO]) && (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)) {
2320 uint8_t icsum, ocsum, iseqno, oseqno;
2321 if (sscanf(blobmsg_get_string(cur), "%u,%u,%hhu,%hhu,%hhu,%hhu",
2322 &ikey, &okey, &icsum, &ocsum, &iseqno, &oseqno) < 6) {
2347 struct in6_addr in6buf;
2348 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2349 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2353 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf);
2356 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2357 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2361 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf);
2363 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, 4);
2366 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo);
2369 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags);
2374 struct in_addr inbuf;
2377 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2378 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2382 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf);
2385 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2386 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2390 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf);
2392 if (IN_MULTICAST(ntohl(inbuf.s_addr))) {
2394 okey = inbuf.s_addr;
2399 ikey = inbuf.s_addr;
2405 if ((cur = tb[TUNNEL_ATTR_DF]))
2406 set_df = blobmsg_get_bool(cur);
2409 /* ttl != 0 and nopmtudisc are incompatible */
2417 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0);
2419 nla_put_u8(nlm, IFLA_GRE_TOS, tos);
2423 nla_put_u8(nlm, IFLA_GRE_TTL, ttl);
2426 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags);
2429 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags);
2432 nla_put_u32(nlm, IFLA_GRE_OKEY, okey);
2435 nla_put_u32(nlm, IFLA_GRE_IKEY, ikey);
2437 nla_nest_end(nlm, infodata);
2438 nla_nest_end(nlm, linkinfo);
2440 return system_rtnl_call(nlm);
2449 static int system_add_vti_tunnel(const char *name, const char *kind,
2450 const unsigned int link, struct blob_attr **tb, bool v6)
2453 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
2454 struct blob_attr *cur;
2455 uint32_t ikey = 0, okey = 0;
2458 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2462 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2463 nla_put_string(nlm, IFLA_IFNAME, name);
2465 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2471 nla_put_string(nlm, IFLA_INFO_KIND, kind);
2472 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2479 nla_put_u32(nlm, IFLA_VTI_LINK, link);
2481 if ((cur = tb[TUNNEL_ATTR_INFO]) && (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)) {
2482 if (sscanf(blobmsg_get_string(cur), "%u,%u",
2483 &ikey, &okey) < 2) {
2490 struct in6_addr in6buf;
2491 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2492 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2496 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(in6buf), &in6buf);
2499 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2500 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2504 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(in6buf), &in6buf);
2508 struct in_addr inbuf;
2510 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2511 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2515 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(inbuf), &inbuf);
2518 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2519 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2523 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(inbuf), &inbuf);
2529 nla_put_u32(nlm, IFLA_VTI_OKEY, htonl(okey));
2532 nla_put_u32(nlm, IFLA_VTI_IKEY, htonl(ikey));
2534 nla_nest_end(nlm, infodata);
2535 nla_nest_end(nlm, linkinfo);
2537 return system_rtnl_call(nlm);
2545 #ifdef IFLA_VXLAN_MAX
2546 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6)
2548 struct blob_attr *tb_data[__VXLAN_DATA_ATTR_MAX];
2550 struct nlattr *linkinfo, *data;
2551 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
2552 struct blob_attr *cur;
2555 if ((cur = tb[TUNNEL_ATTR_DATA]))
2556 blobmsg_parse(vxlan_data_attr_list.params, __VXLAN_DATA_ATTR_MAX, tb_data,
2557 blobmsg_data(cur), blobmsg_len(cur));
2561 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
2566 nlmsg_append(msg, &iim, sizeof(iim), 0);
2568 nla_put_string(msg, IFLA_IFNAME, name);
2570 if ((cur = tb_data[VXLAN_DATA_ATTR_MACADDR])) {
2571 struct ether_addr *ea = ether_aton(blobmsg_get_string(cur));
2577 nla_put(msg, IFLA_ADDRESS, ETH_ALEN, ea);
2580 if ((cur = tb[TUNNEL_ATTR_MTU])) {
2581 uint32_t mtu = blobmsg_get_u32(cur);
2582 nla_put_u32(msg, IFLA_MTU, mtu);
2585 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) {
2590 nla_put_string(msg, IFLA_INFO_KIND, "vxlan");
2592 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) {
2598 nla_put_u32(msg, IFLA_VXLAN_LINK, link);
2600 if ((cur = tb_data[VXLAN_DATA_ATTR_ID])) {
2601 uint32_t id = blobmsg_get_u32(cur);
2602 if (id >= (1u << 24) - 1) {
2607 nla_put_u32(msg, IFLA_VXLAN_ID, id);
2611 struct in6_addr in6buf;
2612 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2613 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2617 nla_put(msg, IFLA_VXLAN_LOCAL6, sizeof(in6buf), &in6buf);
2620 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2621 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2625 nla_put(msg, IFLA_VXLAN_GROUP6, sizeof(in6buf), &in6buf);
2628 struct in_addr inbuf;
2630 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2631 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2635 nla_put(msg, IFLA_VXLAN_LOCAL, sizeof(inbuf), &inbuf);
2638 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2639 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2643 nla_put(msg, IFLA_VXLAN_GROUP, sizeof(inbuf), &inbuf);
2647 uint32_t port = 4789;
2648 if ((cur = tb_data[VXLAN_DATA_ATTR_PORT])) {
2649 port = blobmsg_get_u32(cur);
2650 if (port < 1 || port > 65535) {
2655 nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port));
2657 if ((cur = tb[TUNNEL_ATTR_TOS])) {
2658 char *str = blobmsg_get_string(cur);
2661 if (strcmp(str, "inherit")) {
2662 if (!system_tos_aton(str, &tos))
2666 nla_put_u8(msg, IFLA_VXLAN_TOS, tos);
2669 if ((cur = tb[TUNNEL_ATTR_TTL])) {
2670 uint32_t ttl = blobmsg_get_u32(cur);
2671 if (ttl < 1 || ttl > 255) {
2676 nla_put_u8(msg, IFLA_VXLAN_TTL, ttl);
2679 nla_nest_end(msg, data);
2680 nla_nest_end(msg, linkinfo);
2682 ret = system_rtnl_call(msg);
2684 D(SYSTEM, "Error adding vxlan '%s': %d\n", name, ret);
2694 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb)
2696 struct blob_attr *cur;
2698 struct ip_tunnel_parm p = {
2707 if ((cur = tb[TUNNEL_ATTR_LOCAL]) &&
2708 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1)
2711 if ((cur = tb[TUNNEL_ATTR_REMOTE]) &&
2712 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1)
2715 if ((cur = tb[TUNNEL_ATTR_DF]))
2716 set_df = blobmsg_get_bool(cur);
2718 if ((cur = tb[TUNNEL_ATTR_TTL]))
2719 p.iph.ttl = blobmsg_get_u32(cur);
2721 if ((cur = tb[TUNNEL_ATTR_TOS])) {
2722 char *str = blobmsg_get_string(cur);
2723 if (strcmp(str, "inherit")) {
2726 if (!system_tos_aton(str, &uval))
2734 p.iph.frag_off = set_df ? htons(IP_DF) : 0;
2735 /* ttl !=0 and nopmtudisc are incompatible */
2736 if (p.iph.ttl && p.iph.frag_off == 0)
2739 strncpy(p.name, name, sizeof(p.name));
2741 switch (p.iph.protocol) {
2743 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p);
2745 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p);
2752 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb)
2754 struct blob_attr *cur;
2757 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
2759 str = blobmsg_data(cur);
2761 if (!strcmp(str, "greip") || !strcmp(str, "gretapip") ||
2762 !strcmp(str, "greip6") || !strcmp(str, "gretapip6") ||
2763 !strcmp(str, "vtiip") || !strcmp(str, "vtiip6") ||
2764 !strcmp(str, "vxlan") || !strcmp(str, "vxlan6"))
2765 return system_link_del(name);
2767 return tunnel_ioctl(name, SIOCDELTUNNEL, NULL);
2770 int system_del_ip_tunnel(const char *name, struct blob_attr *attr)
2772 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
2774 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
2775 blob_data(attr), blob_len(attr));
2777 return __system_del_ip_tunnel(name, tb);
2780 int system_update_ipv6_mtu(struct device *dev, int mtu)
2786 snprintf(buf, sizeof(buf), "/proc/sys/net/ipv6/conf/%s/mtu",
2789 fd = open(buf, O_RDWR);
2794 ssize_t len = read(fd, buf, sizeof(buf) - 1);
2801 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0)
2810 int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
2812 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
2813 struct blob_attr *cur;
2816 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
2817 blob_data(attr), blob_len(attr));
2819 __system_del_ip_tunnel(name, tb);
2821 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
2823 str = blobmsg_data(cur);
2825 unsigned int ttl = 0;
2826 if ((cur = tb[TUNNEL_ATTR_TTL])) {
2827 ttl = blobmsg_get_u32(cur);
2832 unsigned int link = 0;
2833 if ((cur = tb[TUNNEL_ATTR_LINK])) {
2834 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
2838 if (iface->l3_dev.dev)
2839 link = iface->l3_dev.dev->ifindex;
2842 if (!strcmp(str, "sit")) {
2843 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
2847 if ((cur = tb[TUNNEL_ATTR_6RD_PREFIX])) {
2849 struct ip_tunnel_6rd p6;
2851 memset(&p6, 0, sizeof(p6));
2853 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur),
2854 &p6.prefix, &mask) || mask > 128)
2856 p6.prefixlen = mask;
2858 if ((cur = tb[TUNNEL_ATTR_6RD_RELAY_PREFIX])) {
2859 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur),
2860 &p6.relay_prefix, &mask) || mask > 32)
2862 p6.relay_prefixlen = mask;
2865 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) {
2866 __system_del_ip_tunnel(name, tb);
2871 #ifdef IFLA_IPTUN_MAX
2872 } else if (!strcmp(str, "ipip6")) {
2873 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK,
2874 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2875 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC };
2881 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2882 nla_put_string(nlm, IFLA_IFNAME, name);
2885 nla_put_u32(nlm, IFLA_LINK, link);
2887 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2892 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl");
2893 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2900 nla_put_u32(nlm, IFLA_IPTUN_LINK, link);
2902 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP);
2903 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64);
2904 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, 4);
2906 struct in6_addr in6buf;
2907 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2908 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2912 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf);
2915 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2916 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2920 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf);
2923 #ifdef IFLA_IPTUN_FMR_MAX
2924 if ((cur = tb[TUNNEL_ATTR_FMRS])) {
2925 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS);
2927 struct blob_attr *fmr;
2928 unsigned rem, fmrcnt = 0;
2929 blobmsg_for_each_attr(fmr, cur, rem) {
2930 if (blobmsg_type(fmr) != BLOBMSG_TYPE_STRING)
2933 unsigned ip4len, ip6len, ealen, offset = 6;
2937 if (sscanf(blobmsg_get_string(fmr), "%47[^/]/%u,%15[^/]/%u,%u,%u",
2938 ip6buf, &ip6len, ip4buf, &ip4len, &ealen, &offset) < 5) {
2943 struct in6_addr ip6prefix;
2944 struct in_addr ip4prefix;
2945 if (inet_pton(AF_INET6, ip6buf, &ip6prefix) != 1 ||
2946 inet_pton(AF_INET, ip4buf, &ip4prefix) != 1) {
2951 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt);
2953 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix);
2954 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix);
2955 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len);
2956 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len);
2957 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen);
2958 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset);
2960 nla_nest_end(nlm, rule);
2963 nla_nest_end(nlm, fmrs);
2967 nla_nest_end(nlm, infodata);
2968 nla_nest_end(nlm, linkinfo);
2970 return system_rtnl_call(nlm);
2974 } else if (!strcmp(str, "greip")) {
2975 return system_add_gre_tunnel(name, "gre", link, tb, false);
2976 } else if (!strcmp(str, "gretapip")) {
2977 return system_add_gre_tunnel(name, "gretap", link, tb, false);
2978 } else if (!strcmp(str, "greip6")) {
2979 return system_add_gre_tunnel(name, "ip6gre", link, tb, true);
2980 } else if (!strcmp(str, "gretapip6")) {
2981 return system_add_gre_tunnel(name, "ip6gretap", link, tb, true);
2983 } else if (!strcmp(str, "vtiip")) {
2984 return system_add_vti_tunnel(name, "vti", link, tb, false);
2985 } else if (!strcmp(str, "vtiip6")) {
2986 return system_add_vti_tunnel(name, "vti6", link, tb, true);
2988 #ifdef IFLA_VXLAN_MAX
2989 } else if(!strcmp(str, "vxlan")) {
2990 return system_add_vxlan(name, link, tb, false);
2991 } else if(!strcmp(str, "vxlan6")) {
2992 return system_add_vxlan(name, link, tb, true);
2995 } else if (!strcmp(str, "ipip")) {
2996 return system_add_proto_tunnel(name, IPPROTO_IPIP, link, tb);