diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 6da6e1a8..3951b25f 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -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 * diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 163fdf6a..be3f643f 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -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); diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 7b7908f6..41c6840a 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -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) *