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.


Reply via email to