diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 3951b25f..e80cedaf 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1215,6 +1215,50 @@ bgp_find_attr(ea_list *attrs, uint 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 @@ -1225,6 +1269,41 @@ struct ea_class ea_bgp_state_startup = { .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 bgp_register_attrs(void) { @@ -1246,6 +1325,9 @@ bgp_register_attrs(void) } 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 ); } @@ -1892,7 +1974,7 @@ bgp_tx_resend(struct bgp_proto *p, struct bgp_channel *bc) */ 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 * diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index be3f643f..cf280a48 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -681,6 +681,12 @@ bgp_conn_enter_established_state(struct bgp_conn *conn) 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->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); proto_notify_state(&p->p, PS_UP); + #ifdef CONFIG_BMP - bmp_peer_up(p, conn->local_open_msg, conn->local_open_length, - conn->remote_open_msg, conn->remote_open_length); + ea_list *ea_l = proto_get_state(p->p.id); + 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 } @@ -809,9 +822,29 @@ bgp_conn_leave_established_state(struct bgp_conn *conn, struct bgp_proto *p) bgp_stop(p, 0, NULL, 0); #ifdef CONFIG_BMP - bmp_peer_down(p, p->last_error_class, - conn->notify_code, conn->notify_subcode, - conn->notify_data, conn->notify_size); + struct { + struct closing_bgp closing_struct; + 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 } @@ -1734,6 +1767,14 @@ bgp_start(struct proto *P) p->remote_id = 0; 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 */ if (p->p.gr_recovery && p->cf->gr_mode) { @@ -1905,6 +1946,9 @@ bgp_init(struct proto_config *CF) /* Add MPLS channel */ proto_configure_mpls_channel(P, CF, RTS_BGP); + PST_LOCKED(ts) + bgp_state_to_eattr(P, ts->states[P->id]); + return P; } @@ -1926,6 +1970,14 @@ bgp_channel_init(struct channel *C, struct channel_config *CF) if (cf->base_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 @@ -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 */ 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 */ struct bgp_conn *ci = &p->incoming_conn; 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); } +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 bgp_show_afis(int code, char *s, u32 *afis, uint count) { diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 41c6840a..b4834849 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -319,6 +319,21 @@ struct bgp_conn { 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 { node n; /* Node in bgp_socket / pending list */ struct bgp_socket *sock; /* Assigned socket */ @@ -644,6 +659,7 @@ extern struct rte_owner_class bgp_rte_owner_class; eattr * 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_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); @@ -698,6 +714,11 @@ bgp_total_aigp_metric(const rte *e) 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 */ extern struct ea_class ea_bgp_state_startup; diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 10ee4bc0..e4758e32 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -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; 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", conn->hold_time, conn->keepalive_time, p->remote_as, p->remote_id, conn->as4_session);