Message ID | 20201212205053.2807651-1-vincent@systemli.org |
---|---|
State | Accepted |
Headers | show |
Series | netifd: add segment routing support | expand |
On Sat, Dec 12, 2020 at 9:51 PM <vincent@systemli.org> wrote: > > From: Nick Hainke <vincent@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 <vincent@systemli.org> Patch applied with some minor tweaks (https://git.openwrt.org/?p=project/netifd.git;a=commit;h=458b1a7e9473c150a40cae5d8be174f4bb03bd39); thx Hans > --- > device.c | 21 +++++++++++++++++++++ > device.h | 5 +++++ > system-linux.c | 22 ++++++++++++++++++++++ > 3 files changed, 48 insertions(+) > > diff --git a/device.c b/device.c > index 73cc4bf..7145788 100644 > --- a/device.c > +++ b/device.c > @@ -36,6 +36,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 }, > @@ -230,6 +231,7 @@ device_merge_settings(struct device *dev, struct device_settings *n) > (s->flags & (DEV_OPT_MACADDR|DEV_OPT_DEFAULT_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; > @@ -299,6 +301,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; > @@ -844,6 +851,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) > @@ -1053,6 +1072,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 ab5a162..6ee439d 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, > }; > > @@ -107,6 +108,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 */ > @@ -173,6 +175,7 @@ struct device_settings { > bool learning; > bool unicast_flood; > bool sendredirects; > + bool ip6segmentrouting; > bool isolate; > }; > > @@ -320,4 +323,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 bf746f9..53a02e9 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; > @@ -1667,6 +1683,12 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned > } > if (apply_mask & DEV_OPT_IPV6) > 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 (apply_mask & DEV_OPT_PROMISC) { > 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
diff --git a/device.c b/device.c index 73cc4bf..7145788 100644 --- a/device.c +++ b/device.c @@ -36,6 +36,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 }, @@ -230,6 +231,7 @@ device_merge_settings(struct device *dev, struct device_settings *n) (s->flags & (DEV_OPT_MACADDR|DEV_OPT_DEFAULT_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; @@ -299,6 +301,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; @@ -844,6 +851,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) @@ -1053,6 +1072,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 ab5a162..6ee439d 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, }; @@ -107,6 +108,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 */ @@ -173,6 +175,7 @@ struct device_settings { bool learning; bool unicast_flood; bool sendredirects; + bool ip6segmentrouting; bool isolate; }; @@ -320,4 +323,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 bf746f9..53a02e9 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; @@ -1667,6 +1683,12 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned } if (apply_mask & DEV_OPT_IPV6) 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 (apply_mask & DEV_OPT_PROMISC) { if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0, !s->promisc ? IFF_PROMISC : 0) < 0)