From c32ce0f7997914e6e3d4d75a76c32ba9644c483e Mon Sep 17 00:00:00 2001 From: Katerina Kubecova Date: Thu, 19 Sep 2024 09:54:06 +0200 Subject: [PATCH] without ea_normalize wrong, with it falls --- lib/route.h | 3 +- nest/proto.c | 3 +- nest/rt-attr.c | 6 ++ proto/bgp/attrs.c | 6 +- proto/bgp/bgp.c | 5 ++ proto/bgp/packets.c | 7 +- proto/bmp/bmp.c | 175 ++++++++++++++++++++++++++++---------------- proto/bmp/bmp.h | 2 +- 8 files changed, 136 insertions(+), 71 deletions(-) diff --git a/lib/route.h b/lib/route.h index d14d336c..b891a810 100644 --- a/lib/route.h +++ b/lib/route.h @@ -469,7 +469,8 @@ extern struct ea_class ea_gen_mpls_label, /* protocol journal attributes */ extern struct ea_class ea_name, ea_protocol_name, ea_protocol_type, ea_table, ea_state, ea_old_state, ea_last_modified, ea_info, ea_proto_id, - ea_channel_id, ea_deleted, ea_bgp_conn, ea_bgp_in_conn, ea_bgp_out_conn, ea_rtable, ea_bgp_afi; + ea_channel_id, ea_deleted, ea_bgp_conn, ea_bgp_in_conn, ea_bgp_out_conn, ea_rtable, ea_bgp_afi, + ea_in_keep; /* 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_local_open_msg, ea_bgp_remote_open_msg, ea_bgp_local_open_msg_len, ea_bgp_remote_open_msg_len, diff --git a/nest/proto.c b/nest/proto.c index 5bdec8eb..a30f9826 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -3018,7 +3018,7 @@ channel_state_to_eattr(struct channel *ch, int proto_deleting) { struct { ea_list l; - eattr a[6]; + eattr a[7]; } eattrs; eattrs.l = (ea_list) {}; @@ -3027,6 +3027,7 @@ channel_state_to_eattr(struct channel *ch, int proto_deleting) eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_id, 0, ch->proto->id); eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_channel_id, 0, ch->id); eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_deleted, 0, proto_deleting); + eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_in_keep, 0, ch->in_keep); eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_PTR(&ea_rtable, 0, ch->table); log("ea_rtable added (%x), eattrs %x, str %x", ch->table, eattrs.l, eattrs.a[0].u.ad->data); diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 66c09cbc..fdf31445 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -1915,6 +1915,11 @@ struct ea_class ea_channel_id = { .type = T_INT, }; +struct ea_class ea_in_keep = { + .name = "channel_in_keep", + .type = T_INT, +}; + struct ea_class ea_bgp_rem_id = { .name = "proto_bgp_rem_id", .type = T_INT, @@ -2053,6 +2058,7 @@ rta_init(void) ea_register_init(&ea_proto_id); ea_register_init(&ea_channel_id); ea_register_init(&ea_deleted); + ea_register_init(&ea_in_keep); /* Protocol bgp attributes */ ea_register_init(&ea_bgp_rem_id); diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 26682981..726374ba 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1320,7 +1320,6 @@ bgp_export_attrs(struct bgp_export_state *s, ea_list *a) static inline int bgp_encode_attr(struct bgp_write_state *s, eattr *a, byte *buf, uint size) { - log("size %i %x", size, a->type); const union bgp_attr_desc *desc = bgp_find_attr_desc(a); if (s->ignore_non_bgp_attrs == 0) ASSERT_DIE(desc); @@ -1348,10 +1347,10 @@ bgp_encode_attrs(struct bgp_write_state *s, ea_list *attrs, byte *buf, byte *end byte *pos = buf; int i, len; + log("attrs count %i", attrs->count); for (i = 0; i < attrs->count; i++) { len = bgp_encode_attr(s, &attrs->attrs[i], pos, end - pos); - if (len < 0) return -1; @@ -1815,7 +1814,10 @@ bgp_done_prefix(struct bgp_ptx_private *c, struct bgp_prefix *px, struct bgp_buc { /* BMP hack */ if (buck->bmp) + { + rem_node(&px->buck_node); return; + } /* Cleanup: We're called from bucket senders. */ ASSERT_DIE(px->cur == buck); diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 8b7b04c1..633935bf 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -1767,6 +1767,11 @@ bgp_start(struct proto *P) p->remote_id = 0; p->link_addr = IPA_NONE; + ea_list *eal = proto_state_table->attrs[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)); + proto_journal_state_push(eal, &p->p, 1); /* Lock all channels when in GR recovery mode */ if (p->p.gr_recovery && p->cf->gr_mode) diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 46a228f8..7a2c4c94 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -1047,6 +1047,9 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len) conn->as4_session = conn->local_caps->as4_support && caps->as4_support; conn->ext_messages = conn->local_caps->ext_messages && caps->ext_messages; p->remote_id = id; + ea_list *eal = proto_state_table->attrs[p->p.id]; + ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_bgp_rem_id, 0, p->remote_id)); + proto_journal_state_push(eal, &p->p, 1); 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); @@ -1605,6 +1608,7 @@ bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX)) { + log("list_length(buck->prefixes) %i size %i >= BGP_NLRI_MAX %i", list_length(&buck->prefixes), size, BGP_NLRI_MAX); struct bgp_prefix *px = HEAD(buck->prefixes); struct net_addr_ip4 *net = NET_PTR_IP4(&px->ni->addr[0]); @@ -2329,6 +2333,7 @@ bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu lr = bgp_encode_nlri(s, buck, buf+4+la, end); + log("buf+4+la+lr = %i %i %i %i", buf, 4, la, lr); return buf+4+la+lr; } @@ -2487,7 +2492,7 @@ bgp_create_update_bmp(ea_list *channel_ea, struct bgp_proto *bgp_p, byte *buf, s .mp_reach = (c->afi != BGP_AF_IPV4) || rem->ext_next_hop, .as4_session = 1, .add_path = c->add_path_rx, - .mpls = c->desc->mpls, //this is problem, but we can have proto. What about find correct channel in proto? TODO + .mpls = c->desc->mpls, .ignore_non_bgp_attrs = 1, }; log("next hop %x (0)", s.mp_next_hop); diff --git a/proto/bmp/bmp.c b/proto/bmp/bmp.c index 6ff5df31..e52d2b85 100644 --- a/proto/bmp/bmp.c +++ b/proto/bmp/bmp.c @@ -217,7 +217,8 @@ static const struct ea_class *bgp_next_hop_ea_class = NULL; static void bmp_connected(struct birdsock *sk); static void bmp_sock_err(sock *sk, int err); static void bmp_close_socket(struct bmp_proto *p); -static void bmp_rt_notify_exp_req(void *p_); +static void bmp_check_routes(void *bt_); +static void bmp_do_pre_policy(void *bt_); static void bmp_send_peer_up_notif_msg(struct bmp_proto *p, ea_list *bgp, @@ -285,6 +286,9 @@ bmp_schedule_tx_packet(struct bmp_proto *p, const byte *payload, const size_t si log("tx_data %x data %x", tx_data, tx_data->data); memcpy(tx_data->data, payload, size); tx_data->data_size = size; + log("schedule tx packet size %i", size); + if (size > 5000) + log("too big"); add_tail(&p->tx_queue, &tx_data->n); if (sk_tx_buffer_empty(p->sk) @@ -541,9 +545,11 @@ bmp_add_table_exp_req(struct bmp_proto *p, rtable *tab) HASH_INSERT(p->table_map, HASH_TABLE, bt); - bt->event.hook = bmp_rt_notify_exp_req; bt->event.data = bt; + log("name %s post %i pre %i", p->p.name, p->monitoring_rib.in_post_policy, p->monitoring_rib.in_pre_policy); + //if(p->monitoring_rib.in_post_policy){ + bt->event.hook = bmp_check_routes; bt->out_req = (struct rt_export_request) { .name = mb_sprintf(p->p.pool, "%s.exp_request", p->p.name), .r = (struct lfjour_recipient) { @@ -559,19 +565,7 @@ bmp_add_table_exp_req(struct bmp_proto *p, rtable *tab) //.dump = channel_dump_export_req, //.fed = channel_export_fed, }; - rt_export_subscribe(tab, all, &bt->out_req); - - /*bt->in_req = (struct rt_export_feeder) { - .name = mb_sprintf(p->p.pool, "%s.imp_request", p->p.name), - .trace_routes = c->debug, - .next_feed_index = channel_reimport_next_feed_index, - }; - bt->reimport_event = (event) { - .hook = bmp_do_pre_policy, - .data = bt, - }; - rt_feeder_subscribe(&c->table->export_all, &bt->in_req);*/ - + rt_export_subscribe(tab, all, &bt->out_req);//} return bt; } @@ -601,7 +595,10 @@ bmp_remove_table_rt(struct bmp_proto *p, struct bmp_table *bt) // still falling channel_set_state(bt->channel, CS_STOP); channel_set_state(bt->channel, CS_DOWN); } - rt_export_unsubscribe(all, &bt->out_req); + //if (p->monitoring_rib.in_post_policy) + rt_export_unsubscribe(all, &bt->out_req); + //else + //rt_feeder_unsubscribe(&bt->in_req); HASH_REMOVE(p->table_map, HASH_TABLE, bt); @@ -654,8 +651,8 @@ static inline void bmp_unlock_table(struct bmp_proto *p, struct bmp_table *bt) static inline u32 bmp_stream_key(u32 afi, bool policy) { return afi ^ (policy ? BMP_STREAM_KEY_POLICY : 0); } -static inline u32 bmp_stream_afi(struct bmp_stream *bs) -{ return bs->key & ~BMP_STREAM_KEY_POLICY; } +//static inline u32 bmp_stream_afi(struct bmp_stream *bs) +//{ return bs->key & ~BMP_STREAM_KEY_POLICY; } static inline bool bmp_stream_policy(struct bmp_stream *bs) { return !!(bs->key & BMP_STREAM_KEY_POLICY); } @@ -665,6 +662,7 @@ bmp_find_stream(struct bmp_proto *p, const struct bgp_proto *bgp, u32 afi, bool { ea_list *bgp_attr = proto_state_table->attrs[bgp->p.id]; return HASH_FIND(p->stream_map, HASH_STREAM, bgp_attr, bmp_stream_key(afi, policy)); + } static struct bmp_stream * @@ -741,13 +739,29 @@ bmp_add_peer(struct bmp_proto *p, ea_list *bgp_attr) { log("chan_attr in bmp_add_peer %i, attrs %i", chan_attr, chan_attr->attrs); rtable *ch_table = (rtable *) ea_get_ptr(chan_attr->attrs, &ea_rtable, 0); + const char *name = ea_get_adata(chan_attr->attrs, &ea_name)->data; + int in_keep = ea_get_int(chan_attr->attrs, &ea_in_keep, 0); + + log("name %s ch_table %i first if %i second if %i in keep %i", name, ch_table, p->monitoring_rib.in_pre_policy, p->monitoring_rib.in_post_policy, in_keep); + - log("name %i ch_table %i first if %i second if %i", &ch_table->name, ch_table, p->monitoring_rib.in_pre_policy, p->monitoring_rib.in_post_policy); if (p->monitoring_rib.in_pre_policy && ch_table) - bmp_add_stream(p, bp, ea_get_int(chan_attr->attrs, &ea_bgp_afi, 0), false, ch_table, chan_attr->attrs, 1); + { + log("in pre"); + if (in_keep == RIK_PREFILTER) + { + log("add stream in keep %i", in_keep); + bmp_add_stream(p, bp, ea_get_int(chan_attr->attrs, &ea_bgp_afi, 0), false, ch_table, chan_attr->attrs, 1); + } + else + log(L_WARN "%s: Try to do pre policy with disabled import tables (channel %s)", p->p.name, name); + } if (p->monitoring_rib.in_post_policy && ch_table) + { + log("in post"); bmp_add_stream(p, bp, ea_get_int(chan_attr->attrs, &ea_bgp_afi, 0), true, ch_table, chan_attr->attrs, 0); + } } return bp; @@ -893,6 +907,7 @@ bmp_is_peer_global_instance(ea_list *bgp) int peer_type = ea_get_int(bgp, &ea_bgp_peer_type, 0); int local_as = ea_get_int(bgp, &ea_bgp_loc_as, 0); int remote_as = ea_get_int(bgp, &ea_bgp_rem_as, 0); + log("bmp_is_peer_global_instance loc as %i rem as %i peer_type %i (constants BGP_PT_EXTERNAL %i, BGP_PT_INTERNAL %i)", local_as, remote_as, peer_type, BGP_PT_EXTERNAL, BGP_PT_INTERNAL); return (peer_type != BGP_PT_EXTERNAL && peer_type != BGP_PT_INTERNAL) ? (local_as != remote_as) @@ -914,6 +929,7 @@ bmp_send_peer_up_notif_msg(struct bmp_proto *p, ea_list *bgp, const int rem_as = ea_get_int(bgp, &ea_bgp_rem_as, 0); const int rem_id = ea_get_int(bgp, &ea_bgp_rem_id, 0); + log("bmp_send_peer_up_notif_msg rem_as %i rem_id %i", rem_as, rem_id); const bool is_global_instance_peer = bmp_is_peer_global_instance(bgp); buffer payload = bmp_buffer_alloc(p->buffer_mpool, DEFAULT_MEM_BLOCK_SIZE); bmp_peer_up_notif_msg_serialize(&payload, is_global_instance_peer, @@ -933,6 +949,7 @@ bmp_route_monitor_put_update(struct bmp_proto *p, struct bmp_stream *bs, const b log("upd_msg %x, data %x", upd_msg, upd_msg->data); memcpy(upd_msg->data, data, length); upd_msg->data_size = length; + add_tail(&p->update_msg_queue, &upd_msg->n); /* Save some metadata */ @@ -953,6 +970,7 @@ static void bmp_route_monitor_notify(struct bmp_proto *p, struct bgp_proto *bgp_p, struct bmp_stream *bs, const net_addr *n, const struct rte *new, const struct rte_src *src) { + log("notified"); byte buf[BGP_MAX_EXT_MSG_LENGTH]; byte *end = bgp_bmp_encode_rte(bs->sender, bgp_p, buf, n, new, src); @@ -1184,30 +1202,41 @@ bmp_rt_notify(struct proto *P, struct channel *c, const net_addr *net, } -static void +/*static void bmp_do_pre_policy(void *bt_) { + log("do pre policy"); struct bmp_table *bt = (struct bmp_table *)bt_; struct bmp_proto *p = bt->p; RT_FEED_WALK(&bt->in_req, f) { bool seen = 0; + log("count rout %i", f->count_routes); for (uint i = 0; i < f->count_routes; i++) { rte *r = &f->block[i]; if (r->flags & REF_OBSOLETE) break; - } - rte new = rte_init_from(r); + rte new = rte_init_from(r); - /* Strip the later attribute layers */ - new.attrs = ea_strip_to(new.attrs, BIT32_ALL(EALS_PREIMPORT)); + // Strip the later attribute layers + new.attrs = ea_strip_to(new.attrs, BIT32_ALL(EALS_PREIMPORT)); + struct proto *rte_proto = (struct proto*) SKIP_BACK(struct proto, sources, new.src->owner); + if (rte_proto->proto != &proto_bgp || !bgp_next_hop_present(new)) + break; + struct bgp_proto *bgp = (struct bgp_proto *) rte_proto; + struct bgp_channel *bc = (struct bgp_channel *) SKIP_BACK(struct channel, in_req, new.sender->req); + struct bgp_channel *src = SKIP_BACK(struct bgp_channel, c.in_req, new.sender->req); + bool policy = (bc->c.table == src->c.table); //TODO? + struct bmp_stream *bs = bmp_find_stream(p, bgp, src->afi, policy); + + bmp_route_monitor_notify(p, bgp, bs, new.net, &new, new.src); } } -} +}*/ int bgp_next_hop_present(const rte *n) @@ -1224,15 +1253,58 @@ bgp_next_hop_present(const rte *n) return 0; } -static void -bmp_rt_notify_exp_req(void *bt_) +void +solve_for_post_and_pre(struct bmp_proto *p, rte *new) { - log("ok in notify exp req"); + struct proto *rte_proto = (struct proto*) SKIP_BACK(struct proto, sources, new->src->owner); + log("solve_for_post_and_pre %s", rte_proto->name); + new->attrs = ea_normalize(new->attrs, 0); + log("after normalize ea_list %x, new %x", new->attrs, new); + log("new next %x", new->attrs->next); + if (rte_proto->proto != &proto_bgp || !bgp_next_hop_present(new)){ + log("CONTINUED %s rte_proto->proto %x!= &proto_bgp %x || !bgp_next_hop_present(new %x) %i", rte_proto->proto->name, rte_proto->proto, &proto_bgp, new, !bgp_next_hop_present(new)); + return; + } + + struct bgp_channel *bc = (struct bgp_channel *) SKIP_BACK(struct channel, in_req, new->sender->req); + struct bgp_proto *bgp = (struct bgp_proto *) rte_proto; + struct bgp_channel *src = SKIP_BACK(struct bgp_channel, c.in_req, new->sender->req); + + struct bmp_stream *bs = bmp_find_stream(p, bgp, src->afi, false); + if (bs) + { + log("s true bmp stream found feed, pre policy %i proto %s", bs->in_pre_policy, p->p.name); + if (bmp_find_peer(p, proto_state_table->attrs[bgp->p.id]) == NULL) + bug("not implemented"); + bmp_route_monitor_notify(p, bgp, bs, new->net, new, new->src); + } + bs = bmp_find_stream(p, bgp, src->afi, true); + if (bs) + { + if (bc->c.in_keep != RIK_PREFILTER){ + log("CONTINUED bc->c.in_keep != RIK_PREFILTER"); + return; + } + log("s false bmp stream found feed, pre policy %i proto %s", bs->in_pre_policy, p->p.name); + if (bmp_find_peer(p, proto_state_table->attrs[bgp->p.id]) == NULL) + bug("not implemented"); + new->attrs = ea_strip_to(new->attrs, BIT32_ALL(EALS_PREIMPORT)); + if (new->attrs == NULL) + bug("Null attrs after ea_strip. This should never happen, because we checked the import table is enabled."); + bmp_route_monitor_notify(p, bgp, bs, new->net, new, new->src); + } + log("attrs out %x %s", new->attrs, rte_proto->name); +} +static void +bmp_check_routes(void *bt_) +{ + log("bmp_check_routes"); struct bmp_table *bt = (struct bmp_table *)bt_; struct bmp_proto *p = bt->p; RT_EXPORT_WALK(&bt->out_req, u) //const struct rt_export_union *_u; { + log("feeder %x rte ptr %x", &bt->out_req, u); switch (u->kind) { case RT_EXPORT_STOP: @@ -1245,49 +1317,22 @@ bmp_rt_notify_exp_req(void *bt_) oldpos++; /* Send updates one after another */ + log("oldpos %i", oldpos); for (uint i = 0; i < oldpos; i++) { rte *new = &u->feed->block[i]; - struct proto *rte_proto = (struct proto*) SKIP_BACK(struct proto, sources, new->src->owner); - if (rte_proto->proto != &proto_bgp || !bgp_next_hop_present(new)) - break; - struct bgp_proto *bgp = (struct bgp_proto *) rte_proto; - struct bgp_channel *bc = (struct bgp_channel *) SKIP_BACK(struct channel, in_req, new->sender->req); - struct bgp_channel *src = SKIP_BACK(struct bgp_channel, c.in_req, new->sender->req); - bool policy = (bc->c.table == src->c.table); //TODO? - struct bmp_stream *bs = bmp_find_stream(p, bgp, src->afi, policy); - if (!bs) - { - log("bmp stream not found in p %i", p); - return; - } - log("bmp stream found feed, policy %i", bs->in_pre_policy); - if (bmp_find_peer(p, proto_state_table->attrs[bgp->p.id]) == NULL) - bug("not implemented"); - bmp_route_monitor_notify(p, bgp, bs, new->net, new, new->src); + log("pre policy %i rte attr %x", p->monitoring_rib.in_pre_policy, new->attrs); + + solve_for_post_and_pre(p, new); } break; case RT_EXPORT_UPDATE: log("export update"); - const rte *new = u->update->new; - const rte *old = u->update->old; - struct proto *rte_proto = (struct proto*) SKIP_BACK(struct proto, sources, (new ?: old)->src->owner); - if (rte_proto->proto != &proto_bgp || !bgp_next_hop_present(new ?: old)) - break; - struct bgp_proto *bgp = (struct bgp_proto *) rte_proto; - struct bgp_channel *bc = (struct bgp_channel *) SKIP_BACK(struct channel, in_req, (new ?: old)->sender->req); - struct bgp_channel *src = SKIP_BACK(struct bgp_channel, c.in_req, (new ?: old)->sender->req); - bool policy = (bc->c.table == src->c.table); //TODO? - struct bmp_stream *bs = bmp_find_stream(p, bgp, src->afi, policy); - if (!bs) - { - log("bmp stream not found in p %i", p); - return; - } - log("bmp stream found update"); - if (bmp_find_peer(p, proto_state_table->attrs[bgp->p.id]) == NULL) - bug("not implemented"); - bmp_route_monitor_notify(p, bgp, bs, (new ?: old)->net, new, (new ?: old)->src); + rte *new = u->update->new; + rte *old = u->update->old; + log("attrs %x", new? new->attrs:1); + + solve_for_post_and_pre(p, (new ?: old)); } } log("end of notify fce"); diff --git a/proto/bmp/bmp.h b/proto/bmp/bmp.h index cb317748..ec7d65cd 100644 --- a/proto/bmp/bmp.h +++ b/proto/bmp/bmp.h @@ -100,8 +100,8 @@ struct bmp_table { struct bmp_table *next; struct channel *channel; struct rt_export_request out_req; - struct rt_export_feeder in_req; struct bmp_proto *p; + struct rt_export_feeder in_req; event event; atomic_int uc; };