From: Nick Hainke <vinc...@systemli.org> seg6_enabled - Bool Accept or drop SR-enabled IPv6 packets on this interface.
More Information: https://www.kernel.org/doc/html/latest/networking/seg6-sysctl.html Now you can set as interface option option ip6segmentrouting '1' It is not enough to turn on "seg6_enabled" on the interface. Further, we have to enable "/all/seg6_enabled". This means that a working config is "interface + all". Signed-off-by: Nick Hainke <vinc...@systemli.org> --- device.c | 21 +++++++++++++++++++++ device.h | 5 +++++ system-linux.c | 22 ++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/device.c b/device.c index 3e2b5e9..ba61a54 100644 --- a/device.c +++ b/device.c @@ -41,6 +41,7 @@ static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = { [DEV_ATTR_TXQUEUELEN] = { .name = "txqueuelen", .type = BLOBMSG_TYPE_INT32 }, [DEV_ATTR_ENABLED] = { .name = "enabled", .type = BLOBMSG_TYPE_BOOL }, [DEV_ATTR_IPV6] = { .name = "ipv6", .type = BLOBMSG_TYPE_BOOL }, + [DEV_ATTR_IP6SEGMENTROUTING] = { .name = "ip6segmentrouting", .type = BLOBMSG_TYPE_BOOL }, [DEV_ATTR_PROMISC] = { .name = "promisc", .type = BLOBMSG_TYPE_BOOL }, [DEV_ATTR_RPFILTER] = { .name = "rpfilter", .type = BLOBMSG_TYPE_STRING }, [DEV_ATTR_ACCEPTLOCAL] = { .name = "acceptlocal", .type = BLOBMSG_TYPE_BOOL }, @@ -228,6 +229,7 @@ device_merge_settings(struct device *dev, struct device_settings *n) (s->flags & DEV_OPT_MACADDR ? s->macaddr : os->macaddr), sizeof(n->macaddr)); n->ipv6 = s->flags & DEV_OPT_IPV6 ? s->ipv6 : os->ipv6; + n->ip6segmentrouting = s->flags & DEV_OPT_IP6SEGMENTROUTING ? s->ip6segmentrouting : os->ip6segmentrouting; n->promisc = s->flags & DEV_OPT_PROMISC ? s->promisc : os->promisc; n->rpfilter = s->flags & DEV_OPT_RPFILTER ? s->rpfilter : os->rpfilter; n->acceptlocal = s->flags & DEV_OPT_ACCEPTLOCAL ? s->acceptlocal : os->acceptlocal; @@ -297,6 +299,11 @@ device_init_settings(struct device *dev, struct blob_attr **tb) s->flags |= DEV_OPT_IPV6; } + if ((cur = tb[DEV_ATTR_IP6SEGMENTROUTING])) { + s->ip6segmentrouting = blobmsg_get_bool(cur); + s->flags |= DEV_OPT_IP6SEGMENTROUTING; + } + if ((cur = tb[DEV_ATTR_PROMISC])) { s->promisc = blobmsg_get_bool(cur); s->flags |= DEV_OPT_PROMISC; @@ -826,6 +833,18 @@ device_init_pending(void) } } +bool +check_ip6segmentrouting(void) +{ + struct device *dev, *tmp; + bool ip6segmentrouting = false; + + avl_for_each_element_safe(&devices, dev, avl, tmp) { + ip6segmentrouting |= dev->settings.ip6segmentrouting; + } + return ip6segmentrouting; +} + static enum dev_change_type device_set_config(struct device *dev, struct device_type *type, struct blob_attr *attr) @@ -1035,6 +1054,8 @@ device_dump_status(struct blob_buf *b, struct device *dev) blobmsg_add_u32(b, "txqueuelen", st.txqueuelen); if (st.flags & DEV_OPT_IPV6) blobmsg_add_u8(b, "ipv6", st.ipv6); + if (st.flags & DEV_OPT_IP6SEGMENTROUTING) + blobmsg_add_u8(b, "ip6segmentrouting", st.ip6segmentrouting); if (st.flags & DEV_OPT_PROMISC) blobmsg_add_u8(b, "promisc", st.promisc); if (st.flags & DEV_OPT_RPFILTER) diff --git a/device.h b/device.h index b2b18ab..6b898e5 100644 --- a/device.h +++ b/device.h @@ -53,6 +53,7 @@ enum { DEV_ATTR_SENDREDIRECTS, DEV_ATTR_NEIGHLOCKTIME, DEV_ATTR_ISOLATE, + DEV_ATTR_IP6SEGMENTROUTING, __DEV_ATTR_MAX, }; @@ -106,6 +107,7 @@ enum { DEV_OPT_SENDREDIRECTS = (1 << 21), DEV_OPT_NEIGHLOCKTIME = (1 << 22), DEV_OPT_ISOLATE = (1 << 23), + DEV_OPT_IP6SEGMENTROUTING = (1 << 24), }; /* events broadcasted to all users of a device */ @@ -172,6 +174,7 @@ struct device_settings { bool learning; bool unicast_flood; bool sendredirects; + bool ip6segmentrouting; bool isolate; }; @@ -319,4 +322,6 @@ device_set_disabled(struct device *dev, bool value) device_refresh_present(dev); } +bool check_ip6segmentrouting(void); + #endif diff --git a/system-linux.c b/system-linux.c index 1d5d232..1d1cf8d 100644 --- a/system-linux.c +++ b/system-linux.c @@ -304,6 +304,11 @@ static void system_set_disable_ipv6(struct device *dev, const char *val) system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6", dev->ifname, val); } +static void system_set_ip6segmentrouting(struct device *dev, const char *val) +{ + system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/seg6_enabled", dev->ifname, val); +} + static void system_set_rpfilter(struct device *dev, const char *val) { system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter", dev->ifname, val); @@ -509,6 +514,12 @@ static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t b dev->ifname, buf, buf_sz); } +static int system_get_ip6segmentrouting(struct device *dev, char *buf, const size_t buf_sz) +{ + return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/seg6_enabled", + dev->ifname, buf, buf_sz); +} + static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz) { return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter", @@ -1572,6 +1583,11 @@ system_if_get_settings(struct device *dev, struct device_settings *s) s->flags |= DEV_OPT_IPV6; } + if (!system_get_ip6segmentrouting(dev, buf, sizeof(buf))) { + s->ip6segmentrouting = strtoul(buf, NULL, 0); + s->flags |= DEV_OPT_IP6SEGMENTROUTING; + } + if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) == 0) { s->promisc = ifr.ifr_flags & IFF_PROMISC; s->flags |= DEV_OPT_PROMISC; @@ -1665,6 +1681,12 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned } if (s->flags & DEV_OPT_IPV6 & apply_mask) system_set_disable_ipv6(dev, s->ipv6 ? "0" : "1"); + if (s->flags & DEV_OPT_IP6SEGMENTROUTING & apply_mask) { + system_set_ip6segmentrouting(dev, s->ip6segmentrouting ? "1" : "0"); + struct device dummy = {.ifname="all"}; + bool ip6segmentrouting = check_ip6segmentrouting(); + system_set_ip6segmentrouting(&dummy, ip6segmentrouting ? "1" : "0"); + } if (s->flags & DEV_OPT_PROMISC & apply_mask) { if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0, !s->promisc ? IFF_PROMISC : 0) < 0) -- 2.29.2 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel