diff --git a/proto/bmp/bmp.c b/proto/bmp/bmp.c index e52d2b85..f143203f 100644 --- a/proto/bmp/bmp.c +++ b/proto/bmp/bmp.c @@ -1253,48 +1253,73 @@ bgp_next_hop_present(const rte *n) return 0; } -void -solve_for_post_and_pre(struct bmp_proto *p, rte *new) +static void +solve_for_post_and_pre(struct bmp_proto *p, const rte *new, const rte *old) { 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 bgp_channel *src_ch = SKIP_BACK(struct bgp_channel, c.in_req, new->sender->req); + ASSERT_DIE(src_ch->c.proto == rte_proto); /* No pipes supported for now */ - struct bmp_stream *bs = bmp_find_stream(p, bgp, src->afi, false); - if (bs) + log("solve_for_post_and_pre %s", rte_proto->name); + + const net_addr *net = (new ?: old)->net; + struct rte_src *src = (new ?: old)->src; + + /* Ignore non-BGP routes */ + if (rte_proto->proto != &proto_bgp) + return; + + /* Checking the pre policy */ + if (p->monitoring_rib.in_pre_policy) { - 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); + /* Compute the pre policy attributes */ + ea_list *new_attrs = new ? ea_strip_to(new->attrs, BIT32_ALL(EALS_PREIMPORT)) : NULL; + ea_list *old_attrs = old ? ea_strip_to(old->attrs, BIT32_ALL(EALS_PREIMPORT)) : NULL; + + if (new_attrs != old_attrs) + { + /* The attributes are actually different, announce the change */ + if (ea_same(new_attrs, old_attrs)) + bug("Two attribute sets are same in the attribute cache."); + + struct bmp_stream *bs = bmp_find_stream(p, bgp, src_ch->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, net, new, src); + } + } } - bs = bmp_find_stream(p, bgp, src->afi, true); - if (bs) + + /* Checking the post policy */ + if (p->monitoring_rib.in_post_policy) { - 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); + /* Compute the post policy attributes */ + ea_list *new_attrs = new ? ea_normalize(new->attrs, 0) : NULL; + ea_list *old_attrs = old ? ea_normalize(old->attrs, 0) : NULL; + + /* TODO: filter only BGP-relevant attributes */ + + if ((new_attrs != old_attrs) || ea_same(new_attrs, old_attrs)) + { + /* The attributes are actually different, announce the change */ + struct bmp_stream *bs = bmp_find_stream(p, bgp, src_ch->afi, true); + 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, net, new, src); + } + } } - log("attrs out %x %s", new->attrs, rte_proto->name); } + static void bmp_check_routes(void *bt_) { @@ -1323,16 +1348,13 @@ bmp_check_routes(void *bt_) rte *new = &u->feed->block[i]; log("pre policy %i rte attr %x", p->monitoring_rib.in_pre_policy, new->attrs); - solve_for_post_and_pre(p, new); + solve_for_post_and_pre(p, new, NULL); } break; case RT_EXPORT_UPDATE: log("export update"); - 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)); + solve_for_post_and_pre(p, u->update->new, u->update->old); } } log("end of notify fce");