Hello Hans, Thanks for committing ! In the multi-homing case, you would typically have two RAs on the same interface with one PIO per RA. Therefore you would define two software interfaces, each with a prefix-filter option making sure a single prefix is included in each RA. So I think it would work in the cases I can imagine today. Maybe other use-cases may require some change in the future.
Thanks, - Pierre > Le 4 janv. 2018 à 13:33, Hans Dedecker <dedec...@gmail.com> a écrit : > > On Thu, Jan 4, 2018 at 11:12 AM, Pierre Pfister (ppfister) > <ppfis...@cisco.com> wrote: >> Hello Hans and happy new year ! >> >> As requested in your comment to v1, I have updated the README file. >> Would you mind reviewing this new version of the patch ? >> >> Thanks, >> >> - Pierre > Hi Pierre, > > Also a happy new year! > I've reviewed the patch and it was committed in > https://git.lede-project.org/?p=project/odhcpd.git;a=commit;h=750e457e3000187b85906814a2529ede24775325. > As the prefix-filter parameter allows to specify only one prefix for a > given logical interface; I'm wondering is this flexible enough for the > multihoming use-case ? > > Hans >> >>> Le 8 déc. 2017 à 15:15, ppfis...@cisco.com a écrit : >>> >>> 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> >>> --- >>> README | 3 +++ >>> src/config.c | 19 +++++++++++++++++++ >>> src/odhcpd.c | 28 +++++++++++++++++++--------- >>> src/odhcpd.h | 2 ++ >>> src/router.c | 5 +++++ >>> 5 files changed, 48 insertions(+), 9 deletions(-) >>> >>> diff --git a/README b/README >>> index 95f59bf..0c562e6 100644 >>> --- a/README >>> +++ b/README >>> @@ -134,6 +134,9 @@ ra_mtu integer 0 >>> MTU to be advertised in >>> RA messages >>> ndproxy_routing bool 1 Learn routes >>> from NDP >>> ndproxy_slave bool 0 NDProxy external slave >>> +prefix_filter string ::/0 Only >>> advertise on-link prefixes within >>> + [IPv6 prefix] the provided IPv6 >>> prefix; others are >>> + filtered out. >>> >>> >>> Sections of type host (static leases) >>> 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 >> _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev