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);
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);
}
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);
*/
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)
{
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)
{
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;
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;
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];
{
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);
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) */
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;
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);
#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)
*