]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Start state is now using extended state
authorMaria Matejka <mq@ucw.cz>
Tue, 15 Oct 2024 11:10:58 +0000 (13:10 +0200)
committerMaria Matejka <mq@ucw.cz>
Thu, 14 Nov 2024 10:41:37 +0000 (11:41 +0100)
proto/bgp/attrs.c
proto/bgp/bgp.c
proto/bgp/bgp.h

index 6da6e1a869221eef8952f125294b0947bf2ed02d..3951b25f6907bfa2bfa5c46e58f6ac2c82505cb0 100644 (file)
@@ -1215,6 +1215,16 @@ bgp_find_attr(ea_list *attrs, uint code)
   return ea_find(attrs, BGP_EA_ID(code));
 }
 
+
+/*
+ *     Protocol extended state information
+ */
+
+struct ea_class ea_bgp_state_startup = {
+  .name = "bgp_state_startup",
+  .type = T_INT,
+};
+
 void
 bgp_register_attrs(void)
 {
@@ -1234,6 +1244,10 @@ bgp_register_attrs(void)
 
     ea_register_init(&bgp_attr_table[i].class);
   }
+
+  EA_REGISTER_ALL(
+      &ea_bgp_state_startup
+      );
 }
 
 struct ea_class *
index 163fdf6a6113a0125c7aef989a7bfb470b2a0fc7..be3f643fa268a47f37ea4fb91c1519f60d53a4ae 100644 (file)
@@ -369,7 +369,7 @@ static void
 bgp_startup(struct bgp_proto *p)
 {
   BGP_TRACE(D_EVENTS, "Started");
-  p->start_state = BSS_CONNECT;
+  bgp_set_start_state(p, BSS_CONNECT);
 
   if (!p->passive)
     bgp_active(p);
@@ -403,7 +403,7 @@ bgp_initiate(struct bgp_proto *p)
 
   if (p->startup_delay)
   {
-    p->start_state = BSS_DELAY;
+    bgp_set_start_state(p, BSS_DELAY);
     BGP_TRACE(D_EVENTS, "Startup delayed by %d seconds due to errors", p->startup_delay);
     bgp_start_timer(p, p->startup_timer, p->startup_delay);
   }
@@ -565,7 +565,7 @@ bgp_graceful_close_conn(struct bgp_conn *conn, int subcode, byte *data, uint len
 static void
 bgp_down(struct bgp_proto *p)
 {
-  if (p->start_state > BSS_PREPARE)
+  if (bgp_start_state(p) > BSS_PREPARE)
   {
     bgp_setup_auth(p, 0);
     bgp_close(p);
@@ -1366,7 +1366,7 @@ bgp_incoming_connection(sock *sk, uint dummy UNUSED)
    */
 
   acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
-    (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);
+    (bgp_start_state(p) >= BSS_CONNECT) && (!p->incoming_conn.sk);
 
   if (p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready)
   {
@@ -1473,7 +1473,7 @@ bgp_neigh_notify(neighbor *n)
   if ((ps == PS_DOWN) || (ps == PS_STOP))
     return;
 
-  int prepare = (ps == PS_START) && (p->start_state == BSS_PREPARE);
+  int prepare = (ps == PS_START) && (bgp_start_state(p) == BSS_PREPARE);
 
   if (n->scope <= 0)
   {
@@ -1706,7 +1706,7 @@ bgp_start(struct proto *P)
 
   p->passive = cf->passive || bgp_is_dynamic(p);
 
-  p->start_state = BSS_PREPARE;
+  bgp_set_start_state(p, BSS_PREPARE);
   p->outgoing_conn.state = BS_IDLE;
   p->incoming_conn.state = BS_IDLE;
   p->neigh = NULL;
@@ -2372,7 +2372,7 @@ bgp_reconfigure(struct proto *P, struct proto_config *CF)
   if (((co->state == BS_OPENCONFIRM) || (co->state == BS_ESTABLISHED)) && !bgp_check_capabilities(co))
     return 0;
 
-  if (p->start_state > BSS_PREPARE)
+  if (bgp_start_state(p) > BSS_PREPARE)
     bgp_update_bfd(p, new->bfd);
 
   return 1;
@@ -2546,7 +2546,7 @@ bgp_state_dsc(struct bgp_proto *p)
     return "Down";
 
   int state = MAX(p->incoming_conn.state, p->outgoing_conn.state);
-  if ((state == BS_IDLE) && (p->start_state >= BSS_CONNECT) && p->passive)
+  if ((state == BS_IDLE) && (bgp_start_state(p) >= BSS_CONNECT) && p->passive)
     return "Passive";
 
   return bgp_state_names[state];
@@ -2756,7 +2756,7 @@ bgp_show_proto_info(struct proto *P)
   {
     struct bgp_conn *oc = &p->outgoing_conn;
 
-    if ((p->start_state < BSS_CONNECT) &&
+    if ((bgp_start_state(p) < BSS_CONNECT) &&
        (tm_active(p->startup_timer)))
       cli_msg(-1006, "    Error wait:       %t/%u",
              tm_remains(p->startup_timer), p->startup_delay);
index 7b7908f6d2f113e02c070b80357d8af736e338fa..41c6840aa47db507aef7f1257892322d71522750 100644 (file)
@@ -338,7 +338,6 @@ struct bgp_proto {
   u32 local_id;                                /* BGP identifier of this router */
   u32 remote_id;                       /* BGP identifier of the neighbor */
   u32 rr_cluster_id;                   /* Route reflector cluster ID */
-  u8 start_state;                      /* Substates that partitions BS_START */
   u8 is_internal;                      /* Internal BGP session (local_as == remote_as) */
   u8 is_interior;                      /* Internal or intra-confederation BGP session */
   u8 as4_session;                      /* Session uses 4B AS numbers in AS_PATH (both sides support it) */
@@ -379,6 +378,10 @@ struct bgp_proto {
                                           are encoded as (bgp_err_code << 16 | bgp_err_subcode) */
 };
 
+#define bgp_ea_state(p)  _Generic((p), \
+    struct bgp_proto *: (p)->p.ea_state, \
+    ea_list *: (p))
+
 struct bgp_channel {
   struct channel c;
 
@@ -695,6 +698,10 @@ bgp_total_aigp_metric(const rte *e)
   return metric;
 }
 
+/* Extended state attributes */
+extern struct ea_class
+             ea_bgp_state_startup;
+
 void bgp_register_attrs(void);
 struct ea_class *bgp_find_ea_class_by_id(uint id);
 
@@ -788,6 +795,13 @@ enum bgp_attr_id {
 #define BSS_DELAY              1       /* Startup delay due to previous errors */
 #define BSS_CONNECT            2       /* Ordinary BGP connecting */
 
+#define bgp_start_state(p)     ea_get_int(bgp_ea_state(p), &ea_bgp_state_startup, BSS_PREPARE)
+#define bgp_set_start_state(p, val)    do {            \
+  ea_list *L = bgp_ea_state(p);                                \
+  ea_set_attr_u32(&L, &ea_bgp_state_startup, 0, val);  \
+  proto_announce_state(&p->p, L);                      \
+} while (0)
+
 
 /* BGP feed states (TX)
  *