X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=system-linux.c;h=8a1173cf539dfc05ad6f29e54b4660cd41972a2e;hb=7cc2f10824fb0f7a519a30a77ed75439aab2b6ff;hp=90b0775d57bd26b6ff29f9040f17bf53031469ad;hpb=fef10041f3a495d79f03f99bdf416a68a0ee91aa;p=project%2Fnetifd.git diff --git a/system-linux.c b/system-linux.c index 90b0775..8a1173c 100644 --- a/system-linux.c +++ b/system-linux.c @@ -52,7 +52,6 @@ #define IFA_FLAGS (IFA_MULTICAST + 1) #endif - #include #include #include @@ -140,7 +139,7 @@ create_socket(int protocol, int groups) static bool create_raw_event_socket(struct event_socket *ev, int protocol, int groups, - uloop_fd_handler cb, int flags) + uloop_fd_handler cb, int flags) { ev->sock = create_socket(protocol, groups); if (!ev->sock) @@ -244,7 +243,7 @@ int system_init(void) return -1; if (!create_raw_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT, 1, - handle_hotplug_event, 0)) + handle_hotplug_event, 0)) return -1; // Receive network link events form kernel @@ -326,6 +325,11 @@ static void system_bridge_set_multicast_to_unicast(struct device *dev, const cha system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_to_unicast", dev->ifname, val); } +static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val) +{ + system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_fast_leave", dev->ifname, val); +} + static void system_bridge_set_hairpin_mode(struct device *dev, const char *val) { system_set_dev_sysctl("/sys/class/net/%s/brport/hairpin_mode", dev->ifname, val); @@ -392,6 +396,11 @@ static void system_bridge_set_unicast_flood(struct device *dev, const char *val) system_set_dev_sysctl("/sys/class/net/%s/brport/unicast_flood", dev->ifname, val); } +static void system_set_sendredirects(struct device *dev, const char *val) +{ + system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects", dev->ifname, val); +} + static int system_get_sysctl(const char *path, char *buf, const size_t buf_sz) { int fd = -1, ret = -1; @@ -480,6 +489,12 @@ static int system_get_dadtransmits(struct device *dev, char *buf, const size_t b dev->ifname, buf, buf_sz); } +static int system_get_sendredirects(struct device *dev, char *buf, const size_t buf_sz) +{ + return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/send_redirects", + dev->ifname, buf, buf_sz); +} + // Evaluate netlink messages static int cb_rtnl_event(struct nl_msg *msg, void *arg) { @@ -495,7 +510,7 @@ static int cb_rtnl_event(struct nl_msg *msg, void *arg) if (!nla[IFLA_IFNAME]) goto out; - struct device *dev = device_get(nla_data(nla[IFLA_IFNAME]), false); + struct device *dev = device_find(nla_data(nla[IFLA_IFNAME])); if (!dev) goto out; @@ -548,7 +563,7 @@ handle_hotplug_msg(char *data, int size) return; found: - dev = device_get(interface, false); + dev = device_find(interface); if (!dev) return; @@ -680,6 +695,10 @@ int system_bridge_addif(struct device *bridge, struct device *dev) system_bridge_set_multicast_router(dev, buf, false); } + if (dev->settings.flags & DEV_OPT_MULTICAST_FAST_LEAVE && + dev->settings.multicast_fast_leave) + system_bridge_set_multicast_fast_leave(dev, "1"); + if (dev->settings.flags & DEV_OPT_LEARNING && !dev->settings.learning) system_bridge_set_learning(dev, "0"); @@ -1157,10 +1176,10 @@ int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlande nlmsg_append(msg, &iim, sizeof(iim), 0); nla_put_string(msg, IFLA_IFNAME, vlandev->ifname); nla_put_u32(msg, IFLA_LINK, dev->ifindex); - + if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) goto nla_put_failure; - + nla_put_string(msg, IFLA_INFO_KIND, "vlan"); if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) @@ -1279,6 +1298,11 @@ system_if_get_settings(struct device *dev, struct device_settings *s) s->dadtransmits = strtoul(buf, NULL, 0); s->flags |= DEV_OPT_DADTRANSMITS; } + + if (!system_get_sendredirects(dev, buf, sizeof(buf))) { + s->sendredirects = strtoul(buf, NULL, 0); + s->flags |= DEV_OPT_SENDREDIRECTS; + } } static void @@ -1384,6 +1408,8 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned !s->multicast ? IFF_MULTICAST : 0) < 0) s->flags &= ~DEV_OPT_MULTICAST; } + if (s->flags & DEV_OPT_SENDREDIRECTS & apply_mask) + system_set_sendredirects(dev, s->sendredirects ? "1" : "0"); system_if_apply_rps_xps(dev, s); } @@ -1755,7 +1781,7 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd) .rtm_dst_len = route->mask, .rtm_src_len = route->sourcemask, .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC, - .rtm_protocol = (route->flags & DEVADDR_KERNEL) ? RTPROT_KERNEL : RTPROT_STATIC, + .rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC, .rtm_scope = RT_SCOPE_NOWHERE, .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST, .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0, @@ -1873,6 +1899,45 @@ bool system_resolve_rt_type(const char *type, unsigned int *id) return system_rtn_aton(type, id); } +bool system_resolve_rt_proto(const char *type, unsigned int *id) +{ + FILE *f; + char *e, buf[128]; + unsigned int n, proto = 256; + + if ((n = strtoul(type, &e, 0)) >= 0 && !*e && e != type) + proto = n; + else if (!strcmp(type, "unspec")) + proto = RTPROT_UNSPEC; + else if (!strcmp(type, "kernel")) + proto = RTPROT_KERNEL; + else if (!strcmp(type, "boot")) + proto = RTPROT_BOOT; + else if (!strcmp(type, "static")) + proto = RTPROT_STATIC; + else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) { + while (fgets(buf, sizeof(buf) - 1, f) != NULL) { + if ((e = strtok(buf, " \t\n")) == NULL || *e == '#') + continue; + + n = strtoul(e, NULL, 10); + e = strtok(NULL, " \t\n"); + + if (e && !strcmp(e, type)) { + proto = n; + break; + } + } + fclose(f); + } + + if (proto > 255) + return false; + + *id = proto; + return true; +} + bool system_resolve_rt_table(const char *name, unsigned int *id) { FILE *f; @@ -2118,7 +2183,7 @@ static int system_add_gre_tunnel(const char *name, const char *kind, uint32_t ikey = 0, okey = 0, flags = 0, flowinfo = 0; uint16_t iflags = 0, oflags = 0; uint8_t tos = 0; - int ret = 0, ttl = 64; + int ret = 0, ttl = 0; nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); if (!nlm) @@ -2146,8 +2211,6 @@ static int system_add_gre_tunnel(const char *name, const char *kind, if ((cur = tb[TUNNEL_ATTR_TTL])) ttl = blobmsg_get_u32(cur); - nla_put_u8(nlm, IFLA_GRE_TTL, ttl); - if ((cur = tb[TUNNEL_ATTR_TOS])) { char *str = blobmsg_get_string(cur); if (strcmp(str, "inherit")) { @@ -2168,7 +2231,7 @@ static int system_add_gre_tunnel(const char *name, const char *kind, else tos = 1; } - } + } if ((cur = tb[TUNNEL_ATTR_INFO]) && (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)) { uint8_t icsum, ocsum, iseqno, oseqno; @@ -2221,6 +2284,9 @@ static int system_add_gre_tunnel(const char *name, const char *kind, if (flags) nla_put_u32(nlm, IFLA_GRE_FLAGS, flags); + + if (!ttl) + ttl = 64; } else { struct in_addr inbuf; bool set_df = true; @@ -2256,17 +2322,23 @@ static int system_add_gre_tunnel(const char *name, const char *kind, if ((cur = tb[TUNNEL_ATTR_DF])) set_df = blobmsg_get_bool(cur); - /* ttl !=0 and nopmtudisc are incompatible */ - if (ttl && !set_df) { - ret = -EINVAL; - goto failure; - } + if (!set_df) { + /* ttl != 0 and nopmtudisc are incompatible */ + if (ttl) { + ret = -EINVAL; + goto failure; + } + } else if (!ttl) + ttl = 64; nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0); nla_put_u8(nlm, IFLA_GRE_TOS, tos); } + if (ttl) + nla_put_u8(nlm, IFLA_GRE_TTL, ttl); + if (oflags) nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags); @@ -2392,7 +2464,7 @@ static int system_add_proto_tunnel(const char *name, const uint8_t proto, const struct blob_attr *cur; bool set_df = true; struct ip_tunnel_parm p = { - .link = link, + .link = link, .iph = { .version = 4, .ihl = 5, @@ -2476,10 +2548,14 @@ int system_update_ipv6_mtu(struct device *dev, int mtu) { int ret = -1; char buf[64]; + int fd; + snprintf(buf, sizeof(buf), "/proc/sys/net/ipv6/conf/%s/mtu", dev->ifname); - int fd = open(buf, O_RDWR); + fd = open(buf, O_RDWR); + if (fd < 0) + return ret; if (!mtu) { ssize_t len = read(fd, buf, sizeof(buf) - 1);