[LEDE-DEV] [PATCH odhcpd v2] Support muliple RAs on single interface
Pierre Pfister (ppfister)
ppfister at cisco.com
Thu Jan 4 04:42:53 PST 2018
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 at gmail.com> a écrit :
>
> On Thu, Jan 4, 2018 at 11:12 AM, Pierre Pfister (ppfister)
> <ppfister at 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 at cisco.com a écrit :
>>>
>>> From: Pierre Pfister <ppfister at 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 at 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 at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/lede-dev
>>
More information about the Lede-dev
mailing list