0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-17 08:38:42 +00:00

Merge branch 'bmp'

This commit is contained in:
Ondrej Zajicek 2023-08-22 15:28:05 +02:00
commit 5121101136
11 changed files with 765 additions and 549 deletions

View File

@ -179,6 +179,7 @@ proto_add_channel(struct proto *p, struct channel_config *cf)
c->merge_limit = cf->merge_limit;
c->in_keep_filtered = cf->in_keep_filtered;
c->rpki_reload = cf->rpki_reload;
c->bmp_hack = cf->bmp_hack;
c->channel_state = CS_DOWN;
c->export_state = ES_DOWN;
@ -523,7 +524,7 @@ channel_setup_in_table(struct channel *c)
cf->addr_type = c->net_type;
cf->internal = 1;
c->in_table = rt_setup(c->proto->pool, cf);
c->in_table = cf->table = rt_setup(c->proto->pool, cf);
c->reload_event = ev_new_init(c->proto->pool, channel_reload_loop, c);
}
@ -574,7 +575,8 @@ channel_do_up(struct channel *c)
static void
channel_do_flush(struct channel *c)
{
rt_schedule_prune(c->table);
if (!c->bmp_hack)
rt_schedule_prune(c->table);
c->gr_wait = 0;
if (c->gr_lock)

View File

@ -214,7 +214,6 @@ struct proto {
void (*if_notify)(struct proto *, unsigned flags, struct iface *i);
void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
void (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old);
void (*rte_update_in_notify)(struct channel *, const net_addr *, const struct rte *, const struct rte_src *);
void (*neigh_notify)(struct neighbor *neigh);
int (*preexport)(struct channel *, struct rte *rt);
void (*reload_routes)(struct channel *);
@ -477,7 +476,8 @@ struct channel_class {
#endif
};
extern struct channel_class channel_bgp;
extern const struct channel_class channel_basic;
extern const struct channel_class channel_bgp;
struct channel_config {
node n;
@ -500,6 +500,7 @@ struct channel_config {
u8 merge_limit; /* Maximal number of nexthops for RA_MERGED */
u8 in_keep_filtered; /* Routes rejected in import filter are kept */
u8 rpki_reload; /* RPKI changes trigger channel reload */
u8 bmp_hack; /* No flush */
};
struct channel {
@ -552,6 +553,7 @@ struct channel {
u8 reload_pending; /* Reloading and another reload is scheduled */
u8 refeed_pending; /* Refeeding and another refeed is scheduled */
u8 rpki_reload; /* RPKI changes trigger channel reload */
u8 bmp_hack; /* No flush */
struct rtable *out_table; /* Internal table for exported routes */
@ -620,6 +622,7 @@ static inline struct channel_config *proto_cf_main_channel(struct proto_config *
struct channel *proto_find_channel_by_table(struct proto *p, struct rtable *t);
struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
void proto_remove_channel(struct proto *p, struct channel *c);
int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);
void channel_set_state(struct channel *c, uint state);

View File

@ -2148,11 +2148,11 @@ rt_setup(pool *pp, struct rtable_config *cf)
init_list(&t->flowspec_links);
init_list(&t->subscribers);
hmap_init(&t->id_map, p, 1024);
hmap_set(&t->id_map, 0);
if (!(t->internal = cf->internal))
{
hmap_init(&t->id_map, p, 1024);
hmap_set(&t->id_map, 0);
t->rt_event = ev_new_init(p, rt_event, t);
t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
t->last_rt_change = t->gc_time = current_time();
@ -3096,9 +3096,6 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
{
old->flags &= ~(REF_STALE | REF_DISCARD | REF_MODIFY);
if (c->proto->rte_update_in_notify)
c->proto->rte_update_in_notify(c, n, old, src);
return 1;
}
@ -3111,28 +3108,15 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
/* Remove the old rte */
*pos = old->next;
rte_free_quick(old);
tab->rt_count--;
break;
}
if (!new)
{
if (!old)
goto drop_withdraw;
if (!net->routes)
fib_delete(&tab->fib, net);
if (c->proto->rte_update_in_notify)
c->proto->rte_update_in_notify(c, n, NULL, src);
return 1;
}
if (!old && !new)
goto drop_withdraw;
struct channel_limit *l = &c->rx_limit;
if (l->action && !old)
if (l->action && !old && new)
{
if (tab->rt_count >= l->limit)
channel_notify_limit(c, l, PLD_RX, tab->rt_count);
@ -3147,18 +3131,39 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
}
}
/* Insert the new rte */
rte *e = rte_do_cow(new);
e->flags |= REF_COW;
e->net = net;
e->sender = c;
e->lastmod = current_time();
e->next = *pos;
*pos = e;
tab->rt_count++;
if (new)
{
/* Insert the new rte */
rte *e = rte_do_cow(new);
e->flags |= REF_COW;
e->net = net;
e->sender = c;
e->lastmod = current_time();
e->next = *pos;
*pos = new = e;
tab->rt_count++;
if (c->proto->rte_update_in_notify)
c->proto->rte_update_in_notify(c, n, e, src);
if (!old)
{
new->id = hmap_first_zero(&tab->id_map);
hmap_set(&tab->id_map, new->id);
}
else
new->id = old->id;
}
rte_announce(tab, RA_ANY, net, new, old, NULL, NULL);
if (old)
{
if (!new)
hmap_clear(&tab->id_map, old->id);
rte_free_quick(old);
}
if (!net->routes)
fib_delete(&tab->fib, net);
return 1;

View File

@ -380,10 +380,20 @@ bgp_close_conn(struct bgp_conn *conn)
rfree(conn->sk);
conn->sk = NULL;
mb_free(conn->local_open_msg);
conn->local_open_msg = NULL;
mb_free(conn->remote_open_msg);
conn->remote_open_msg = NULL;
conn->local_open_length = 0;
conn->remote_open_length = 0;
mb_free(conn->local_caps);
conn->local_caps = NULL;
mb_free(conn->remote_caps);
conn->remote_caps = NULL;
conn->notify_data = NULL;
conn->notify_size = 0;
}
@ -682,10 +692,12 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
bgp_conn_set_state(conn, BS_ESTABLISHED);
proto_notify_state(&p->p, PS_UP);
bmp_peer_up(p, conn->local_open_msg, conn->local_open_length,
conn->remote_open_msg, conn->remote_open_length);
}
static void
bgp_conn_leave_established_state(struct bgp_proto *p)
bgp_conn_leave_established_state(struct bgp_conn *conn, struct bgp_proto *p)
{
BGP_TRACE(D_EVENTS, "BGP session closed");
p->last_established = current_time();
@ -693,6 +705,10 @@ bgp_conn_leave_established_state(struct bgp_proto *p)
if (p->p.proto_state == PS_UP)
bgp_stop(p, 0, NULL, 0);
bmp_peer_down(p, p->last_error_class,
conn->notify_code, conn->notify_subcode,
conn->notify_data, conn->notify_size);
}
void
@ -709,7 +725,7 @@ bgp_conn_enter_close_state(struct bgp_conn *conn)
bgp_start_timer(conn->hold_timer, 10);
if (os == BS_ESTABLISHED)
bgp_conn_leave_established_state(p);
bgp_conn_leave_established_state(conn, p);
}
void
@ -723,7 +739,7 @@ bgp_conn_enter_idle_state(struct bgp_conn *conn)
ev_schedule(p->event);
if (os == BS_ESTABLISHED)
bgp_conn_leave_established_state(p);
bgp_conn_leave_established_state(conn, p);
}
/**
@ -867,10 +883,7 @@ bgp_graceful_restart_timeout(timer *t)
}
}
else
{
bgp_stop(p, 0, NULL, 0);
bmp_peer_down(p, BE_NONE, NULL, 0);
}
}
static void
@ -994,10 +1007,7 @@ bgp_sock_err(sock *sk, int err)
if (err)
BGP_TRACE(D_EVENTS, "Connection lost (%M)", err);
else
{
BGP_TRACE(D_EVENTS, "Connection closed");
bmp_peer_down(p, BE_SOCKET, NULL, 0);
}
if ((conn->state == BS_ESTABLISHED) && p->gr_ready)
bgp_handle_graceful_restart(p);
@ -1322,7 +1332,6 @@ bgp_neigh_notify(neighbor *n)
bgp_store_error(p, NULL, BE_MISC, BEM_NEIGHBOR_LOST);
/* Perhaps also run bgp_update_startup_delay(p)? */
bgp_stop(p, 0, NULL, 0);
bmp_peer_down(p, BE_MISC, NULL, 0);
}
}
else if (p->cf->check_link && !(n->iface->flags & IF_LINK_UP))
@ -1334,7 +1343,6 @@ bgp_neigh_notify(neighbor *n)
if (ps == PS_UP)
bgp_update_startup_delay(p);
bgp_stop(p, 0, NULL, 0);
bmp_peer_down(p, BE_MISC, NULL, 0);
}
}
else
@ -1376,7 +1384,6 @@ bgp_bfd_notify(struct bfd_request *req)
if (ps == PS_UP)
bgp_update_startup_delay(p);
bgp_stop(p, 0, NULL, 0);
bmp_peer_down(p, BE_MISC, NULL, 0);
}
}
}
@ -1705,10 +1712,6 @@ bgp_init(struct proto_config *CF)
P->rte_modify = bgp_rte_modify_stale;
P->rte_igp_metric = bgp_rte_igp_metric;
#ifdef CONFIG_BMP
P->rte_update_in_notify = bgp_rte_update_in_notify;
#endif
p->cf = cf;
p->is_internal = (cf->local_as == cf->remote_as);
p->is_interior = p->is_internal || cf->confederation_member;
@ -2261,12 +2264,13 @@ bgp_error(struct bgp_conn *c, uint code, uint subcode, byte *data, int len)
bgp_log_error(p, BE_BGP_TX, "Error", code, subcode, data, ABS(len));
bgp_store_error(p, c, BE_BGP_TX, (code << 16) | subcode);
bgp_conn_enter_close_state(c);
c->notify_code = code;
c->notify_subcode = subcode;
c->notify_data = data;
c->notify_size = (len > 0) ? len : 0;
bgp_conn_enter_close_state(c);
bgp_schedule_packet(c, NULL, PKT_NOTIFICATION);
if (code != 6)
@ -2634,7 +2638,7 @@ bgp_show_proto_info(struct proto *P)
}
}
struct channel_class channel_bgp = {
const struct channel_class channel_bgp = {
.channel_size = sizeof(struct bgp_channel),
.config_size = sizeof(struct bgp_channel_config),
.init = bgp_channel_init,

View File

@ -287,6 +287,11 @@ struct bgp_conn {
u8 ext_messages; /* Session uses extended message length */
u32 received_as; /* ASN received in OPEN message */
byte *local_open_msg; /* Saved OPEN messages (no header) */
byte *remote_open_msg;
uint local_open_length;
uint remote_open_length;
struct bgp_caps *local_caps;
struct bgp_caps *remote_caps;
timer *connect_timer;
@ -487,6 +492,7 @@ struct bgp_parse_state {
#define BGP_PORT 179
#define BGP_VERSION 4
#define BGP_HEADER_LENGTH 19
#define BGP_HDR_MARKER_LENGTH 16
#define BGP_MAX_MESSAGE_LENGTH 4096
#define BGP_MAX_EXT_MSG_LENGTH 65535
#define BGP_RX_BUFFER_SIZE 4096
@ -625,11 +631,12 @@ struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool);
u32 bgp_rte_igp_metric(struct rte *);
void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old);
int bgp_preexport(struct channel *, struct rte *);
void bgp_rte_update_in_notify(struct channel *C, const net_addr *n, const struct rte *new, const struct rte_src *src);
int bgp_get_attr(const struct eattr *e, byte *buf, int buflen);
void bgp_get_route_info(struct rte *, byte *buf);
int bgp_total_aigp_metric_(rte *e, u64 *metric, const struct adata **ad);
byte * bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n, const struct rte *new, const struct rte_src *src);
#define BGP_AIGP_METRIC 1
#define BGP_AIGP_MAX U64(0xffffffffffffffff)
@ -658,8 +665,8 @@ const char * bgp_error_dsc(unsigned code, unsigned subcode);
void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len);
void bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to);
byte *bgp_create_end_mark_(struct bgp_channel *c, byte *buf);
byte * bgp_create_end_mark(struct bgp_channel *c, byte *buf);
/* Packet types */

