]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Do not assume that all channels are struct bgp_channel
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 8 Sep 2022 17:41:02 +0000 (19:41 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 3 Oct 2022 18:18:12 +0000 (20:18 +0200)
In principle, the channel list is a list of parent struct proto and can
contain general structures of type struct channel, That is useful e.g.
for adding MPLS channels to BGP.

nest/proto.c
proto/bgp/attrs.c
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c

index 7074f73a4e491ef1e0d5f15448ef4252fe3e66b8..60a749643f932b1a32837647e3d7ff1bc61e732e 100644 (file)
@@ -829,6 +829,9 @@ static int reconfigure_type;  /* Hack to propagate type info to channel_reconfig
 int
 channel_reconfigure(struct channel *c, struct channel_config *cf)
 {
+  /* Touched by reconfiguration */
+  c->stale = 0;
+
   /* FIXME: better handle these changes, also handle in_keep_filtered */
   if ((c->table != cf->table->table) || (cf->ra_mode && (c->ra_mode != cf->ra_mode)))
     return 0;
index a56aeb19774d9a7959ea185cc4a78e29c2385b02..1e234b163e77fad7d361b956bb9778977c54b49a 100644 (file)
@@ -1725,6 +1725,10 @@ bgp_preexport(struct channel *C, rte *e)
   struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (struct bgp_proto *) SRC : NULL;
   struct bgp_channel *c = (struct bgp_channel *) C;
 
+  /* Ignore non-BGP channels */
+  if (C->channel != &channel_bgp)
+    return -1;
+
   /* Reject our routes */
   if (src == p)
     return -1;
@@ -1922,6 +1926,10 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old)
   struct bgp_prefix *px;
   u32 path;
 
