0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

BGP: exporting protocol-specific state information

This commit is contained in:
Maria Matejka 2024-10-11 12:38:18 +02:00
parent b8a8b9f01b
commit 826191080d
4 changed files with 198 additions and 6 deletions

View File

@ -1215,6 +1215,50 @@ bgp_find_attr(ea_list *attrs, uint code)
return ea_find(attrs, BGP_EA_ID(code)); return ea_find(attrs, BGP_EA_ID(code));
} }
struct ea_class ea_bgp_rem_id = {
.name = "proto_bgp_rem_id",
.type = T_INT,
};
struct ea_class ea_bgp_rem_as = {
.name = "proto_bgp_rem_as",
.type = T_INT,
};
struct ea_class ea_bgp_loc_as = {
.name = "proto_bgp_loc_as",
.type = T_INT,
};
struct ea_class ea_bgp_rem_ip = {
.name = "proto_bgp_rem_ip",
.type = T_IP,
};
struct ea_class ea_bgp_conn = {
.name = "proto_bgp_rem_conn",
.type = T_PTR,
};
struct ea_class ea_bgp_in_conn = {
.name = "proto_bgp_rem_in_conn",
.type = T_PTR,
};
struct ea_class ea_bgp_out_conn = {
.name = "proto_bgp_rem_out_conn",
.type = T_PTR,
};
struct ea_class ea_bgp_afi = {
.name = "bgp_afi",
.type = T_INT,
};
struct ea_class ea_bgp_peer_type = {
.name = "bgp_peer_type",
.type = T_INT,
};
/* /*
* Protocol extended state information * Protocol extended state information
@ -1225,6 +1269,41 @@ struct ea_class ea_bgp_state_startup = {
.type = T_INT, .type = T_INT,
}; };
struct ea_class ea_bgp_local_open_msg_len = {
.name = "bgp_local_open_msg_len",
.type = T_INT,
};
struct ea_class ea_bgp_remote_open_msg_len = {
.name = "bgp_remote_open_msg_len",
.type = T_INT,
};
struct ea_class ea_bgp_local_open_msg = {
.name = "bgp_local_open_msg",
.type = T_BYTESTRING,
};
struct ea_class ea_bgp_remote_open_msg = {
.name = "bgp_remote_open_msg",
.type = T_BYTESTRING,
};
struct ea_class ea_bgp_close_bmp = {
.name = "bgp_close_bmp",
.type = T_OPAQUE,
};
struct ea_class ea_bgp_close_bmp_set = {
.name = "bgp_close_bmp_set",
.type = T_INT,
};
struct ea_class ea_bgp_as4_session = {
.name = "bgp_as4_session",
.type = T_INT,
};
void void
bgp_register_attrs(void) bgp_register_attrs(void)
{ {
@ -1246,6 +1325,9 @@ bgp_register_attrs(void)
} }
EA_REGISTER_ALL( EA_REGISTER_ALL(
&ea_bgp_rem_id, &ea_bgp_rem_as, &ea_bgp_loc_as, &ea_bgp_rem_ip, &ea_bgp_peer_type, &ea_bgp_afi,
&ea_bgp_local_open_msg, &ea_bgp_remote_open_msg, &ea_bgp_local_open_msg_len, &ea_bgp_remote_open_msg_len,
&ea_bgp_conn, &ea_bgp_in_conn, &ea_bgp_out_conn, &ea_bgp_close_bmp, &ea_bgp_close_bmp_set, &ea_bgp_as4_session,
&ea_bgp_state_startup &ea_bgp_state_startup
); );
} }
@ -1892,7 +1974,7 @@ bgp_tx_resend(struct bgp_proto *p, struct bgp_channel *bc)
*/ */
static void static void
bgp_out_item_done(struct lfjour *j, struct lfjour_item *i) bgp_out_item_done(struct lfjour *j UNUSED, struct lfjour_item *i UNUSED)
{} {}
static struct rt_export_feed * static struct rt_export_feed *

View File