View File

@ -167,7 +167,6 @@ bgp_create_notification(struct bgp_conn *conn, byte *buf)
buf[0] = conn->notify_code;
buf[1] = conn->notify_subcode;
memcpy(buf+2, conn->notify_data, conn->notify_size);
bmp_peer_down(p, BE_NONE, buf, conn->notify_size + 2);
return buf + 2 + conn->notify_size;
}
@ -776,6 +775,14 @@ err:
return -1;
}
static byte *
bgp_copy_open(struct bgp_proto *p, const byte *pkt, uint len)
{
char *buf = mb_alloc(p->p.pool, len - BGP_HEADER_LENGTH);
memcpy(buf, pkt + BGP_HEADER_LENGTH, len - BGP_HEADER_LENGTH);
return buf;
}
static byte *
bgp_create_open(struct bgp_conn *conn, byte *buf)
{
@ -850,6 +857,9 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
id = get_u32(pkt+24);
BGP_TRACE(D_PACKETS, "Got OPEN(as=%d,hold=%d,id=%R)", asn, hold, id);
conn->remote_open_msg = bgp_copy_open(p, pkt, len);
conn->remote_open_length = len - BGP_HEADER_LENGTH;
if (bgp_read_options(conn, pkt+29, pkt[28], len-29) < 0)
return;
@ -981,7 +991,6 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE);
bgp_start_timer(conn->hold_timer, conn->hold_time);
bgp_conn_enter_openconfirm_state(conn);
bmp_put_recv_bgp_open_msg(p, pkt, len);
}
@ -2419,15 +2428,20 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
{
struct bgp_proto *p = (void *) c->c.proto;
byte *end = buf + (BGP_MAX_EXT_MSG_LENGTH - BGP_HEADER_LENGTH);
byte *res = NULL;
/* FIXME: must be a bit shorter */
struct lp_state tmpp;
lp_save(tmp_linpool, &tmpp);
struct bgp_caps *peer = p->conn->remote_caps;
const struct bgp_af_caps *rem = bgp_find_af_caps(peer, c->afi);
struct bgp_write_state s = {
.proto = p,
.channel = c,
.pool = tmp_linpool,
.mp_reach = (c->afi != BGP_AF_IPV4) || rem->ext_next_hop,
.mp_reach = (c->afi != BGP_AF_IPV4) || (rem && rem->ext_next_hop),
.as4_session = 1,
.add_path = c->add_path_rx,
.mpls = c->desc->mpls,
@ -2436,16 +2450,20 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
if (!update)
{
return !s.mp_reach ?
res = !s.mp_reach ?
bgp_create_ip_unreach(&s, buck, buf, end):
bgp_create_mp_unreach(&s, buck, buf, end);
}
else
{
return !s.mp_reach ?
res = !s.mp_reach ?
bgp_create_ip_reach(&s, buck, buf, end):
bgp_create_mp_reach(&s, buck, buf, end);
}
lp_restore(tmp_linpool, &tmpp);
return res;
}
static byte *
@ -2458,14 +2476,11 @@ bgp_bmp_prepare_bgp_hdr(byte *buf, const u16 msg_size, const u8 msg_type)
return buf + BGP_MSG_HDR_TYPE_POS + BGP_MSG_HDR_TYPE_SIZE;
}
void
bgp_rte_update_in_notify(struct channel *C, const net_addr *n,
const struct rte *new, const struct rte_src *src)
byte *
bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n,
const struct rte *new, const struct rte_src *src)
{
// struct bgp_proto *p = (void *) C->proto;
struct bgp_channel *c = (void *) C;
byte buf[BGP_MAX_EXT_MSG_LENGTH];
// struct bgp_proto *p = (void *) c->c.proto;
byte *pkt = buf + BGP_HEADER_LENGTH;
ea_list *attrs = new ? new->attrs->eattrs : NULL;
@ -2489,11 +2504,11 @@ bgp_rte_update_in_notify(struct channel *C, const net_addr *n,
add_tail(&b->prefixes, &px->buck_node);
byte *end = bgp_create_update_bmp(c, pkt, b, !!new);
if (!end)
return;
bgp_bmp_prepare_bgp_hdr(buf, end - buf, PKT_UPDATE);
bmp_route_monitor_put_update_in_pre_msg(buf, end - buf);
if (end)
bgp_bmp_prepare_bgp_hdr(buf, end - buf, PKT_UPDATE);
return end;
}
#endif /* CONFIG_BMP */
@ -2600,6 +2615,14 @@ bgp_create_mp_end_mark(struct bgp_channel *c, byte *buf)
}
byte *
bgp_create_end_mark_(struct bgp_channel *c, byte *buf)
{
return (c->afi == BGP_AF_IPV4) ?
bgp_create_ip_end_mark(c, buf):
bgp_create_mp_end_mark(c, buf);
}
static byte *
bgp_create_end_mark(struct bgp_channel *c, byte *buf)
{
struct bgp_proto *p = (void *) c->c.proto;
@ -2607,9 +2630,7 @@ bgp_create_end_mark(struct bgp_channel *c, byte *buf)
BGP_TRACE(D_PACKETS, "Sending END-OF-RIB");
p->stats.tx_updates++;
return (c->afi == BGP_AF_IPV4) ?
bgp_create_ip_end_mark(c, buf):
bgp_create_mp_end_mark(c, buf);
return bgp_create_end_mark_(c, buf);
}
static inline void
@ -2750,8 +2771,6 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
s.ip_reach_len = len - pos;
s.ip_reach_nlri = pkt + pos;
bmp_route_monitor_update_in_pre_begin();
if (s.attr_len)
ea = bgp_decode_attrs(&s, s.attrs, s.attr_len);
else
@ -2782,9 +2801,6 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
bgp_decode_nlri(&s, s.mp_reach_af, s.mp_reach_nlri, s.mp_reach_len,
ea, s.mp_next_hop_data, s.mp_next_hop_len);
bmp_route_monitor_update_in_pre_commit(p);
bmp_route_monitor_update_in_pre_end();
done:
rta_free(s.cached_rta);
lp_restore(tmp_linpool, &tmpp);
@ -2988,7 +3004,7 @@ bgp_send(struct bgp_conn *conn, uint type, uint len)
conn->bgp->stats.tx_messages++;
conn->bgp->stats.tx_bytes += len;
memset(buf, 0xff, 16); /* Marker */
memset(buf, 0xff, BGP_HDR_MARKER_LENGTH);
put_u16(buf+16, len);
buf[18] = type;
@ -3036,12 +3052,11 @@ bgp_fire_tx(struct bgp_conn *conn)
{
conn->packets_to_send &= ~(1 << PKT_OPEN);
end = bgp_create_open(conn, pkt);
int rv = bgp_send(conn, PKT_OPEN, end - buf);
if (rv >= 0)
{
bmp_put_sent_bgp_open_msg(p, pkt, end - buf);
}
return rv;
conn->local_open_msg = bgp_copy_open(p, buf, end - buf);
conn->local_open_length = end - buf - BGP_HEADER_LENGTH;
return bgp_send(conn, PKT_OPEN, end - buf);
}
else if (s & (1 << PKT_KEEPALIVE))
{
@ -3322,6 +3337,11 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
bgp_log_error(p, BE_BGP_RX, "Received", code, subcode, pkt+21, len-21);
bgp_store_error(p, conn, BE_BGP_RX, (code << 16) | subcode);
conn->notify_code = code;
conn->notify_subcode = subcode;
conn->notify_data = pkt+21;
conn->notify_size = len-21;
bgp_conn_enter_close_state(conn);
bgp_schedule_packet(conn, NULL, PKT_SCHEDULE_CLOSE);
@ -3340,8 +3360,6 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
p->p.disabled = 1;
}
}
bmp_peer_down(p, BE_NONE, pkt, len);
}
static void

