]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit 'ef814fb2d6415206fce280c37466ea889291b043' into HEAD
authorMaria Matejka <mq@ucw.cz>
Fri, 8 Dec 2023 11:13:58 +0000 (12:13 +0100)
committerMaria Matejka <mq@ucw.cz>
Fri, 8 Dec 2023 11:13:58 +0000 (12:13 +0100)
1  2 
nest/rt-table.c

diff --cc nest/rt-table.c
index 1f3f1008feca09858f52c19fd707e140e8297bf0,f73744d12c179252c72d5e94a3327e3dc580b2f7..bb236d497c820da2df9200e42caf61a7c21ebcf9
@@@ -487,30 -292,58 +372,61 @@@ net_route(struct rtable_private *tab, c
   * must have type NET_IP4 or NET_IP6, respectively.
   */
  int
 -net_roa_check(rtable *tab, const net_addr *n, u32 asn)
 +net_roa_check(rtable *tp, const net_addr *n, u32 asn)
  {
-   int out = ROA_UNKNOWN;
+   net_addr_union *nu = SKIP_BACK(net_addr_union, n, n);
+   int anything = 0;
+   struct fib_node *fn;
+ #define TW(ipv) do {                                                          \
+   TRIE_WALK_TO_ROOT_IP##ipv(tab->trie, &(nu->ip##ipv), var) {                 \
+     net_addr_roa##ipv roa0 = NET_ADDR_ROA##ipv(var.prefix, var.pxlen, 0, 0);  \
+     ROA_PARTIAL_CHECK(ipv);                                                   \
+   } TRIE_WALK_TO_ROOT_END;                                                    \
+   return anything ? ROA_INVALID : ROA_UNKNOWN;                                        \
+ } while (0)
+ #define FW(ipv) do {                                                          \
+   net_addr_roa##ipv roa0 = NET_ADDR_ROA##ipv(nu->ip##ipv.prefix, nu->ip##ipv.pxlen, 0, 0);\
+   while (1) {                                                                 \
+     ROA_PARTIAL_CHECK(ipv);                                                   \
+     if (roa0.pxlen == 0) break;                                                       \
+     roa0.pxlen--; ip##ipv##_clrbit(&roa0.prefix, roa0.pxlen);                 \
+   }                                                                           \
+ } while (0)
+ #define ROA_PARTIAL_CHECK(ipv) do {                                           \
+   for (fn = fib_get_chain(&tab->fib, (net_addr *) &roa0); fn; fn = fn->next)  \
+   {                                                                           \
+     net_addr_roa##ipv *roa = (void *) fn->addr;                               \
+     net *r = fib_node_to_user(&tab->fib, fn);                                 \
+     if (net_equal_prefix_roa##ipv(roa, &roa0) && rte_is_valid(r->routes))     \
+     {                                                                         \
+       anything = 1;                                                           \
+       if (asn && (roa->asn == asn) && (roa->max_pxlen >= nu->ip##ipv.pxlen))  \
+       return ROA_VALID;                                                       \
+     }                                                                         \
+   }                                                                           \
+ } while (0)
  
 -  if ((tab->addr_type == NET_ROA4) && (n->type == NET_IP4))
 +  RT_LOCKED(tp, tab)
    {
 -    if (tab->trie)  TW(4);
 -    else          FW(4);
 -  }
 -  else if ((tab->addr_type == NET_ROA6) && (n->type == NET_IP6))
 -  {
 -    if (tab->trie)  TW(6);
 -    else          FW(6);
 +    if ((tab->addr_type == NET_ROA4) && (n->type == NET_IP4))
 +    {
-       if (tab->trie)
-       out = net_roa_check_ip4_trie(tab, (const net_addr_ip4 *) n, asn);
-       else
-       out = net_roa_check_ip4_fib (tab, (const net_addr_ip4 *) n, asn);
++      if (tab->trie)  TW(4);
++      else            FW(4);
 +    }
 +    else if ((tab->addr_type == NET_ROA6) && (n->type == NET_IP6))
 +    {
-       if (tab->trie)
-       out = net_roa_check_ip6_trie(tab, (const net_addr_ip6 *) n, asn);
-       else
-       out = net_roa_check_ip6_fib (tab, (const net_addr_ip6 *) n, asn);
++      if (tab->trie)  TW(6);
++      else            FW(6);
 +    }
-     else
-       out = ROA_UNKNOWN;      /* Should not happen */
    }
-   return out;
+   return anything ? ROA_INVALID : ROA_UNKNOWN;
+ #undef ROA_PARTIAL_CHECK
+ #undef TW
+ #undef FW
  }
  
  /**