mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
BMP: refactored lists and table locks to tlists
This commit is contained in:
parent
d5f01efbe6
commit
f1a04ce190
@ -583,11 +583,6 @@ bmp_add_table(struct bmp_proto *p, rtable *tab)
|
|||||||
static void
|
static void
|
||||||
bmp_remove_table(struct bmp_proto *p, struct bmp_table *bt)
|
bmp_remove_table(struct bmp_proto *p, struct bmp_table *bt)
|
||||||
{
|
{
|
||||||
if (bt->channel)
|
|
||||||
{
|
|
||||||
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);
|
||||||
@ -598,38 +593,10 @@ bmp_remove_table(struct bmp_proto *p, struct bmp_table *bt)
|
|||||||
mb_free(bt);
|
mb_free(bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bmp_lock_table(struct bmp_proto *p UNUSED, struct bmp_table *bt)
|
static inline struct bmp_table *
|
||||||
{ bt->uc++; }
|
|
||||||
|
|
||||||
struct bmp_table *
|
|
||||||
bmp_get_table(struct bmp_proto *p, rtable *tab)
|
bmp_get_table(struct bmp_proto *p, rtable *tab)
|
||||||
{
|
{
|
||||||
struct bmp_table *bt = bmp_find_table(p, tab);
|
return bmp_find_table(p, tab) ?: bmp_add_table(p, tab);
|
||||||
if (bt)
|
|
||||||
{
|
|
||||||
while (true) {
|
|
||||||
atomic_int i = bt->uc;
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
struct bmp_table *new = bmp_add_table(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(p, tab);
|
|
||||||
bmp_lock_table(p, new);
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bmp_unlock_table(struct bmp_proto *p, struct bmp_table *bt)
|
|
||||||
{ atomic_int i = 1;
|
|
||||||
if (atomic_compare_exchange_strong_explicit(&bt->uc, &i, 0, memory_order_acq_rel, memory_order_relaxed))
|
|
||||||
bmp_remove_table(p, bt);
|
|
||||||
else
|
|
||||||
bt->uc--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -674,10 +641,11 @@ bmp_add_stream(struct bmp_proto *p, struct bmp_peer *bp, u32 afi, bool policy, r
|
|||||||
bs->bgp = bp->bgp;
|
bs->bgp = bp->bgp;
|
||||||
bs->key = bmp_stream_key(afi, policy);
|
bs->key = bmp_stream_key(afi, policy);
|
||||||
|
|
||||||
add_tail(&bp->streams, &bs->n);
|
bmp_peer_stream_add_tail(&bp->streams, bs);
|
||||||
HASH_INSERT(p->stream_map, HASH_STREAM, bs);
|
HASH_INSERT(p->stream_map, HASH_STREAM, bs);
|
||||||
|
|
||||||
bs->table = bmp_get_table(p, tab);
|
struct bmp_table *bt = bmp_get_table(p, tab);
|
||||||
|
bmp_table_stream_add_tail(&bt->streams, bs);
|
||||||
|
|
||||||
bs->sender = sender;
|
bs->sender = sender;
|
||||||
bs->sync = false;
|
bs->sync = false;
|
||||||
@ -689,11 +657,13 @@ bmp_add_stream(struct bmp_proto *p, struct bmp_peer *bp, u32 afi, bool policy, r
|
|||||||
static void
|
static void
|
||||||
bmp_remove_stream(struct bmp_proto *p, struct bmp_stream *bs)
|
bmp_remove_stream(struct bmp_proto *p, struct bmp_stream *bs)
|
||||||
{
|
{
|
||||||
rem_node(&bs->n);
|
bmp_peer_stream_rem_node(bmp_peer_stream_enlisted(bs), bs);
|
||||||
HASH_REMOVE(p->stream_map, HASH_STREAM, bs);
|
HASH_REMOVE(p->stream_map, HASH_STREAM, bs);
|
||||||
|
|
||||||
bmp_unlock_table(p, bs->table);
|
SKIP_BACK_DECLARE(struct bmp_table, bt, streams, bmp_table_stream_enlisted(bs));
|
||||||
bs->table = NULL;
|
bmp_table_stream_rem_node(&bt->streams, bs);
|
||||||
|
if (EMPTY_TLIST(bmp_table_stream, &bt->streams))
|
||||||
|
bmp_remove_table(p, bt);
|
||||||
|
|
||||||
mb_free(bs);
|
mb_free(bs);
|
||||||
}
|
}
|
||||||
@ -723,7 +693,7 @@ bmp_add_peer(struct bmp_proto *p, ea_list *bgp_attr)
|
|||||||
}
|
}
|
||||||
bp->bgp = bgp_attr;
|
bp->bgp = bgp_attr;
|
||||||
|
|
||||||
init_list(&bp->streams);
|
bp->streams = (TLIST_LIST(bmp_peer_stream)) {};
|
||||||
|
|
||||||
HASH_INSERT(p->peer_map, HASH_PEER, bp);
|
HASH_INSERT(p->peer_map, HASH_PEER, bp);
|
||||||
|
|
||||||
@ -764,8 +734,7 @@ 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;
|
WALK_TLIST_DELSAFE(bmp_peer_stream, bs, &bp->streams)
|
||||||
WALK_LIST_DELSAFE(bs, bs_next, bp->streams)
|
|
||||||
bmp_remove_stream(p, bs);
|
bmp_remove_stream(p, bs);
|
||||||
|
|
||||||
HASH_REMOVE(p->peer_map, HASH_PEER, bp);
|
HASH_REMOVE(p->peer_map, HASH_PEER, bp);
|
||||||
@ -1115,7 +1084,7 @@ bmp_feed_end(struct rt_export_request *req)
|
|||||||
|
|
||||||
HASH_WALK(p->stream_map, next, bs)
|
HASH_WALK(p->stream_map, next, bs)
|
||||||
{
|
{
|
||||||
if ((bs->table == bt) && !bs->sync)
|
if ((bmp_table_stream_enlisted(bs) == &bt->streams) && !bs->sync)
|
||||||
{
|
{
|
||||||
bmp_route_monitor_end_of_rib(p, bs);
|
bmp_route_monitor_end_of_rib(p, bs);
|
||||||
bs->sync = true;
|
bs->sync = true;
|
||||||
@ -1377,8 +1346,7 @@ bmp_process_proto_state_change(struct bmp_proto *p, struct lfjour_item *last_up)
|
|||||||
* notifications from that peer. Therefore, peers established after BMP
|
* notifications from that peer. Therefore, peers established after BMP
|
||||||
* session are considered synced with empty RIB.
|
* session are considered synced with empty RIB.
|
||||||
*/
|
*/
|
||||||
struct bmp_stream *bs;
|
WALK_TLIST(bmp_peer_stream, bs, &bp->streams)
|
||||||
WALK_LIST(bs, bp->streams)
|
|
||||||
{
|
{
|
||||||
bmp_route_monitor_end_of_rib(p, bs);
|
bmp_route_monitor_end_of_rib(p, bs);
|
||||||
bs->sync = true;
|
bs->sync = true;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "nest/bird.h"
|
#include "nest/bird.h"
|
||||||
#include "nest/protocol.h"
|
#include "nest/protocol.h"
|
||||||
#include "lib/lists.h"
|
#include "lib/lists.h"
|
||||||
|
#include "lib/tlists.h"
|
||||||
#include "nest/route.h"
|
#include "nest/route.h"
|
||||||
#include "lib/event.h"
|
#include "lib/event.h"
|
||||||
#include "lib/hash.h"
|
#include "lib/hash.h"
|
||||||
@ -91,33 +92,46 @@ struct bmp_proto {
|
|||||||
byte msgbuf[BMP_MSGBUF_LEN]; // Buffer for preparing the messages before sending them out
|
byte msgbuf[BMP_MSGBUF_LEN]; // Buffer for preparing the messages before sending them out
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bmp_peer {
|
|
||||||
ea_list *bgp;
|
|
||||||
struct bmp_peer *next;
|
|
||||||
list streams;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmp_stream {
|
struct bmp_stream {
|
||||||
node n;
|
TLIST_NODE(bmp_peer_stream, struct bmp_stream) peer_node;
|
||||||
|
TLIST_NODE(bmp_table_stream, struct bmp_stream) table_node;
|
||||||
ea_list *bgp;
|
ea_list *bgp;
|
||||||
u32 key;
|
u32 key;
|
||||||
bool sync;
|
bool sync;
|
||||||
bool shutting_down;
|
bool shutting_down;
|
||||||
struct bmp_stream *next;
|
struct bmp_stream *next;
|
||||||
struct bmp_table *table;
|
|
||||||
ea_list *sender;
|
ea_list *sender;
|
||||||
int in_pre_policy;
|
int in_pre_policy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TLIST_PREFIX bmp_peer_stream
|
||||||
|
#define TLIST_TYPE struct bmp_stream
|
||||||
|
#define TLIST_ITEM peer_node
|
||||||
|
#define TLIST_WANT_ADD_TAIL
|
||||||
|
|
||||||
|
#include "lib/tlists.h"
|
||||||
|
|
||||||
|
#define TLIST_PREFIX bmp_table_stream
|
||||||
|
#define TLIST_TYPE struct bmp_stream
|
||||||
|
#define TLIST_ITEM table_node
|
||||||
|
#define TLIST_WANT_ADD_TAIL
|
||||||
|
|
||||||
|
#include "lib/tlists.h"
|
||||||
|
|
||||||
|
struct bmp_peer {
|
||||||
|
ea_list *bgp;
|
||||||
|
struct bmp_peer *next;
|
||||||
|
TLIST_LIST(bmp_peer_stream) streams;
|
||||||
|
};
|
||||||
|
|
||||||
struct bmp_table {
|
struct bmp_table {
|
||||||
rtable *table;
|
rtable *table;
|
||||||
struct bmp_table *next;
|
struct bmp_table *next;
|
||||||
struct channel *channel;
|
|
||||||
struct rt_export_request out_req;
|
struct rt_export_request out_req;
|
||||||
struct bmp_proto *p;
|
struct bmp_proto *p;
|
||||||
struct rt_export_feeder in_req;
|
struct rt_export_feeder in_req;
|
||||||
event event;
|
event event;
|
||||||
atomic_int uc;
|
TLIST_LIST(bmp_table_stream) streams;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user