View File

@ -1,6 +1,6 @@
ABOUT
This package |proto/bmp/*| provide implementation of BGP Monitoring Protocol (BMP).
It has been started by Akamai Technologies, Inc. as a pilot program for support BMP in BIRD.
It provides only basic features of BMP specification which are needed by Akamai evaluation of
It provides only basic features of BMP specification which are needed by Akamai evaluation of
feasible BMP protocol.
Content of this package has been provided as a patch for BIRD release v2.0.7.
Content of this package has been provided as a patch for BIRD release v2.0.7.

File diff suppressed because it is too large Load Diff

View File

@ -35,118 +35,94 @@ struct bmp_config {
struct proto_config c;
const char *sys_descr; // sysDescr MIB-II [RFC1213] object
const char *sys_name; // sysName MIB-II [RFC1213] object
ip_addr local_addr; // Local IP address
ip_addr station_ip; // Monitoring station address
u16 station_port; // Monitoring station TCP port
bool monitoring_rib_in_pre_policy; // Route monitoring pre-policy Adj-Rib-In
bool monitoring_rib_in_post_policy; // Route monitoring post-policy Adj-Rib-In
bool monitoring_rib_local; // Route monitoring Local Rib
bool monitoring_rib_in_post_policy; // Route monitoring post-policy Adj-Rib-In
};
/* Forward declarations */
struct bgp_proto;
struct bmp_proto;
// Stores sent and received BGP OPEN MSGs
struct bmp_peer_open_msg {
struct bmp_peer_map tx_msg;
struct bmp_peer_map rx_msg;
};
// Keeps necessary information during composing BGP UPDATE MSG which is going
// to be sent to the BMP collector
struct rt_table_info {
list update_msg_queue; // Stores all composed BGP UPDATE MSGs
size_t update_msg_size; // Size of all BGP UPDATE MSGs
struct timeval update_begin_time; // Keeps timestamp of starting BGP UPDATE MSGs composing
bool update_in_progress; // Holds information whether composing process is still in progress
};
struct bmp_proto {
struct proto p; // Parent proto
const struct bmp_config *cf; // Shortcut to BMP configuration
node bmp_node; // Node in bmp_proto_list
HASH(struct bmp_peer) peer_map;
HASH(struct bmp_stream) stream_map;
HASH(struct bmp_table) table_map;
sock *sk; // TCP connection
event *tx_ev; // TX event
event *tx_ev; // TX event
event *update_ev; // Update event
char sys_descr[MIB_II_STR_LEN]; // sysDescr MIB-II [RFC1213] object
char sys_name[MIB_II_STR_LEN]; // sysName MIB-II [RFC1213] object
ip_addr local_addr; // Source local IP address
ip_addr station_ip; // Monitoring station IP address
u16 station_port; // Monitoring station TCP port
struct monitoring_rib monitoring_rib;
// Below fields are for internal use
struct bmp_peer_map bgp_peers; // Stores 'bgp_proto' structure per BGP peer
struct bmp_peer_open_msg peer_open_msg; // Stores sent and received BGP OPEN MSG per BGP peer
// struct bmp_peer_map bgp_peers; // Stores 'bgp_proto' structure per BGP peer
pool *buffer_mpool; // Memory pool used for BMP buffer allocations
pool *map_mem_pool; // Memory pool used for BMP map allocations
pool *tx_mem_pool; // Memory pool used for packet allocations designated to BMP collector
pool *update_msg_mem_pool; // Memory pool used for BPG UPDATE MSG allocations
list tx_queue; // Stores queued packets going to be sent
timer *connect_retry_timer; // Timer for retrying connection to the BMP collector
struct rt_table_info rt_table_in_pre_policy; // Pre-policy route import table
list update_msg_queue; // Stores all composed BGP UPDATE MSGs
bool started; // Flag that stores running status of BMP instance
int sock_err; // Last socket error code
};
struct bmp_peer {
struct bgp_proto *bgp;
struct bmp_peer *next;
list streams;
};
struct bmp_stream {
node n;
struct bgp_proto *bgp;
u32 key;
bool sync;
struct bmp_stream *next;
struct bmp_table *table;
struct bgp_channel *sender;
};
struct bmp_table {
struct rtable *table;
struct bmp_table *next;
struct channel *channel;
u32 uc;
};
#ifdef CONFIG_BMP
/**
* bmp_put_sent_bgp_open_msg - save sent BGP OPEN msg packet in BMP implementation.
* NOTE: If there has been passed sent and received BGP OPEN MSGs to the BMP
* implementation, then there is going to be send BMP Peer Up Notification
* message to the BMP collector.
* bmp_peer_up - send notification that BGP peer connection is established
*/
void
bmp_put_sent_bgp_open_msg(const struct bgp_proto *bgp, const byte* pkt,
const size_t pkt_size);
/**
* bmp_put_recv_bgp_open_msg - save received BGP OPEN msg packet in BMP implementation.
* NOTE: If there has been passed sent and received BGP OPEN MSGs to the BMP
* implementation, then there is going to be send BMP Peer Up Notification
* message to the BMP collector.
*/
void
bmp_put_recv_bgp_open_msg(const struct bgp_proto *bgp, const byte* pkt,
const size_t pkt_size);
/**
* The following 4 functions create BMP Route Monitoring message based on
* pre-policy Adj-RIB-In. Composing Route Monitoring message consist of few
* stages. First of all call bmp_route_monitor_update_in_pre_begin() in order
* to start composing message. As a second step, call
* bmp_route_monitor_put_update_in_pre_msg() in order to save BGP UPDATE msg.
* As a third step call bmp_route_monitor_update_in_pre_commit() in order to
* send BMP Route Monitoring message to the BMP collector. As a last step,
* call bmp_route_monitor_update_in_pre_end() in order to release resources.
*/
void
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);
void
bmp_route_monitor_update_in_pre_commit(const struct bgp_proto *bgp);
void
bmp_route_monitor_update_in_pre_end(void);
bmp_peer_up(struct bgp_proto *bgp,
const byte *tx_open_msg, uint tx_open_length,
const byte *rx_open_msg, uint rx_open_length);
/**
* bmp_peer_down - send notification that BGP peer connection is not in
* established state
*/
void
bmp_peer_down(const struct bgp_proto *bgp, const int err_class, const byte *pkt,
size_t pkt_size);
bmp_peer_down(const struct bgp_proto *bgp, int err_class, int code, int subcode, const byte *data, int length);
#else /* BMP build disabled */
static inline void bmp_put_sent_bgp_open_msg(const struct bgp_proto *bgp UNUSED, const byte* pkt UNUSED, const size_t pkt_size UNUSED) { }
static inline void bmp_put_recv_bgp_open_msg(const struct bgp_proto *bgp UNUSED, const byte* pkt UNUSED, const size_t pkt_size UNUSED) { }
static inline void bmp_route_monitor_update_in_pre_begin(void) { }
static inline void bmp_route_monitor_put_update_in_pre_msg(const byte *data UNUSED, const size_t data_size UNUSED) { }
static inline void bmp_route_monitor_update_in_pre_commit(const struct bgp_proto *bgp UNUSED) { }
static inline void bmp_route_monitor_update_in_pre_end(void) { }
static inline void bmp_peer_down(const struct bgp_proto *bgp UNUSED, const int err_class UNUSED, const byte *pkt UNUSED, size_t pkt_size UNUSED) { }
static inline void bmp_peer_up(struct bgp_proto *bgp UNUSED, const byte *tx_open_msg UNUSED, uint tx_open_length UNUSED, const byte *rx_open_msg UNUSED, uint rx_open_length UNUSED) { }
static inline void bmp_peer_down(const struct bgp_proto *bgp UNUSED, const int err_class UNUSED, int code UNUSED, int subcode UNUSED, const byte *data UNUSED, int length UNUSED) { }
#endif /* CONFIG_BMP */

