mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-15 13:31:54 +00:00
commit before krt falling
This commit is contained in:
parent
0754e59d9b
commit
565cb46582
108
proto/bmp/bmp.c
108
proto/bmp/bmp.c
@ -561,6 +561,17 @@ bmp_add_table_exp_req(struct bmp_proto *p, rtable *tab)
|
|||||||
};
|
};
|
||||||
rt_export_subscribe(tab, all, &bt->out_req);
|
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);*/
|
||||||
|
|
||||||
return bt;
|
return bt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,11 +593,14 @@ bmp_remove_table(struct bmp_proto *p, struct bmp_table *bt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bmp_remove_table_rt(struct bmp_proto *p, struct bmp_table *bt)
|
bmp_remove_table_rt(struct bmp_proto *p, struct bmp_table *bt) // still falling in krt routes... The thread synchronization was maybe not needed...
|
||||||
{
|
{
|
||||||
log("removing table - bmp table %x chann %x, (subscr %x uc %x)",bt, bt->channel, &bt->channel->roa_subscriptions, &bt->uc);
|
log("removing table - bmp table %x chann %x, (subscr %x uc %x)",bt, bt->channel, &bt->channel->roa_subscriptions, &bt->uc);
|
||||||
channel_set_state(bt->channel, CS_STOP);
|
if (bt->channel)
|
||||||
channel_set_state(bt->channel, CS_DOWN);
|
{
|
||||||
|
channel_set_state(bt->channel, CS_STOP);
|
||||||
|
channel_set_state(bt->channel, CS_DOWN);
|
||||||
|
}
|
||||||
rt_export_unsubscribe(all, &bt->out_req);
|
rt_export_unsubscribe(all, &bt->out_req);
|
||||||
|
|
||||||
HASH_REMOVE(p->table_map, HASH_TABLE, bt);
|
HASH_REMOVE(p->table_map, HASH_TABLE, bt);
|
||||||
@ -596,16 +610,41 @@ bmp_remove_table_rt(struct bmp_proto *p, struct bmp_table *bt)
|
|||||||
|
|
||||||
log("free table %x", bt);
|
log("free table %x", bt);
|
||||||
mb_free(bt);
|
mb_free(bt);
|
||||||
|
//log("free done");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct bmp_table *bmp_get_table(struct bmp_proto *p, rtable *tab)
|
|
||||||
{ return bmp_find_table(p, tab) ?: bmp_add_table_exp_req(p, tab); }
|
|
||||||
|
|
||||||
static inline void bmp_lock_table(struct bmp_proto *p UNUSED, struct bmp_table *bt)
|
static inline void bmp_lock_table(struct bmp_proto *p UNUSED, struct bmp_table *bt)
|
||||||
{ bt->uc++; }
|
{ bt->uc++; }
|
||||||
|
|
||||||
|
struct bmp_table *bmp_get_table(struct bmp_proto *p, rtable *tab)
|
||||||
|
{
|
||||||
|
struct bmp_table *bt = bmp_find_table(p, tab);
|
||||||
|
if (bt)
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
atomic_int i = bt->uc;
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
struct bmp_table *new = bmp_add_table_exp_req(p, tab);
|
||||||
|
bmp_lock_table(p, new);
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
if (atomic_compare_exchange_strong_explicit(&bt->uc, &i, i+1, memory_order_acq_rel, memory_order_relaxed))
|
||||||
|
return bt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct bmp_table *new = bmp_add_table_exp_req(p, tab);
|
||||||
|
bmp_lock_table(p, new);
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void bmp_unlock_table(struct bmp_proto *p, struct bmp_table *bt)
|
static inline void bmp_unlock_table(struct bmp_proto *p, struct bmp_table *bt)
|
||||||
{ bt->uc--; if (!bt->uc) bmp_remove_table_rt(p, bt); } // TODO: should it be atomic?
|
{ atomic_int i = 1;
|
||||||
|
if (atomic_compare_exchange_strong_explicit(&bt->uc, &i, 0, memory_order_acq_rel, memory_order_relaxed))
|
||||||
|
bmp_remove_table_rt(p, bt);
|
||||||
|
else
|
||||||
|
bt->uc--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -640,7 +679,7 @@ bmp_add_stream(struct bmp_proto *p, struct bmp_peer *bp, u32 afi, bool policy, r
|
|||||||
HASH_INSERT(p->stream_map, HASH_STREAM, bs);
|
HASH_INSERT(p->stream_map, HASH_STREAM, bs);
|
||||||
|
|
||||||
bs->table = bmp_get_table(p, tab);
|
bs->table = bmp_get_table(p, tab);
|
||||||
bmp_lock_table(p, bs->table);
|
//bmp_lock_table(p, bs->table);
|
||||||
|
|
||||||
bs->sender = sender;
|
bs->sender = sender;
|
||||||
bs->sync = false;
|
bs->sync = false;
|
||||||
@ -717,11 +756,9 @@ bmp_add_peer(struct bmp_proto *p, ea_list *bgp_attr)
|
|||||||
static void
|
static void
|
||||||
bmp_remove_peer(struct bmp_proto *p, struct bmp_peer *bp)
|
bmp_remove_peer(struct bmp_proto *p, struct bmp_peer *bp)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
struct bmp_stream *bs, *bs_next;
|
struct bmp_stream *bs, *bs_next;
|
||||||
WALK_LIST_DELSAFE(bs, bs_next, bp->streams)
|
WALK_LIST_DELSAFE(bs, bs_next, bp->streams)
|
||||||
bmp_remove_stream(p, bs);
|
bmp_remove_stream(p, bs);//TODO//TODO//TODO
|
||||||
*/
|
|
||||||
|
|
||||||
HASH_REMOVE(p->peer_map, HASH_PEER, bp);
|
HASH_REMOVE(p->peer_map, HASH_PEER, bp);
|
||||||
|
|
||||||
@ -1146,17 +1183,43 @@ bmp_rt_notify(struct proto *P, struct channel *c, const net_addr *net,
|
|||||||
bmp_route_monitor_notify(p, bgp, bs, net, new, (new ?: old)->src);
|
bmp_route_monitor_notify(p, bgp, bs, net, new, (new ?: old)->src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
bmp_do_pre_policy(void *bt_)
|
||||||
|
{
|
||||||
|
struct bmp_table *bt = (struct bmp_table *)bt_;
|
||||||
|
struct bmp_proto *p = bt->p;
|
||||||
|
|
||||||
|
RT_FEED_WALK(&bt->in_req, f)
|
||||||
|
{
|
||||||
|
bool seen = 0;
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Strip the later attribute layers */
|
||||||
|
new.attrs = ea_strip_to(new.attrs, BIT32_ALL(EALS_PREIMPORT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bgp_next_hop_present(rte *n)
|
bgp_next_hop_present(const rte *n)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < n->attrs->count; i++)
|
for (int i = 0; i < n->attrs->count; i++)
|
||||||
{
|
{
|
||||||
eattr a = n->attrs->attrs[i];
|
eattr a = n->attrs->attrs[i];
|
||||||
const struct ea_class *class = ea_class_find(a.id);
|
const struct ea_class *class = ea_class_find(a.id);
|
||||||
log("ea class %s", class->name);
|
log("ea class %s", class->name);
|
||||||
//if (class == &(get_bgp_attr_table()[BA_NEXT_HOP].class)) //TODO
|
if (class == bgp_next_hop_ea_class)
|
||||||
// return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
log("BAD RTE, BAD.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1166,6 +1229,7 @@ bmp_rt_notify_exp_req(void *bt_)
|
|||||||
log("ok in notify exp req");
|
log("ok in notify exp req");
|
||||||
struct bmp_table *bt = (struct bmp_table *)bt_;
|
struct bmp_table *bt = (struct bmp_table *)bt_;
|
||||||
struct bmp_proto *p = bt->p;
|
struct bmp_proto *p = bt->p;
|
||||||
|
|
||||||
RT_EXPORT_WALK(&bt->out_req, u) //const struct rt_export_union *_u;
|
RT_EXPORT_WALK(&bt->out_req, u) //const struct rt_export_union *_u;
|
||||||
{
|
{
|
||||||
switch (u->kind)
|
switch (u->kind)
|
||||||
@ -1184,7 +1248,7 @@ bmp_rt_notify_exp_req(void *bt_)
|
|||||||
{
|
{
|
||||||
rte *new = &u->feed->block[i];
|
rte *new = &u->feed->block[i];
|
||||||
struct proto *rte_proto = (struct proto*) SKIP_BACK(struct proto, sources, new->src->owner);
|
struct proto *rte_proto = (struct proto*) SKIP_BACK(struct proto, sources, new->src->owner);
|
||||||
if (rte_proto->proto != &proto_bgp)
|
if (rte_proto->proto != &proto_bgp || !bgp_next_hop_present(new))
|
||||||
break;
|
break;
|
||||||
struct bgp_proto *bgp = (struct bgp_proto *) rte_proto;
|
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 *bc = (struct bgp_channel *) SKIP_BACK(struct channel, in_req, new->sender->req);
|
||||||
@ -1197,6 +1261,8 @@ bmp_rt_notify_exp_req(void *bt_)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log("bmp stream found feed, policy %i", bs->in_pre_policy);
|
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);
|
bmp_route_monitor_notify(p, bgp, bs, new->net, new, new->src);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1204,11 +1270,11 @@ bmp_rt_notify_exp_req(void *bt_)
|
|||||||
log("export update");
|
log("export update");
|
||||||
const rte *new = u->update->new;
|
const rte *new = u->update->new;
|
||||||
const rte *old = u->update->old;
|
const rte *old = u->update->old;
|
||||||
struct proto *rte_proto = (struct proto*) SKIP_BACK(struct proto, sources, new->src->owner);
|
struct proto *rte_proto = (struct proto*) SKIP_BACK(struct proto, sources, (new ?: old)->src->owner);
|
||||||
if (rte_proto->proto != &proto_bgp)
|
if (rte_proto->proto != &proto_bgp || !bgp_next_hop_present(new ?: old))
|
||||||
break;
|
break;
|
||||||
struct bgp_proto *bgp = (struct bgp_proto *) rte_proto;
|
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 *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);
|
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?
|
bool policy = (bc->c.table == src->c.table); //TODO?
|
||||||
struct bmp_stream *bs = bmp_find_stream(p, bgp, src->afi, policy);
|
struct bmp_stream *bs = bmp_find_stream(p, bgp, src->afi, policy);
|
||||||
@ -1218,7 +1284,9 @@ bmp_rt_notify_exp_req(void *bt_)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log("bmp stream found update");
|
log("bmp stream found update");
|
||||||
bmp_route_monitor_notify(p, bgp, bs, new->net, new, (new ?: old)->src);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log("end of notify fce");
|
log("end of notify fce");
|
||||||
@ -1314,6 +1382,7 @@ bmp_down(struct bmp_proto *p)
|
|||||||
{
|
{
|
||||||
ASSERT(p->started);
|
ASSERT(p->started);
|
||||||
p->started = false;
|
p->started = false;
|
||||||
|
log("_!p->peer_map.count (%i) && !p->stream_map.count (%i)&& !p->table_map.count(%i)", p->peer_map.count, p->stream_map.count, p->table_map.count);
|
||||||
|
|
||||||
TRACE(D_EVENTS, "BMP session closed");
|
TRACE(D_EVENTS, "BMP session closed");
|
||||||
|
|
||||||
@ -1326,6 +1395,7 @@ bmp_down(struct bmp_proto *p)
|
|||||||
HASH_WALK_END;
|
HASH_WALK_END;
|
||||||
|
|
||||||
/* Removing peers should also remove all streams and tables */ //TODO
|
/* Removing peers should also remove all streams and tables */ //TODO
|
||||||
|
log("!p->peer_map.count (%i) && !p->stream_map.count (%i)&& !p->table_map.count(%i)", p->peer_map.count, p->stream_map.count, p->table_map.count);
|
||||||
ASSERT(!p->peer_map.count && !p->stream_map.count && !p->table_map.count);
|
ASSERT(!p->peer_map.count && !p->stream_map.count && !p->table_map.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,9 +100,10 @@ struct bmp_table {
|
|||||||
struct bmp_table *next;
|
struct bmp_table *next;
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
struct rt_export_request out_req;
|
struct rt_export_request out_req;
|
||||||
|
struct rt_export_feeder in_req;
|
||||||
struct bmp_proto *p;
|
struct bmp_proto *p;
|
||||||
event event;
|
event event;
|
||||||
u32 uc;
|
atomic_int uc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user