summaryrefslogtreecommitdiff
path: root/proto/bmp/bmp.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2023-06-08 04:56:41 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2023-06-08 05:03:15 +0200
commite8838d930cd5c875f32aa2b7da5d84995b14ccac (patch)
tree4cb70981a898dd1d294e6074399a76a6ab679537 /proto/bmp/bmp.c
parent0799fc99abb523432bc3f903f6a32eafbe37d043 (diff)
BMP: Support multiple instances of BMP protocol
Add internal BMP functions with plicit bmp_proto *p as first argument, which allows using TRACE() macro. Keep list of BMP instances and call internal functions. Old BMP functions are wrappers that call internal functions for all enabled BMP instances. Extract End-of-RIB mark into separate function. Based on patch from Michal Zagorski <mzagorsk@akamai.com>. Thanks!
Diffstat (limited to 'proto/bmp/bmp.c')
-rw-r--r--proto/bmp/bmp.c168
1 files changed, 110 insertions, 58 deletions
diff --git a/proto/bmp/bmp.c b/proto/bmp/bmp.c
index 5c261584..aed9d9d6 100644
--- a/proto/bmp/bmp.c
+++ b/proto/bmp/bmp.c
@@ -56,8 +56,8 @@
#include "nest/iface.h"
#include "nest/route.h"
-// We allow for single instance of BMP protocol
-static struct bmp_proto *g_bmp;
+// List of BMP instances
+static list STATIC_LIST_INIT(bmp_proto_list);
/* BMP Common Header [RFC 7854 - Section 4.1] */
enum bmp_version {
@@ -214,7 +214,7 @@ struct bmp_data_node {
};
static void
-bmp_route_monitor_pre_policy_table_in_snapshot(struct bgp_channel *c);
+bmp_route_monitor_pre_policy_table_in_snapshot(struct bmp_proto *p, struct bgp_channel *c);
static void
bmp_common_hdr_serialize(buffer *stream, const enum bmp_message_type type, const u32 data_size)
@@ -447,16 +447,16 @@ bmp_peer_down_notif_msg_serialize(buffer *stream, const bool is_peer_global,
bmp_put_data(stream, data, data_size);
}
-void
-bmp_peer_up(const struct bgp_proto *bgp,
+static void
+bmp_peer_up_(struct bmp_proto *p, const struct bgp_proto *bgp,
const byte *tx_open_msg, uint tx_open_length,
const byte *rx_open_msg, uint rx_open_length)
{
- struct bmp_proto *p = g_bmp;
-
- if (!p || !p->started)
+ if (!p->started)
return;
+ TRACE(D_STATES, "Peer up for %s", bgp->p.name);
+
// struct bmp_peer_map_key key = bmp_peer_map_key_create(bgp->remote_ip, bgp->remote_as);
// bmp_peer_map_insert(&p->bgp_peers, key, (const byte *) &bgp, sizeof (bgp));
@@ -464,11 +464,21 @@ bmp_peer_up(const struct bgp_proto *bgp,
struct bgp_channel *c;
BGP_WALK_CHANNELS(bgp, c)
- bmp_route_monitor_pre_policy_table_in_snapshot(c);
+ bmp_route_monitor_pre_policy_table_in_snapshot(p, c);
+}
+
+void
+bmp_peer_up(const struct bgp_proto *bgp,
+ const byte *tx_open_msg, uint tx_open_length,
+ const byte *rx_open_msg, uint rx_open_length)
+{
+ struct bmp_proto *p; node *n;
+ WALK_LIST2(p, n, bmp_proto_list, bmp_node)
+ bmp_peer_up_(p, bgp, tx_open_msg, tx_open_length, rx_open_msg, rx_open_length);
}
static void
-bmp_peer_init(const struct bgp_proto *bgp)
+bmp_peer_init(struct bmp_proto *p, const struct bgp_proto *bgp)
{
struct bgp_conn *conn = bgp->conn;
@@ -476,8 +486,8 @@ bmp_peer_init(const struct bgp_proto *bgp)
!conn->local_open_msg || !conn->remote_open_msg)
return;
- bmp_peer_up(bgp, conn->local_open_msg, conn->local_open_length,
- conn->remote_open_msg, conn->remote_open_length);
+ bmp_peer_up_(p, bgp, conn->local_open_msg, conn->local_open_length,
+ conn->remote_open_msg, conn->remote_open_length);
}
static const struct birdsock *
@@ -569,12 +579,10 @@ bmp_send_peer_up_notif_msg(struct bmp_proto *p, const struct bgp_proto *bgp,
}
-void
-bmp_route_monitor_update_in_pre_begin(void)
+static void
+bmp_route_monitor_update_in_pre_begin_(struct bmp_proto *p)
{
- struct bmp_proto *p = g_bmp;
-
- if (!p || !p->started)
+ if (!p->started)
return;
if (p->monitoring_rib.in_pre_policy == false)
@@ -592,11 +600,17 @@ bmp_route_monitor_update_in_pre_begin(void)
}
void
-bmp_route_monitor_put_update_in_pre_msg(const byte *data, const size_t data_size)
+bmp_route_monitor_update_in_pre_begin(void)
{
- struct bmp_proto *p = g_bmp;
+ struct bmp_proto *p; node *n;
+ WALK_LIST2(p, n, bmp_proto_list, bmp_node)
+ bmp_route_monitor_update_in_pre_begin_(p);
+}
- if (!p || !p->started)
+void
+bmp_route_monitor_put_update_in_pre_msg(struct bmp_proto *p, const byte *data, const size_t data_size)
+{
+ if (!p->started)
return;
if (p->monitoring_rib.in_pre_policy == false)
@@ -617,11 +631,20 @@ bmp_route_monitor_put_update_in_pre_msg(const byte *data, const size_t data_size
}
void
-bmp_route_monitor_update_in_pre_commit(const struct bgp_proto *bgp)
+bmp_route_monitor_update_in_notify(struct channel *C, const net_addr *n,
+ const struct rte *new, const struct rte_src *src)
{
- struct bmp_proto *p = g_bmp;
+ struct bgp_channel *c = (void *) C;
+
+ struct bmp_proto *p; node *nx;
+ WALK_LIST2(p, nx, bmp_proto_list, bmp_node)
+ bgp_bmp_encode_rte(c, p, n, new, src);
+}
- if (!p || !p->started)
+static void
+bmp_route_monitor_update_in_pre_commit_(struct bmp_proto *p, const struct bgp_proto *bgp)
+{
+ if (!p->started)
return;
if (p->monitoring_rib.in_pre_policy == false)
@@ -670,11 +693,17 @@ bmp_route_monitor_update_in_pre_commit(const struct bgp_proto *bgp)
}
void
-bmp_route_monitor_update_in_pre_end(void)
+bmp_route_monitor_update_in_pre_commit(const struct bgp_proto *bgp)
{
- struct bmp_proto *p = g_bmp;
+ struct bmp_proto *p; node *n;
+ WALK_LIST2(p, n, bmp_proto_list, bmp_node)
+ bmp_route_monitor_update_in_pre_commit_(p, bgp);
+}
- if (!p || !p->started)
+static void
+bmp_route_monitor_update_in_pre_end_(struct bmp_proto *p)
+{
+ if (!p->started)
return;
if (p->monitoring_rib.in_pre_policy == false)
@@ -692,11 +721,37 @@ bmp_route_monitor_update_in_pre_end(void)
p->rt_table_in_pre_policy.update_in_progress = false;
}
+void
+bmp_route_monitor_update_in_pre_end(void)
+{
+ struct bmp_proto *p; node *n;
+ WALK_LIST2(p, n, bmp_proto_list, bmp_node)
+ bmp_route_monitor_update_in_pre_end_(p);
+}
+
static void
-bmp_route_monitor_pre_policy_table_in_snapshot(struct bgp_channel *c)
+bmp_route_monitor_end_of_rib_msg(struct bmp_proto *p, struct bgp_channel *c)
{
- struct bmp_proto *p = g_bmp;
+ struct bgp_proto *bgp = (void *) c->c.proto;
+
+ TRACE(D_PACKETS, "Sending END-OF-RIB for %s.%s", bgp->p.name, c->c.name);
+
+ byte rx_end_payload[DEFAULT_MEM_BLOCK_SIZE];
+ byte *pos = bgp_create_end_mark_(c, rx_end_payload + BGP_HEADER_LENGTH);
+ memset(rx_end_payload + BGP_MSG_HDR_MARKER_POS, 0xff,
+ BGP_MSG_HDR_MARKER_SIZE); // BGP UPDATE MSG marker
+ put_u16(rx_end_payload + BGP_MSG_HDR_LENGTH_POS, pos - rx_end_payload);
+ put_u8(rx_end_payload + BGP_MSG_HDR_TYPE_POS, PKT_UPDATE);
+
+ bmp_route_monitor_update_in_pre_begin_(p);
+ bmp_route_monitor_put_update_in_pre_msg(p, rx_end_payload, pos - rx_end_payload);
+ bmp_route_monitor_update_in_pre_commit_(p, bgp);
+ bmp_route_monitor_update_in_pre_end_(p);
+}
+static void
+bmp_route_monitor_pre_policy_table_in_snapshot(struct bmp_proto *p, struct bgp_channel *c)
+{
if (p->monitoring_rib.in_pre_policy == false)
return;
@@ -713,37 +768,22 @@ bmp_route_monitor_pre_policy_table_in_snapshot(struct bgp_channel *c)
{
P = n->routes->sender->proto;
if (P->proto->class != PROTOCOL_BGP)
- {
continue;
- }
- bmp_route_monitor_update_in_pre_begin();
+ bmp_route_monitor_update_in_pre_begin_(p);
rte *e;
for (e = n->routes; e; e = e->next)
- {
- bgp_rte_update_in_notify(&c->c, n->n.addr, e, e->src);
- }
+ bgp_bmp_encode_rte(c, p, n->n.addr, e, e->src);
- bmp_route_monitor_update_in_pre_commit((struct bgp_proto *) P);
- bmp_route_monitor_update_in_pre_end();
+ bmp_route_monitor_update_in_pre_commit_(p, (struct bgp_proto *) P);
+ bmp_route_monitor_update_in_pre_end_(p);
++cnt;
}
FIB_ITERATE_END;
if (cnt > 0)
- {
- bmp_route_monitor_update_in_pre_begin();
- byte rx_end_payload[DEFAULT_MEM_BLOCK_SIZE];
- byte *pos = bgp_create_end_mark(c, rx_end_payload + BGP_HEADER_LENGTH);
- memset(rx_end_payload + BGP_MSG_HDR_MARKER_POS, 0xff,
- BGP_MSG_HDR_MARKER_SIZE); // BGP UPDATE MSG marker
- put_u16(rx_end_payload + BGP_MSG_HDR_LENGTH_POS, pos - rx_end_payload);
- put_u8(rx_end_payload + BGP_MSG_HDR_TYPE_POS, PKT_UPDATE);
- bmp_route_monitor_put_update_in_pre_msg(rx_end_payload, pos - rx_end_payload);
- bmp_route_monitor_update_in_pre_commit((struct bgp_proto *) c->c.proto);
- bmp_route_monitor_update_in_pre_end();
- }
+ bmp_route_monitor_end_of_rib_msg(p, c);
}
static void
@@ -765,15 +805,15 @@ bmp_send_peer_down_notif_msg(struct bmp_proto *p, const struct bgp_proto *bgp,
bmp_buffer_free(&payload);
}
-void
-bmp_peer_down(const struct bgp_proto *bgp, const int err_class,
- const byte *msg, size_t msg_length)
+static void
+bmp_peer_down_(struct bmp_proto *p, const struct bgp_proto *bgp,
+ const int err_class, const byte *msg, size_t msg_length)
{
- struct bmp_proto *p = g_bmp;
-
- if (!p || !p->started)
+ if (!p->started)
return;
+ TRACE(D_STATES, "Peer down for %s", bgp->p.name);
+
// struct bmp_peer_map_key key = bmp_peer_map_key_create(bgp->remote_ip, bgp->remote_as);
// bmp_peer_map_remove(&p->bgp_peers, key);
@@ -809,6 +849,15 @@ bmp_peer_down(const struct bgp_proto *bgp, const int err_class,
bmp_buffer_free(&payload);
}
+void
+bmp_peer_down(const struct bgp_proto *bgp, const int err_class,
+ const byte *msg, size_t msg_length)
+{
+ struct bmp_proto *p; node *n;
+ WALK_LIST2(p, n, bmp_proto_list, bmp_node)
+ bmp_peer_down_(p, bgp, err_class, msg, msg_length);
+}
+
static void
bmp_send_termination_msg(struct bmp_proto *p,
const enum bmp_term_reason reason)
@@ -857,7 +906,7 @@ bmp_startup(struct bmp_proto *p)
struct proto *peer;
WALK_LIST(peer, proto_list)
if ((peer->proto->class == PROTOCOL_BGP) && (peer->proto_state == PS_UP))
- bmp_peer_init((struct bgp_proto *) peer);
+ bmp_peer_init(p, (struct bgp_proto *) peer);
proto_notify_state(&p->p, PS_UP);
}
@@ -905,6 +954,8 @@ bmp_connect(struct bmp_proto *p)
p->sk = sk;
sk->data = p;
+ TRACE(D_EVENTS, "Connecting to %I port %u", sk->daddr, sk->dport);
+
int rc = sk_open(sk);
if (rc < 0)
@@ -919,6 +970,8 @@ bmp_connected(struct birdsock *sk)
{
struct bmp_proto *p = (void *) sk->data;
+ TRACE(D_EVENTS, "Connected");
+
sk->rx_hook = bmp_rx;
sk->tx_hook = bmp_tx;
tm_stop(p->connect_retry_timer);
@@ -1025,11 +1078,10 @@ bmp_start(struct proto *P)
init_list(&p->rt_table_in_pre_policy.update_msg_queue);
p->started = false;
p->sock_err = 0;
+ add_tail(&bmp_proto_list, &p->bmp_node);
tm_start(p->connect_retry_timer, CONNECT_INIT_TIME);
- g_bmp = p;
-
return PS_START;
}
@@ -1045,7 +1097,7 @@ bmp_shutdown(struct proto *P)
}
p->sock_err = 0;
- g_bmp = NULL;
+ rem_node(&p->bmp_node);
return PS_DOWN;
}