View File

@ -15,7 +15,6 @@ bmp_buffer_alloc(pool *ppool, const size_t n)
buf.start = mb_alloc(ppool, n);
buf.pos = buf.start;
buf.end = buf.start + n;
return buf;
}
@ -26,33 +25,41 @@ bmp_buffer_free(buffer *buf)
buf->start = buf->pos = buf->end = NULL;
}
/**
* @brief bmp_buffer_grow
* @param buf - buffer to grow
* @param n - required amount of available space
* Resize buffer in a way that there is at least @n bytes of available space.
*/
static void
bmp_buffer_grow(buffer *buf, const size_t n)
{
const size_t pos = bmp_buffer_pos(buf);
buf->start = mb_realloc(buf->start, n);
size_t pos = bmp_buffer_pos(buf);
size_t size = bmp_buffer_size(buf);
size_t req = pos + n;
while (size < req)
size = size * 3 / 2;
buf->start = mb_realloc(buf->start, size);
buf->pos = buf->start + pos;
buf->end = buf->start + n;
buf->end = buf->start + size;
}
void
bmp_buffer_need(buffer *buf, const size_t n)
{
if (bmp_buffer_avail(buf) < n)
{
bmp_buffer_grow(buf, n);
}
}
void
bmp_put_data(buffer *buf, const void *src, const size_t n)
{
if (!n)
{
return;
}
bmp_buffer_need(buf, n);
memcpy(buf->pos, src, n);
buf->pos += n;
}
}

