]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Dropping netindex fragile manipulation
authorMaria Matejka <mq@ucw.cz>
Fri, 7 Jun 2024 16:01:22 +0000 (18:01 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 12 Jun 2024 07:23:50 +0000 (09:23 +0200)
Now the netindex doesn't expose its internals and can be converted
to the spinlocked implementation much easier.

lib/netindex.c
lib/netindex_private.h
nest/rt-table.c

index 8f6363499058750b39fb247726a55207b6bfd0c4..809e9286cd0636cfb0495b493d0ccbb8845720fd 100644 (file)
@@ -201,14 +201,6 @@ netindex_hash_delete(netindex_hash *h, event *e, event_list *t)
 /*
  * Private index manipulation
  */
-struct netindex *
-net_find_index_fragile_chain(struct netindex_hash_private *hp, const net_addr *n)
-{
-  ASSERT_DIE(n->type == hp->net_type);
-  u32 h = net_hash(n);
-  return HASH_FIND_CHAIN(hp->hash, NETINDEX, h, n);
-}
-
 struct netindex *
 net_find_index_fragile(struct netindex_hash_private *hp, const net_addr *n)
 {
index a9a9304860c8b7a7e511943ec3c07fb5b3f2c98c..42dbf894c9af323b9f11ff3ddfba1cc6d726e6da 100644 (file)
@@ -41,11 +41,4 @@ extern struct netindex netindex_in_progress;
 LOBJ_UNLOCK_CLEANUP(netindex_hash, attrs);
 #define NH_LOCK(h, hp) LOBJ_LOCK(h, hp, netindex_hash, attrs)
 
-/* Find indices in a locked context with no usecounting */
-struct netindex *net_find_index_fragile(struct netindex_hash_private *hp, const net_addr *n);
-
-/* The same but instead of returning the exact match,
- * return the first item in hash chain */
-struct netindex *net_find_index_fragile_chain(struct netindex_hash_private *hp, const net_addr *n);
-
 #endif
index 5f1a61093e4e24e7763d1ae2c30a59990869b9c8..4afee94ccd56f425ae09b78f4121fb2106f9e8f8 100644 (file)
 #include "lib/alloca.h"
 #include "lib/flowspec.h"
 #include "lib/idm.h"
-#include "lib/netindex_private.h"
 
 #ifdef CONFIG_BGP
 #include "proto/bgp/bgp.h"
@@ -254,9 +253,9 @@ net_find(struct rtable_reading *tr, const struct netindex *i)
 }
 
 static inline net *
-net_find_valid(struct rtable_reading *tr, struct netindex_hash_private *nh, const net_addr *addr)
+net_find_valid(struct rtable_reading *tr, netindex_hash *nh, const net_addr *addr)
 {
-  struct netindex *i = net_find_index_fragile(nh, addr);
+  struct netindex *i = net_find_index(nh, addr);
   if (!i)
     return NULL;
 
@@ -273,41 +272,33 @@ net_find_valid(struct rtable_reading *tr, struct netindex_hash_private *nh, cons
 }
 
 static inline void *
-net_route_ip6_sadr_trie(struct rtable_reading *tr, struct netindex_hash_private *nh, const net_addr_ip6_sadr *n0)
+net_route_ip6_sadr_trie(struct rtable_reading *tr, netindex_hash *nh, const net_addr_ip6_sadr *n0)
 {
   u32 bs = atomic_load_explicit(&tr->t->routes_block_size, memory_order_acquire);
   const struct f_trie *trie = atomic_load_explicit(&tr->t->trie, memory_order_acquire);
   TRIE_WALK_TO_ROOT_IP6(trie, (const net_addr_ip6 *) n0, px)
   {
-    net_addr_ip6_sadr n = NET_ADDR_IP6_SADR(px.prefix, px.pxlen, n0->src_prefix, n0->src_pxlen);
-    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 longest matching src prefix. */
-    for (struct netindex *i = net_find_index_fragile_chain(nh, (net_addr *) &n); i; i = i->next)
-    {
-      net_addr_ip6_sadr *a = (void *) i->addr;
+    net_addr_union n = {
+      .ip6_sadr = NET_ADDR_IP6_SADR(px.prefix, px.pxlen, n0->src_prefix, n0->src_pxlen),
+    };
 
-      if ((i->index < bs) &&
-         net_equal_dst_ip6_sadr(&n, a) &&
-         net_in_net_src_ip6_sadr(&n, a) &&
-         (a->src_pxlen >= best_pxlen))
+    while (1)
+    {
+      struct netindex *i = net_find_index(nh, &n.n);
+      if (i && (i->index < bs))
       {
        net *cur = &(atomic_load_explicit(&tr->t->routes, memory_order_acquire)[i->index]);
        struct rte_storage *s = NET_READ_BEST_ROUTE(tr, cur);
 
        if (s && rte_is_valid(&s->rte))
-       {
-         best = cur;
-         best_pxlen = a->src_pxlen;
-       }
+         return s;
       }
-    }
 
-    if (best)
-      return best;
+      if (!n.ip6_sadr.src_pxlen)
+       break;
+
+      ip6_clrbit(&n.ip6_sadr.src_prefix, --n.ip6_sadr.src_pxlen);
+    }
   }
   TRIE_WALK_TO_ROOT_END;
 
@@ -316,7 +307,7 @@ net_route_ip6_sadr_trie(struct rtable_reading *tr, struct netindex_hash_private
 
 
 static inline void *
-net_route_ip6_sadr_fib(struct rtable_reading *tr, struct netindex_hash_private *nh, const net_addr_ip6_sadr *n0)
+net_route_ip6_sadr_fib(struct rtable_reading *tr, netindex_hash *nh, const net_addr_ip6_sadr *n0)
 {
   u32 bs = atomic_load_explicit(&tr->t->routes_block_size, memory_order_acquire);
 
@@ -325,36 +316,27 @@ net_route_ip6_sadr_fib(struct rtable_reading *tr, struct netindex_hash_private *
 
   while (1)
   {
-    net *best = NULL;
-    int best_pxlen = 0;
+    net_addr_union nn = {
+      .ip6_sadr = n,
+    };
 
-    /* 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 longest matching src prefix. */
-    for (struct netindex *i = net_find_index_fragile_chain(nh, (net_addr *) &n); i; i = i->next)
+    while (1)
     {
-      net_addr_ip6_sadr *a = (void *) i->addr;
-
-      if ((i->index < bs) &&
-         net_equal_dst_ip6_sadr(&n, a) &&
-         net_in_net_src_ip6_sadr(&n, a) &&
-         (a->src_pxlen >= best_pxlen))
+      struct netindex *i = net_find_index(nh, &nn.n);
+      if (i && (i->index < bs))
       {
        net *cur = &(atomic_load_explicit(&tr->t->routes, memory_order_acquire)[i->index]);
        struct rte_storage *s = NET_READ_BEST_ROUTE(tr, cur);
-       if (RTE_IS_OBSOLETE(s))
-         RT_READ_RETRY(tr);
 
        if (s && rte_is_valid(&s->rte))
-       {
-         best = cur;
-         best_pxlen = a->src_pxlen;
-       }
+         return s;
       }
-    }
 
-    if (best)
-      return best;
+      if (!nn.ip6_sadr.src_pxlen)
+       break;
+
+      ip6_clrbit(&nn.ip6_sadr.src_prefix, --nn.ip6_sadr.src_pxlen);
+    }
 
     if (!n.dst_pxlen)
       break;
@@ -374,7 +356,7 @@ net_route(struct rtable_reading *tr, const net_addr *n)
 
   const struct f_trie *trie = atomic_load_explicit(&tr->t->trie, memory_order_acquire);
 
-  NH_LOCK(tr->t->netindex, nh);
+  netindex_hash *nh = tr->t->netindex;
 
 #define TW(ipv, what) \
   TRIE_WALK_TO_ROOT_IP##ipv(trie, &(nu->ip##ipv), var) \
@@ -3867,11 +3849,9 @@ rt_flowspec_check(rtable *tab_ip, struct rtable_private *tab_flow, const net_add
     return FLOWSPEC_INVALID;
 
   /* RFC 8955 6. c) More-specific routes are from the same AS as the best-match route */
-  NH_LOCK(tip->t->netindex, nh);
-
   TRIE_WALK(ip_trie, subnet, &dst)
   {
-    net *nc = net_find_valid(tip, nh, &subnet);
+    net *nc = net_find_valid(tip, tip->t->netindex, &subnet);
     if (!nc)
       continue;