]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
fixup! rt-feed-by-fib: addr to trie
authorkaterina.kubecova <katerina.kubecova@nic.cz>
Mon, 2 Oct 2023 09:51:46 +0000 (11:51 +0200)
committerkaterina.kubecova <katerina.kubecova@nic.cz>
Mon, 2 Oct 2023 09:51:46 +0000 (11:51 +0200)
nest/proto.c
nest/rt-table.c
nest/rt.h
proto/bgp/attrs.c

index e7331b3736d62c0fa680036d2b5ee44279a4be9e..fa4ada7c1d57e34a198af1df10446bdcdbff82c4 100644 (file)
@@ -522,23 +522,27 @@ channel_start_export(struct channel *c)
   }
 
   ASSERT(c->channel_state == CS_UP);
-  
-  c->reqv_trie_lp = lp_new(c->proto->pool);
-  struct f_trie * trie = f_new_trie(c->reqv_trie_lp, 0);
-  trie_add_prefix(trie, c->out_subprefix, net_pxlen(c->out_subprefix), net_pxlen(c->out_subprefix));
 
   c->out_req = (struct rt_export_request) {
     .name = mb_sprintf(c->proto->pool, "%s.%s", c->proto->name, c->name),
     .list = proto_work_list(c->proto),
     .pool = c->proto->pool,
     .feed_block_size = c->feed_block_size,
-    .prefilter.net_filter_trie = trie,
     .prefilter.addr_mode = c->out_subprefix ? TE_ADDR_IN : TE_ADDR_NONE,
     .trace_routes = c->debug | c->proto->debug,
     .dump_req = channel_dump_export_req,
     .log_state_change = channel_export_log_state_change,
   };
 
+  if(c->out_subprefix!=0){
+    c->reqv_trie_lp = lp_new(c->proto->pool);
+    struct f_trie * trie = f_new_trie(c->reqv_trie_lp, 0);
+    if (c->out_subprefix->type == NET_IP4 || c->out_subprefix->type == NET_VPN4 || c->out_subprefix->type == NET_ROA4){
+      trie_add_prefix(trie, c->out_subprefix, net_pxlen(c->out_subprefix), 48);
+    }
+    else trie_add_prefix(trie, c->out_subprefix, net_pxlen(c->out_subprefix), 128);
+    c->out_req.prefilter.net_filter_trie = trie;
+  }
   bmap_init(&c->export_map, c->proto->pool, 16);
   bmap_init(&c->export_reject_map, c->proto->pool, 16);
 
index a9368780f7bc41974e760d75791eea7da0ea7d1a..e6c9407232de31c454a3fedac0bf18a9a7c0ee0e 100644 (file)
@@ -1204,19 +1204,18 @@ rte_export(struct rt_table_export_hook *th, struct rt_pending_export *rpe)
     goto ignore;       /* Seen already */
 
   const net_addr *n = rpe->new_best ? rpe->new_best->rte.net : rpe->old_best->rte.net;