View File

@ -25,13 +25,8 @@ proto: bmp_proto '}' ;
bmp_proto_start: proto_start BMP {
this_proto = proto_config_new(&proto_bmp, $1);
BMP_CFG->station_ip = IPA_NONE4;
BMP_CFG->station_port = 0;
BMP_CFG->sys_descr = "Not defined";
BMP_CFG->sys_name = "Not defined";
BMP_CFG->monitoring_rib_in_pre_policy = false;
BMP_CFG->monitoring_rib_in_post_policy = false;
BMP_CFG->monitoring_rib_local = false;
}
;
@ -52,6 +47,9 @@ bmp_station_address:
bmp_proto:
bmp_proto_start proto_name '{'
| bmp_proto proto_item ';'
| bmp_proto LOCAL ADDRESS ipa ';' {
BMP_CFG->local_addr = $4;
}
| bmp_proto STATION ADDRESS bmp_station_address ';'
| bmp_proto SYSTEM DESCRIPTION text ';' {
if (!$4 || (strlen($4) == 0))
@ -73,9 +71,6 @@ bmp_proto:
| bmp_proto MONITORING RIB IN POST_POLICY bool ';' {
BMP_CFG->monitoring_rib_in_post_policy = $6;
}
| bmp_proto MONITORING RIB LOCAL bool ';' {
BMP_CFG->monitoring_rib_local = $5;
}
;
CF_CODE