+  /* Ignore non-BGP channels */
+  if (C->channel != &channel_bgp)
+    return;
+
   if (new)
   {
     struct ea_list *attrs = bgp_update_attrs(p, c, new, new->attrs->eattrs, tmp_linpool);
index f07fcc16c5994923a6135ffca42e6cddf6919338..e1e0d796815a582d8c140b96213de93066f2aa44 100644 (file)
@@ -260,7 +260,7 @@ static inline struct bgp_channel *
 bgp_find_channel(struct bgp_proto *p, u32 afi)
 {
   struct bgp_channel *c;
-  WALK_LIST(c, p->p.channels)
+  BGP_WALK_CHANNELS(p, c)
     if (c->afi == afi)
       return c;
 
@@ -586,7 +586,7 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
   /* Summary state of ADD_PATH RX for active channels */
   uint summary_add_path_rx = 0;
 
-  WALK_LIST(c, p->p.channels)
+  BGP_WALK_CHANNELS(p, c)
   {
     const struct bgp_af_caps *loc = bgp_find_af_caps(local, c->afi);
     const struct bgp_af_caps *rem = bgp_find_af_caps(peer,  c->afi);
@@ -668,7 +668,7 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
   p->channel_count = num;
   p->summary_add_path_rx = summary_add_path_rx;
 
-  WALK_LIST(c, p->p.channels)
+  BGP_WALK_CHANNELS(p, c)
   {
     if (c->c.disabled)
       continue;
@@ -747,7 +747,7 @@ bgp_handle_graceful_restart(struct bgp_proto *p)
   p->gr_active_num = 0;
 
   struct bgp_channel *c;
-  WALK_LIST(c, p->p.channels)
+  BGP_WALK_CHANNELS(p, c)
   {
     /* FIXME: perhaps check for channel state instead of disabled flag? */
     if (c->c.disabled)
@@ -842,7 +842,7 @@ bgp_graceful_restart_timeout(timer *t)
   if (p->llgr_ready)
   {
     struct bgp_channel *c;
-    WALK_LIST(c, p->p.channels)
+    BGP_WALK_CHANNELS(p, c)
     {
       /* Channel is not in GR and is already flushed */
       if (!c->gr_active)
@@ -1394,6 +1394,10 @@ bgp_reload_routes(struct channel *C)
   struct bgp_proto *p = (void *) C->proto;
   struct bgp_channel *c = (void *) C;
 
+  /* Ignore non-BGP channels */
+  if (C->channel != &channel_bgp)
+    return;
+
   ASSERT(p->conn && (p->route_refresh || c->c.in_table));
 
   if (c->c.in_table)
@@ -1408,6 +1412,10 @@ bgp_feed_begin(struct channel *C, int initial)
   struct bgp_proto *p = (void *) C->proto;
   struct bgp_channel *c = (void *) C;
 
+  /* Ignore non-BGP channels */
+  if (C->channel != &channel_bgp)
+    return;
+
   /* This should not happen */
   if (!p->conn)
     return;
@@ -1433,6 +1441,10 @@ bgp_feed_end(struct channel *C)
   struct bgp_proto *p = (void *) C->proto;
   struct bgp_channel *c = (void *) C;
 
+  /* Ignore non-BGP channels */
+  if (C->channel != &channel_bgp)
+    return;
+
   /* This should not happen */
   if (!p->conn)
     return;
@@ -1547,7 +1559,7 @@ bgp_start(struct proto *P)
   if (p->p.gr_recovery && p->cf->gr_mode)
   {
     struct bgp_channel *c;
-    WALK_LIST(c, p->p.channels)
+    BGP_WALK_CHANNELS(p, c)
       channel_graceful_restart_lock(&c->c);
   }
 
@@ -1701,7 +1713,7 @@ bgp_init(struct proto_config *CF)
 
   /* Add all channels */
   struct bgp_channel_config *cc;
-  WALK_LIST(cc, CF->channels)
+  BGP_CF_WALK_CHANNELS(cf, cc)
     proto_add_channel(P, &cc->c);
 
   return P;
@@ -1847,7 +1859,7 @@ bgp_find_channel_config(struct bgp_config *cf, u32 afi)
 {
   struct bgp_channel_config *cc;
 
-  WALK_LIST(cc, cf->c.channels)
+  BGP_CF_WALK_CHANNELS(cf, cc)
     if (cc->afi == afi)
       return cc;
 
@@ -1997,7 +2009,7 @@ bgp_postconfig(struct proto_config *CF)
 
 
   struct bgp_channel_config *cc;
-  WALK_LIST(cc, CF->channels)
+  BGP_CF_WALK_CHANNELS(cf, cc)
   {
     /* Handle undefined import filter */
     if (cc->c.in_filter == FILTER_UNDEF)
@@ -2104,20 +2116,16 @@ bgp_reconfigure(struct proto *P, struct proto_config *CF)
   WALK_LIST(C, p->p.channels)
     C->stale = 1;
 
-  WALK_LIST(cc, new->c.channels)
+  BGP_CF_WALK_CHANNELS(new, cc)
   {
     C = (struct channel *) bgp_find_channel(p, cc->afi);
     same = proto_configure_channel(P, &C, &cc->c) && same;
-
-    if (C)
-      C->stale = 0;
   }
 
   WALK_LIST_DELSAFE(C, C2, p->p.channels)
     if (C->stale)
       same = proto_configure_channel(P, &C, NULL) && same;
 
-
   if (same && (p->start_state > BSS_PREPARE))
     bgp_update_bfd(p, new->bfd);
 
@@ -2562,6 +2570,9 @@ bgp_show_proto_info(struct proto *P)
     {
       channel_show_info(&c->c);
 
+      if (c->c.channel != &channel_bgp)
+       continue;
+
       if (p->gr_active_num)
        cli_msg(-1006, "    Neighbor GR:    %s", bgp_gr_states[c->gr_active]);
 
index 15a759fb98fab47c7394427ff09a0af78f08d5d9..5d0e9791d63f58d239a3aa86fdd3e4fdc496d914 100644 (file)
@@ -485,6 +485,9 @@ struct bgp_parse_state {
 #define BGP_RX_BUFFER_EXT_SIZE 65535
 #define BGP_TX_BUFFER_EXT_SIZE 65535
 
+#define BGP_CF_WALK_CHANNELS(P,C) WALK_LIST(C, P->c.channels) if (C->c.channel == &channel_bgp)
+#define BGP_WALK_CHANNELS(P,C) WALK_LIST(C, P->p.channels) if (C->c.channel == &channel_bgp)
+
 static inline int bgp_channel_is_ipv4(struct bgp_channel *c)
 { return BGP_AFI(c->afi) == BGP_AFI_IPV4; }
 
index 3aa62c39db34bac685c724ee878ba2fa1a752e59..fc23897d70d163bb3708840923653120fcf3b712 100644 (file)
@@ -262,7 +262,7 @@ bgp_prepare_capabilities(struct bgp_conn *conn)
   }
 
   /* Allocate and fill per-AF fields */
-  WALK_LIST(c, p->p.channels)
+  BGP_WALK_CHANNELS(p, c)
   {
     ac = &caps->af_data[caps->af_count++];
     ac->afi = c->afi;
@@ -681,7 +681,7 @@ bgp_check_capabilities(struct bgp_conn *conn)
   /* This is partially overlapping with bgp_conn_enter_established_state(),
      but we need to run this just after we receive OPEN message */
 
-  WALK_LIST(c, p->p.channels)
+  BGP_WALK_CHANNELS(p, c)
   {
     const struct bgp_af_caps *loc = bgp_find_af_caps(local,  c->afi);
     const struct bgp_af_caps *rem = bgp_find_af_caps(remote, c->afi);