-  ASSERT_DIE(1);
   switch (hook->req->prefilter.addr_mode)
     {
       case TE_ADDR_NONE:
        break;
 
       case TE_ADDR_IN:
-       if (!net_in_netX(n, hook->req->prefilter.addr))
+       if (!net_in_netX_from_export_request(n, hook->req->prefilter.addr))
          goto ignore;
        break;
 
       case TE_ADDR_EQUAL:
-       if (!net_equal(n, hook->req->prefilter.addr))
+       if (!net_equal_from_export_request(n, hook->req->prefilter.addr))
          goto ignore;
        break;
 
@@ -2163,7 +2162,7 @@ rt_table_export_start_feed(struct rtable_private *tab, struct rt_table_export_ho
       {
        hook->walk_state = mb_allocz(hook->h.pool, sizeof (struct f_trie_walk_state));
        hook->walk_lock = rt_lock_trie(tab);
-       trie_walk_init(hook->walk_state, tab->trie, req->addr);
+       trie_walk_init(hook->walk_state, tab->trie, req->prefilter.addr);
        hook->h.event.hook = rt_feed_by_trie;
        hook->walk_last.type = 0;
        break;
@@ -4423,7 +4422,7 @@ rt_feed_equal(void *data)
     ASSERT_DIE(atomic_load_explicit(&c->h.export_state, memory_order_relaxed) == TES_FEEDING);
     ASSERT_DIE(c->h.req->prefilter.addr_mode == TE_ADDR_EQUAL);
 
-    if (n = net_find(tab, c->h.req->addr))
+    if (n = net_find(tab, c->h.req->prefilter.addr))
       ASSERT_DIE(rt_prepare_feed(c, n, &block));
   }
 
@@ -4445,7 +4444,7 @@ rt_feed_for(void *data)
     ASSERT_DIE(atomic_load_explicit(&c->h.export_state, memory_order_relaxed) == TES_FEEDING);
     ASSERT_DIE(c->h.req->prefilter.addr_mode == TE_ADDR_FOR);
 
-    if (n = net_route(tab, c->h.req->addr))
+    if (n = net_route(tab, c->h.req->prefilter.addr))
       ASSERT_DIE(rt_prepare_feed(c, n, &block));
   }
 
index e76a8955e58f9b0abeb6b29f29c99a2dbacaf65c..1dbb684fe35b941c44efe6abb9989656432dfdb4 100644 (file)
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -291,13 +291,18 @@ struct rt_prefilter_address{
     const struct f_trie *net_filter_trie;
     const net_addr *addr;              /* Network prefilter address */
   };
-  u8 addr_mode;                                /* Network prefilter mode (TE_ADDR_*) */
+                               /* Network prefilter mode (TE_ADDR_*) */
+  enum {
+    TE_ADDR_NONE=0,            /* No address matching */
+    TE_ADDR_EQUAL,             /* Exact query - show route <addr> */
+    TE_ADDR_FOR,               /* Longest prefix match - show route for <addr> */
+    TE_ADDR_IN                 /* Interval query - show route in <addr> */
+  } addr_mode;
 }PACKED;
 
 struct rt_export_request {
   struct rt_export_hook *hook;         /* Table part of the export */
-  char *name;
-  const net_addr *addr;                        /* Network prefilter address */
+  char *name;          /* Network prefilter address */
   u8 trace_routes;
   uint feed_block_size;                        /* How many routes to feed at once */
   struct rt_prefilter_address prefilter;
@@ -321,6 +326,16 @@ struct rt_export_request {
   void (*log_state_change)(struct rt_export_request *req, u8);
 };
 
+static inline int net_in_netX_from_export_request(const net_addr *a, const net_addr *n){
+  if (a->type != n->type)
+    return 0;
+
+  return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n);
+}
+
+static inline int net_equal_from_export_request(const net_addr *a, const net_addr *b)
+{ return (a->length == b->length) && !memcmp(a, b, a->length); }
+
 struct rt_export_hook {
   node n;
   struct rt_exporter *table;           /* The connected table */
@@ -390,12 +405,6 @@ struct rt_table_export_hook {
 #define TES_STOP       4
 #define TES_MAX                5
 
-/* Value of addr_mode */
-#define TE_ADDR_NONE   0               /* No address matching */
-#define TE_ADDR_EQUAL  1               /* Exact query - show route <addr> */
-#define TE_ADDR_FOR    2               /* Longest prefix match - show route for <addr> */
-#define TE_ADDR_IN     3               /* Interval query - show route in <addr> */
-
 
 #define TFT_FIB                1
 #define TFT_TRIE       2
index b1983ef6e21ee14db369c935e9a0c296ab7050f1..9c72113a8a7c0c21442d92c7d00290d0a59b4446 100644 (file)
@@ -1896,7 +1896,7 @@ bgp_out_table_feed(void *data)
 
   int max = 512;
 
-  const net_addr *neq = (hook->h.req->prefilter.addr_mode == TE_ADDR_EQUAL) ? hook->h.req->addr : NULL;
+  const net_addr *neq = (hook->h.req->prefilter.addr_mode == TE_ADDR_EQUAL) ? hook->h.req->prefilter.addr : NULL;
   const net_addr *cand = NULL;
 
   do {
@@ -1905,7 +1905,7 @@ bgp_out_table_feed(void *data)
       switch (hook->h.req->prefilter.addr_mode)
       {
        case TE_ADDR_IN:
-         if (!net_in_netX(n->net, hook->h.req->addr))
+         if (!net_in_netX_from_export_request(n->net, hook->h.req->prefilter.addr))
            continue;
          /* fall through */
        case TE_ADDR_NONE:
@@ -1917,13 +1917,13 @@ bgp_out_table_feed(void *data)
        case TE_ADDR_FOR:
          if (!neq)
          {
-           if (net_in_netX(hook->h.req->addr, n->net) && (!cand || (n->net->length > cand->length)))
+           if (net_in_netX_from_export_request(hook->h.req->prefilter.addr, n->net) && (!cand || (n->net->length > cand->length)))
              cand = n->net;
            continue;
          }
          /* fall through */
        case TE_ADDR_EQUAL:
-         if (!net_equal(n->net, neq))
+         if (!net_equal_from_export_request(n->net, neq))
            continue;
          break;
       }