On 05/22/2017 03:30 PM, Ondrej Zajicek wrote:
@@ -231,6 +232,20 @@ fib_find(struct fib *f, const net_addr *a)
case NET_ROA6: return FIB_FIND(f, a, roa6);
case NET_FLOW4: return FIB_FIND(f, a, flow4);
case NET_FLOW6: return FIB_FIND(f, a, flow6);
+ case NET_SADR_IP6:
+ {
+ if (a->length != sizeof(net_addr_sadr_ip6))
+ {
+ // dst only search
+ net_addr_ip6 a0;
+ net_copy((net_addr *)&a0, a);
+ a0.length = sizeof(net_addr_sadr_ip6);
+
+ return FIB_FIND(f, &a0, sadr_dst);
+ }
+ else
+ return FIB_FIND(f, a, sadr_ip6);
+ }
No. Generic fib_find() should implement exact-match search with matching
net_addr type. If you need/want partial match, it should be done as a
separate function. BTW, where do you need that?
I use it in net_route_sadr_ip6 below, the call to net_route_ip6 does
destination only search. I wouldn't want to search all source prefix
lengths for a specific dst length if there is no entry for that dst
length at all.
Perhaps we should add some generic function partial-match IP-based search
for network types that support it (e.g., ROA, SADR). But it would need
a different interface, so caller could enumerate all valid matches.
This seems like a good idea.
+static inline void *
+net_route_sadr_ip6(rtable *t, net_addr_sadr_ip6 *n)
+{
+ net *r;
+
+ net_addr_ip6 dst = NET_ADDR_IP6(n->dst_prefix, n->dst_pxlen);
+ dst.type = NET_SADR_IP6;
+
+ // search for matching dst
+ while (r = net_route_ip6(t, &dst))
+ {
+ // found a matching dst, start search for entries that match both prefixes
+ net_addr_sadr_ip6 full_addr =
+ NET_ADDR_SADR_IP6(dst.prefix, dst.pxlen, n->src_prefix, n->src_pxlen);
+
+ while (r = net_find_valid(t, (net_addr *) &full_addr), (!r) &&
(full_addr.src_pxlen > 0))
+ {
+ full_addr.src_pxlen--;
+ ip6_clrbit(&full_addr.src_prefix, full_addr.src_pxlen);
+ }
+
+ if (r)
+ return r;
+ dst.pxlen--;
You should set dst.pxlen based on r found by net_route_ip6(),
to avoid repeated iteration over the same prefix lengths that
did not match in the inner cycle.
That would be set in the call to net_route_ip6.