On Fri, Dec 8, 2017 at 10:33 AM, <ppfis...@cisco.com> wrote: > From: Pierre Pfister <ppfis...@cisco.com> > > IETF is moving toward implementing IPv6 multihoming by sending > multiple RAs on a single interface: > - draft-ietf-intarea-provisioning-domains-00 > - draft-ietf-rtgwg-enterprise-pa-multihoming-02 > > odhcpd supports configuration of multiple software interfaces > on the same physical interface, which already advertises > multiple RAs, but had two issues: > - Each RA includes all the prefixes available on the interface. > - Replies to sollicits with a single RA. > > This patch introduces the prefix_filter configuration parameter > which allows filtering prefixes that are sent in a given RA, > and fixes the sollicit code in order to reply with all the RAs > that are configured on a given interface. > > Signed-off-by: Pierre Pfister <ppfis...@cisco.com> > --- > src/config.c | 19 +++++++++++++++++++ > src/odhcpd.c | 28 +++++++++++++++++++--------- > src/odhcpd.h | 2 ++ > src/router.c | 5 +++++ > 4 files changed, 45 insertions(+), 9 deletions(-) > > diff --git a/src/config.c b/src/config.c > index bb885d0..409b3b8 100644 > --- a/src/config.c > +++ b/src/config.c > @@ -62,6 +62,7 @@ enum { > IFACE_ATTR_PD_CER, > IFACE_ATTR_NDPROXY_ROUTING, > IFACE_ATTR_NDPROXY_SLAVE, > + IFACE_ATTR_PREFIX_FILTER, > IFACE_ATTR_MAX > }; > > @@ -104,6 +105,7 @@ static const struct blobmsg_policy > iface_attrs[IFACE_ATTR_MAX] = { > [IFACE_ATTR_RA_MTU] = { .name = "ra_mtu", .type = BLOBMSG_TYPE_INT32 > }, > [IFACE_ATTR_NDPROXY_ROUTING] = { .name = "ndproxy_routing", .type = > BLOBMSG_TYPE_BOOL }, > [IFACE_ATTR_NDPROXY_SLAVE] = { .name = "ndproxy_slave", .type = > BLOBMSG_TYPE_BOOL }, > + [IFACE_ATTR_PREFIX_FILTER] = { .name = "prefix_filter", .type = > BLOBMSG_TYPE_STRING }, > }; > > static const struct uci_blob_param_info iface_attr_info[IFACE_ATTR_MAX] = { > @@ -720,6 +722,23 @@ int config_parse_interface(void *data, size_t len, const > char *name, bool overwr > if ((c = tb[IFACE_ATTR_NDPROXY_SLAVE])) > iface->external = blobmsg_get_bool(c); > > + if ((c = tb[IFACE_ATTR_PREFIX_FILTER])) { > + const char *str = blobmsg_get_string(c); > + char *astr = malloc(strlen(str) + 1); > + char *delim; > + int l; > + if (!astr || !strcpy(astr, str) || > + (delim = strchr(astr, '/')) == NULL || > (*(delim++) = 0) || > + sscanf(delim, "%i", &l) == 0 || l > 128 || > + inet_pton(AF_INET6, astr, > &iface->pio_filter_addr) == 0) { > + iface->pio_filter_length = 0; > + } else { > + iface->pio_filter_length = l; > + } > + if (astr) > + free(astr); > + } > + > return 0; > > err: > diff --git a/src/odhcpd.c b/src/odhcpd.c > index 97a6de9..58c4338 100644 > --- a/src/odhcpd.c > +++ b/src/odhcpd.c > @@ -371,12 +371,6 @@ static void odhcpd_receive_packets(struct uloop_fd *u, > _unused unsigned int even > if (addr.ll.sll_family == AF_PACKET) > destiface = addr.ll.sll_ifindex; > > - struct interface *iface = > - odhcpd_get_interface_by_index(destiface); > - > - if (!iface && addr.nl.nl_family != AF_NETLINK) > - continue; > - > char ipbuf[INET6_ADDRSTRLEN] = "kernel"; > if (addr.ll.sll_family == AF_PACKET && > len >= (ssize_t)sizeof(struct ip6_hdr)) > @@ -386,10 +380,26 @@ static void odhcpd_receive_packets(struct uloop_fd *u, > _unused unsigned int even > else if (addr.in.sin_family == AF_INET) > inet_ntop(AF_INET, &addr.in.sin_addr, ipbuf, > sizeof(ipbuf)); > > - syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", (long)len, > - ipbuf, (iface) ? iface->ifname : "netlink"); > + // From netlink > + if (addr.nl.nl_family == AF_NETLINK) { > + syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", > (long)len, > + ipbuf, "netlink"); > + e->handle_dgram(&addr, data_buf, len, NULL, dest); > + return; > + } else if (destiface != 0) { > + struct interface *iface; > + list_for_each_entry(iface, &interfaces, head) { > + if (iface->ifindex != destiface) > + continue; > + > + syslog(LOG_DEBUG, "Received %li Bytes from > %s%%%s", (long)len, > + ipbuf, iface->ifname); > + > + e->handle_dgram(&addr, data_buf, len, iface, > dest); > + } > + } > + > > - e->handle_dgram(&addr, data_buf, len, iface, dest); > } > } > > diff --git a/src/odhcpd.h b/src/odhcpd.h > index fbfeb67..48ee51e 100644 > --- a/src/odhcpd.h > +++ b/src/odhcpd.h > @@ -208,6 +208,8 @@ struct interface { > bool ra_advrouter; > bool ra_useleasetime; > bool no_dynamic_dhcp; > + uint8_t pio_filter_length; > + struct in6_addr pio_filter_addr; > > // RA > int learn_routes; > diff --git a/src/router.c b/src/router.c > index c35cd12..7bc94ed 100644 > --- a/src/router.c > +++ b/src/router.c > @@ -380,6 +380,11 @@ static uint64_t send_router_advert(struct interface > *iface, const struct in6_add > continue; > } > > + if (odhcpd_bmemcmp(&addr->addr, &iface->pio_filter_addr, > + iface->pio_filter_length) != 0 || > + addr->prefix < iface->pio_filter_length) > + continue; // PIO filtered out of this RA > + > struct nd_opt_prefix_info *p = NULL; > for (size_t i = 0; i < pfxs_cnt; ++i) { > if (addr->prefix == pfxs[i].nd_opt_pi_prefix_len && > -- > 2.13.6 (Apple Git-96) > > > _______________________________________________ > Lede-dev mailing list > Lede-dev@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/lede-dev Hi,
Thx for the patch; could you also document the prefix_filter uci parameter in the README file ? Hans _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev