Message ID | 20171208141502.13264-1-ppfister@cisco.com |
---|---|
State | Accepted |
Delegated to: | Hans Dedecker |
Headers | show |
Series | [LEDE-DEV,odhcpd,v2] Support muliple RAs on single interface | expand |
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 > Le 8 déc. 2017 à 15:15, ppfister@cisco.com a écrit : > > From: Pierre Pfister <ppfister@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 <ppfister@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
On Thu, Jan 4, 2018 at 11:12 AM, Pierre Pfister (ppfister) <ppfister@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, ppfister@cisco.com a écrit : >> >> From: Pierre Pfister <ppfister@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 <ppfister@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 >
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 <dedeckeh@gmail.com> a écrit : > > On Thu, Jan 4, 2018 at 11:12 AM, Pierre Pfister (ppfister) > <ppfister@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, ppfister@cisco.com a écrit : >>> >>> From: Pierre Pfister <ppfister@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 <ppfister@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 >>
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 &&