From be17805c0bbd37e865dc9b17b56e8e8d210c2c6c Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Tue, 13 Feb 2018 16:27:57 +0100 Subject: Add support for source-specific IPv6 routes to BIRD core This patch adds support for source-specific IPv6 routes to BIRD core. This is based on Dean Luga's original patch, with the review comments addressed. SADR support is added to network address parsing in confbase.Y and to the kernel protocol on Linux. Currently there is no way to mix source-specific and non-source-specific routes (i.e., SADR tables cannot be connected to non-SADR tables). Thanks to Toke Hoiland-Jorgensen for the original patch. Minor changes by Ondrej Santiago Zajicek. --- nest/rt-table.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'nest/rt-table.c') diff --git a/nest/rt-table.c b/nest/rt-table.c index 0f53c93f..686d0e84 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -85,6 +85,45 @@ net_route_ip6(rtable *t, net_addr_ip6 *n) return r; } +static inline void * +net_route_ip6_sadr(rtable *t, net_addr_ip6_sadr *n) +{ + struct fib_node *fn; + + while (1) + { + net *best = NULL; + int best_pxlen = 0; + + /* We need to do dst first matching. Since sadr addresses are hashed on dst + prefix only, find the hash table chain and go through it to find the + match with the smallest matching src prefix. */ + for (fn = fib_get_chain(&t->fib, (net_addr *) n); fn; fn = fn->next) + { + net_addr_ip6_sadr *a = (void *) fn->addr; + + if (net_equal_dst_ip6_sadr(n, a) && + net_in_net_src_ip6_sadr(n, a) && + (a->src_pxlen >= best_pxlen)) + { + best = fib_node_to_user(&t->fib, fn); + best_pxlen = a->src_pxlen; + } + } + + if (best) + return best; + + if (!n->dst_pxlen) + break; + + n->dst_pxlen--; + ip6_clrbit(&n->dst_prefix, n->dst_pxlen); + } + + return NULL; +} + void * net_route(rtable *tab, const net_addr *n) { @@ -105,6 +144,9 @@ net_route(rtable *tab, const net_addr *n) case NET_ROA6: return net_route_ip6(tab, (net_addr_ip6 *) n0); + case NET_IP6_SADR: + return net_route_ip6_sadr(tab, (net_addr_ip6_sadr *) n0); + default: return NULL; } -- cgit v1.2.3