]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP/BMP: Moved temporary allocation checks to the freeing functions
authorMaria Matejka <mq@ucw.cz>
Wed, 11 Oct 2023 20:23:34 +0000 (22:23 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 11 Oct 2023 20:23:34 +0000 (22:23 +0200)
proto/bgp/attrs.c
proto/bgp/bgp.h
proto/bgp/packets.c

index de45cae0e6181d90829f51e423c614795e6bb5c4..adc201a7b05183aaa951a9e8c3a5f39373d8bd79 100644 (file)
@@ -1631,6 +1631,9 @@ bgp_defer_bucket(struct bgp_channel *c, struct bgp_bucket *b)
 void
 bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b)
 {
+  if (b->bmp)
+    return;
+
   struct bgp_proto *p = (void *) c->c.proto;
   struct bgp_bucket *wb = bgp_get_withdraw_bucket(c);
 
@@ -1710,6 +1713,14 @@ bgp_get_prefix(struct bgp_channel *c, net_addr *net, u32 path_id)
 void
 bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px)
 {
+  /* BMP hack */
+  if (
+      !NODE_VALID(px->buck_node.prev) &&
+      !NODE_VALID(px->buck_node.next) &&
+      !SKIP_BACK(struct bgp_bucket, prefixes.head, px->buck_node.prev)->bmp
+      )
+    return;
+
   rem_node(&px->buck_node);
   HASH_REMOVE2(c->prefix_hash, PXH, c->pool, px);
 
index 324df43c3e24053429609de69e6915b00bf5a3bd..7368654573ba2cc4b4c0cd8bc52f1a33c2eeee42 100644 (file)
@@ -413,6 +413,7 @@ struct bgp_bucket {
   struct bgp_bucket *next;             /* Node in bucket hash table */
   list prefixes;                       /* Prefixes in this bucket (struct bgp_prefix) */
   u32 hash;                            /* Hash over extended attributes */
+  u32 bmp:1;                           /* Temporary bucket for BMP encoding */
   ea_list eattrs[0];                   /* Per-bucket extended attributes */
 };
 
@@ -439,7 +440,6 @@ struct bgp_write_state {
   int as4_session;
   int add_path;
   int mpls;
-  int sham;
 
   eattr *mp_next_hop;
   const adata *mpls_labels;
index 6b728b4ec8a7d4b458c11ec35cef1f02f7f64dfa..6b11eaf7ef13c76eb8cfd00d9e3f43b28fa29783 100644 (file)
@@ -1575,10 +1575,7 @@ bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
     memcpy(pos, &a, b);
     ADVANCE(pos, size, b);
 
-    if (!s->sham)
-      bgp_free_prefix(s->channel, px);
-    else
-      rem_node(&px->buck_node);
+    bgp_free_prefix(s->channel, px);
   }
 
   return pos - buf;
@@ -1663,10 +1660,7 @@ bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
     memcpy(pos, &a, b);
     ADVANCE(pos, size, b);
 
-    if (!s->sham)
-      bgp_free_prefix(s->channel, px);
-    else
-      rem_node(&px->buck_node);
+    bgp_free_prefix(s->channel, px);
   }
 
   return pos - buf;
@@ -1754,10 +1748,7 @@ bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b
     memcpy(pos, &a, b);
     ADVANCE(pos, size, b);
 
-    if (!s->sham)
-      bgp_free_prefix(s->channel, px);
-    else
-      rem_node(&px->buck_node);
+    bgp_free_prefix(s->channel, px);
   }
 
   return pos - buf;
@@ -1854,10 +1845,7 @@ bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b
     memcpy(pos, &a, b);
     ADVANCE(pos, size, b);
 
-    if (!s->sham)
-      bgp_free_prefix(s->channel, px);
-    else
-      rem_node(&px->buck_node);
+    bgp_free_prefix(s->channel, px);
   }
 
   return pos - buf;
@@ -1944,10 +1932,7 @@ bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *
     memcpy(pos, net->data, flen);
     ADVANCE(pos, size, flen);
 
-    if (!s->sham)
-      bgp_free_prefix(s->channel, px);
-    else
-      rem_node(&px->buck_node);
+    bgp_free_prefix(s->channel, px);
   }
 
   return pos - buf;
@@ -2039,10 +2024,7 @@ bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *
     memcpy(pos, net->data, flen);
     ADVANCE(pos, size, flen);
 
-    if (!s->sham)
-      bgp_free_prefix(s->channel, px);
-    else
-      rem_node(&px->buck_node);
+    bgp_free_prefix(s->channel, px);
   }
 
   return pos - buf;
@@ -2286,8 +2268,7 @@ bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
   if (la < 0)
   {
     /* Attribute list too long */
-    if (!s->sham)
-      bgp_withdraw_bucket(s->channel, buck);
+    bgp_withdraw_bucket(s->channel, buck);
     return NULL;
   }
 
@@ -2334,8 +2315,7 @@ bgp_create_mp_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
   if (la < 0)
   {
     /* Attribute list too long */
-    if (!s->sham)
-      bgp_withdraw_bucket(s->channel, buck);
+    bgp_withdraw_bucket(s->channel, buck);
     return NULL;
   }
 
@@ -2427,9 +2407,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
   byte *res = NULL;
   /* FIXME: must be a bit shorter */
 
-  struct lp_state tmpp;
-  lp_save(tmp_linpool, &tmpp);
-
   struct bgp_caps *peer = p->conn->remote_caps;
   const struct bgp_af_caps *rem = bgp_find_af_caps(peer, c->afi);
 
@@ -2441,7 +2418,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
     .as4_session = 1,
     .add_path = c->add_path_rx,
     .mpls = c->desc->mpls,
-    .sham = 1,
   };
 
   if (!update)
@@ -2457,8 +2433,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
       bgp_create_mp_reach(&s, buck, buf, end);
   }
 
-  lp_restore(tmp_linpool, &tmpp);
-
   return res;
 }
 
@@ -2484,17 +2458,19 @@ bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n,
   uint bucket_size = sizeof(struct bgp_bucket) + ea_size;
   uint prefix_size = sizeof(struct bgp_prefix) + n->length;
 
-  /* Sham bucket */
-  struct bgp_bucket *b = alloca(bucket_size);
-  *b = (struct bgp_bucket) { };
+  struct lp_state tmpp;
+  lp_save(tmp_linpool, &tmpp);
+
+  /* Temporary bucket */
+  struct bgp_bucket *b = tmp_allocz(bucket_size);
+  b->bmp = 1;
   init_list(&b->prefixes);
 
   if (attrs)
     memcpy(b->eattrs, attrs, ea_size);
 
-  /* Sham prefix */
-  struct bgp_prefix *px = alloca(prefix_size);
-  *px = (struct bgp_prefix) { };
+  /* Temporary prefix */
+  struct bgp_prefix *px = tmp_allocz(prefix_size);
   px->path_id = src->private_id;
   net_copy(px->net, n);
   add_tail(&b->prefixes, &px->buck_node);
@@ -2504,6 +2480,8 @@ bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n,
   if (end)
     bgp_bmp_prepare_bgp_hdr(buf, end - buf, PKT_UPDATE);
 
+  lp_restore(tmp_linpool, &tmpp);
+
   return end;
 }