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_afi = {
+ .name = "bgp_afi",
+ .type = T_INT,
+};
+
+struct ea_class ea_bgp_peer_type = {
+ .name = "bgp_peer_type",
+ .type = T_INT,
+};
+
+/*
+ * Protocol connections information
+ */
+
+struct ea_class ea_bgp_in_conn_local_open_msg = {
+ .name = "bgp_in_conn_local_open_msg",
+ .type = T_BYTESTRING,
+};
+
+struct ea_class ea_bgp_in_conn_remote_open_msg = {
+ .name = "bgp_in_conn_remote_open_msg",
+ .type = T_BYTESTRING,
+};
+
+struct ea_class ea_bgp_out_conn_local_open_msg = {
+ .name = "bgp_out_conn_local_open_msg",
+ .type = T_BYTESTRING,
+};
+
+struct ea_class ea_bgp_out_conn_remote_open_msg = {
+ .name = "bgp_out_conn_remote_open_msg",
+ .type = T_BYTESTRING,
+};
+
+struct ea_class ea_bgp_in_conn_state = {
+ .name = "bgp_in_conn_state",
+ .type = T_INT,
+};
+
+struct ea_class ea_bgp_out_conn_state = {
+ .name = "bgp_out_conn_state",
+ .type = T_INT,
+};
+
+struct ea_class ea_bgp_in_conn_sk = {
+ .name = "bgp_in_conn_sk",
+ .type = T_OPAQUE,
+};
+
+struct ea_class ea_bgp_out_conn_sk = {
+ .name = "bgp_out_conn_sk",
+ .type = T_OPAQUE,
+};
/*
* Protocol extended state information
.type = T_INT,
};
+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,
+};
+
+struct ea_class ea_bgp_as4_in_conn = {
+ .name = "bgp_as4_in_conn",
+ .type = T_INT,
+};
+
+struct ea_class ea_bgp_as4_out_conn = {
+ .name = "bgp_as4_out_conn",
+ .type = T_INT,
+};
+
void
bgp_register_attrs(void)
{
}
EA_REGISTER_ALL(
- &ea_bgp_state_startup
+ &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_in_conn_local_open_msg, &ea_bgp_out_conn_local_open_msg, &ea_bgp_in_conn_remote_open_msg,
+ &ea_bgp_out_conn_remote_open_msg, &ea_bgp_close_bmp, &ea_bgp_close_bmp_set, &ea_bgp_as4_session,
+ &ea_bgp_state_startup, &ea_bgp_in_conn_state, &ea_bgp_out_conn_state,
+ &ea_bgp_in_conn_sk, &ea_bgp_out_conn_sk, &ea_bgp_as4_in_conn, &ea_bgp_as4_out_conn
);
}
*/
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 *
conn->local_open_length = 0;
conn->remote_open_length = 0;
+ ea_list *attr = conn->bgp->p.ea_state;
+ if (conn == &conn->bgp->incoming_conn)
+ {
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_local_open_msg, 0, NULL, 0));
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_remote_open_msg, 0, NULL, 0));
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_sk, 0, NULL, 0));
+ }
+ else
+ {
+ ASSERT_DIE(conn == &conn->bgp->outgoing_conn);
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_local_open_msg, 0, NULL, 0));
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_remote_open_msg, 0, NULL, 0));
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_sk, 0, NULL, 0));
+ }
+ conn->bgp->p.ea_state = ea_lookup(conn->bgp->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&conn->bgp->p, attr);
+
mb_free(conn->local_caps);
conn->local_caps = NULL;
mb_free(conn->remote_caps);
bgp_dump_state_change(conn, conn->state, new_state);
conn->state = new_state;
+
+ if (conn == &conn->bgp->incoming_conn)
+ ea_set_attr(&conn->bgp->p.ea_state, EA_LITERAL_EMBEDDED(&ea_bgp_in_conn_state, 0, new_state));
+ else
+ {
+ ASSERT_DIE(conn == &conn->bgp->outgoing_conn);
+ ea_set_attr(&conn->bgp->p.ea_state, EA_LITERAL_EMBEDDED(&ea_bgp_out_conn_state, 0, new_state));
+ }
+ conn->bgp->p.ea_state = ea_lookup(conn->bgp->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&conn->bgp->p, conn->bgp->p.ea_state);
}
void
p->last_error_code = 0;
p->as4_session = conn->as4_session;
+ ea_set_attr(&p->p.ea_state, EA_LITERAL_EMBEDDED(&ea_bgp_as4_session, 0, conn->as4_session));
+ p->p.ea_state = ea_lookup(p->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&conn->bgp->p, conn->bgp->p.ea_state);
p->route_refresh = peer->route_refresh;
p->enhanced_refresh = local->enhanced_refresh && peer->enhanced_refresh;
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);
-#endif
}
static void
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_set_attr(&p->p.ea_state, EA_LITERAL_STORE_ADATA(&ea_bgp_close_bmp, 0, &to_ea.closing_struct, sizeof(to_ea)));
+ ea_set_attr(&p->p.ea_state, EA_LITERAL_EMBEDDED(&ea_bgp_close_bmp_set, 0, 1));
+ p->p.ea_state = ea_lookup(p->p.ea_state, 0, EALS_CUSTOM);
+
+ proto_announce_state_later(&p->p, p->p.ea_state);
+
+ //bmp_peer_down(p, p->last_error_class,
+ // conn->notify_code, conn->notify_subcode,
+ // conn->notify_data, conn->notify_size);
#endif
}
conn->hold_timer = tm_new_init(p->p.pool, bgp_hold_timeout, conn, 0, 0);
conn->keepalive_timer = tm_new_init(p->p.pool, bgp_keepalive_timeout, conn, 0, 0);
conn->send_hold_timer = tm_new_init(p->p.pool, bgp_send_hold_timeout, conn, 0, 0);
+
+ ea_list *attr = conn->bgp->p.ea_state;
+ if (conn == &conn->bgp->incoming_conn)
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_sk, 0, NULL, 0));
+ else
+ {
+ ASSERT_DIE(conn == &conn->bgp->outgoing_conn);
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_sk, 0, NULL, 0));
+ }
+ conn->bgp->p.ea_state = ea_lookup(conn->bgp->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&p->p, attr);
}
static void
s->err_hook = bgp_sock_err;
s->fast_rx = 1;
conn->sk = s;
+
+ struct bgp_conn_sk_ea sk_ea = {
+ .saddr = s->saddr,
+ .daddr = s->daddr,
+ .sport = s->sport,
+ .dport = s->dport
+ };
+
+ ea_list *attr = conn->bgp->p.ea_state;
+ if (conn == &conn->bgp->incoming_conn)
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_sk, 0, (byte*)(&sk_ea), sizeof(sk_ea)));
+ else
+ {
+ ASSERT_DIE(conn == &conn->bgp->outgoing_conn);
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_sk, 0, (byte*)(&sk_ea), sizeof(sk_ea)));
+ }
+ conn->bgp->p.ea_state = ea_lookup(conn->bgp->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&conn->bgp->p, attr);
}
static void
p->remote_id = 0;
p->link_addr = IPA_NONE;
+ ea_list *eal = p->p.ea_state;
+ 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)));
+
+ ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_out_conn_state, 0, BS_IDLE));
+ ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_in_conn_state, 0, BS_IDLE));
+
+ proto_announce_state(&p->p, eal);
+
/* Lock all channels when in GR recovery mode */
if (p->p.gr_recovery && p->cf->gr_mode)
{
/* 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;
}
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
/* 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));
+ p->p.ea_state = ea_lookup(p->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&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))
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));
+
+ ea_set_attr(&state, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_local_open_msg, 0, NULL, 0));
+ ea_set_attr(&state, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_remote_open_msg, 0, NULL, 0));
+ ea_set_attr(&state, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_local_open_msg, 0, NULL, 0));
+ ea_set_attr(&state, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_remote_open_msg, 0, NULL, 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)
{
conn->remote_open_msg = bgp_copy_open(p, pkt, len);
conn->remote_open_length = len - BGP_HEADER_LENGTH;
+ ea_list *attr = p->p.ea_state;
+ if (conn == &conn->bgp->incoming_conn)
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_remote_open_msg, 0, conn->remote_open_msg, conn->remote_open_length));
+ else
+ {
+ ASSERT_DIE(conn == &conn->bgp->outgoing_conn);
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_remote_open_msg, 0, conn->remote_open_msg, conn->remote_open_length));
+ }
+ p->p.ea_state = ea_lookup(p->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&p->p, attr);
+
if (bgp_read_options(conn, pkt+29, pkt[28], len-29) < 0)
return;
conn->ext_messages = conn->local_caps->ext_messages && caps->ext_messages;
p->remote_id = id;
+ ea_set_attr(&p->p.ea_state, EA_LITERAL_EMBEDDED(&ea_bgp_rem_id, 0, p->remote_id));
+
+ if (conn == &p->incoming_conn)
+ ea_set_attr(&p->p.ea_state, EA_LITERAL_EMBEDDED(&ea_bgp_as4_in_conn, 0, conn->as4_session));
+ else
+ {
+ ASSERT_DIE(conn == &p->outgoing_conn);
+ ea_set_attr(&p->p.ea_state, EA_LITERAL_EMBEDDED(&ea_bgp_as4_out_conn, 0, conn->as4_session));
+ }
+
+ p->p.ea_state = ea_lookup(p->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&p->p, p->p.ea_state);
+
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->local_open_msg = bgp_copy_open(p, buf, end - buf);
conn->local_open_length = end - buf - BGP_HEADER_LENGTH;
+ ea_list *attr = p->p.ea_state;
+ if (conn == &conn->bgp->incoming_conn)
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_in_conn_local_open_msg, 0, conn->local_open_msg, conn->local_open_length));
+ else
+ {
+ ASSERT_DIE(conn == &conn->bgp->outgoing_conn);
+ ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_bgp_out_conn_local_open_msg, 0, conn->local_open_msg, conn->local_open_length));
+ }
+ p->p.ea_state = ea_lookup(p->p.ea_state, 0, EALS_CUSTOM);
+ proto_announce_state_later(&p->p, attr);
+
return bgp_send(conn, PKT_OPEN, end - buf);
}
else if (s & (1 << PKT_KEEPALIVE))