diff options
Diffstat (limited to 'bgpd/bgp_bmp.c')
-rw-r--r-- | bgpd/bgp_bmp.c | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 1de48a0..43f8006 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -38,6 +38,7 @@ #include "bgpd/bgp_vty.h" #include "bgpd/bgp_trace.h" #include "bgpd/bgp_network.h" +#include "bgpd/bgp_label.h" static void bmp_close(struct bmp *bmp); static struct bmp_bgp *bmp_bgp_find(struct bgp *bgp); @@ -391,11 +392,11 @@ static int bmp_send_initiation(struct bmp *bmp) bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_INITIATION); -#define BMP_INFO_TYPE_SYSDESCR 1 -#define BMP_INFO_TYPE_SYSNAME 2 - bmp_put_info_tlv(s, BMP_INFO_TYPE_SYSDESCR, - FRR_FULL_NAME " " FRR_VER_SHORT); - bmp_put_info_tlv(s, BMP_INFO_TYPE_SYSNAME, cmd_hostname_get()); +#define BMP_INIT_INFO_TYPE_SYSDESCR 1 +#define BMP_INIT_INFO_TYPE_SYSNAME 2 + bmp_put_info_tlv(s, BMP_INIT_INFO_TYPE_SYSDESCR, + FRR_FULL_NAME " " FRR_VER_SHORT); + bmp_put_info_tlv(s, BMP_INIT_INFO_TYPE_SYSNAME, cmd_hostname_get()); len = stream_get_endp(s); stream_putl_at(s, BMP_LENGTH_POS, len); /* message length is set. */ @@ -438,6 +439,7 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down) monotime_to_realtime(&uptime, &uptime_real); #define BGP_BMP_MAX_PACKET_SIZE 1024 +#define BMP_PEERUP_INFO_TYPE_STRING 0 s = stream_new(BGP_MAX_PACKET_SIZE); if (peer_established(peer->connection) && !down) { @@ -493,7 +495,8 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down) } if (peer->desc) - bmp_put_info_tlv(s, 0, peer->desc); + bmp_put_info_tlv(s, BMP_PEERUP_INFO_TYPE_STRING, + peer->desc); } else { uint8_t type; size_t type_pos; @@ -910,7 +913,8 @@ static void bmp_eor(struct bmp *bmp, afi_t afi, safi_t safi, uint8_t flags, static struct stream *bmp_update(const struct prefix *p, struct prefix_rd *prd, struct peer *peer, struct attr *attr, - afi_t afi, safi_t safi) + afi_t afi, safi_t safi, mpls_label_t *label, + uint32_t num_labels) { struct bpacket_attr_vec_arr vecarr; struct stream *s; @@ -946,8 +950,8 @@ static struct stream *bmp_update(const struct prefix *p, struct prefix_rd *prd, mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, &vecarr, attr); - bgp_packet_mpattr_prefix(s, afi, safi, p, prd, NULL, 0, 0, 0, - attr); + bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, + num_labels, 0, 0, attr); bgp_packet_mpattr_end(s, mpattrlen_pos); total_attr_len += stream_get_endp(s) - p1; } @@ -1002,7 +1006,8 @@ static struct stream *bmp_withdraw(const struct prefix *p, static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags, uint8_t peer_type_flag, const struct prefix *p, struct prefix_rd *prd, struct attr *attr, afi_t afi, - safi_t safi, time_t uptime) + safi_t safi, time_t uptime, mpls_label_t *label, + uint32_t num_labels) { struct stream *hdr, *msg; struct timeval tv = { .tv_sec = uptime, .tv_usec = 0 }; @@ -1019,7 +1024,8 @@ static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags, monotime_to_realtime(&tv, &uptime_real); if (attr) - msg = bmp_update(p, prd, peer, attr, afi, safi); + msg = bmp_update(p, prd, peer, attr, afi, safi, label, + num_labels); else msg = bmp_withdraw(p, prd, afi, safi); @@ -1041,6 +1047,7 @@ static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags, static bool bmp_wrsync(struct bmp *bmp, struct pullwr *pullwr) { + uint8_t bpi_num_labels; afi_t afi; safi_t safi; @@ -1214,23 +1221,31 @@ afibreak: (safi == SAFI_MPLS_VPN)) prd = (struct prefix_rd *)bgp_dest_get_prefix(bmp->syncrdpos); + bpi_num_labels = bgp_path_info_num_labels(bpi); + if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_SELECTED) && CHECK_FLAG(bmp->targets->afimon[afi][safi], BMP_MON_LOC_RIB)) { bmp_monitor(bmp, bpi->peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, bn_p, prd, bpi->attr, afi, safi, bpi && bpi->extra ? bpi->extra->bgp_rib_uptime - : (time_t)(-1L)); + : (time_t)(-1L), + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); } if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_VALID) && CHECK_FLAG(bmp->targets->afimon[afi][safi], BMP_MON_POSTPOLICY)) bmp_monitor(bmp, bpi->peer, BMP_PEER_FLAG_L, BMP_PEER_TYPE_GLOBAL_INSTANCE, bn_p, prd, bpi->attr, - afi, safi, bpi->uptime); + afi, safi, bpi->uptime, + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); if (adjin) + /* TODO: set label here when adjin supports labels */ bmp_monitor(bmp, adjin->peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, - bn_p, prd, adjin->attr, afi, safi, adjin->uptime); + bn_p, prd, adjin->attr, afi, safi, adjin->uptime, + NULL, 0); if (bn) bgp_dest_unlock_node(bn); @@ -1281,6 +1296,7 @@ static bool bmp_wrqueue_locrib(struct bmp *bmp, struct pullwr *pullwr) struct peer *peer; struct bgp_dest *bn = NULL; bool written = false; + uint8_t bpi_num_labels; bqe = bmp_pull_locrib(bmp); if (!bqe) @@ -1340,10 +1356,14 @@ static bool bmp_wrqueue_locrib(struct bmp *bmp, struct pullwr *pullwr) break; } + bpi_num_labels = bgp_path_info_num_labels(bpi); + bmp_monitor(bmp, peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, &bqe->p, prd, bpi ? bpi->attr : NULL, afi, safi, bpi && bpi->extra ? bpi->extra->bgp_rib_uptime - : (time_t)(-1L)); + : (time_t)(-1L), + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); written = true; out: @@ -1362,6 +1382,7 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) struct peer *peer; struct bgp_dest *bn = NULL; bool written = false; + uint8_t bpi_num_labels; bqe = bmp_pull(bmp); if (!bqe) @@ -1413,10 +1434,14 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) break; } + bpi_num_labels = bgp_path_info_num_labels(bpi); + bmp_monitor(bmp, peer, BMP_PEER_FLAG_L, BMP_PEER_TYPE_GLOBAL_INSTANCE, &bqe->p, prd, bpi ? bpi->attr : NULL, afi, safi, - bpi ? bpi->uptime : monotime(NULL)); + bpi ? bpi->uptime : monotime(NULL), + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); written = true; } @@ -1428,9 +1453,10 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) if (adjin->peer == peer) break; } + /* TODO: set label here when adjin supports labels */ bmp_monitor(bmp, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, &bqe->p, prd, adjin ? adjin->attr : NULL, afi, safi, - adjin ? adjin->uptime : monotime(NULL)); + adjin ? adjin->uptime : monotime(NULL), NULL, 0); written = true; } @@ -1578,6 +1604,15 @@ static void bmp_stat_put_u32(struct stream *s, size_t *cnt, uint16_t type, (*cnt)++; } +static void bmp_stat_put_u64(struct stream *s, size_t *cnt, uint16_t type, + uint64_t value) +{ + stream_putw(s, type); + stream_putw(s, 8); + stream_putq(s, value); + (*cnt)++; +} + static void bmp_stats(struct event *thread) { struct bmp_targets *bt = EVENT_ARG(thread); @@ -1619,8 +1654,13 @@ static void bmp_stats(struct event *thread) peer->stat_pfx_dup_withdraw); bmp_stat_put_u32(s, &count, BMP_STATS_UPD_7606_WITHDRAW, peer->stat_upd_7606); - bmp_stat_put_u32(s, &count, BMP_STATS_FRR_NH_INVALID, - peer->stat_pfx_nh_invalid); + if (bt->stats_send_experimental) + bmp_stat_put_u32(s, &count, BMP_STATS_FRR_NH_INVALID, + peer->stat_pfx_nh_invalid); + bmp_stat_put_u64(s, &count, BMP_STATS_SIZE_ADJ_RIB_IN, + peer->stat_pfx_adj_rib_in); + bmp_stat_put_u64(s, &count, BMP_STATS_SIZE_LOC_RIB, + peer->stat_pfx_loc_rib); stream_putl_at(s, count_pos, count); @@ -1875,6 +1915,7 @@ static struct bmp_targets *bmp_targets_get(struct bgp *bgp, const char *name) bt->name = XSTRDUP(MTYPE_BMP_TARGETSNAME, name); bt->bgp = bgp; bt->bmpbgp = bmp_bgp_get(bgp); + bt->stats_send_experimental = true; bmp_session_init(&bt->sessions); bmp_qhash_init(&bt->updhash); bmp_qlist_init(&bt->updlist); @@ -2455,6 +2496,21 @@ DEFPY(bmp_stats_cfg, return CMD_SUCCESS; } +DEFPY(bmp_stats_send_experimental, + bmp_stats_send_experimental_cmd, + "[no] bmp stats send-experimental", + NO_STR + BMP_STR + "Send BMP statistics messages\n" + "Send experimental BMP stats [65531-65534]\n") +{ + VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt); + + bt->stats_send_experimental = !no; + + return CMD_SUCCESS; +} + #define BMP_POLICY_IS_LOCRIB(str) ((str)[0] == 'l') /* __l__oc-rib */ #define BMP_POLICY_IS_PRE(str) ((str)[1] == 'r') /* p__r__e-policy */ @@ -2747,6 +2803,9 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty) if (bt->acl_name) vty_out(vty, " ip access-list %s\n", bt->acl_name); + if (!bt->stats_send_experimental) + vty_out(vty, " no bmp stats send-experimental\n"); + if (bt->stat_msec) vty_out(vty, " bmp stats interval %d\n", bt->stat_msec); @@ -2802,6 +2861,7 @@ static int bgp_bmp_init(struct event_loop *tm) install_element(BMP_NODE, &no_bmp_listener_cmd); install_element(BMP_NODE, &bmp_connect_cmd); install_element(BMP_NODE, &bmp_acl_cmd); + install_element(BMP_NODE, &bmp_stats_send_experimental_cmd); install_element(BMP_NODE, &bmp_stats_cmd); install_element(BMP_NODE, &bmp_monitor_cmd); install_element(BMP_NODE, &bmp_mirror_cmd); |