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>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
19 #include <sys/socket.h>
20 #include <sys/ioctl.h>
22 #include <sys/syscall.h>
25 #include <net/if_arp.h>
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
30 #include <linux/rtnetlink.h>
31 #include <linux/sockios.h>
33 #include <linux/if_addr.h>
34 #include <linux/if_link.h>
35 #include <linux/if_vlan.h>
36 #include <linux/if_bridge.h>
37 #include <linux/if_tunnel.h>
38 #include <linux/ip6_tunnel.h>
39 #include <linux/ethtool.h>
40 #include <linux/fib_rules.h>
41 #include <linux/version.h>
43 #ifndef RTN_FAILED_POLICY
44 #define RTN_FAILED_POLICY 12
47 #ifndef RT_TABLE_PRELOCAL
48 #define RT_TABLE_PRELOCAL 128
51 #ifndef IFA_F_NOPREFIXROUTE
52 #define IFA_F_NOPREFIXROUTE 0x200
56 #define IFA_FLAGS (IFA_MULTICAST + 1)
66 #include <netlink/msg.h>
67 #include <netlink/attr.h>
68 #include <netlink/socket.h>
69 #include <libubox/uloop.h>
76 struct uloop_fd uloop;
81 static int sock_ioctl = -1;
82 static struct nl_sock *sock_rtnl = NULL;
84 static int cb_rtnl_event(struct nl_msg *msg, void *arg);
85 static void handle_hotplug_event(struct uloop_fd *u, unsigned int events);
87 static char dev_buf[256];
90 handler_nl_event(struct uloop_fd *u, unsigned int events)
92 struct event_socket *ev = container_of(u, struct event_socket, uloop);
94 socklen_t errlen = sizeof(err);
97 nl_recvmsgs_default(ev->sock);
101 if (getsockopt(u->fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen))
106 // Increase rx buffer size on netlink socket
108 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
111 // Request full dump since some info got dropped
112 struct rtgenmsg msg = { .rtgen_family = AF_UNSPEC };
113 nl_send_simple(ev->sock, RTM_GETLINK, NLM_F_DUMP, &msg, sizeof(msg));
123 uloop_fd_delete(&ev->uloop);
127 static struct nl_sock *
128 create_socket(int protocol, int groups)
130 struct nl_sock *sock;
132 sock = nl_socket_alloc();
137 nl_join_groups(sock, groups);
139 if (nl_connect(sock, protocol))
146 create_raw_event_socket(struct event_socket *ev, int protocol, int groups,
147 uloop_fd_handler cb, int flags)
149 ev->sock = create_socket(protocol, groups);
153 ev->uloop.fd = nl_socket_get_fd(ev->sock);
155 if (uloop_fd_add(&ev->uloop, ULOOP_READ|flags))
162 create_event_socket(struct event_socket *ev, int protocol,
163 int (*cb)(struct nl_msg *msg, void *arg))
165 if (!create_raw_event_socket(ev, protocol, 0, handler_nl_event, ULOOP_ERROR_CB))
168 // Install the valid custom callback handler
169 nl_socket_modify_cb(ev->sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL);
171 // Disable sequence number checking on event sockets
172 nl_socket_disable_seq_check(ev->sock);
174 // Increase rx buffer size to 65K on event sockets
176 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
183 system_rtn_aton(const char *src, unsigned int *dst)
188 if (!strcmp(src, "local"))
190 else if (!strcmp(src, "nat"))
192 else if (!strcmp(src, "broadcast"))
194 else if (!strcmp(src, "anycast"))
196 else if (!strcmp(src, "multicast"))
198 else if (!strcmp(src, "prohibit"))
200 else if (!strcmp(src, "unreachable"))
202 else if (!strcmp(src, "blackhole"))
204 else if (!strcmp(src, "xresolve"))
206 else if (!strcmp(src, "unicast"))
208 else if (!strcmp(src, "throw"))
210 else if (!strcmp(src, "failed_policy"))
211 n = RTN_FAILED_POLICY;
213 n = strtoul(src, &e, 0);
214 if (!e || *e || e == src || n > 255)
223 system_tos_aton(const char *src, unsigned *dst)
227 *dst = strtoul(src, &e, 16);
228 if (e == src || *e || *dst > 255)
234 int system_init(void)
236 static struct event_socket rtnl_event;
237 static struct event_socket hotplug_event;
239 sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0);
240 system_fd_set_cloexec(sock_ioctl);
242 // Prepare socket for routing / address control
243 sock_rtnl = create_socket(NETLINK_ROUTE, 0);
247 if (!create_event_socket(&rtnl_event, NETLINK_ROUTE, cb_rtnl_event))
250 if (!create_raw_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT, 1,
251 handle_hotplug_event, 0))
254 // Receive network link events form kernel
255 nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK);
260 static void system_set_sysctl(const char *path, const char *val)
264 fd = open(path, O_WRONLY);
268 if (write(fd, val, strlen(val))) {}
272 static void system_set_dev_sysctl(const char *path, const char *device, const char *val)
274 snprintf(dev_buf, sizeof(dev_buf), path, device);
275 system_set_sysctl(dev_buf, val);
278 static void system_set_disable_ipv6(struct device *dev, const char *val)
280 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6", dev->ifname, val);
283 static void system_set_rpfilter(struct device *dev, const char *val)
285 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter", dev->ifname, val);
288 static void system_set_acceptlocal(struct device *dev, const char *val)
290 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local", dev->ifname, val);
293 static void system_set_igmpversion(struct device *dev, const char *val)
295 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version", dev->ifname, val);
298 static void system_set_mldversion(struct device *dev, const char *val)
300 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version", dev->ifname, val);
303 static void system_set_neigh4reachabletime(struct device *dev, const char *val)
305 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms", dev->ifname, val);
308 static void system_set_neigh6reachabletime(struct device *dev, const char *val)
310 system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", dev->ifname, val);
313 static int system_get_sysctl(const char *path, char *buf, const size_t buf_sz)
315 int fd = -1, ret = -1;
317 fd = open(path, O_RDONLY);
321 ssize_t len = read(fd, buf, buf_sz - 1);
335 system_get_dev_sysctl(const char *path, const char *device, char *buf, const size_t buf_sz)
337 snprintf(dev_buf, sizeof(dev_buf), path, device);
338 return system_get_sysctl(dev_buf, buf, buf_sz);
341 static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t buf_sz)
343 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6",
344 dev->ifname, buf, buf_sz);
347 static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz)
349 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter",
350 dev->ifname, buf, buf_sz);
353 static int system_get_acceptlocal(struct device *dev, char *buf, const size_t buf_sz)
355 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local",
356 dev->ifname, buf, buf_sz);
359 static int system_get_igmpversion(struct device *dev, char *buf, const size_t buf_sz)
361 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version",
362 dev->ifname, buf, buf_sz);
365 static int system_get_mldversion(struct device *dev, char *buf, const size_t buf_sz)
367 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version",
368 dev->ifname, buf, buf_sz);
371 static int system_get_neigh4reachabletime(struct device *dev, char *buf, const size_t buf_sz)
373 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms",
374 dev->ifname, buf, buf_sz);
377 static int system_get_neigh6reachabletime(struct device *dev, char *buf, const size_t buf_sz)
379 return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms",
380 dev->ifname, buf, buf_sz);
383 // Evaluate netlink messages
384 static int cb_rtnl_event(struct nl_msg *msg, void *arg)
386 struct nlmsghdr *nh = nlmsg_hdr(msg);
387 struct nlattr *nla[__IFLA_MAX];
391 if (nh->nlmsg_type != RTM_NEWLINK)
394 nlmsg_parse(nh, sizeof(struct ifinfomsg), nla, __IFLA_MAX - 1, NULL);
395 if (!nla[IFLA_IFNAME])
398 struct device *dev = device_get(nla_data(nla[IFLA_IFNAME]), false);
399 if (!dev || dev->type->keep_link_status)
402 if (!system_get_dev_sysctl("/sys/class/net/%s/carrier", dev->ifname, buf, sizeof(buf)))
403 link_state = strtoul(buf, NULL, 0);
405 device_set_link(dev, link_state ? true : false);
412 handle_hotplug_msg(char *data, int size)
414 const char *subsystem = NULL, *interface = NULL;
415 char *cur, *end, *sep;
420 if (!strncmp(data, "add@", 4))
422 else if (!strncmp(data, "remove@", 7))
427 skip = strlen(data) + 1;
430 for (cur = data + skip; cur < end; cur += skip) {
431 skip = strlen(cur) + 1;
433 sep = strchr(cur, '=');
438 if (!strcmp(cur, "INTERFACE"))
440 else if (!strcmp(cur, "SUBSYSTEM")) {
442 if (strcmp(subsystem, "net") != 0)
445 if (subsystem && interface)
451 dev = device_get(interface, false);
455 if (dev->type != &simple_device_type)
458 if (add && system_if_force_external(dev->ifname))
461 device_set_present(dev, add);
465 handle_hotplug_event(struct uloop_fd *u, unsigned int events)
467 struct event_socket *ev = container_of(u, struct event_socket, uloop);
468 struct sockaddr_nl nla;
469 unsigned char *buf = NULL;
472 while ((size = nl_recv(ev->sock, &nla, &buf, NULL)) > 0) {
474 handle_hotplug_msg((char *) buf, size);
480 static int system_rtnl_call(struct nl_msg *msg)
484 ret = nl_send_auto_complete(sock_rtnl, msg);
490 return nl_wait_for_ack(sock_rtnl);
493 int system_bridge_delbr(struct device *bridge)
495 return ioctl(sock_ioctl, SIOCBRDELBR, bridge->ifname);
498 static int system_bridge_if(const char *bridge, struct device *dev, int cmd, void *data)
502 memset(&ifr, 0, sizeof(ifr));
504 ifr.ifr_ifindex = dev->ifindex;
507 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name));
508 return ioctl(sock_ioctl, cmd, &ifr);
511 static bool system_is_bridge(const char *name, char *buf, int buflen)
515 snprintf(buf, buflen, "/sys/devices/virtual/net/%s/bridge", name);
516 if (stat(buf, &st) < 0)
522 static char *system_get_bridge(const char *name, char *buf, int buflen)
528 snprintf(buf, buflen, "/sys/devices/virtual/net/*/brif/%s/bridge", name);
529 if (glob(buf, GLOB_NOSORT, NULL, &gl) < 0)
533 len = readlink(gl.gl_pathv[0], buf, buflen);
541 path = strrchr(buf, '/');
548 static void system_bridge_set_wireless(const char *bridge, const char *dev)
550 snprintf(dev_buf, sizeof(dev_buf),
551 "/sys/devices/virtual/net/%s/brif/%s/multicast_to_unicast",
553 system_set_sysctl(dev_buf, "1");
556 int system_bridge_addif(struct device *bridge, struct device *dev)
561 oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
562 if (!oldbr || strcmp(oldbr, bridge->ifname) != 0)
563 ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
566 system_bridge_set_wireless(bridge->ifname, dev->ifname);
571 int system_bridge_delif(struct device *bridge, struct device *dev)
573 return system_bridge_if(bridge->ifname, dev, SIOCBRDELIF, NULL);
576 int system_if_resolve(struct device *dev)
579 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
580 if (!ioctl(sock_ioctl, SIOCGIFINDEX, &ifr))
581 return ifr.ifr_ifindex;
586 static int system_if_flags(const char *ifname, unsigned add, unsigned rem)
590 memset(&ifr, 0, sizeof(ifr));
591 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
592 ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr);
593 ifr.ifr_flags |= add;
594 ifr.ifr_flags &= ~rem;
595 return ioctl(sock_ioctl, SIOCSIFFLAGS, &ifr);
607 static bool check_ifaddr(struct nlmsghdr *hdr, int ifindex)
609 struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
611 return ifa->ifa_index == ifindex;
614 static bool check_route(struct nlmsghdr *hdr, int ifindex)
616 struct rtmsg *r = NLMSG_DATA(hdr);
617 struct nlattr *tb[__RTA_MAX];
619 if (r->rtm_protocol == RTPROT_KERNEL &&
620 r->rtm_family == AF_INET6)
623 nlmsg_parse(hdr, sizeof(struct rtmsg), tb, __RTA_MAX - 1, NULL);
627 return *(int *)RTA_DATA(tb[RTA_OIF]) == ifindex;
630 static bool check_rule(struct nlmsghdr *hdr, int ifindex)
635 static int cb_clear_event(struct nl_msg *msg, void *arg)
637 struct clear_data *clr = arg;
638 struct nlmsghdr *hdr = nlmsg_hdr(msg);
639 bool (*cb)(struct nlmsghdr *, int ifindex);
645 if (hdr->nlmsg_type != RTM_NEWADDR)
652 if (hdr->nlmsg_type != RTM_NEWROUTE)
659 if (hdr->nlmsg_type != RTM_NEWRULE)
668 if (!cb(hdr, clr->dev ? clr->dev->ifindex : 0))
671 if (type == RTM_DELRULE)
672 D(SYSTEM, "Remove a rule\n");
674 D(SYSTEM, "Remove %s from device %s\n",
675 type == RTM_DELADDR ? "an address" : "a route",
677 memcpy(nlmsg_hdr(clr->msg), hdr, hdr->nlmsg_len);
678 hdr = nlmsg_hdr(clr->msg);
679 hdr->nlmsg_type = type;
680 hdr->nlmsg_flags = NLM_F_REQUEST;
682 nl_socket_disable_auto_ack(sock_rtnl);
683 nl_send_auto_complete(sock_rtnl, clr->msg);
684 nl_socket_enable_auto_ack(sock_rtnl);
690 cb_finish_event(struct nl_msg *msg, void *arg)
698 error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
701 *pending = err->error;
706 system_if_clear_entries(struct device *dev, int type, int af)
708 struct clear_data clr;
709 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
712 .rtm_flags = RTM_F_CLONED,
714 int flags = NLM_F_DUMP;
723 clr.size = sizeof(struct rtgenmsg);
726 clr.size = sizeof(struct rtmsg);
735 clr.msg = nlmsg_alloc_simple(type, flags);
739 nlmsg_append(clr.msg, &rtm, clr.size, 0);
740 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_clear_event, &clr);
741 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_finish_event, &pending);
742 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &pending);
744 nl_send_auto_complete(sock_rtnl, clr.msg);
746 nl_recvmsgs(sock_rtnl, cb);
754 * Clear bridge (membership) state and bring down device
756 void system_if_clear_state(struct device *dev)
758 static char buf[256];
761 device_set_ifindex(dev, system_if_resolve(dev));
762 if (dev->external || !dev->ifindex)
765 system_if_flags(dev->ifname, 0, IFF_UP);
767 if (system_is_bridge(dev->ifname, buf, sizeof(buf))) {
768 D(SYSTEM, "Delete existing bridge named '%s'\n", dev->ifname);
769 system_bridge_delbr(dev);
773 bridge = system_get_bridge(dev->ifname, buf, sizeof(buf));
775 D(SYSTEM, "Remove device '%s' from bridge '%s'\n", dev->ifname, bridge);
776 system_bridge_if(bridge, dev, SIOCBRDELIF, NULL);
779 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET);
780 system_if_clear_entries(dev, RTM_GETADDR, AF_INET);
781 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET6);
782 system_if_clear_entries(dev, RTM_GETADDR, AF_INET6);
783 system_set_disable_ipv6(dev, "0");
786 static inline unsigned long
787 sec_to_jiffies(int val)
789 return (unsigned long) val * 100;
792 int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg)
794 unsigned long args[4] = {};
796 if (ioctl(sock_ioctl, SIOCBRADDBR, bridge->ifname) < 0)
799 args[0] = BRCTL_SET_BRIDGE_STP_STATE;
800 args[1] = !!cfg->stp;
801 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
803 args[0] = BRCTL_SET_BRIDGE_FORWARD_DELAY;
804 args[1] = sec_to_jiffies(cfg->forward_delay);
805 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
807 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_snooping",
808 bridge->ifname, cfg->igmp_snoop ? "1" : "0");
810 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_querier",
811 bridge->ifname, cfg->multicast_querier ? "1" : "0");
813 args[0] = BRCTL_SET_BRIDGE_PRIORITY;
814 args[1] = cfg->priority;
815 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
817 if (cfg->flags & BRIDGE_OPT_AGEING_TIME) {
818 args[0] = BRCTL_SET_AGEING_TIME;
819 args[1] = sec_to_jiffies(cfg->ageing_time);
820 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
823 if (cfg->flags & BRIDGE_OPT_HELLO_TIME) {
824 args[0] = BRCTL_SET_BRIDGE_HELLO_TIME;
825 args[1] = sec_to_jiffies(cfg->hello_time);
826 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
829 if (cfg->flags & BRIDGE_OPT_MAX_AGE) {
830 args[0] = BRCTL_SET_BRIDGE_MAX_AGE;
831 args[1] = sec_to_jiffies(cfg->max_age);
832 system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
838 int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvlan_config *cfg)
841 struct nlattr *linkinfo, *data;
842 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
844 static const struct {
846 enum macvlan_mode val;
848 { "private", MACVLAN_MODE_PRIVATE },
849 { "vepa", MACVLAN_MODE_VEPA },
850 { "bridge", MACVLAN_MODE_BRIDGE },
851 { "passthru", MACVLAN_MODE_PASSTHRU },
854 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
859 nlmsg_append(msg, &iim, sizeof(iim), 0);
861 if (cfg->flags & MACVLAN_OPT_MACADDR)
862 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
863 nla_put_string(msg, IFLA_IFNAME, macvlan->ifname);
864 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
866 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
867 goto nla_put_failure;
869 nla_put_string(msg, IFLA_INFO_KIND, "macvlan");
871 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
872 goto nla_put_failure;
875 for (i = 0; i < ARRAY_SIZE(modes); i++) {
876 if (strcmp(cfg->mode, modes[i].name) != 0)
879 nla_put_u32(msg, IFLA_MACVLAN_MODE, modes[i].val);
884 nla_nest_end(msg, data);
885 nla_nest_end(msg, linkinfo);
887 rv = system_rtnl_call(msg);
889 D(SYSTEM, "Error adding macvlan '%s' over '%s': %d\n", macvlan->ifname, dev->ifname, rv);
898 static int system_link_del(const char *ifname)
901 struct ifinfomsg iim = {
902 .ifi_family = AF_UNSPEC,
906 msg = nlmsg_alloc_simple(RTM_DELLINK, NLM_F_REQUEST);
911 nlmsg_append(msg, &iim, sizeof(iim), 0);
912 nla_put_string(msg, IFLA_IFNAME, ifname);
913 return system_rtnl_call(msg);
916 int system_macvlan_del(struct device *macvlan)
918 return system_link_del(macvlan->ifname);
921 static int system_vlan(struct device *dev, int id)
923 struct vlan_ioctl_args ifr = {
924 .cmd = SET_VLAN_NAME_TYPE_CMD,
925 .u.name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD,
928 ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);
931 ifr.cmd = DEL_VLAN_CMD;
934 ifr.cmd = ADD_VLAN_CMD;
937 strncpy(ifr.device1, dev->ifname, sizeof(ifr.device1));
938 return ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);
941 int system_vlan_add(struct device *dev, int id)
943 return system_vlan(dev, id);
946 int system_vlan_del(struct device *dev)
948 return system_vlan(dev, -1);
951 int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlandev_config *cfg)
954 struct nlattr *linkinfo, *data;
955 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC };
958 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
963 nlmsg_append(msg, &iim, sizeof(iim), 0);
964 nla_put_string(msg, IFLA_IFNAME, vlandev->ifname);
965 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
967 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
968 goto nla_put_failure;
970 nla_put_string(msg, IFLA_INFO_KIND, "vlan");
972 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
973 goto nla_put_failure;
975 nla_put_u16(msg, IFLA_VLAN_ID, cfg->vid);
977 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
978 nla_put_u16(msg, IFLA_VLAN_PROTOCOL, htons(cfg->proto));
980 if(cfg->proto == VLAN_PROTO_8021AD)
981 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);
984 nla_nest_end(msg, data);
985 nla_nest_end(msg, linkinfo);
987 rv = system_rtnl_call(msg);
989 D(SYSTEM, "Error adding vlandev '%s' over '%s': %d\n", vlandev->ifname, dev->ifname, rv);
998 int system_vlandev_del(struct device *vlandev)
1000 return system_link_del(vlandev->ifname);
1004 system_if_get_settings(struct device *dev, struct device_settings *s)
1009 memset(&ifr, 0, sizeof(ifr));
1010 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
1012 if (ioctl(sock_ioctl, SIOCGIFMTU, &ifr) == 0) {
1013 s->mtu = ifr.ifr_mtu;
1014 s->flags |= DEV_OPT_MTU;
1017 if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) {
1018 s->txqueuelen = ifr.ifr_qlen;
1019 s->flags |= DEV_OPT_TXQUEUELEN;
1022 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) {
1023 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr));
1024 s->flags |= DEV_OPT_MACADDR;
1027 if (!system_get_disable_ipv6(dev, buf, sizeof(buf))) {
1028 s->ipv6 = !strtoul(buf, NULL, 0);
1029 s->flags |= DEV_OPT_IPV6;
1032 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) == 0) {
1033 s->promisc = ifr.ifr_flags & IFF_PROMISC;
1034 s->flags |= DEV_OPT_PROMISC;
1037 if (!system_get_rpfilter(dev, buf, sizeof(buf))) {
1038 s->rpfilter = strtoul(buf, NULL, 0);
1039 s->flags |= DEV_OPT_RPFILTER;
1042 if (!system_get_acceptlocal(dev, buf, sizeof(buf))) {
1043 s->acceptlocal = strtoul(buf, NULL, 0);
1044 s->flags |= DEV_OPT_ACCEPTLOCAL;
1047 if (!system_get_igmpversion(dev, buf, sizeof(buf))) {
1048 s->igmpversion = strtoul(buf, NULL, 0);
1049 s->flags |= DEV_OPT_IGMPVERSION;
1052 if (!system_get_mldversion(dev, buf, sizeof(buf))) {
1053 s->mldversion = strtoul(buf, NULL, 0);
1054 s->flags |= DEV_OPT_MLDVERSION;
1057 if (!system_get_neigh4reachabletime(dev, buf, sizeof(buf))) {
1058 s->neigh4reachabletime = strtoul(buf, NULL, 0);
1059 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
1062 if (!system_get_neigh6reachabletime(dev, buf, sizeof(buf))) {
1063 s->neigh6reachabletime = strtoul(buf, NULL, 0);
1064 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
1069 system_if_set_rps_xps_val(const char *path, int val)
1075 if (glob(path, 0, NULL, &gl))
1078 snprintf(val_buf, sizeof(val_buf), "%x", val);
1079 for (i = 0; i < gl.gl_pathc; i++)
1080 system_set_sysctl(gl.gl_pathv[i], val_buf);
1084 system_if_apply_rps_xps(struct device *dev, struct device_settings *s)
1086 long n_cpus = sysconf(_SC_NPROCESSORS_ONLN);
1092 val = (1 << n_cpus) - 1;
1093 snprintf(dev_buf, sizeof(dev_buf), "/sys/class/net/%s/queues/*/rps_cpus", dev->ifname);
1094 system_if_set_rps_xps_val(dev_buf, s->rps ? val : 0);
1096 snprintf(dev_buf, sizeof(dev_buf), "/sys/class/net/%s/queues/*/xps_cpus", dev->ifname);
1097 system_if_set_rps_xps_val(dev_buf, s->xps ? val : 0);
1101 system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned int apply_mask)
1105 memset(&ifr, 0, sizeof(ifr));
1106 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
1107 if (s->flags & DEV_OPT_MTU & apply_mask) {
1108 ifr.ifr_mtu = s->mtu;
1109 if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0)
1110 s->flags &= ~DEV_OPT_MTU;
1112 if (s->flags & DEV_OPT_TXQUEUELEN & apply_mask) {
1113 ifr.ifr_qlen = s->txqueuelen;
1114 if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0)
1115 s->flags &= ~DEV_OPT_TXQUEUELEN;
1117 if ((s->flags & DEV_OPT_MACADDR & apply_mask) && !dev->external) {
1118 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
1119 memcpy(&ifr.ifr_hwaddr.sa_data, s->macaddr, sizeof(s->macaddr));
1120 if (ioctl(sock_ioctl, SIOCSIFHWADDR, &ifr) < 0)
1121 s->flags &= ~DEV_OPT_MACADDR;
1123 if (s->flags & DEV_OPT_IPV6 & apply_mask)
1124 system_set_disable_ipv6(dev, s->ipv6 ? "0" : "1");
1125 if (s->flags & DEV_OPT_PROMISC & apply_mask) {
1126 if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0,
1127 !s->promisc ? IFF_PROMISC : 0) < 0)
1128 s->flags &= ~DEV_OPT_PROMISC;
1130 if (s->flags & DEV_OPT_RPFILTER & apply_mask) {
1133 snprintf(buf, sizeof(buf), "%d", s->rpfilter);
1134 system_set_rpfilter(dev, buf);
1136 if (s->flags & DEV_OPT_ACCEPTLOCAL & apply_mask)
1137 system_set_acceptlocal(dev, s->acceptlocal ? "1" : "0");
1138 if (s->flags & DEV_OPT_IGMPVERSION & apply_mask) {
1141 snprintf(buf, sizeof(buf), "%d", s->igmpversion);
1142 system_set_igmpversion(dev, buf);
1144 if (s->flags & DEV_OPT_MLDVERSION & apply_mask) {
1147 snprintf(buf, sizeof(buf), "%d", s->mldversion);
1148 system_set_mldversion(dev, buf);
1150 if (s->flags & DEV_OPT_NEIGHREACHABLETIME & apply_mask) {
1153 snprintf(buf, sizeof(buf), "%d", s->neigh4reachabletime);
1154 system_set_neigh4reachabletime(dev, buf);
1155 snprintf(buf, sizeof(buf), "%d", s->neigh6reachabletime);
1156 system_set_neigh6reachabletime(dev, buf);
1159 system_if_apply_rps_xps(dev, s);
1162 int system_if_up(struct device *dev)
1164 system_if_get_settings(dev, &dev->orig_settings);
1165 /* Only keep orig settings based on what needs to be set */
1166 dev->orig_settings.flags &= dev->settings.flags;
1167 system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
1168 return system_if_flags(dev->ifname, IFF_UP, 0);
1171 int system_if_down(struct device *dev)
1173 int ret = system_if_flags(dev->ifname, 0, IFF_UP);
1174 system_if_apply_settings(dev, &dev->orig_settings, dev->orig_settings.flags);
1178 struct if_check_data {
1184 #ifndef IFF_LOWER_UP
1185 #define IFF_LOWER_UP 0x10000
1188 static int cb_if_check_valid(struct nl_msg *msg, void *arg)
1190 struct nlmsghdr *nh = nlmsg_hdr(msg);
1191 struct ifinfomsg *ifi = NLMSG_DATA(nh);
1192 struct if_check_data *chk = (struct if_check_data *)arg;
1194 if (nh->nlmsg_type != RTM_NEWLINK)
1197 device_set_present(chk->dev, ifi->ifi_index > 0 ? true : false);
1198 device_set_link(chk->dev, ifi->ifi_flags & IFF_LOWER_UP ? true : false);
1203 static int cb_if_check_ack(struct nl_msg *msg, void *arg)
1205 struct if_check_data *chk = (struct if_check_data *)arg;
1210 static int cb_if_check_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1212 struct if_check_data *chk = (struct if_check_data *)arg;
1214 device_set_present(chk->dev, false);
1215 device_set_link(chk->dev, false);
1216 chk->pending = err->error;
1221 int system_if_check(struct device *dev)
1223 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1225 struct ifinfomsg ifi = {
1226 .ifi_family = AF_UNSPEC,
1229 struct if_check_data chk = {
1235 msg = nlmsg_alloc_simple(RTM_GETLINK, 0);
1236 if (!msg || nlmsg_append(msg, &ifi, sizeof(ifi), 0) ||
1237 nla_put_string(msg, IFLA_IFNAME, dev->ifname))
1240 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_check_valid, &chk);
1241 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_check_ack, &chk);
1242 nl_cb_err(cb, NL_CB_CUSTOM, cb_if_check_error, &chk);
1244 nl_send_auto_complete(sock_rtnl, msg);
1245 while (chk.pending > 0)
1246 nl_recvmsgs(sock_rtnl, cb);
1257 system_if_get_parent(struct device *dev)
1259 char buf[64], *devname;
1260 int ifindex, iflink, len;
1263 snprintf(buf, sizeof(buf), "/sys/class/net/%s/iflink", dev->ifname);
1264 f = fopen(buf, "r");
1268 len = fread(buf, 1, sizeof(buf) - 1, f);
1275 iflink = strtoul(buf, NULL, 0);
1276 ifindex = system_if_resolve(dev);
1277 if (!iflink || iflink == ifindex)
1280 devname = if_indextoname(iflink, buf);
1284 return device_get(devname, true);
1288 read_string_file(int dir_fd, const char *file, char *buf, int len)
1294 fd = openat(dir_fd, file, O_RDONLY);
1299 len = read(fd, buf, len - 1);
1303 } else if (len > 0) {
1306 c = strchr(buf, '\n');
1319 read_uint64_file(int dir_fd, const char *file, uint64_t *val)
1324 ret = read_string_file(dir_fd, file, buf, sizeof(buf));
1326 *val = strtoull(buf, NULL, 0);
1331 /* Assume advertised flags == supported flags */
1332 static const struct {
1335 } ethtool_link_modes[] = {
1336 { ADVERTISED_10baseT_Half, "10H" },
1337 { ADVERTISED_10baseT_Full, "10F" },
1338 { ADVERTISED_100baseT_Half, "100H" },
1339 { ADVERTISED_100baseT_Full, "100F" },
1340 { ADVERTISED_1000baseT_Half, "1000H" },
1341 { ADVERTISED_1000baseT_Full, "1000F" },
1344 static void system_add_link_modes(struct blob_buf *b, __u32 mask)
1347 for (i = 0; i < ARRAY_SIZE(ethtool_link_modes); i++) {
1348 if (mask & ethtool_link_modes[i].mask)
1349 blobmsg_add_string(b, NULL, ethtool_link_modes[i].name);
1354 system_if_force_external(const char *ifname)
1359 snprintf(buf, sizeof(buf), "/sys/class/net/%s/phy80211", ifname);
1360 return stat(buf, &s) == 0;
1364 system_if_dump_info(struct device *dev, struct blob_buf *b)
1366 struct ethtool_cmd ecmd;
1372 snprintf(buf, sizeof(buf), "/sys/class/net/%s", dev->ifname);
1373 dir_fd = open(buf, O_DIRECTORY);
1375 memset(&ecmd, 0, sizeof(ecmd));
1376 memset(&ifr, 0, sizeof(ifr));
1377 strcpy(ifr.ifr_name, dev->ifname);
1378 ifr.ifr_data = (caddr_t) &ecmd;
1379 ecmd.cmd = ETHTOOL_GSET;
1381 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == 0) {
1382 c = blobmsg_open_array(b, "link-advertising");
1383 system_add_link_modes(b, ecmd.advertising);
1384 blobmsg_close_array(b, c);
1386 c = blobmsg_open_array(b, "link-supported");
1387 system_add_link_modes(b, ecmd.supported);
1388 blobmsg_close_array(b, c);
1390 s = blobmsg_alloc_string_buffer(b, "speed", 8);
1391 snprintf(s, 8, "%d%c", ethtool_cmd_speed(&ecmd),
1392 ecmd.duplex == DUPLEX_HALF ? 'H' : 'F');
1393 blobmsg_add_string_buffer(b);
1401 system_if_dump_stats(struct device *dev, struct blob_buf *b)
1403 const char *const counters[] = {
1404 "collisions", "rx_frame_errors", "tx_compressed",
1405 "multicast", "rx_length_errors", "tx_dropped",
1406 "rx_bytes", "rx_missed_errors", "tx_errors",
1407 "rx_compressed", "rx_over_errors", "tx_fifo_errors",
1408 "rx_crc_errors", "rx_packets", "tx_heartbeat_errors",
1409 "rx_dropped", "tx_aborted_errors", "tx_packets",
1410 "rx_errors", "tx_bytes", "tx_window_errors",
1411 "rx_fifo_errors", "tx_carrier_errors",
1418 snprintf(buf, sizeof(buf), "/sys/class/net/%s/statistics", dev->ifname);
1419 stats_dir = open(buf, O_DIRECTORY);
1423 for (i = 0; i < ARRAY_SIZE(counters); i++)
1424 if (read_uint64_file(stats_dir, counters[i], &val))
1425 blobmsg_add_u64(b, counters[i], val);
1431 static int system_addr(struct device *dev, struct device_addr *addr, int cmd)
1433 bool v4 = ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4);
1434 int alen = v4 ? 4 : 16;
1435 unsigned int flags = 0;
1436 struct ifaddrmsg ifa = {
1437 .ifa_family = (alen == 4) ? AF_INET : AF_INET6,
1438 .ifa_prefixlen = addr->mask,
1439 .ifa_index = dev->ifindex,
1443 if (cmd == RTM_NEWADDR)
1444 flags |= NLM_F_CREATE | NLM_F_REPLACE;
1446 msg = nlmsg_alloc_simple(cmd, flags);
1450 nlmsg_append(msg, &ifa, sizeof(ifa), 0);
1451 nla_put(msg, IFA_LOCAL, alen, &addr->addr);
1453 if (addr->broadcast)
1454 nla_put_u32(msg, IFA_BROADCAST, addr->broadcast);
1455 if (addr->point_to_point)
1456 nla_put_u32(msg, IFA_ADDRESS, addr->point_to_point);
1458 time_t now = system_get_rtime();
1459 struct ifa_cacheinfo cinfo = {0xffffffffU, 0xffffffffU, 0, 0};
1461 if (addr->preferred_until) {
1462 int64_t preferred = addr->preferred_until - now;
1465 else if (preferred > UINT32_MAX)
1466 preferred = UINT32_MAX;
1468 cinfo.ifa_prefered = preferred;
1471 if (addr->valid_until) {
1472 int64_t valid = addr->valid_until - now;
1475 else if (valid > UINT32_MAX)
1478 cinfo.ifa_valid = valid;
1481 nla_put(msg, IFA_CACHEINFO, sizeof(cinfo), &cinfo);
1483 if (cmd == RTM_NEWADDR && (addr->flags & DEVADDR_OFFLINK))
1484 nla_put_u32(msg, IFA_FLAGS, IFA_F_NOPREFIXROUTE);
1487 return system_rtnl_call(msg);
1490 int system_add_address(struct device *dev, struct device_addr *addr)
1492 return system_addr(dev, addr, RTM_NEWADDR);
1495 int system_del_address(struct device *dev, struct device_addr *addr)
1497 return system_addr(dev, addr, RTM_DELADDR);
1500 static int system_rt(struct device *dev, struct device_route *route, int cmd)
1502 int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
1504 unsigned int flags = 0;
1507 have_gw = !!route->nexthop.in.s_addr;
1509 have_gw = route->nexthop.in6.s6_addr32[0] ||
1510 route->nexthop.in6.s6_addr32[1] ||
1511 route->nexthop.in6.s6_addr32[2] ||
1512 route->nexthop.in6.s6_addr32[3];
1514 unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))
1515 ? route->table : RT_TABLE_MAIN;
1517 struct rtmsg rtm = {
1518 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
1519 .rtm_dst_len = route->mask,
1520 .rtm_src_len = route->sourcemask,
1521 .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC,
1522 .rtm_protocol = (route->flags & DEVADDR_KERNEL) ? RTPROT_KERNEL : RTPROT_STATIC,
1523 .rtm_scope = RT_SCOPE_NOWHERE,
1524 .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST,
1525 .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0,
1529 if (cmd == RTM_NEWROUTE) {
1530 flags |= NLM_F_CREATE | NLM_F_REPLACE;
1532 if (!dev) { // Add null-route
1533 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
1534 rtm.rtm_type = RTN_UNREACHABLE;
1537 rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
1540 if (route->flags & DEVROUTE_TYPE) {
1541 rtm.rtm_type = route->type;
1542 if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) {
1543 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST ||
1544 rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST)
1545 rtm.rtm_table = RT_TABLE_LOCAL;
1548 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) {
1549 rtm.rtm_scope = RT_SCOPE_HOST;
1550 } else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
1551 rtm.rtm_type == RTN_ANYCAST) {
1552 rtm.rtm_scope = RT_SCOPE_LINK;
1553 } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE ||
1554 rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY) {
1555 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
1560 msg = nlmsg_alloc_simple(cmd, flags);
1564 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1567 nla_put(msg, RTA_DST, alen, &route->addr);
1569 if (route->sourcemask) {
1570 if (rtm.rtm_family == AF_INET)
1571 nla_put(msg, RTA_PREFSRC, alen, &route->source);
1573 nla_put(msg, RTA_SRC, alen, &route->source);
1576 if (route->metric > 0)
1577 nla_put_u32(msg, RTA_PRIORITY, route->metric);
1580 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop);
1583 nla_put_u32(msg, RTA_OIF, dev->ifindex);
1586 nla_put_u32(msg, RTA_TABLE, table);
1588 if (route->flags & DEVROUTE_MTU) {
1589 struct nlattr *metrics;
1591 if (!(metrics = nla_nest_start(msg, RTA_METRICS)))
1592 goto nla_put_failure;
1594 nla_put_u32(msg, RTAX_MTU, route->mtu);
1596 nla_nest_end(msg, metrics);
1599 return system_rtnl_call(msg);
1606 int system_add_route(struct device *dev, struct device_route *route)
1608 return system_rt(dev, route, RTM_NEWROUTE);
1611 int system_del_route(struct device *dev, struct device_route *route)
1613 return system_rt(dev, route, RTM_DELROUTE);
1616 int system_flush_routes(void)
1618 const char *names[] = {
1619 "/proc/sys/net/ipv4/route/flush",
1620 "/proc/sys/net/ipv6/route/flush"
1624 for (i = 0; i < ARRAY_SIZE(names); i++) {
1625 fd = open(names[i], O_WRONLY);
1629 if (write(fd, "-1", 2)) {}
1635 bool system_resolve_rt_type(const char *type, unsigned int *id)
1637 return system_rtn_aton(type, id);
1640 bool system_resolve_rt_table(const char *name, unsigned int *id)
1644 unsigned int n, table = RT_TABLE_UNSPEC;
1646 /* first try to parse table as number */
1647 if ((n = strtoul(name, &e, 0)) > 0 && !*e)
1650 /* handle well known aliases */
1651 else if (!strcmp(name, "default"))
1652 table = RT_TABLE_DEFAULT;
1653 else if (!strcmp(name, "main"))
1654 table = RT_TABLE_MAIN;
1655 else if (!strcmp(name, "local"))
1656 table = RT_TABLE_LOCAL;
1657 else if (!strcmp(name, "prelocal"))
1658 table = RT_TABLE_PRELOCAL;
1660 /* try to look up name in /etc/iproute2/rt_tables */
1661 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL)
1663 while (fgets(buf, sizeof(buf) - 1, f) != NULL)
1665 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
1668 n = strtoul(e, NULL, 10);
1669 e = strtok(NULL, " \t\n");
1671 if (e && !strcmp(e, name))
1681 if (table == RT_TABLE_UNSPEC)
1688 bool system_is_default_rt_table(unsigned int id)
1690 return (id == RT_TABLE_MAIN);
1693 bool system_resolve_rpfilter(const char *filter, unsigned int *id)
1698 if (!strcmp(filter, "strict"))
1700 else if (!strcmp(filter, "loose"))
1703 n = strtoul(filter, &e, 0);
1704 if (*e || e == filter || n > 2)
1712 static int system_iprule(struct iprule *rule, int cmd)
1714 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16;
1717 struct rtmsg rtm = {
1718 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
1719 .rtm_protocol = RTPROT_STATIC,
1720 .rtm_scope = RT_SCOPE_UNIVERSE,
1721 .rtm_table = RT_TABLE_UNSPEC,
1722 .rtm_type = RTN_UNSPEC,
1726 if (cmd == RTM_NEWRULE) {
1727 rtm.rtm_type = RTN_UNICAST;
1728 rtm.rtm_flags |= NLM_F_REPLACE | NLM_F_EXCL;
1732 rtm.rtm_flags |= FIB_RULE_INVERT;
1734 if (rule->flags & IPRULE_SRC)
1735 rtm.rtm_src_len = rule->src_mask;
1737 if (rule->flags & IPRULE_DEST)
1738 rtm.rtm_dst_len = rule->dest_mask;
1740 if (rule->flags & IPRULE_TOS)
1741 rtm.rtm_tos = rule->tos;
1743 if (rule->flags & IPRULE_LOOKUP) {
1744 if (rule->lookup < 256)
1745 rtm.rtm_table = rule->lookup;
1748 if (rule->flags & IPRULE_ACTION)
1749 rtm.rtm_type = rule->action;
1750 else if (rule->flags & IPRULE_GOTO)
1751 rtm.rtm_type = FR_ACT_GOTO;
1752 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO)))
1753 rtm.rtm_type = FR_ACT_NOP;
1755 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST);
1760 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1762 if (rule->flags & IPRULE_IN)
1763 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev);
1765 if (rule->flags & IPRULE_OUT)
1766 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev);
1768 if (rule->flags & IPRULE_SRC)
1769 nla_put(msg, FRA_SRC, alen, &rule->src_addr);
1771 if (rule->flags & IPRULE_DEST)
1772 nla_put(msg, FRA_DST, alen, &rule->dest_addr);
1774 if (rule->flags & IPRULE_PRIORITY)
1775 nla_put_u32(msg, FRA_PRIORITY, rule->priority);
1776 else if (cmd == RTM_NEWRULE)
1777 nla_put_u32(msg, FRA_PRIORITY, rule->order);
1779 if (rule->flags & IPRULE_FWMARK)
1780 nla_put_u32(msg, FRA_FWMARK, rule->fwmark);
1782 if (rule->flags & IPRULE_FWMASK)
1783 nla_put_u32(msg, FRA_FWMASK, rule->fwmask);
1785 if (rule->flags & IPRULE_LOOKUP) {
1786 if (rule->lookup >= 256)
1787 nla_put_u32(msg, FRA_TABLE, rule->lookup);
1790 if (rule->flags & IPRULE_GOTO)
1791 nla_put_u32(msg, FRA_GOTO, rule->gotoid);
1793 return system_rtnl_call(msg);
1796 int system_add_iprule(struct iprule *rule)
1798 return system_iprule(rule, RTM_NEWRULE);
1801 int system_del_iprule(struct iprule *rule)
1803 return system_iprule(rule, RTM_DELRULE);
1806 int system_flush_iprules(void)
1811 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET);
1812 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6);
1814 memset(&rule, 0, sizeof(rule));
1817 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP;
1820 rule.lookup = RT_TABLE_PRELOCAL;
1821 rv |= system_iprule(&rule, RTM_NEWRULE);
1824 rule.lookup = RT_TABLE_LOCAL;
1825 rv |= system_iprule(&rule, RTM_NEWRULE);
1827 rule.priority = 32766;
1828 rule.lookup = RT_TABLE_MAIN;
1829 rv |= system_iprule(&rule, RTM_NEWRULE);
1831 rule.priority = 32767;
1832 rule.lookup = RT_TABLE_DEFAULT;
1833 rv |= system_iprule(&rule, RTM_NEWRULE);
1836 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP;
1839 rule.lookup = RT_TABLE_PRELOCAL;
1840 rv |= system_iprule(&rule, RTM_NEWRULE);
1843 rule.lookup = RT_TABLE_LOCAL;
1844 rv |= system_iprule(&rule, RTM_NEWRULE);
1846 rule.priority = 32766;
1847 rule.lookup = RT_TABLE_MAIN;
1848 rv |= system_iprule(&rule, RTM_NEWRULE);
1853 bool system_resolve_iprule_action(const char *action, unsigned int *id)
1855 return system_rtn_aton(action, id);
1858 time_t system_get_rtime(void)
1863 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts) == 0)
1866 if (gettimeofday(&tv, NULL) == 0)
1873 #define IP_DF 0x4000
1876 static int tunnel_ioctl(const char *name, int cmd, void *p)
1880 memset(&ifr, 0, sizeof(ifr));
1881 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
1882 ifr.ifr_ifru.ifru_data = p;
1883 return ioctl(sock_ioctl, cmd, &ifr);
1886 #ifdef IFLA_IPTUN_MAX
1887 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000)
1888 static int system_add_gre_tunnel(const char *name, const char *kind,
1889 const unsigned int link, struct blob_attr **tb, bool v6)
1892 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
1893 struct blob_attr *cur;
1894 uint32_t ikey = 0, okey = 0, flags = 0, flowinfo = 0;
1895 uint16_t iflags = 0, oflags = 0;
1897 int ret = 0, ttl = 64;
1899 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
1903 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
1904 nla_put_string(nlm, IFLA_IFNAME, name);
1906 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
1912 nla_put_string(nlm, IFLA_INFO_KIND, kind);
1913 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
1920 nla_put_u32(nlm, IFLA_GRE_LINK, link);
1922 if ((cur = tb[TUNNEL_ATTR_TTL]))
1923 ttl = blobmsg_get_u32(cur);
1925 nla_put_u8(nlm, IFLA_GRE_TTL, ttl);
1927 if ((cur = tb[TUNNEL_ATTR_TOS])) {
1928 char *str = blobmsg_get_string(cur);
1929 if (strcmp(str, "inherit")) {
1932 if (!system_tos_aton(str, &uval)) {
1938 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS;
1943 flags |= IP6_TNL_F_USE_ORIG_TCLASS;
1949 if ((cur = tb[TUNNEL_ATTR_INFO]) && (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)) {
1950 uint8_t icsum, ocsum, iseqno, oseqno;
1951 if (sscanf(blobmsg_get_string(cur), "%u,%u,%hhu,%hhu,%hhu,%hhu",
1952 &ikey, &okey, &icsum, &ocsum, &iseqno, &oseqno) < 6) {
1977 struct in6_addr in6buf;
1978 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
1979 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
1983 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf);
1986 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
1987 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
1991 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf);
1993 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, 4);
1996 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo);
1999 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags);
2001 struct in_addr inbuf;
2004 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2005 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2009 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf);
2012 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2013 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2017 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf);
2019 if (IN_MULTICAST(ntohl(inbuf.s_addr))) {
2021 okey = inbuf.s_addr;
2026 ikey = inbuf.s_addr;
2032 if ((cur = tb[TUNNEL_ATTR_DF]))
2033 set_df = blobmsg_get_bool(cur);
2035 /* ttl !=0 and nopmtudisc are incompatible */
2036 if (ttl && !set_df) {
2041 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0);
2043 nla_put_u8(nlm, IFLA_GRE_TOS, tos);
2047 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags);
2050 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags);
2053 nla_put_u32(nlm, IFLA_GRE_OKEY, okey);
2056 nla_put_u32(nlm, IFLA_GRE_IKEY, ikey);
2058 nla_nest_end(nlm, infodata);
2059 nla_nest_end(nlm, linkinfo);
2061 return system_rtnl_call(nlm);
2069 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb)
2071 struct blob_attr *cur;
2073 struct ip_tunnel_parm p = {
2082 if ((cur = tb[TUNNEL_ATTR_LOCAL]) &&
2083 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1)
2086 if ((cur = tb[TUNNEL_ATTR_REMOTE]) &&
2087 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1)
2090 if ((cur = tb[TUNNEL_ATTR_DF]))
2091 set_df = blobmsg_get_bool(cur);
2093 if ((cur = tb[TUNNEL_ATTR_TTL]))
2094 p.iph.ttl = blobmsg_get_u32(cur);
2096 if ((cur = tb[TUNNEL_ATTR_TOS])) {
2097 char *str = blobmsg_get_string(cur);
2098 if (strcmp(str, "inherit")) {
2101 if (!system_tos_aton(str, &uval))
2109 p.iph.frag_off = set_df ? htons(IP_DF) : 0;
2110 /* ttl !=0 and nopmtudisc are incompatible */
2111 if (p.iph.ttl && p.iph.frag_off == 0)
2114 strncpy(p.name, name, sizeof(p.name));
2116 switch (p.iph.protocol) {
2118 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p);
2120 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p);
2127 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb)
2129 struct blob_attr *cur;
2132 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
2134 str = blobmsg_data(cur);
2136 if (!strcmp(str, "greip") || !strcmp(str, "gretapip") ||
2137 !strcmp(str, "greip6") || !strcmp(str, "gretapip6"))
2138 return system_link_del(name);
2140 return tunnel_ioctl(name, SIOCDELTUNNEL, NULL);
2143 int system_del_ip_tunnel(const char *name, struct blob_attr *attr)
2145 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
2147 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
2148 blob_data(attr), blob_len(attr));
2150 return __system_del_ip_tunnel(name, tb);
2153 int system_update_ipv6_mtu(struct device *dev, int mtu)
2157 snprintf(buf, sizeof(buf), "/proc/sys/net/ipv6/conf/%s/mtu",
2160 int fd = open(buf, O_RDWR);
2161 ssize_t len = read(fd, buf, sizeof(buf) - 1);
2168 if (!mtu || ret <= mtu)
2171 lseek(fd, 0, SEEK_SET);
2172 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) <= 0)
2180 int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
2182 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
2183 struct blob_attr *cur;
2186 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
2187 blob_data(attr), blob_len(attr));
2189 __system_del_ip_tunnel(name, tb);
2191 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
2193 str = blobmsg_data(cur);
2195 unsigned int ttl = 0;
2196 if ((cur = tb[TUNNEL_ATTR_TTL])) {
2197 ttl = blobmsg_get_u32(cur);
2202 unsigned int link = 0;
2203 if ((cur = tb[TUNNEL_ATTR_LINK])) {
2204 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
2208 if (iface->l3_dev.dev)
2209 link = iface->l3_dev.dev->ifindex;
2212 if (!strcmp(str, "sit")) {
2213 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
2217 if ((cur = tb[TUNNEL_ATTR_6RD_PREFIX])) {
2219 struct ip_tunnel_6rd p6;
2221 memset(&p6, 0, sizeof(p6));
2223 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur),
2224 &p6.prefix, &mask) || mask > 128)
2226 p6.prefixlen = mask;
2228 if ((cur = tb[TUNNEL_ATTR_6RD_RELAY_PREFIX])) {
2229 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur),
2230 &p6.relay_prefix, &mask) || mask > 32)
2232 p6.relay_prefixlen = mask;
2235 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) {
2236 __system_del_ip_tunnel(name, tb);
2241 #ifdef IFLA_IPTUN_MAX
2242 } else if (!strcmp(str, "ipip6")) {
2243 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK,
2244 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2245 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC };
2251 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2252 nla_put_string(nlm, IFLA_IFNAME, name);
2255 nla_put_u32(nlm, IFLA_LINK, link);
2257 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2262 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl");
2263 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2270 nla_put_u32(nlm, IFLA_IPTUN_LINK, link);
2272 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP);
2273 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64);
2274 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, 4);
2276 struct in6_addr in6buf;
2277 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2278 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2282 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf);
2285 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2286 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2290 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf);
2293 #ifdef IFLA_IPTUN_FMR_MAX
2294 if ((cur = tb[TUNNEL_ATTR_FMRS])) {
2295 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS);
2297 struct blob_attr *fmr;
2298 unsigned rem, fmrcnt = 0;
2299 blobmsg_for_each_attr(fmr, cur, rem) {
2300 if (blobmsg_type(fmr) != BLOBMSG_TYPE_STRING)
2303 unsigned ip4len, ip6len, ealen, offset = 6;
2307 if (sscanf(blobmsg_get_string(fmr), "%47[^/]/%u,%15[^/]/%u,%u,%u",
2308 ip6buf, &ip6len, ip4buf, &ip4len, &ealen, &offset) < 5) {
2313 struct in6_addr ip6prefix;
2314 struct in_addr ip4prefix;
2315 if (inet_pton(AF_INET6, ip6buf, &ip6prefix) != 1 ||
2316 inet_pton(AF_INET, ip4buf, &ip4prefix) != 1) {
2321 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt);
2323 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix);
2324 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix);
2325 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len);
2326 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len);
2327 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen);
2328 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset);
2330 nla_nest_end(nlm, rule);
2333 nla_nest_end(nlm, fmrs);
2337 nla_nest_end(nlm, infodata);
2338 nla_nest_end(nlm, linkinfo);
2340 return system_rtnl_call(nlm);
2344 } else if (!strcmp(str, "greip")) {
2345 return system_add_gre_tunnel(name, "gre", link, tb, false);
2346 } else if (!strcmp(str, "gretapip")) {
2347 return system_add_gre_tunnel(name, "gretap", link, tb, false);
2348 } else if (!strcmp(str, "greip6")) {
2349 return system_add_gre_tunnel(name, "ip6gre", link, tb, true);
2350 } else if (!strcmp(str, "gretapip6")) {
2351 return system_add_gre_tunnel(name, "ip6gretap", link, tb, true);
2353 } else if (!strcmp(str, "ipip")) {
2354 return system_add_proto_tunnel(name, IPPROTO_IPIP, link, tb);