@ -681,6 +681,12 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
p->as4_session = conn->as4_session; p->as4_session = conn->as4_session;
ea_list *eal = proto_get_state(p->p.id);
ea_set_attr(&eal, EA_LITERAL_STORE_PTR(&ea_bgp_conn, 0, p->conn));
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_as4_session, 0, p->as4_session));
proto_announce_state(&p->p, eal);
p->route_refresh = peer->route_refresh; p->route_refresh = peer->route_refresh;
p->enhanced_refresh = local->enhanced_refresh && peer->enhanced_refresh; p->enhanced_refresh = local->enhanced_refresh && peer->enhanced_refresh;
@ -792,9 +798,16 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
bgp_conn_set_state(conn, BS_ESTABLISHED); bgp_conn_set_state(conn, BS_ESTABLISHED);
proto_notify_state(&p->p, PS_UP); proto_notify_state(&p->p, PS_UP);
#ifdef CONFIG_BMP #ifdef CONFIG_BMP
bmp_peer_up(p, conn->local_open_msg, conn->local_open_length, ea_list *ea_l = proto_get_state(p->p.id);
conn->remote_open_msg, conn->remote_open_length); ea_set_attr(&ea_l, EA_LITERAL_STORE_ADATA(&ea_bgp_local_open_msg, 0, conn->local_open_msg, conn->local_open_length));
ea_set_attr(&ea_l, EA_LITERAL_STORE_ADATA(&ea_bgp_remote_open_msg, 0, conn->remote_open_msg, conn->remote_open_length));
ea_set_attr(&ea_l, EA_LITERAL_EMBEDDED(&ea_bgp_local_open_msg_len, 0, conn->local_open_length));
ea_set_attr(&ea_l, EA_LITERAL_EMBEDDED(&ea_bgp_remote_open_msg_len, 0, conn->remote_open_length));
ea_l = ea_lookup(ea_l, 0, EALS_CUSTOM);
proto_announce_state(&p->p, eal_l);
#endif #endif
} }
@ -809,9 +822,29 @@ bgp_conn_leave_established_state(struct bgp_conn *conn, struct bgp_proto *p)
bgp_stop(p, 0, NULL, 0); bgp_stop(p, 0, NULL, 0);
#ifdef CONFIG_BMP #ifdef CONFIG_BMP
bmp_peer_down(p, p->last_error_class, struct {
conn->notify_code, conn->notify_subcode, struct closing_bgp closing_struct;
conn->notify_data, conn->notify_size); byte data[conn->notify_size];
} to_ea;
to_ea.closing_struct = (struct closing_bgp) {
.err_class = p->last_error_class,
.err_code = conn->notify_code,
.err_subcode = conn->notify_subcode,
.length = conn->notify_size,
};
memcpy(to_ea.data, conn->notify_data, conn->notify_size);
ea_list *eal = proto_get_state(p->p.id);
ea_set_attr(&eal, EA_LITERAL_STORE_PTR(&ea_bgp_conn, 0, p->conn));
ea_set_attr(&eal, EA_LITERAL_STORE_ADATA(&ea_bgp_close_bmp, 0, &to_ea.closing_struct, sizeof(to_ea)));
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_close_bmp_set, 0, 1));
proto_announce_state(&p->p, eal);
//bmp_peer_down(p, p->last_error_class,
// conn->notify_code, conn->notify_subcode,
// conn->notify_data, conn->notify_size);
#endif #endif
} }
@ -1734,6 +1767,14 @@ bgp_start(struct proto *P)
p->remote_id = 0; p->remote_id = 0;
p->link_addr = IPA_NONE; p->link_addr = IPA_NONE;
ea_list *eal = proto_get_state(p->p.id);
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_rem_id, 0, p->remote_id));
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_loc_as, 0, p->local_as));
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_rem_as, 0, p->remote_as));
ea_set_attr(&eal, EA_LITERAL_STORE_ADATA(&ea_bgp_rem_ip, 0, &p->remote_ip, sizeof(ip_addr)));
proto_announce_state(&p->p, eal);
/* Lock all channels when in GR recovery mode */ /* Lock all channels when in GR recovery mode */
if (p->p.gr_recovery && p->cf->gr_mode) if (p->p.gr_recovery && p->cf->gr_mode)
{ {
@ -1905,6 +1946,9 @@ bgp_init(struct proto_config *CF)
/* Add MPLS channel */ /* Add MPLS channel */
proto_configure_mpls_channel(P, CF, RTS_BGP); proto_configure_mpls_channel(P, CF, RTS_BGP);
PST_LOCKED(ts)
bgp_state_to_eattr(P, ts->states[P->id]);
return P; return P;
} }
@ -1926,6 +1970,14 @@ bgp_channel_init(struct channel *C, struct channel_config *CF)
if (cf->base_table) if (cf->base_table)
c->base_table = cf->base_table->table; c->base_table = cf->base_table->table;
PST_LOCKED(ts)
{
ea_list *eal = ea_free_later(ts->channels[c->c.id]);
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_afi, 0, c->afi));
ts->channels[c->c.id] = ea_lookup_slow(eal, 0, EALS_IN_TABLE);
}
} }
static int static int
@ -2363,6 +2415,11 @@ bgp_reconfigure(struct proto *P, struct proto_config *CF)
/* We should update our copy of configuration ptr as old configuration will be freed */ /* We should update our copy of configuration ptr as old configuration will be freed */
p->cf = new; p->cf = new;
ea_list *eal = proto_get_state(p->p.id);
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_peer_type, 0, p->cf->peer_type));
proto_announce_state(&p->p, eal);
/* Check whether existing connections are compatible with required capabilities */ /* Check whether existing connections are compatible with required capabilities */
struct bgp_conn *ci = &p->incoming_conn; struct bgp_conn *ci = &p->incoming_conn;
if (((ci->state == BS_OPENCONFIRM) || (ci->state == BS_ESTABLISHED)) && !bgp_check_capabilities(ci)) if (((ci->state == BS_OPENCONFIRM) || (ci->state == BS_ESTABLISHED)) && !bgp_check_capabilities(ci))
@ -2566,6 +2623,33 @@ bgp_get_status(struct proto *P, byte *buf)
bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2); bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2);
} }
int
bgp_state_to_eattr(struct proto *P, struct ea_list *state)
{
struct bgp_proto *p = (struct bgp_proto *) P;
ea_set_attr(&state, EA_LITERAL_EMBEDDED(&ea_bgp_rem_id, 0, p->remote_id));
ea_set_attr(&state, EA_LITERAL_STORE_ADATA(&ea_bgp_rem_ip, 0, &p->remote_ip, sizeof(ip_addr)));
ea_set_attr(&state, EA_LITERAL_EMBEDDED(&ea_bgp_peer_type, 0, p->cf->peer_type));
ea_set_attr(&state, EA_LITERAL_EMBEDDED(&ea_bgp_loc_as, 0, p->local_as));
ea_set_attr(&state, EA_LITERAL_EMBEDDED(&ea_bgp_rem_as, 0, p->remote_as));
ea_set_attr(&state, EA_LITERAL_EMBEDDED(&ea_bgp_as4_session, 0, p->as4_session));
if (p->conn)
{
ea_set_attr(&state, EA_LITERAL_STORE_PTR(&ea_bgp_conn, 0, &p->conn));
ea_set_attr(&state, EA_LITERAL_STORE_PTR(&ea_bgp_in_conn, 0, &p->incoming_conn));
ea_set_attr(&state, EA_LITERAL_STORE_PTR(&ea_bgp_out_conn, 0, &p->outgoing_conn));
}
ea_set_attr(&state, EA_LITERAL_STORE_ADATA(&ea_bgp_local_open_msg, 0, NULL, 0));
ea_set_attr(&state, EA_LITERAL_STORE_ADATA(&ea_bgp_remote_open_msg, 0, NULL, 0));
ea_set_attr(&state, EA_LITERAL_EMBEDDED(&ea_bgp_local_open_msg_len, 0, 0));
ea_set_attr(&state, EA_LITERAL_EMBEDDED(&ea_bgp_remote_open_msg_len, 0, 0));
ea_set_attr(&state, EA_LITERAL_STORE_ADATA(&ea_bgp_close_bmp, 0, NULL, 0));
ea_set_attr(&state, EA_LITERAL_EMBEDDED(&ea_bgp_close_bmp_set, 0, 0));
return 1;
}
static void static void
bgp_show_afis(int code, char *s, u32 *afis, uint count) bgp_show_afis(int code, char *s, u32 *afis, uint count)
{ {

View File

@ -319,6 +319,21 @@ struct bgp_conn {
uint hold_time, keepalive_time, send_hold_time; /* Times calculated from my and neighbor's requirements */ uint hold_time, keepalive_time, send_hold_time; /* Times calculated from my and neighbor's requirements */
}; };
struct journal_bgp_conn {
struct bgp_conn *conn;
struct bgp_conn outgoing_conn;
struct bgp_conn incoming_conn;
};
struct closing_bgp {
int err_class;
int err_code;
int err_subcode;
int length;
byte data[0];
};
struct bgp_listen_request { struct bgp_listen_request {
node n; /* Node in bgp_socket / pending list */ node n; /* Node in bgp_socket / pending list */
struct bgp_socket *sock; /* Assigned socket */ struct bgp_socket *sock; /* Assigned socket */
@ -644,6 +659,7 @@ extern struct rte_owner_class bgp_rte_owner_class;
eattr * eattr *
bgp_find_attr(ea_list *attrs, uint code); bgp_find_attr(ea_list *attrs, uint code);
int bgp_state_to_eattr(struct proto *P, struct ea_list *state);
void bgp_set_attr_u32(ea_list **to, uint code, uint flags, u32 val); void bgp_set_attr_u32(ea_list **to, uint code, uint flags, u32 val);
void bgp_set_attr_ptr(ea_list **to, uint code, uint flags, const struct adata *ad); void bgp_set_attr_ptr(ea_list **to, uint code, uint flags, const struct adata *ad);
void bgp_set_attr_data(ea_list **to, uint code, uint flags, void *data, uint len); void bgp_set_attr_data(ea_list **to, uint code, uint flags, void *data, uint len);
@ -698,6 +714,11 @@ bgp_total_aigp_metric(const rte *e)
return metric; return metric;
} }
/* bgp protocol journal attributes */
extern struct ea_class ea_bgp_rem_id, ea_bgp_rem_as, ea_bgp_loc_as, ea_bgp_rem_ip, ea_bgp_peer_type, ea_bgp_afi,
ea_bgp_local_open_msg, ea_bgp_remote_open_msg, ea_bgp_local_open_msg_len, ea_bgp_remote_open_msg_len,
ea_bgp_conn, ea_bgp_in_conn, ea_bgp_out_conn, ea_bgp_close_bmp, ea_bgp_close_bmp_set, ea_bgp_as4_session;
/* Extended state attributes */ /* Extended state attributes */
extern struct ea_class extern struct ea_class
ea_bgp_state_startup; ea_bgp_state_startup;

View File

@ -1048,6 +1048,11 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
conn->ext_messages = conn->local_caps->ext_messages && caps->ext_messages; conn->ext_messages = conn->local_caps->ext_messages && caps->ext_messages;
p->remote_id = id; p->remote_id = id;
ea_list *eal = proto_get_state(p->p.id);
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_rem_id, 0, p->remote_id));
proto_announce_state(&p->p, eal);
DBG("BGP: Hold timer set to %d, keepalive to %d, AS to %d, ID to %x, AS4 session to %d\n", DBG("BGP: Hold timer set to %d, keepalive to %d, AS to %d, ID to %x, AS4 session to %d\n",
conn->hold_time, conn->keepalive_time, p->remote_as, p->remote_id, conn->as4_session); conn->hold_time, conn->keepalive_time, p->remote_as, p->remote_id, conn->as4_session);