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>
8 * Copyright (C) 2018 Hans Dedecker <dedeckeh@gmail.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
21 #include <sys/socket.h>
22 #include <sys/ioctl.h>
24 #include <sys/syscall.h>
27 #include <net/if_arp.h>
30 #include <arpa/inet.h>
31 #include <netinet/ether.h>
32 #include <netinet/in.h>
34 #include <linux/rtnetlink.h>
35 #include <linux/neighbour.h>
36 #include <linux/sockios.h>
38 #include <linux/if_addr.h>
39 #include <linux/if_link.h>
40 #include <linux/if_vlan.h>
41 #include <linux/if_bridge.h>
42 #include <linux/if_tunnel.h>
43 #include <linux/ip6_tunnel.h>
44 #include <linux/ethtool.h>
45 #include <linux/fib_rules.h>
46 #include <linux/veth.h>
47 #include <linux/version.h>
51 #ifndef RTN_FAILED_POLICY
52 #define RTN_FAILED_POLICY 12
55 #ifndef IFA_F_NOPREFIXROUTE
56 #define IFA_F_NOPREFIXROUTE 0x200
60 #define IFA_FLAGS (IFA_MULTICAST + 1)
69 #include <netlink/msg.h>
70 #include <netlink/attr.h>
71 #include <netlink/socket.h>
72 #include <libubox/uloop.h>
80 struct uloop_fd uloop;
85 static int sock_ioctl = -1;
86 static struct nl_sock *sock_rtnl = NULL;
88 static int cb_rtnl_event(struct nl_msg *msg, void *arg);
89 static void handle_hotplug_event(struct uloop_fd *u, unsigned int events);
90 static int system_add_proto_tunnel(const char *name, const uint8_t proto,
91 const unsigned int link, struct blob_attr **tb);
92 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb);
94 static char dev_buf[256];
97 handler_nl_event(struct uloop_fd *u, unsigned int events)
99 struct event_socket *ev = container_of(u, struct event_socket, uloop);
101 socklen_t errlen = sizeof(err);
104 nl_recvmsgs_default(ev->sock);
108 if (getsockopt(u->fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen))
113 /* Increase rx buffer size on netlink socket */
115 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
118 /* Request full dump since some info got dropped */
119 struct rtgenmsg msg = { .rtgen_family = AF_UNSPEC };
120 nl_send_simple(ev->sock, RTM_GETLINK, NLM_F_DUMP, &msg, sizeof(msg));
130 uloop_fd_delete(&ev->uloop);
134 static struct nl_sock *
135 create_socket(int protocol, int groups)
137 struct nl_sock *sock;
139 sock = nl_socket_alloc();
144 nl_join_groups(sock, groups);
146 if (nl_connect(sock, protocol)) {
147 nl_socket_free(sock);
155 create_raw_event_socket(struct event_socket *ev, int protocol, int groups,
156 uloop_fd_handler cb, int flags)
158 ev->sock = create_socket(protocol, groups);
162 ev->uloop.fd = nl_socket_get_fd(ev->sock);
164 if (uloop_fd_add(&ev->uloop, ULOOP_READ|flags))
171 create_event_socket(struct event_socket *ev, int protocol,
172 int (*cb)(struct nl_msg *msg, void *arg))
174 if (!create_raw_event_socket(ev, protocol, 0, handler_nl_event, ULOOP_ERROR_CB))
177 /* Install the valid custom callback handler */
178 nl_socket_modify_cb(ev->sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL);
180 /* Disable sequence number checking on event sockets */
181 nl_socket_disable_seq_check(ev->sock);
183 /* Increase rx buffer size to 65K on event sockets */
185 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
192 create_hotplug_event_socket(struct event_socket *ev, int protocol,
193 void (*cb)(struct uloop_fd *u, unsigned int events))
195 if (!create_raw_event_socket(ev, protocol, 1, cb, ULOOP_ERROR_CB))
198 /* Increase rx buffer size to 65K on event sockets */
200 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
207 system_rtn_aton(const char *src, unsigned int *dst)
212 if (!strcmp(src, "local"))
214 else if (!strcmp(src, "nat"))
216 else if (!strcmp(src, "broadcast"))
218 else if (!strcmp(src, "anycast"))
220 else if (!strcmp(src, "multicast"))
222 else if (!strcmp(src, "prohibit"))
224 else if (!strcmp(src, "unreachable"))
226 else if (!strcmp(src, "blackhole"))
228 else if (!strcmp(src, "xresolve"))
230 else if (!strcmp(src, "unicast"))
232 else if (!strcmp(src, "throw"))
234 else if (!strcmp(src, "failed_policy"))
235 n = RTN_FAILED_POLICY;
237 n = strtoul(src, &e, 0);
238 if (!e || *e || e == src || n > 255)
247 system_tos_aton(const char *src, unsigned *dst)
251 *dst = strtoul(src, &e, 16);
252 if (e == src || *e || *dst > 255)
258 int system_init(void)
260 static struct event_socket rtnl_event;
261 static struct event_socket hotplug_event;
263 sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0);
264 system_fd_set_cloexec(sock_ioctl);
266 /* Prepare socket for routing / address control */
267 sock_rtnl = create_socket(NETLINK_ROUTE, 0);
271 if (!create_event_socket(&rtnl_event, NETLINK_ROUTE, cb_rtnl_event))
274 if (!create_hotplug_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT,
275 handle_hotplug_event))
278 /* Receive network link events form kernel */
279 nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK);
284 static void system_set_sysctl(const char *path, const char *val)
288 fd = open(path, O_WRONLY);
292 if (write(fd, val, strlen(val))) {}
296 static void system_set_dev_sysctl(const char *path, const char *device, const char *val)
298 snprintf(dev_buf, sizeof(dev_buf), path, device);
299 system_set_sysctl(dev_buf, val);
302 static void system_set_disable_ipv6(struct device *dev, const char *val)
304 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6", dev->ifname, val);
307 static void system_set_rpfilter(struct device *dev, const char *val)
309 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter", dev->ifname, val);
312 static void system_set_acceptlocal(struct device *dev, const char *val)
314 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local", dev->ifname, val);
317 static void system_set_igmpversion(struct device *dev, const char *val)
319 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version", dev->ifname, val);
322 static void system_set_mldversion(struct device *dev, const char *val)
324 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version", dev->ifname, val);
327 static void system_set_neigh4reachabletime(struct device *dev, const char *val)
329 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms", dev->ifname, val);
332 static void system_set_neigh6reachabletime(struct device *dev, const char *val)
334 system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", dev->ifname, val);
337 static void system_set_neigh4gcstaletime(struct device *dev, const char *val)
339 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/gc_stale_time", dev->ifname, val);
342 static void system_set_neigh6gcstaletime(struct device *dev, const char *val)
344 system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time", dev->ifname, val);
347 static void system_set_neigh4locktime(struct device *dev, const char *val)
349 system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/locktime", dev->ifname, val);
352 static void system_set_dadtransmits(struct device *dev, const char *val)
354 system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits", dev->ifname, val);
357 static void system_bridge_set_multicast_to_unicast(struct device *dev, const char *val)
359 system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_to_unicast", dev->ifname, val);
362 static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val)
364 system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_fast_leave", dev->ifname, val);
367 static void system_bridge_set_hairpin_mode(struct device *dev, const char *val)
369 system_set_dev_sysctl("/sys/class/net/%s/brport/hairpin_mode", dev->ifname, val);
372 static void system_bridge_set_isolated(struct device *dev, const char *val)
374 system_set_dev_sysctl("/sys/class/net/%s/brport/isolated", dev->ifname, val);
377 static void system_bridge_set_multicast_router(struct device *dev, const char *val, bool bridge)
379 system_set_dev_sysctl(bridge ? "/sys/class/net/%s/bridge/multicast_router" :
380 "/sys/class/net/%s/brport/multicast_router",
384 static void system_bridge_set_robustness(struct device *dev, const char *val)
386 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_startup_query_count",
388 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_last_member_count",
392 static void system_bridge_set_query_interval(struct device *dev, const char *val)
394 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_query_interval",
398 static void system_bridge_set_query_response_interval(struct device *dev, const char *val)
400 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_query_response_interval",
404 static void system_bridge_set_last_member_interval(struct device *dev, const char *val)
406 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_last_member_interval",
410 static void system_bridge_set_membership_interval(struct device *dev, const char *val)
412 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_membership_interval",
416 static void system_bridge_set_other_querier_timeout(struct device *dev, const char *val)
418 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_querier_interval",
422 static void system_bridge_set_startup_query_interval(struct device *dev, const char *val)
424 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_startup_query_interval",
428 static void system_bridge_set_stp_state(struct device *dev, const char *val)
430 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/stp_state", dev->ifname, val);
433 static void system_bridge_set_forward_delay(struct device *dev, const char *val)
435 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/forward_delay", dev->ifname, val);
438 static void system_bridge_set_priority(struct device *dev, const char *val)
440 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/priority", dev->ifname, val);
443 static void system_bridge_set_ageing_time(struct device *dev, const char *val)
445 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/ageing_time", dev->ifname, val);
448 static void system_bridge_set_hello_time(struct device *dev, const char *val)
450 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/hello_time", dev->ifname, val);
453 static void system_bridge_set_max_age(struct device *dev, const char *val)
455 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/max_age", dev->ifname, val);
458 static void system_bridge_set_learning(struct device *dev, const char *val)
460 system_set_dev_sysctl("/sys/class/net/%s/brport/learning", dev->ifname, val);
463 static void system_bridge_set_unicast_flood(struct device *dev, const char *val)
465 system_set_dev_sysctl("/sys/class/net/%s/brport/unicast_flood", dev->ifname, val);
468 static void system_set_sendredirects(struct device *dev, const char *val)
470 system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects", dev->ifname, val);
473 static int system_get_sysctl(const char *path, char *buf, const size_t buf_sz)
475 int fd = -1, ret = -1;
477 fd = open(path, O_RDONLY);
481 ssize_t len = read(fd, buf, buf_sz - 1);
495 system_get_dev_sysctl(const char *path, const char *device, char *buf, const size_t buf_sz)
497 snprintf(dev_buf, sizeof(dev_buf), path, device);
498 return system_get_sysctl(dev_buf, buf, buf_sz);
501 static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t buf_sz)
503 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6",
504 dev->ifname, buf, buf_sz);
507 static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz)
509 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter",
510 dev->ifname, buf, buf_sz);
513 static int system_get_acceptlocal(struct device *dev, char *buf, const size_t buf_sz)
515 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local",
516 dev->ifname, buf, buf_sz);
519 static int system_get_igmpversion(struct device *dev, char *buf, const size_t buf_sz)
521 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version",
522 dev->ifname, buf, buf_sz);
525 static int system_get_mldversion(struct device *dev, char *buf, const size_t buf_sz)
527 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version",
528 dev->ifname, buf, buf_sz);
531 static int system_get_neigh4reachabletime(struct device *dev, char *buf, const size_t buf_sz)
533 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms",
534 dev->ifname, buf, buf_sz);
537 static int system_get_neigh6reachabletime(struct device *dev, char *buf, const size_t buf_sz)
539 return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms",
540 dev->ifname, buf, buf_sz);
543 static int system_get_neigh4gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
545 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/gc_stale_time",
546 dev->ifname, buf, buf_sz);
549 static int system_get_neigh6gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
551 return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time",
552 dev->ifname, buf, buf_sz);
555 static int system_get_neigh4locktime(struct device *dev, char *buf, const size_t buf_sz)
557 return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/locktime",
558 dev->ifname, buf, buf_sz);
561 static int system_get_dadtransmits(struct device *dev, char *buf, const size_t buf_sz)
563 return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits",
564 dev->ifname, buf, buf_sz);
567 static int system_get_sendredirects(struct device *dev, char *buf, const size_t buf_sz)
569 return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects",
570 dev->ifname, buf, buf_sz);
573 /* Evaluate netlink messages */
574 static int cb_rtnl_event(struct nl_msg *msg, void *arg)
576 struct nlmsghdr *nh = nlmsg_hdr(msg);
577 struct nlattr *nla[__IFLA_MAX];
581 if (nh->nlmsg_type != RTM_NEWLINK)
584 nlmsg_parse(nh, sizeof(struct ifinfomsg), nla, __IFLA_MAX - 1, NULL);
585 if (!nla[IFLA_IFNAME])
588 struct device *dev = device_find(nla_data(nla[IFLA_IFNAME]));
592 if (!system_get_dev_sysctl("/sys/class/net/%s/carrier", dev->ifname, buf, sizeof(buf)))
593 link_state = strtoul(buf, NULL, 0);
595 device_set_link(dev, link_state ? true : false);
602 handle_hotplug_msg(char *data, int size)
604 const char *subsystem = NULL, *interface = NULL, *interface_old = NULL;
605 char *cur, *end, *sep;
608 bool add, move = false;
610 if (!strncmp(data, "add@", 4))
612 else if (!strncmp(data, "remove@", 7))
614 else if (!strncmp(data, "move@", 5)) {
621 skip = strlen(data) + 1;
624 for (cur = data + skip; cur < end; cur += skip) {
625 skip = strlen(cur) + 1;
627 sep = strchr(cur, '=');
632 if (!strcmp(cur, "INTERFACE"))
634 else if (!strcmp(cur, "SUBSYSTEM")) {
636 if (strcmp(subsystem, "net") != 0)
638 } else if (!strcmp(cur, "DEVPATH_OLD")) {
639 interface_old = strrchr(sep + 1, '/');
645 if (subsystem && interface) {
646 if (move && interface_old)
655 dev = device_find(interface_old);
659 if (dev->type != &simple_device_type)
662 device_set_present(dev, false);
665 dev = device_find(interface);
669 if (dev->type != &simple_device_type)
672 if (add && system_if_force_external(dev->ifname))
675 device_set_present(dev, add);
679 handle_hotplug_event(struct uloop_fd *u, unsigned int events)
681 struct event_socket *ev = container_of(u, struct event_socket, uloop);
682 struct sockaddr_nl nla;
683 unsigned char *buf = NULL;
686 socklen_t errlen = sizeof(err);
689 while ((size = nl_recv(ev->sock, &nla, &buf, NULL)) > 0) {
691 handle_hotplug_msg((char *) buf, size);
698 if (getsockopt(u->fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen))
703 /* Increase rx buffer size on netlink socket */
705 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
716 uloop_fd_delete(&ev->uloop);
720 static int system_rtnl_call(struct nl_msg *msg)
724 ret = nl_send_auto_complete(sock_rtnl, msg);
730 return nl_wait_for_ack(sock_rtnl);
733 int system_bridge_delbr(struct device *bridge)
735 return ioctl(sock_ioctl, SIOCBRDELBR, bridge->ifname);
738 static int system_bridge_if(const char *bridge, struct device *dev, int cmd, void *data)
742 memset(&ifr, 0, sizeof(ifr));
744 ifr.ifr_ifindex = dev->ifindex;
747 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
748 return ioctl(sock_ioctl, cmd, &ifr);
751 static bool system_is_bridge(const char *name, char *buf, int buflen)
755 snprintf(buf, buflen, "/sys/devices/virtual/net/%s/bridge", name);
756 if (stat(buf, &st) < 0)
762 static char *system_get_bridge(const char *name, char *buf, int buflen)
768 snprintf(buf, buflen, "/sys/devices/virtual/net/*/brif/%s/bridge", name);
769 if (glob(buf, GLOB_NOSORT, NULL, &gl) < 0)
773 len = readlink(gl.gl_pathv[0], buf, buflen);
781 path = strrchr(buf, '/');
789 system_bridge_set_wireless(struct device *bridge, struct device *dev)
791 bool mcast_to_ucast = dev->wireless_ap;
794 if (bridge->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST &&
795 !bridge->settings.multicast_to_unicast)
796 mcast_to_ucast = false;
798 if (!mcast_to_ucast || dev->wireless_isolate)
801 system_bridge_set_multicast_to_unicast(dev, mcast_to_ucast ? "1" : "0");
802 system_bridge_set_hairpin_mode(dev, hairpin ? "1" : "0");
805 int system_bridge_addif(struct device *bridge, struct device *dev)
811 oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
812 if (!oldbr || strcmp(oldbr, bridge->ifname) != 0)
813 ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
816 system_bridge_set_wireless(bridge, dev);
818 if (dev->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
819 snprintf(buf, sizeof(buf), "%u", dev->settings.multicast_router);
820 system_bridge_set_multicast_router(dev, buf, false);
823 if (dev->settings.flags & DEV_OPT_MULTICAST_FAST_LEAVE &&
824 dev->settings.multicast_fast_leave)
825 system_bridge_set_multicast_fast_leave(dev, "1");
827 if (dev->settings.flags & DEV_OPT_LEARNING &&
828 !dev->settings.learning)
829 system_bridge_set_learning(dev, "0");
831 if (dev->settings.flags & DEV_OPT_UNICAST_FLOOD &&
832 !dev->settings.unicast_flood)
833 system_bridge_set_unicast_flood(dev, "0");
835 if (dev->settings.flags & DEV_OPT_ISOLATE &&
836 dev->settings.isolate)
837 system_bridge_set_isolated(dev, "1");
842 int system_bridge_delif(struct device *bridge, struct device *dev)
844 return system_bridge_if(bridge->ifname, dev, SIOCBRDELIF, NULL);
847 int system_if_resolve(struct device *dev)
850 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
851 if (!ioctl(sock_ioctl, SIOCGIFINDEX, &ifr))
852 return ifr.ifr_ifindex;
857 static int system_if_flags(const char *ifname, unsigned add, unsigned rem)
861 memset(&ifr, 0, sizeof(ifr));
862 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
863 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) < 0)
866 ifr.ifr_flags |= add;
867 ifr.ifr_flags &= ~rem;
868 return ioctl(sock_ioctl, SIOCSIFFLAGS, &ifr);
880 static bool check_ifaddr(struct nlmsghdr *hdr, int ifindex)
882 struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
884 return ifa->ifa_index == ifindex;
887 static bool check_route(struct nlmsghdr *hdr, int ifindex)
889 struct rtmsg *r = NLMSG_DATA(hdr);
890 struct nlattr *tb[__RTA_MAX];
892 if (r->rtm_protocol == RTPROT_KERNEL &&
893 r->rtm_family == AF_INET6)
896 nlmsg_parse(hdr, sizeof(struct rtmsg), tb, __RTA_MAX - 1, NULL);
900 return *(int *)RTA_DATA(tb[RTA_OIF]) == ifindex;
903 static bool check_rule(struct nlmsghdr *hdr, int ifindex)
908 static int cb_clear_event(struct nl_msg *msg, void *arg)
910 struct clear_data *clr = arg;
911 struct nlmsghdr *hdr = nlmsg_hdr(msg);
912 bool (*cb)(struct nlmsghdr *, int ifindex);
918 if (hdr->nlmsg_type != RTM_NEWADDR)
925 if (hdr->nlmsg_type != RTM_NEWROUTE)
932 if (hdr->nlmsg_type != RTM_NEWRULE)
941 if (!cb(hdr, clr->dev ? clr->dev->ifindex : 0))
944 if (type == RTM_DELRULE)
945 D(SYSTEM, "Remove a rule\n");
947 D(SYSTEM, "Remove %s from device %s\n",
948 type == RTM_DELADDR ? "an address" : "a route",
951 memcpy(nlmsg_hdr(clr->msg), hdr, hdr->nlmsg_len);
952 hdr = nlmsg_hdr(clr->msg);
953 hdr->nlmsg_type = type;
954 hdr->nlmsg_flags = NLM_F_REQUEST;
956 nl_socket_disable_auto_ack(sock_rtnl);
957 ret = nl_send_auto_complete(sock_rtnl, clr->msg);
959 if (type == RTM_DELRULE)
960 D(SYSTEM, "Error deleting a rule: %d\n", ret);
962 D(SYSTEM, "Error deleting %s from device '%s': %d\n",
963 type == RTM_DELADDR ? "an address" : "a route",
964 clr->dev->ifname, ret);
967 nl_socket_enable_auto_ack(sock_rtnl);
973 cb_finish_event(struct nl_msg *msg, void *arg)
981 error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
984 *pending = err->error;
989 system_if_clear_entries(struct device *dev, int type, int af)
991 struct clear_data clr;
995 .rtm_flags = RTM_F_CLONED,
997 int flags = NLM_F_DUMP;
1006 clr.size = sizeof(struct rtgenmsg);
1009 clr.size = sizeof(struct rtmsg);
1015 cb = nl_cb_alloc(NL_CB_DEFAULT);
1019 clr.msg = nlmsg_alloc_simple(type, flags);
1023 nlmsg_append(clr.msg, &rtm, clr.size, 0);
1024 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_clear_event, &clr);
1025 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_finish_event, &pending);
1026 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &pending);
1028 if (nl_send_auto_complete(sock_rtnl, clr.msg) < 0)
1032 nl_recvmsgs(sock_rtnl, cb);
1035 nlmsg_free(clr.msg);
1041 * Clear bridge (membership) state and bring down device
1043 void system_if_clear_state(struct device *dev)
1045 static char buf[256];
1047 device_set_ifindex(dev, system_if_resolve(dev));
1049 if (dev->external || !dev->ifindex)
1052 system_if_flags(dev->ifname, 0, IFF_UP);
1054 if (system_is_bridge(dev->ifname, buf, sizeof(buf))) {
1055 D(SYSTEM, "Delete existing bridge named '%s'\n", dev->ifname);
1056 system_bridge_delbr(dev);
1060 bridge = system_get_bridge(dev->ifname, buf, sizeof(buf));
1062 D(SYSTEM, "Remove device '%s' from bridge '%s'\n", dev->ifname, bridge);
1063 system_bridge_if(bridge, dev, SIOCBRDELIF, NULL);
1066 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET);
1067 system_if_clear_entries(dev, RTM_GETADDR, AF_INET);
1068 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET6);
1069 system_if_clear_entries(dev, RTM_GETADDR, AF_INET6);
1070 system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET);
1071 system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET6);
1072 system_set_disable_ipv6(dev, "0");
1075 static inline unsigned long
1076 sec_to_jiffies(int val)
1078 return (unsigned long) val * 100;
1081 static void system_bridge_conf_multicast_deps(struct device *bridge,
1082 struct bridge_config *cfg,
1088 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS ||
1089 cfg->flags & BRIDGE_OPT_QUERY_INTERVAL ||
1090 cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
1091 val = cfg->robustness * cfg->query_interval +
1092 cfg->query_response_interval;
1094 snprintf(buf, buf_len, "%i", val);
1095 system_bridge_set_membership_interval(bridge, buf);
1097 val = cfg->robustness * cfg->query_interval +
1098 cfg->query_response_interval / 2;
1100 snprintf(buf, buf_len, "%i", val);
1101 system_bridge_set_other_querier_timeout(bridge, buf);
1104 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
1105 val = cfg->query_interval / 4;
1107 snprintf(buf, buf_len, "%i", val);
1108 system_bridge_set_startup_query_interval(bridge, buf);
1112 static void system_bridge_conf_multicast(struct device *bridge,
1113 struct bridge_config *cfg,
1117 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_snooping",
1118 bridge->ifname, cfg->igmp_snoop ? "1" : "0");
1120 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_querier",
1121 bridge->ifname, cfg->multicast_querier ? "1" : "0");
1123 snprintf(buf, buf_len, "%i", cfg->hash_max);
1124 system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/hash_max",
1125 bridge->ifname, buf);
1127 if (bridge->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
1128 snprintf(buf, buf_len, "%u", bridge->settings.multicast_router);
1129 system_bridge_set_multicast_router(bridge, buf, true);
1132 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS) {
1133 snprintf(buf, buf_len, "%i", cfg->robustness);
1134 system_bridge_set_robustness(bridge, buf);
1137 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
1138 snprintf(buf, buf_len, "%i", cfg->query_interval);
1139 system_bridge_set_query_interval(bridge, buf);
1142 if (cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
1143 snprintf(buf, buf_len, "%i", cfg->query_response_interval);
1144 system_bridge_set_query_response_interval(bridge, buf);
1147 if (cfg->flags & BRIDGE_OPT_LAST_MEMBER_INTERVAL) {
1148 snprintf(buf, buf_len, "%i", cfg->last_member_interval);
1149 system_bridge_set_last_member_interval(bridge, buf);
1152 system_bridge_conf_multicast_deps(bridge, cfg, buf, buf_len);
1155 int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg)
1159 if (ioctl(sock_ioctl, SIOCBRADDBR, bridge->ifname) < 0)
1162 system_bridge_set_stp_state(bridge, cfg->stp ? "1" : "0");
1164 snprintf(buf, sizeof(buf), "%lu", sec_to_jiffies(cfg->forward_delay));
1165 system_bridge_set_forward_delay(bridge, buf);
1167 system_bridge_conf_multicast(bridge, cfg, buf, sizeof(buf));
1169 snprintf(buf, sizeof(buf), "%d", cfg->priority);
1170 system_bridge_set_priority(bridge, buf);
1172 if (cfg->flags & BRIDGE_OPT_AGEING_TIME) {
1173 snprintf(buf, sizeof(buf), "%lu", sec_to_jiffies(cfg->ageing_time));
1174 system_bridge_set_ageing_time(bridge, buf);
1177 if (cfg->flags & BRIDGE_OPT_HELLO_TIME) {
1178 snprintf(buf, sizeof(buf), "%lu", sec_to_jiffies(cfg->hello_time));
1179 system_bridge_set_hello_time(bridge, buf);
1182 if (cfg->flags & BRIDGE_OPT_MAX_AGE) {
1183 snprintf(buf, sizeof(buf), "%lu", sec_to_jiffies(cfg->max_age));
1184 system_bridge_set_max_age(bridge, buf);
1190 int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvlan_config *cfg)
1193 struct nlattr *linkinfo, *data;
1194 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
1196 static const struct {
1198 enum macvlan_mode val;
1200 { "private", MACVLAN_MODE_PRIVATE },
1201 { "vepa", MACVLAN_MODE_VEPA },
1202 { "bridge", MACVLAN_MODE_BRIDGE },
1203 { "passthru", MACVLAN_MODE_PASSTHRU },
1206 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1211 nlmsg_append(msg, &iim, sizeof(iim), 0);
1213 if (cfg->flags & MACVLAN_OPT_MACADDR)
1214 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1215 nla_put_string(msg, IFLA_IFNAME, macvlan->ifname);
1216 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1218 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1219 goto nla_put_failure;
1221 nla_put_string(msg, IFLA_INFO_KIND, "macvlan");
1223 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1224 goto nla_put_failure;
1227 for (i = 0; i < ARRAY_SIZE(modes); i++) {
1228 if (strcmp(cfg->mode, modes[i].name) != 0)
1231 nla_put_u32(msg, IFLA_MACVLAN_MODE, modes[i].val);
1236 nla_nest_end(msg, data);
1237 nla_nest_end(msg, linkinfo);
1239 rv = system_rtnl_call(msg);
1241 D(SYSTEM, "Error adding macvlan '%s' over '%s': %d\n", macvlan->ifname, dev->ifname, rv);
1250 int system_link_netns_move(struct device *dev, int netns_fd, const char *target_ifname)
1253 struct ifinfomsg iim = {
1254 .ifi_family = AF_UNSPEC,
1260 iim.ifi_index = system_if_resolve(dev);
1261 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST);
1266 nlmsg_append(msg, &iim, sizeof(iim), 0);
1268 nla_put_string(msg, IFLA_IFNAME, target_ifname);
1270 nla_put_u32(msg, IFLA_NET_NS_FD, netns_fd);
1271 return system_rtnl_call(msg);
1274 static int system_link_del(const char *ifname)
1277 struct ifinfomsg iim = {
1278 .ifi_family = AF_UNSPEC,
1282 msg = nlmsg_alloc_simple(RTM_DELLINK, NLM_F_REQUEST);
1287 nlmsg_append(msg, &iim, sizeof(iim), 0);
1288 nla_put_string(msg, IFLA_IFNAME, ifname);
1289 return system_rtnl_call(msg);
1292 int system_macvlan_del(struct device *macvlan)
1294 return system_link_del(macvlan->ifname);
1297 int system_netns_open(const pid_t target_ns)
1299 char pid_net_path[PATH_MAX];
1301 snprintf(pid_net_path, sizeof(pid_net_path), "/proc/%u/ns/net", target_ns);
1303 return open(pid_net_path, O_RDONLY);
1306 int system_netns_set(int netns_fd)
1308 return setns(netns_fd, CLONE_NEWNET);
1311 int system_veth_add(struct device *veth, struct veth_config *cfg)
1314 struct ifinfomsg empty_iim = {};
1315 struct nlattr *linkinfo, *data, *veth_info;
1318 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1323 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
1325 if (cfg->flags & VETH_OPT_MACADDR)
1326 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1327 nla_put_string(msg, IFLA_IFNAME, veth->ifname);
1329 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1330 goto nla_put_failure;
1332 nla_put_string(msg, IFLA_INFO_KIND, "veth");
1334 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1335 goto nla_put_failure;
1337 if (!(veth_info = nla_nest_start(msg, VETH_INFO_PEER)))
1338 goto nla_put_failure;
1340 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
1342 if (cfg->flags & VETH_OPT_PEER_NAME)
1343 nla_put_string(msg, IFLA_IFNAME, cfg->peer_name);
1344 if (cfg->flags & VETH_OPT_PEER_MACADDR)
1345 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->peer_macaddr), cfg->peer_macaddr);
1347 nla_nest_end(msg, veth_info);
1348 nla_nest_end(msg, data);
1349 nla_nest_end(msg, linkinfo);
1351 rv = system_rtnl_call(msg);
1353 if (cfg->flags & VETH_OPT_PEER_NAME)
1354 D(SYSTEM, "Error adding veth '%s' with peer '%s': %d\n", veth->ifname, cfg->peer_name, rv);
1356 D(SYSTEM, "Error adding veth '%s': %d\n", veth->ifname, rv);
1366 int system_veth_del(struct device *veth)
1368 return system_link_del(veth->ifname);
1371 static int system_vlan(struct device *dev, int id)
1373 struct vlan_ioctl_args ifr = {
1374 .cmd = SET_VLAN_NAME_TYPE_CMD,
1375 .u.name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD,
1378 if (ioctl(sock_ioctl, SIOCSIFVLAN, &ifr) < 0)
1382 ifr.cmd = DEL_VLAN_CMD;
1385 ifr.cmd = ADD_VLAN_CMD;
1388 strncpy(ifr.device1, dev->ifname, sizeof(ifr.device1));
1389 return ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);
1392 int system_vlan_add(struct device *dev, int id)
1394 return system_vlan(dev, id);
1397 int system_vlan_del(struct device *dev)
1399 return system_vlan(dev, -1);
1402 int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlandev_config *cfg)
1405 struct nlattr *linkinfo, *data, *qos;
1406 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC };
1407 struct vlan_qos_mapping *elem;
1408 struct ifla_vlan_qos_mapping nl_qos_map;
1411 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1416 nlmsg_append(msg, &iim, sizeof(iim), 0);
1417 nla_put_string(msg, IFLA_IFNAME, vlandev->ifname);
1418 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1420 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1421 goto nla_put_failure;
1423 nla_put_string(msg, IFLA_INFO_KIND, "vlan");
1425 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1426 goto nla_put_failure;
1428 nla_put_u16(msg, IFLA_VLAN_ID, cfg->vid);
1430 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
1431 nla_put_u16(msg, IFLA_VLAN_PROTOCOL, htons(cfg->proto));
1433 if(cfg->proto == VLAN_PROTO_8021AD)
1434 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);
1437 if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS)))
1438 goto nla_put_failure;
1440 vlist_simple_for_each_element(&cfg->ingress_qos_mapping_list, elem, node) {
1441 nl_qos_map.from = elem->from;
1442 nl_qos_map.to = elem->to;
1443 nla_put(msg, IFLA_VLAN_QOS_MAPPING, sizeof(nl_qos_map), &nl_qos_map);
1445 nla_nest_end(msg, qos);
1447 if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS)))
1448 goto nla_put_failure;
1450 vlist_simple_for_each_element(&cfg->egress_qos_mapping_list, elem, node) {
1451 nl_qos_map.from = elem->from;
1452 nl_qos_map.to = elem->to;
1453 nla_put(msg, IFLA_VLAN_QOS_MAPPING, sizeof(nl_qos_map), &nl_qos_map);
1455 nla_nest_end(msg, qos);
1457 nla_nest_end(msg, data);
1458 nla_nest_end(msg, linkinfo);
1460 rv = system_rtnl_call(msg);
1462 D(SYSTEM, "Error adding vlandev '%s' over '%s': %d\n", vlandev->ifname, dev->ifname, rv);
1471 int system_vlandev_del(struct device *vlandev)
1473 return system_link_del(vlandev->ifname);
1477 system_if_get_settings(struct device *dev, struct device_settings *s)
1482 memset(&ifr, 0, sizeof(ifr));
1483 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1485 if (ioctl(sock_ioctl, SIOCGIFMTU, &ifr) == 0) {
1486 s->mtu = ifr.ifr_mtu;
1487 s->flags |= DEV_OPT_MTU;
1490 s->mtu6 = system_update_ipv6_mtu(dev, 0);
1492 s->flags |= DEV_OPT_MTU6;
1494 if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) {
1495 s->txqueuelen = ifr.ifr_qlen;
1496 s->flags |= DEV_OPT_TXQUEUELEN;
1499 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) {
1500 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr));
1501 s->flags |= DEV_OPT_MACADDR;
1504 if (!system_get_disable_ipv6(dev, buf, sizeof(buf))) {
1505 s->ipv6 = !strtoul(buf, NULL, 0);
1506 s->flags |= DEV_OPT_IPV6;
1509 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) == 0) {
1510 s->promisc = ifr.ifr_flags & IFF_PROMISC;
1511 s->flags |= DEV_OPT_PROMISC;
1513 s->multicast = ifr.ifr_flags & IFF_MULTICAST;
1514 s->flags |= DEV_OPT_MULTICAST;
1517 if (!system_get_rpfilter(dev, buf, sizeof(buf))) {
1518 s->rpfilter = strtoul(buf, NULL, 0);
1519 s->flags |= DEV_OPT_RPFILTER;
1522 if (!system_get_acceptlocal(dev, buf, sizeof(buf))) {
1523 s->acceptlocal = strtoul(buf, NULL, 0);
1524 s->flags |= DEV_OPT_ACCEPTLOCAL;
1527 if (!system_get_igmpversion(dev, buf, sizeof(buf))) {
1528 s->igmpversion = strtoul(buf, NULL, 0);
1529 s->flags |= DEV_OPT_IGMPVERSION;
1532 if (!system_get_mldversion(dev, buf, sizeof(buf))) {
1533 s->mldversion = strtoul(buf, NULL, 0);
1534 s->flags |= DEV_OPT_MLDVERSION;
1537 if (!system_get_neigh4reachabletime(dev, buf, sizeof(buf))) {
1538 s->neigh4reachabletime = strtoul(buf, NULL, 0);
1539 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
1542 if (!system_get_neigh6reachabletime(dev, buf, sizeof(buf))) {
1543 s->neigh6reachabletime = strtoul(buf, NULL, 0);
1544 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
1547 if (!system_get_neigh4locktime(dev, buf, sizeof(buf))) {
1548 s->neigh4locktime = strtol(buf, NULL, 0);
1549 s->flags |= DEV_OPT_NEIGHLOCKTIME;
1552 if (!system_get_neigh4gcstaletime(dev, buf, sizeof(buf))) {
1553 s->neigh4gcstaletime = strtoul(buf, NULL, 0);
1554 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
1557 if (!system_get_neigh6gcstaletime(dev, buf, sizeof(buf))) {
1558 s->neigh6gcstaletime = strtoul(buf, NULL, 0);
1559 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
1562 if (!system_get_dadtransmits(dev, buf, sizeof(buf))) {
1563 s->dadtransmits = strtoul(buf, NULL, 0);
1564 s->flags |= DEV_OPT_DADTRANSMITS;
1567 if (!system_get_sendredirects(dev, buf, sizeof(buf))) {
1568 s->sendredirects = strtoul(buf, NULL, 0);
1569 s->flags |= DEV_OPT_SENDREDIRECTS;
1574 system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned int apply_mask)
1579 memset(&ifr, 0, sizeof(ifr));
1580 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1581 if (s->flags & DEV_OPT_MTU & apply_mask) {
1582 ifr.ifr_mtu = s->mtu;
1583 if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0)
1584 s->flags &= ~DEV_OPT_MTU;
1586 if (s->flags & DEV_OPT_MTU6 & apply_mask) {
1587 system_update_ipv6_mtu(dev, s->mtu6);
1589 if (s->flags & DEV_OPT_TXQUEUELEN & apply_mask) {
1590 ifr.ifr_qlen = s->txqueuelen;
1591 if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0)
1592 s->flags &= ~DEV_OPT_TXQUEUELEN;
1594 if ((s->flags & DEV_OPT_MACADDR & apply_mask) && !dev->external) {
1595 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
1596 memcpy(&ifr.ifr_hwaddr.sa_data, s->macaddr, sizeof(s->macaddr));
1597 if (ioctl(sock_ioctl, SIOCSIFHWADDR, &ifr) < 0)
1598 s->flags &= ~DEV_OPT_MACADDR;
1600 if (s->flags & DEV_OPT_IPV6 & apply_mask)
1601 system_set_disable_ipv6(dev, s->ipv6 ? "0" : "1");
1602 if (s->flags & DEV_OPT_PROMISC & apply_mask) {
1603 if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0,
1604 !s->promisc ? IFF_PROMISC : 0) < 0)
1605 s->flags &= ~DEV_OPT_PROMISC;
1607 if (s->flags & DEV_OPT_RPFILTER & apply_mask) {
1608 snprintf(buf, sizeof(buf), "%u", s->rpfilter);
1609 system_set_rpfilter(dev, buf);
1611 if (s->flags & DEV_OPT_ACCEPTLOCAL & apply_mask)
1612 system_set_acceptlocal(dev, s->acceptlocal ? "1" : "0");
1613 if (s->flags & DEV_OPT_IGMPVERSION & apply_mask) {
1614 snprintf(buf, sizeof(buf), "%u", s->igmpversion);
1615 system_set_igmpversion(dev, buf);
1617 if (s->flags & DEV_OPT_MLDVERSION & apply_mask) {
1618 snprintf(buf, sizeof(buf), "%u", s->mldversion);
1619 system_set_mldversion(dev, buf);
1621 if (s->flags & DEV_OPT_NEIGHREACHABLETIME & apply_mask) {
1622 snprintf(buf, sizeof(buf), "%u", s->neigh4reachabletime);
1623 system_set_neigh4reachabletime(dev, buf);
1624 snprintf(buf, sizeof(buf), "%u", s->neigh6reachabletime);
1625 system_set_neigh6reachabletime(dev, buf);
1627 if (s->flags & DEV_OPT_NEIGHLOCKTIME & apply_mask) {
1628 snprintf(buf, sizeof(buf), "%d", s->neigh4locktime);
1629 system_set_neigh4locktime(dev, buf);
1631 if (s->flags & DEV_OPT_NEIGHGCSTALETIME & apply_mask) {
1632 snprintf(buf, sizeof(buf), "%u", s->neigh4gcstaletime);
1633 system_set_neigh4gcstaletime(dev, buf);
1634 snprintf(buf, sizeof(buf), "%u", s->neigh6gcstaletime);
1635 system_set_neigh6gcstaletime(dev, buf);
1637 if (s->flags & DEV_OPT_DADTRANSMITS & apply_mask) {
1638 snprintf(buf, sizeof(buf), "%u", s->dadtransmits);
1639 system_set_dadtransmits(dev, buf);
1641 if (s->flags & DEV_OPT_MULTICAST & apply_mask) {
1642 if (system_if_flags(dev->ifname, s->multicast ? IFF_MULTICAST : 0,
1643 !s->multicast ? IFF_MULTICAST : 0) < 0)
1644 s->flags &= ~DEV_OPT_MULTICAST;
1646 if (s->flags & DEV_OPT_SENDREDIRECTS & apply_mask)
1647 system_set_sendredirects(dev, s->sendredirects ? "1" : "0");
1650 int system_if_up(struct device *dev)
1652 system_if_get_settings(dev, &dev->orig_settings);
1653 /* Only keep orig settings based on what needs to be set */
1654 dev->orig_settings.valid_flags = dev->orig_settings.flags;
1655 dev->orig_settings.flags &= dev->settings.flags;
1656 system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
1657 return system_if_flags(dev->ifname, IFF_UP, 0);
1660 int system_if_down(struct device *dev)
1662 int ret = system_if_flags(dev->ifname, 0, IFF_UP);
1663 system_if_apply_settings(dev, &dev->orig_settings, dev->orig_settings.flags);
1667 struct if_check_data {
1673 #ifndef IFF_LOWER_UP
1674 #define IFF_LOWER_UP 0x10000
1677 static int cb_if_check_valid(struct nl_msg *msg, void *arg)
1679 struct nlmsghdr *nh = nlmsg_hdr(msg);
1680 struct ifinfomsg *ifi = NLMSG_DATA(nh);
1681 struct if_check_data *chk = (struct if_check_data *)arg;
1683 if (nh->nlmsg_type != RTM_NEWLINK)
1686 device_set_present(chk->dev, ifi->ifi_index > 0 ? true : false);
1687 device_set_link(chk->dev, ifi->ifi_flags & IFF_LOWER_UP ? true : false);
1692 static int cb_if_check_ack(struct nl_msg *msg, void *arg)
1694 struct if_check_data *chk = (struct if_check_data *)arg;
1699 static int cb_if_check_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1701 struct if_check_data *chk = (struct if_check_data *)arg;
1703 device_set_present(chk->dev, false);
1704 device_set_link(chk->dev, false);
1705 chk->pending = err->error;
1710 int system_if_check(struct device *dev)
1712 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1714 struct ifinfomsg ifi = {
1715 .ifi_family = AF_UNSPEC,
1718 struct if_check_data chk = {
1727 msg = nlmsg_alloc_simple(RTM_GETLINK, 0);
1731 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) ||
1732 nla_put_string(msg, IFLA_IFNAME, dev->ifname))
1735 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_check_valid, &chk);
1736 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_check_ack, &chk);
1737 nl_cb_err(cb, NL_CB_CUSTOM, cb_if_check_error, &chk);
1739 ret = nl_send_auto_complete(sock_rtnl, msg);
1743 while (chk.pending > 0)
1744 nl_recvmsgs(sock_rtnl, cb);
1756 system_if_get_parent(struct device *dev)
1758 char buf[64], *devname;
1759 int ifindex, iflink, len;
1762 snprintf(buf, sizeof(buf), "/sys/class/net/%s/iflink", dev->ifname);
1763 f = fopen(buf, "r");
1767 len = fread(buf, 1, sizeof(buf) - 1, f);
1774 iflink = strtoul(buf, NULL, 0);
1775 ifindex = system_if_resolve(dev);
1776 if (!iflink || iflink == ifindex)
1779 devname = if_indextoname(iflink, buf);
1783 return device_get(devname, true);
1787 read_string_file(int dir_fd, const char *file, char *buf, int len)
1793 fd = openat(dir_fd, file, O_RDONLY);
1798 len = read(fd, buf, len - 1);
1802 } else if (len > 0) {
1805 c = strchr(buf, '\n');
1818 read_uint64_file(int dir_fd, const char *file, uint64_t *val)
1823 ret = read_string_file(dir_fd, file, buf, sizeof(buf));
1825 *val = strtoull(buf, NULL, 0);
1830 /* Assume advertised flags == supported flags */
1831 static const struct {
1834 } ethtool_link_modes[] = {
1835 { ADVERTISED_10baseT_Half, "10baseT-H" },
1836 { ADVERTISED_10baseT_Full, "10baseT-F" },
1837 { ADVERTISED_100baseT_Half, "100baseT-H" },
1838 { ADVERTISED_100baseT_Full, "100baseT-F" },
1839 { ADVERTISED_1000baseT_Half, "1000baseT-H" },
1840 { ADVERTISED_1000baseT_Full, "1000baseT-F" },
1841 { ADVERTISED_1000baseKX_Full, "1000baseKX-F" },
1842 { ADVERTISED_2500baseX_Full, "2500baseX-F" },
1843 { ADVERTISED_10000baseT_Full, "10000baseT-F" },
1844 { ADVERTISED_10000baseKX4_Full, "10000baseKX4-F" },
1845 { ADVERTISED_10000baseKR_Full, "10000baseKR-F" },
1846 { ADVERTISED_20000baseMLD2_Full, "20000baseMLD2-F" },
1847 { ADVERTISED_20000baseKR2_Full, "20000baseKR2-F" },
1848 { ADVERTISED_40000baseKR4_Full, "40000baseKR4-F" },
1849 { ADVERTISED_40000baseCR4_Full, "40000baseCR4-F" },
1850 { ADVERTISED_40000baseSR4_Full, "40000baseSR4-F" },
1851 { ADVERTISED_40000baseLR4_Full, "40000baseLR4-F" },
1852 #ifdef ADVERTISED_56000baseKR4_Full
1853 { ADVERTISED_56000baseKR4_Full, "56000baseKR4-F" },
1854 { ADVERTISED_56000baseCR4_Full, "56000baseCR4-F" },
1855 { ADVERTISED_56000baseSR4_Full, "56000baseSR4-F" },
1856 { ADVERTISED_56000baseLR4_Full, "56000baseLR4-F" },
1860 static void system_add_link_modes(struct blob_buf *b, __u32 mask)
1863 for (i = 0; i < ARRAY_SIZE(ethtool_link_modes); i++) {
1864 if (mask & ethtool_link_modes[i].mask)
1865 blobmsg_add_string(b, NULL, ethtool_link_modes[i].name);
1870 system_if_force_external(const char *ifname)
1875 snprintf(buf, sizeof(buf), "/sys/class/net/%s/phy80211", ifname);
1876 return stat(buf, &s) == 0;
1880 system_if_dump_info(struct device *dev, struct blob_buf *b)
1882 struct ethtool_cmd ecmd;
1887 memset(&ecmd, 0, sizeof(ecmd));
1888 memset(&ifr, 0, sizeof(ifr));
1889 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1890 ifr.ifr_data = (caddr_t) &ecmd;
1891 ecmd.cmd = ETHTOOL_GSET;
1893 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == 0) {
1894 c = blobmsg_open_array(b, "link-advertising");
1895 system_add_link_modes(b, ecmd.advertising);
1896 blobmsg_close_array(b, c);
1898 c = blobmsg_open_array(b, "link-partner-advertising");
1899 system_add_link_modes(b, ecmd.lp_advertising);
1900 blobmsg_close_array(b, c);
1902 c = blobmsg_open_array(b, "link-supported");
1903 system_add_link_modes(b, ecmd.supported);
1904 blobmsg_close_array(b, c);
1906 s = blobmsg_alloc_string_buffer(b, "speed", 8);
1907 snprintf(s, 8, "%d%c", ethtool_cmd_speed(&ecmd),
1908 ecmd.duplex == DUPLEX_HALF ? 'H' : 'F');
1909 blobmsg_add_string_buffer(b);
1911 blobmsg_add_u8(b, "autoneg", !!ecmd.autoneg);
1918 system_if_dump_stats(struct device *dev, struct blob_buf *b)
1920 const char *const counters[] = {
1921 "collisions", "rx_frame_errors", "tx_compressed",
1922 "multicast", "rx_length_errors", "tx_dropped",
1923 "rx_bytes", "rx_missed_errors", "tx_errors",
1924 "rx_compressed", "rx_over_errors", "tx_fifo_errors",
1925 "rx_crc_errors", "rx_packets", "tx_heartbeat_errors",
1926 "rx_dropped", "tx_aborted_errors", "tx_packets",
1927 "rx_errors", "tx_bytes", "tx_window_errors",
1928 "rx_fifo_errors", "tx_carrier_errors",
1935 snprintf(buf, sizeof(buf), "/sys/class/net/%s/statistics", dev->ifname);
1936 stats_dir = open(buf, O_DIRECTORY);
1940 for (i = 0; i < ARRAY_SIZE(counters); i++)
1941 if (read_uint64_file(stats_dir, counters[i], &val))
1942 blobmsg_add_u64(b, counters[i], val);
1948 static int system_addr(struct device *dev, struct device_addr *addr, int cmd)
1950 bool v4 = ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4);
1951 int alen = v4 ? 4 : 16;
1952 unsigned int flags = 0;
1953 struct ifaddrmsg ifa = {
1954 .ifa_family = (alen == 4) ? AF_INET : AF_INET6,
1955 .ifa_prefixlen = addr->mask,
1956 .ifa_index = dev->ifindex,
1960 if (cmd == RTM_NEWADDR)
1961 flags |= NLM_F_CREATE | NLM_F_REPLACE;
1963 msg = nlmsg_alloc_simple(cmd, flags);
1967 nlmsg_append(msg, &ifa, sizeof(ifa), 0);
1968 nla_put(msg, IFA_LOCAL, alen, &addr->addr);
1970 if (addr->broadcast)
1971 nla_put_u32(msg, IFA_BROADCAST, addr->broadcast);
1972 if (addr->point_to_point)
1973 nla_put_u32(msg, IFA_ADDRESS, addr->point_to_point);
1975 time_t now = system_get_rtime();
1976 struct ifa_cacheinfo cinfo = {0xffffffffU, 0xffffffffU, 0, 0};
1978 if (addr->preferred_until) {
1979 int64_t preferred = addr->preferred_until - now;
1982 else if (preferred > UINT32_MAX)
1983 preferred = UINT32_MAX;
1985 cinfo.ifa_prefered = preferred;
1988 if (addr->valid_until) {
1989 int64_t valid = addr->valid_until - now;
1994 else if (valid > UINT32_MAX)
1997 cinfo.ifa_valid = valid;
2000 nla_put(msg, IFA_CACHEINFO, sizeof(cinfo), &cinfo);
2002 if (cmd == RTM_NEWADDR && (addr->flags & DEVADDR_OFFLINK))
2003 nla_put_u32(msg, IFA_FLAGS, IFA_F_NOPREFIXROUTE);
2006 return system_rtnl_call(msg);
2009 int system_add_address(struct device *dev, struct device_addr *addr)
2011 return system_addr(dev, addr, RTM_NEWADDR);
2014 int system_del_address(struct device *dev, struct device_addr *addr)
2016 return system_addr(dev, addr, RTM_DELADDR);
2019 static int system_neigh(struct device *dev, struct device_neighbor *neighbor, int cmd)
2021 int alen = ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
2022 unsigned int flags = 0;
2023 struct ndmsg ndm = {
2024 .ndm_family = (alen == 4) ? AF_INET : AF_INET6,
2025 .ndm_ifindex = dev->ifindex,
2026 .ndm_state = NUD_PERMANENT,
2027 .ndm_flags = (neighbor->proxy ? NTF_PROXY : 0) | (neighbor->router ? NTF_ROUTER : 0),
2031 if (cmd == RTM_NEWNEIGH)
2032 flags |= NLM_F_CREATE | NLM_F_REPLACE;
2034 msg = nlmsg_alloc_simple(cmd, flags);
2039 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
2041 nla_put(msg, NDA_DST, alen, &neighbor->addr);
2042 if (neighbor->flags & DEVNEIGH_MAC)
2043 nla_put(msg, NDA_LLADDR, sizeof(neighbor->macaddr), &neighbor->macaddr);
2046 return system_rtnl_call(msg);
2049 int system_add_neighbor(struct device *dev, struct device_neighbor *neighbor)
2051 return system_neigh(dev, neighbor, RTM_NEWNEIGH);
2054 int system_del_neighbor(struct device *dev, struct device_neighbor *neighbor)
2056 return system_neigh(dev, neighbor, RTM_DELNEIGH);
2059 static int system_rt(struct device *dev, struct device_route *route, int cmd)
2061 int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
2063 unsigned int flags = 0;
2066 have_gw = !!route->nexthop.in.s_addr;
2068 have_gw = route->nexthop.in6.s6_addr32[0] ||
2069 route->nexthop.in6.s6_addr32[1] ||
2070 route->nexthop.in6.s6_addr32[2] ||
2071 route->nexthop.in6.s6_addr32[3];
2073 unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))
2074 ? route->table : RT_TABLE_MAIN;
2076 struct rtmsg rtm = {
2077 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
2078 .rtm_dst_len = route->mask,
2079 .rtm_src_len = route->sourcemask,
2080 .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC,
2081 .rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC,
2082 .rtm_scope = RT_SCOPE_NOWHERE,
2083 .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST,
2084 .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0,
2088 if (cmd == RTM_NEWROUTE) {
2089 flags |= NLM_F_CREATE | NLM_F_REPLACE;
2091 if (!dev) { /* Add null-route */
2092 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
2093 rtm.rtm_type = RTN_UNREACHABLE;
2096 rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
2099 if (route->flags & DEVROUTE_TYPE) {
2100 rtm.rtm_type = route->type;
2101 if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) {
2102 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST ||
2103 rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST)
2104 rtm.rtm_table = RT_TABLE_LOCAL;
2107 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) {
2108 rtm.rtm_scope = RT_SCOPE_HOST;
2109 } else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
2110 rtm.rtm_type == RTN_ANYCAST) {
2111 rtm.rtm_scope = RT_SCOPE_LINK;
2112 } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE ||
2113 rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY ||
2114 rtm.rtm_type == RTN_THROW) {
2115 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
2120 msg = nlmsg_alloc_simple(cmd, flags);
2124 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
2127 nla_put(msg, RTA_DST, alen, &route->addr);
2129 if (route->sourcemask) {
2130 if (rtm.rtm_family == AF_INET)
2131 nla_put(msg, RTA_PREFSRC, alen, &route->source);
2133 nla_put(msg, RTA_SRC, alen, &route->source);
2136 if (route->metric > 0)
2137 nla_put_u32(msg, RTA_PRIORITY, route->metric);
2140 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop);
2143 nla_put_u32(msg, RTA_OIF, dev->ifindex);
2146 nla_put_u32(msg, RTA_TABLE, table);
2148 if (route->flags & DEVROUTE_MTU) {
2149 struct nlattr *metrics;
2151 if (!(metrics = nla_nest_start(msg, RTA_METRICS)))
2152 goto nla_put_failure;
2154 nla_put_u32(msg, RTAX_MTU, route->mtu);
2156 nla_nest_end(msg, metrics);
2159 return system_rtnl_call(msg);
2166 int system_add_route(struct device *dev, struct device_route *route)
2168 return system_rt(dev, route, RTM_NEWROUTE);
2171 int system_del_route(struct device *dev, struct device_route *route)
2173 return system_rt(dev, route, RTM_DELROUTE);
2176 int system_flush_routes(void)
2178 const char *names[] = {
2179 "/proc/sys/net/ipv4/route/flush",
2180 "/proc/sys/net/ipv6/route/flush"
2184 for (i = 0; i < ARRAY_SIZE(names); i++) {
2185 fd = open(names[i], O_WRONLY);
2189 if (write(fd, "-1", 2)) {}
2195 bool system_resolve_rt_type(const char *type, unsigned int *id)
2197 return system_rtn_aton(type, id);
2200 bool system_resolve_rt_proto(const char *type, unsigned int *id)
2204 unsigned int n, proto = 256;
2205 n = strtoul(type, &e, 0);
2206 if (!*e && e != type)
2208 else if (!strcmp(type, "unspec"))
2209 proto = RTPROT_UNSPEC;
2210 else if (!strcmp(type, "kernel"))
2211 proto = RTPROT_KERNEL;
2212 else if (!strcmp(type, "boot"))
2213 proto = RTPROT_BOOT;
2214 else if (!strcmp(type, "static"))
2215 proto = RTPROT_STATIC;
2216 else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) {
2217 while (fgets(buf, sizeof(buf) - 1, f) != NULL) {
2218 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2221 n = strtoul(e, NULL, 10);
2222 e = strtok(NULL, " \t\n");
2224 if (e && !strcmp(e, type)) {
2239 bool system_resolve_rt_table(const char *name, unsigned int *id)
2243 unsigned int n, table = RT_TABLE_UNSPEC;
2245 /* first try to parse table as number */
2246 if ((n = strtoul(name, &e, 0)) > 0 && !*e)
2249 /* handle well known aliases */
2250 else if (!strcmp(name, "default"))
2251 table = RT_TABLE_DEFAULT;
2252 else if (!strcmp(name, "main"))
2253 table = RT_TABLE_MAIN;
2254 else if (!strcmp(name, "local"))
2255 table = RT_TABLE_LOCAL;
2257 /* try to look up name in /etc/iproute2/rt_tables */
2258 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL)
2260 while (fgets(buf, sizeof(buf) - 1, f) != NULL)
2262 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2265 n = strtoul(e, NULL, 10);
2266 e = strtok(NULL, " \t\n");
2268 if (e && !strcmp(e, name))
2278 if (table == RT_TABLE_UNSPEC)
2285 bool system_is_default_rt_table(unsigned int id)
2287 return (id == RT_TABLE_MAIN);
2290 bool system_resolve_rpfilter(const char *filter, unsigned int *id)
2295 if (!strcmp(filter, "strict"))
2297 else if (!strcmp(filter, "loose"))
2300 n = strtoul(filter, &e, 0);
2301 if (*e || e == filter || n > 2)
2309 static int system_iprule(struct iprule *rule, int cmd)
2311 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16;
2314 struct rtmsg rtm = {
2315 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
2316 .rtm_protocol = RTPROT_STATIC,
2317 .rtm_scope = RT_SCOPE_UNIVERSE,
2318 .rtm_table = RT_TABLE_UNSPEC,
2319 .rtm_type = RTN_UNSPEC,
2323 if (cmd == RTM_NEWRULE)
2324 rtm.rtm_type = RTN_UNICAST;
2327 rtm.rtm_flags |= FIB_RULE_INVERT;
2329 if (rule->flags & IPRULE_SRC)
2330 rtm.rtm_src_len = rule->src_mask;
2332 if (rule->flags & IPRULE_DEST)
2333 rtm.rtm_dst_len = rule->dest_mask;
2335 if (rule->flags & IPRULE_TOS)
2336 rtm.rtm_tos = rule->tos;
2338 if (rule->flags & IPRULE_LOOKUP) {
2339 if (rule->lookup < 256)
2340 rtm.rtm_table = rule->lookup;
2343 if (rule->flags & IPRULE_ACTION)
2344 rtm.rtm_type = rule->action;
2345 else if (rule->flags & IPRULE_GOTO)
2346 rtm.rtm_type = FR_ACT_GOTO;
2347 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO)))
2348 rtm.rtm_type = FR_ACT_NOP;
2350 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST);
2355 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
2357 if (rule->flags & IPRULE_IN)
2358 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev);
2360 if (rule->flags & IPRULE_OUT)
2361 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev);
2363 if (rule->flags & IPRULE_SRC)
2364 nla_put(msg, FRA_SRC, alen, &rule->src_addr);
2366 if (rule->flags & IPRULE_DEST)
2367 nla_put(msg, FRA_DST, alen, &rule->dest_addr);
2369 if (rule->flags & IPRULE_PRIORITY)
2370 nla_put_u32(msg, FRA_PRIORITY, rule->priority);
2371 else if (cmd == RTM_NEWRULE)
2372 nla_put_u32(msg, FRA_PRIORITY, rule->order);
2374 if (rule->flags & IPRULE_FWMARK)
2375 nla_put_u32(msg, FRA_FWMARK, rule->fwmark);
2377 if (rule->flags & IPRULE_FWMASK)
2378 nla_put_u32(msg, FRA_FWMASK, rule->fwmask);
2380 if (rule->flags & IPRULE_LOOKUP) {
2381 if (rule->lookup >= 256)
2382 nla_put_u32(msg, FRA_TABLE, rule->lookup);
2385 if (rule->flags & IPRULE_SUP_PREFIXLEN)
2386 nla_put_u32(msg, FRA_SUPPRESS_PREFIXLEN, rule->sup_prefixlen);
2388 if (rule->flags & IPRULE_GOTO)
2389 nla_put_u32(msg, FRA_GOTO, rule->gotoid);
2391 return system_rtnl_call(msg);
2394 int system_add_iprule(struct iprule *rule)
2396 return system_iprule(rule, RTM_NEWRULE);
2399 int system_del_iprule(struct iprule *rule)
2401 return system_iprule(rule, RTM_DELRULE);
2404 int system_flush_iprules(void)
2409 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET);
2410 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6);
2412 memset(&rule, 0, sizeof(rule));
2415 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2418 rule.lookup = RT_TABLE_LOCAL;
2419 rv |= system_iprule(&rule, RTM_NEWRULE);
2421 rule.priority = 32766;
2422 rule.lookup = RT_TABLE_MAIN;
2423 rv |= system_iprule(&rule, RTM_NEWRULE);
2425 rule.priority = 32767;
2426 rule.lookup = RT_TABLE_DEFAULT;
2427 rv |= system_iprule(&rule, RTM_NEWRULE);
2430 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2433 rule.lookup = RT_TABLE_LOCAL;
2434 rv |= system_iprule(&rule, RTM_NEWRULE);
2436 rule.priority = 32766;
2437 rule.lookup = RT_TABLE_MAIN;
2438 rv |= system_iprule(&rule, RTM_NEWRULE);
2443 bool system_resolve_iprule_action(const char *action, unsigned int *id)
2445 return system_rtn_aton(action, id);
2448 time_t system_get_rtime(void)
2453 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
2456 if (gettimeofday(&tv, NULL) == 0)
2463 #define IP_DF 0x4000
2466 static int tunnel_ioctl(const char *name, int cmd, void *p)
2470 memset(&ifr, 0, sizeof(ifr));
2471 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
2472 ifr.ifr_ifru.ifru_data = p;
2473 return ioctl(sock_ioctl, cmd, &ifr);
2476 #ifdef IFLA_IPTUN_MAX
2477 static int system_add_ip6_tunnel(const char *name, const unsigned int link,
2478 struct blob_attr **tb)
2480 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK,
2481 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2482 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC };
2483 struct blob_attr *cur;
2484 int ret = 0, ttl = 0;
2489 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2490 nla_put_string(nlm, IFLA_IFNAME, name);
2493 nla_put_u32(nlm, IFLA_LINK, link);
2495 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2501 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl");
2502 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2509 nla_put_u32(nlm, IFLA_IPTUN_LINK, link);
2511 if ((cur = tb[TUNNEL_ATTR_TTL]))
2512 ttl = blobmsg_get_u32(cur);
2514 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP);
2515 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64);
2517 struct in6_addr in6buf;
2518 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2519 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2523 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf);
2526 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2527 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2531 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf);
2534 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2535 struct blob_attr *tb_data[__IPIP6_DATA_ATTR_MAX];
2536 uint32_t tun_flags = IP6_TNL_F_IGN_ENCAP_LIMIT;
2538 blobmsg_parse(ipip6_data_attr_list.params, __IPIP6_DATA_ATTR_MAX, tb_data,
2539 blobmsg_data(cur), blobmsg_len(cur));
2541 if ((cur = tb_data[IPIP6_DATA_ENCAPLIMIT])) {
2542 char *str = blobmsg_get_string(cur);
2544 if (strcmp(str, "ignore")) {
2546 unsigned encap_limit = strtoul(str, &e, 0);
2548 if (e == str || *e || encap_limit > 255) {
2553 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, encap_limit);
2554 tun_flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
2558 #ifdef IFLA_IPTUN_FMR_MAX
2559 if ((cur = tb_data[IPIP6_DATA_FMRS])) {
2560 struct blob_attr *rcur;
2561 unsigned rrem, fmrcnt = 0;
2562 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS);
2569 blobmsg_for_each_attr(rcur, cur, rrem) {
2570 struct blob_attr *tb_fmr[__FMR_DATA_ATTR_MAX], *tb_cur;
2571 struct in6_addr ip6prefix;
2572 struct in_addr ip4prefix;
2573 unsigned ip4len, ip6len, ealen, offset;
2575 blobmsg_parse(fmr_data_attr_list.params, __FMR_DATA_ATTR_MAX, tb_fmr,
2576 blobmsg_data(rcur), blobmsg_len(rcur));
2578 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX6]) ||
2579 !parse_ip_and_netmask(AF_INET6,
2580 blobmsg_data(tb_cur), &ip6prefix,
2586 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX4]) ||
2587 !parse_ip_and_netmask(AF_INET,
2588 blobmsg_data(tb_cur), &ip4prefix,
2594 if (!(tb_cur = tb_fmr[FMR_DATA_EALEN])) {
2598 ealen = blobmsg_get_u32(tb_cur);
2600 if (!(tb_cur = tb_fmr[FMR_DATA_OFFSET])) {
2604 offset = blobmsg_get_u32(tb_cur);
2606 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt);
2612 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix);
2613 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix);
2614 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len);
2615 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len);
2616 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen);
2617 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset);
2619 nla_nest_end(nlm, rule);
2622 nla_nest_end(nlm, fmrs);
2626 nla_put_u32(nlm, IFLA_IPTUN_FLAGS, tun_flags);
2629 nla_nest_end(nlm, infodata);
2630 nla_nest_end(nlm, linkinfo);
2632 return system_rtnl_call(nlm);
2640 #ifdef IFLA_IPTUN_MAX
2641 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000)
2642 static int system_add_gre_tunnel(const char *name, const char *kind,
2643 const unsigned int link, struct blob_attr **tb, bool v6)
2646 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
2647 struct blob_attr *cur;
2648 uint32_t ikey = 0, okey = 0, flowinfo = 0, flags6 = IP6_TNL_F_IGN_ENCAP_LIMIT;
2649 uint16_t iflags = 0, oflags = 0;
2651 int ret = 0, ttl = 0;
2652 unsigned encap_limit = 0;
2654 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2658 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2659 nla_put_string(nlm, IFLA_IFNAME, name);
2661 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2667 nla_put_string(nlm, IFLA_INFO_KIND, kind);
2668 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2675 nla_put_u32(nlm, IFLA_GRE_LINK, link);
2677 if ((cur = tb[TUNNEL_ATTR_TTL]))
2678 ttl = blobmsg_get_u32(cur);
2680 if ((cur = tb[TUNNEL_ATTR_TOS])) {
2681 char *str = blobmsg_get_string(cur);
2682 if (strcmp(str, "inherit")) {
2685 if (!system_tos_aton(str, &uval)) {
2691 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS;
2696 flags6 |= IP6_TNL_F_USE_ORIG_TCLASS;
2702 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2703 struct blob_attr *tb_data[__GRE_DATA_ATTR_MAX];
2705 blobmsg_parse(gre_data_attr_list.params, __GRE_DATA_ATTR_MAX, tb_data,
2706 blobmsg_data(cur), blobmsg_len(cur));
2708 if ((cur = tb_data[GRE_DATA_IKEY])) {
2709 if ((ikey = blobmsg_get_u32(cur)))
2713 if ((cur = tb_data[GRE_DATA_OKEY])) {
2714 if ((okey = blobmsg_get_u32(cur)))
2718 if ((cur = tb_data[GRE_DATA_ICSUM])) {
2719 if (blobmsg_get_bool(cur))
2723 if ((cur = tb_data[GRE_DATA_OCSUM])) {
2724 if (blobmsg_get_bool(cur))
2728 if ((cur = tb_data[GRE_DATA_ISEQNO])) {
2729 if (blobmsg_get_bool(cur))
2733 if ((cur = tb_data[GRE_DATA_OSEQNO])) {
2734 if (blobmsg_get_bool(cur))
2738 if ((cur = tb_data[GRE_DATA_ENCAPLIMIT])) {
2739 char *str = blobmsg_get_string(cur);
2741 if (strcmp(str, "ignore")) {
2744 encap_limit = strtoul(str, &e, 0);
2746 if (e == str || *e || encap_limit > 255) {
2751 flags6 &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
2757 struct in6_addr in6buf;
2758 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2759 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2763 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf);
2766 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2767 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2771 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf);
2774 if (!(flags6 & IP6_TNL_F_IGN_ENCAP_LIMIT))
2775 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, encap_limit);
2778 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo);
2781 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags6);
2786 struct in_addr inbuf;
2789 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2790 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2794 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf);
2797 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2798 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2802 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf);
2804 if (IN_MULTICAST(ntohl(inbuf.s_addr))) {
2806 okey = inbuf.s_addr;
2811 ikey = inbuf.s_addr;
2817 if ((cur = tb[TUNNEL_ATTR_DF]))
2818 set_df = blobmsg_get_bool(cur);
2821 /* ttl != 0 and nopmtudisc are incompatible */
2829 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0);
2831 nla_put_u8(nlm, IFLA_GRE_TOS, tos);
2835 nla_put_u8(nlm, IFLA_GRE_TTL, ttl);
2838 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags);
2841 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags);
2844 nla_put_u32(nlm, IFLA_GRE_OKEY, htonl(okey));
2847 nla_put_u32(nlm, IFLA_GRE_IKEY, htonl(ikey));
2849 nla_nest_end(nlm, infodata);
2850 nla_nest_end(nlm, linkinfo);
2852 return system_rtnl_call(nlm);
2861 static int system_add_vti_tunnel(const char *name, const char *kind,
2862 const unsigned int link, struct blob_attr **tb, bool v6)
2865 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
2866 struct blob_attr *cur;
2869 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2873 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2874 nla_put_string(nlm, IFLA_IFNAME, name);
2876 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2882 nla_put_string(nlm, IFLA_INFO_KIND, kind);
2883 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2890 nla_put_u32(nlm, IFLA_VTI_LINK, link);
2893 struct in6_addr in6buf;
2894 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2895 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2899 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(in6buf), &in6buf);
2902 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2903 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2907 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(in6buf), &in6buf);
2911 struct in_addr inbuf;
2913 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2914 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2918 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(inbuf), &inbuf);
2921 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2922 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
2926 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(inbuf), &inbuf);
2931 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2932 struct blob_attr *tb_data[__VTI_DATA_ATTR_MAX];
2933 uint32_t ikey = 0, okey = 0;
2935 blobmsg_parse(vti_data_attr_list.params, __VTI_DATA_ATTR_MAX, tb_data,
2936 blobmsg_data(cur), blobmsg_len(cur));
2938 if ((cur = tb_data[VTI_DATA_IKEY])) {
2939 if ((ikey = blobmsg_get_u32(cur)))
2940 nla_put_u32(nlm, IFLA_VTI_IKEY, htonl(ikey));
2943 if ((cur = tb_data[VTI_DATA_OKEY])) {
2944 if ((okey = blobmsg_get_u32(cur)))
2945 nla_put_u32(nlm, IFLA_VTI_OKEY, htonl(okey));
2949 nla_nest_end(nlm, infodata);
2950 nla_nest_end(nlm, linkinfo);
2952 return system_rtnl_call(nlm);
2960 #ifdef IFLA_XFRM_MAX
2961 static int system_add_xfrm_tunnel(const char *name, const char *kind,
2962 const unsigned int link, struct blob_attr **tb)
2965 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
2966 struct blob_attr *cur;
2969 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2973 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2974 nla_put_string(nlm, IFLA_IFNAME, name);
2976 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2982 nla_put_string(nlm, IFLA_INFO_KIND, kind);
2983 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2990 nla_put_u32(nlm, IFLA_XFRM_LINK, link);
2992 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2993 struct blob_attr *tb_data[__XFRM_DATA_ATTR_MAX];
2996 blobmsg_parse(xfrm_data_attr_list.params, __XFRM_DATA_ATTR_MAX, tb_data,
2997 blobmsg_data(cur), blobmsg_len(cur));
2999 if ((cur = tb_data[XFRM_DATA_IF_ID])) {
3000 if ((if_id = blobmsg_get_u32(cur)))
3001 nla_put_u32(nlm, IFLA_XFRM_IF_ID, if_id);
3006 nla_nest_end(nlm, infodata);
3007 nla_nest_end(nlm, linkinfo);
3009 return system_rtnl_call(nlm);
3017 #ifdef IFLA_VXLAN_MAX
3018 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6)
3020 struct blob_attr *tb_data[__VXLAN_DATA_ATTR_MAX];
3022 struct nlattr *linkinfo, *data;
3023 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
3024 struct blob_attr *cur;
3027 if ((cur = tb[TUNNEL_ATTR_DATA]))
3028 blobmsg_parse(vxlan_data_attr_list.params, __VXLAN_DATA_ATTR_MAX, tb_data,
3029 blobmsg_data(cur), blobmsg_len(cur));
3033 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
3038 nlmsg_append(msg, &iim, sizeof(iim), 0);
3040 nla_put_string(msg, IFLA_IFNAME, name);
3042 if ((cur = tb_data[VXLAN_DATA_ATTR_MACADDR])) {
3043 struct ether_addr *ea = ether_aton(blobmsg_get_string(cur));
3049 nla_put(msg, IFLA_ADDRESS, ETH_ALEN, ea);
3052 if ((cur = tb[TUNNEL_ATTR_MTU])) {
3053 uint32_t mtu = blobmsg_get_u32(cur);
3054 nla_put_u32(msg, IFLA_MTU, mtu);
3057 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) {
3062 nla_put_string(msg, IFLA_INFO_KIND, "vxlan");
3064 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) {
3070 nla_put_u32(msg, IFLA_VXLAN_LINK, link);
3072 if ((cur = tb_data[VXLAN_DATA_ATTR_ID])) {
3073 uint32_t id = blobmsg_get_u32(cur);
3074 if (id >= (1u << 24) - 1) {
3079 nla_put_u32(msg, IFLA_VXLAN_ID, id);
3083 struct in6_addr in6buf;
3084 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3085 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3089 nla_put(msg, IFLA_VXLAN_LOCAL6, sizeof(in6buf), &in6buf);
3092 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3093 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3097 nla_put(msg, IFLA_VXLAN_GROUP6, sizeof(in6buf), &in6buf);
3100 struct in_addr inbuf;
3102 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3103 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3107 nla_put(msg, IFLA_VXLAN_LOCAL, sizeof(inbuf), &inbuf);
3110 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3111 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3115 nla_put(msg, IFLA_VXLAN_GROUP, sizeof(inbuf), &inbuf);
3119 uint32_t port = 4789;
3120 if ((cur = tb_data[VXLAN_DATA_ATTR_PORT])) {
3121 port = blobmsg_get_u32(cur);
3122 if (port < 1 || port > 65535) {
3127 nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port));
3129 if ((cur = tb_data[VXLAN_DATA_ATTR_RXCSUM])) {
3130 bool rxcsum = blobmsg_get_bool(cur);
3131 nla_put_u8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, !rxcsum);
3134 if ((cur = tb_data[VXLAN_DATA_ATTR_TXCSUM])) {
3135 bool txcsum = blobmsg_get_bool(cur);
3136 nla_put_u8(msg, IFLA_VXLAN_UDP_CSUM, txcsum);
3137 nla_put_u8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, !txcsum);
3140 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3141 char *str = blobmsg_get_string(cur);
3144 if (strcmp(str, "inherit")) {
3145 if (!system_tos_aton(str, &tos)) {
3151 nla_put_u8(msg, IFLA_VXLAN_TOS, tos);
3154 if ((cur = tb[TUNNEL_ATTR_TTL])) {
3155 uint32_t ttl = blobmsg_get_u32(cur);
3156 if (ttl < 1 || ttl > 255) {
3161 nla_put_u8(msg, IFLA_VXLAN_TTL, ttl);
3164 nla_nest_end(msg, data);
3165 nla_nest_end(msg, linkinfo);
3167 ret = system_rtnl_call(msg);
3169 D(SYSTEM, "Error adding vxlan '%s': %d\n", name, ret);
3179 static int system_add_sit_tunnel(const char *name, const unsigned int link, struct blob_attr **tb)
3181 struct blob_attr *cur;
3184 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
3188 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3189 struct blob_attr *tb_data[__SIXRD_DATA_ATTR_MAX];
3191 struct ip_tunnel_6rd p6;
3193 blobmsg_parse(sixrd_data_attr_list.params, __SIXRD_DATA_ATTR_MAX, tb_data,
3194 blobmsg_data(cur), blobmsg_len(cur));
3196 memset(&p6, 0, sizeof(p6));
3198 if ((cur = tb_data[SIXRD_DATA_PREFIX])) {
3199 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur),
3200 &p6.prefix, &mask) || mask > 128) {
3205 p6.prefixlen = mask;
3208 if ((cur = tb_data[SIXRD_DATA_RELAY_PREFIX])) {
3209 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur),
3210 &p6.relay_prefix, &mask) || mask > 32) {
3215 p6.relay_prefixlen = mask;
3218 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) {
3228 __system_del_ip_tunnel(name, tb);
3232 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb)
3234 struct blob_attr *cur;
3236 struct ip_tunnel_parm p = {
3245 if ((cur = tb[TUNNEL_ATTR_LOCAL]) &&
3246 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1)
3249 if ((cur = tb[TUNNEL_ATTR_REMOTE]) &&
3250 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1)
3253 if ((cur = tb[TUNNEL_ATTR_DF]))
3254 set_df = blobmsg_get_bool(cur);
3256 if ((cur = tb[TUNNEL_ATTR_TTL]))
3257 p.iph.ttl = blobmsg_get_u32(cur);
3259 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3260 char *str = blobmsg_get_string(cur);
3261 if (strcmp(str, "inherit")) {
3264 if (!system_tos_aton(str, &uval))
3272 p.iph.frag_off = set_df ? htons(IP_DF) : 0;
3273 /* ttl !=0 and nopmtudisc are incompatible */
3274 if (p.iph.ttl && p.iph.frag_off == 0)
3277 strncpy(p.name, name, sizeof(p.name) - 1);
3279 switch (p.iph.protocol) {
3281 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p);
3283 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p);
3290 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb)
3292 struct blob_attr *cur;
3295 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
3297 str = blobmsg_data(cur);
3299 if (!strcmp(str, "greip") || !strcmp(str, "gretapip") ||
3300 !strcmp(str, "greip6") || !strcmp(str, "gretapip6") ||
3301 !strcmp(str, "vtiip") || !strcmp(str, "vtiip6") ||
3302 !strcmp(str, "vxlan") || !strcmp(str, "vxlan6") ||
3303 !strcmp(str, "xfrm"))
3304 return system_link_del(name);
3306 return tunnel_ioctl(name, SIOCDELTUNNEL, NULL);
3309 int system_del_ip_tunnel(const char *name, struct blob_attr *attr)
3311 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
3313 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
3314 blob_data(attr), blob_len(attr));
3316 return __system_del_ip_tunnel(name, tb);
3319 int system_update_ipv6_mtu(struct device *dev, int mtu)
3325 snprintf(buf, sizeof(buf), "/proc/sys/net/ipv6/conf/%s/mtu",
3328 fd = open(buf, O_RDWR);
3333 ssize_t len = read(fd, buf, sizeof(buf) - 1);
3340 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0)
3349 int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
3351 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
3352 struct blob_attr *cur;
3355 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
3356 blob_data(attr), blob_len(attr));
3358 __system_del_ip_tunnel(name, tb);
3360 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
3362 str = blobmsg_data(cur);
3364 unsigned int ttl = 0;
3365 if ((cur = tb[TUNNEL_ATTR_TTL])) {
3366 ttl = blobmsg_get_u32(cur);
3371 unsigned int link = 0;
3372 if ((cur = tb[TUNNEL_ATTR_LINK])) {
3373 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
3377 if (iface->l3_dev.dev)
3378 link = iface->l3_dev.dev->ifindex;
3381 if (!strcmp(str, "sit"))
3382 return system_add_sit_tunnel(name, link, tb);
3383 #ifdef IFLA_IPTUN_MAX
3384 else if (!strcmp(str, "ipip6")) {
3385 return system_add_ip6_tunnel(name, link, tb);
3386 } else if (!strcmp(str, "greip")) {
3387 return system_add_gre_tunnel(name, "gre", link, tb, false);
3388 } else if (!strcmp(str, "gretapip")) {
3389 return system_add_gre_tunnel(name, "gretap", link, tb, false);
3390 } else if (!strcmp(str, "greip6")) {
3391 return system_add_gre_tunnel(name, "ip6gre", link, tb, true);
3392 } else if (!strcmp(str, "gretapip6")) {
3393 return system_add_gre_tunnel(name, "ip6gretap", link, tb, true);
3395 } else if (!strcmp(str, "vtiip")) {
3396 return system_add_vti_tunnel(name, "vti", link, tb, false);
3397 } else if (!strcmp(str, "vtiip6")) {
3398 return system_add_vti_tunnel(name, "vti6", link, tb, true);
3400 #ifdef IFLA_XFRM_MAX
3401 } else if (!strcmp(str, "xfrm")) {
3402 return system_add_xfrm_tunnel(name, "xfrm", link, tb);
3404 #ifdef IFLA_VXLAN_MAX
3405 } else if(!strcmp(str, "vxlan")) {
3406 return system_add_vxlan(name, link, tb, false);
3407 } else if(!strcmp(str, "vxlan6")) {
3408 return system_add_vxlan(name, link, tb, true);
3411 } else if (!strcmp(str, "ipip")) {
3412 return system_add_proto_tunnel(name, IPPROTO_IPIP, link, tb);