diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 4346cd5d..b7a9fe34 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1158,14 +1158,6 @@ bgp_attr_name(uint code) return (code < ARRAY_SIZE(bgp_attr_table)) ? bgp_attr_table[code].name : NULL; } -void bgp_fix_attr_flags(ea_list *attrs) -{ - for (u8 i = 0; i < attrs->count; i++) - { - attrs->attrs[i].flags = bgp_attr_table[EA_ID(attrs->attrs[i].id)].flags; - } -} - /* * Attribute export */ @@ -1645,6 +1637,9 @@ bgp_defer_bucket(struct bgp_channel *c, struct bgp_bucket *b) void bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b) { + if (b->bmp) + return; + struct bgp_proto *p = (void *) c->c.proto; struct bgp_bucket *wb = bgp_get_withdraw_bucket(c); @@ -1724,6 +1719,14 @@ bgp_get_prefix(struct bgp_channel *c, net_addr *net, u32 path_id) void bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px) { + /* BMP hack */ + if ( + !NODE_VALID(px->buck_node.prev) && + !NODE_VALID(px->buck_node.next) && + !SKIP_BACK(struct bgp_bucket, prefixes.head, px->buck_node.prev)->bmp + ) + return; + rem_node(&px->buck_node); HASH_REMOVE2(c->prefix_hash, PXH, c->pool, px); diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index f8146bdf..bfe24bcb 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -125,7 +125,9 @@ #include "lib/string.h" #include "bgp.h" +#ifdef CONFIG_BMP #include "proto/bmp/bmp.h" +#endif static list STATIC_LIST_INIT(bgp_sockets); /* Global list of listening sockets */ @@ -694,8 +696,11 @@ 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); +#endif } static void @@ -708,9 +713,11 @@ bgp_conn_leave_established_state(struct bgp_conn *conn, struct bgp_proto *p) if (p->p.proto_state == PS_UP) 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); +#endif } void diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 2e95037c..9fc5b964 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -414,6 +414,7 @@ struct bgp_bucket { struct bgp_bucket *next; /* Node in bucket hash table */ list prefixes; /* Prefixes in this bucket (struct bgp_prefix) */ u32 hash; /* Hash over extended attributes */ + u32 bmp:1; /* Temporary bucket for BMP encoding */ ea_list eattrs[0]; /* Per-bucket extended attributes */ }; @@ -440,7 +441,6 @@ struct bgp_write_state { int as4_session; int add_path; int mpls; - int sham; eattr *mp_next_hop; const adata *mpls_labels; @@ -557,8 +557,6 @@ void bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code void bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len); const char *bgp_format_role_name(u8 role); -void bgp_fix_attr_flags(ea_list *attrs); - static inline int rte_resolvable(rte *rt) { diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index b7df5a7a..1dd49ae1 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -26,7 +26,9 @@ #include "nest/cli.h" #include "bgp.h" +#ifdef CONFIG_BMP #include "proto/bmp/bmp.h" +#endif #define BGP_RR_REQUEST 0 @@ -1578,10 +1580,7 @@ bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu memcpy(pos, &a, b); ADVANCE(pos, size, b); - if (!s->sham) - bgp_free_prefix(s->channel, px); - else - rem_node(&px->buck_node); + bgp_free_prefix(s->channel, px); } return pos - buf; @@ -1666,10 +1665,7 @@ bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu memcpy(pos, &a, b); ADVANCE(pos, size, b); - if (!s->sham) - bgp_free_prefix(s->channel, px); - else - rem_node(&px->buck_node); + bgp_free_prefix(s->channel, px); } return pos - buf; @@ -1757,10 +1753,7 @@ bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b memcpy(pos, &a, b); ADVANCE(pos, size, b); - if (!s->sham) - bgp_free_prefix(s->channel, px); - else - rem_node(&px->buck_node); + bgp_free_prefix(s->channel, px); } return pos - buf; @@ -1857,10 +1850,7 @@ bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b memcpy(pos, &a, b); ADVANCE(pos, size, b); - if (!s->sham) - bgp_free_prefix(s->channel, px); - else - rem_node(&px->buck_node); + bgp_free_prefix(s->channel, px); } return pos - buf; @@ -1947,10 +1937,7 @@ bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte * memcpy(pos, net->data, flen); ADVANCE(pos, size, flen); - if (!s->sham) - bgp_free_prefix(s->channel, px); - else - rem_node(&px->buck_node); + bgp_free_prefix(s->channel, px); } return pos - buf; @@ -2042,10 +2029,7 @@ bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte * memcpy(pos, net->data, flen); ADVANCE(pos, size, flen); - if (!s->sham) - bgp_free_prefix(s->channel, px); - else - rem_node(&px->buck_node); + bgp_free_prefix(s->channel, px); } return pos - buf; @@ -2289,8 +2273,7 @@ bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu if (la < 0) { /* Attribute list too long */ - if (!s->sham) - bgp_withdraw_bucket(s->channel, buck); + bgp_withdraw_bucket(s->channel, buck); return NULL; } @@ -2337,8 +2320,7 @@ bgp_create_mp_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu if (la < 0) { /* Attribute list too long */ - if (!s->sham) - bgp_withdraw_bucket(s->channel, buck); + bgp_withdraw_bucket(s->channel, buck); return NULL; } @@ -2430,9 +2412,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck, byte *res = NULL; /* FIXME: must be a bit shorter */ - struct lp_state tmpp; - lp_save(tmp_linpool, &tmpp); - struct bgp_caps *peer = p->conn->remote_caps; const struct bgp_af_caps *rem = bgp_find_af_caps(peer, c->afi); @@ -2444,7 +2423,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck, .as4_session = 1, .add_path = c->add_path_rx, .mpls = c->desc->mpls, - .sham = 1, }; if (!update) @@ -2460,8 +2438,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck, bgp_create_mp_reach(&s, buck, buf, end); } - lp_restore(tmp_linpool, &tmpp); - return res; } @@ -2487,17 +2463,19 @@ bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n, uint bucket_size = sizeof(struct bgp_bucket) + ea_size; uint prefix_size = sizeof(struct bgp_prefix) + n->length; - /* Sham bucket */ - struct bgp_bucket *b = alloca(bucket_size); - *b = (struct bgp_bucket) { }; + struct lp_state tmpp; + lp_save(tmp_linpool, &tmpp); + + /* Temporary bucket */ + struct bgp_bucket *b = tmp_allocz(bucket_size); + b->bmp = 1; init_list(&b->prefixes); if (attrs) memcpy(b->eattrs, attrs, ea_size); - /* Sham prefix */ - struct bgp_prefix *px = alloca(prefix_size); - *px = (struct bgp_prefix) { }; + /* Temporary prefix */ + struct bgp_prefix *px = tmp_allocz(prefix_size); px->path_id = (u32) src->private_id; net_copy(px->net, n); add_tail(&b->prefixes, &px->buck_node); @@ -2507,6 +2485,8 @@ bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n, if (end) bgp_bmp_prepare_bgp_hdr(buf, end - buf, PKT_UPDATE); + lp_restore(tmp_linpool, &tmpp); + return end; }