diff options
author | Donatas Abraitis <donatas.abraitis@gmail.com> | 2021-04-09 08:33:41 +0200 |
---|---|---|
committer | Donatas Abraitis <donatas.abraitis@gmail.com> | 2021-04-12 09:43:53 +0200 |
commit | 7d3cae70b22ee6124a403b179db7b4fbab70dff6 (patch) | |
tree | 47deed1aec0f1871a20841543f89eb4b1a461e92 | |
parent | bgpd: Show BGP table version which was used for a particular prefix (diff) | |
download | frr-7d3cae70b22ee6124a403b179db7b4fbab70dff6.tar.xz frr-7d3cae70b22ee6124a403b179db7b4fbab70dff6.zip |
bgpd: Filter BGP routes by prefix version
The idea is to find out prefixes including specific BGP table version and
above.
Let's say I have a converged network and suddently I noticed a couple of
prefixes seems hijacked.
I want to look what new prefixes arrived with a specific BGP table version.
```
exit1-debian-9# show ip bgp version 8
BGP table version is 9, local router ID is 192.168.100.1, vrf id 0
Default local pref 100, local AS 65534
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
* 192.168.2.0/24 192.168.0.2 0 0 65030 ?
*> 192.168.0.2 0 0 65030 ?
* 192.168.3.0/24 192.168.0.2 0 0 65030 ?
*> 192.168.0.2 0 0 65030 ?
Displayed 2 routes and 18 total paths
exit1-debian-9#
```
```
exit1-debian-9# show ip bgp version 8 json
{
"vrfId": 0,
"vrfName": "default",
"tableVersion": 9,
"routerId": "192.168.100.1",
"defaultLocPrf": 100,
"localAS": 65534,
"routes": { "192.168.2.0/24": [
{
"valid":true,
"pathFrom":"external",
"prefix":"192.168.2.0",
"prefixLen":24,
"network":"192.168.2.0\/24",
"version":8,
"metric":0,
"weight":0,
"peerId":"2a02:bbd::2",
"path":"65030",
"origin":"incomplete",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"home-spine1.donatas.net",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"selectionReason":"Neighbor IP",
"pathFrom":"external",
"prefix":"192.168.2.0",
"prefixLen":24,
"network":"192.168.2.0\/24",
"version":8,
"metric":0,
"weight":0,
"peerId":"192.168.0.2",
"path":"65030",
"origin":"incomplete",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"home-spine1.donatas.net",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.3.0/24": [
{
"valid":true,
"pathFrom":"external",
"prefix":"192.168.3.0",
"prefixLen":24,
"network":"192.168.3.0\/24",
"version":9,
"metric":0,
"weight":0,
"peerId":"2a02:bbd::2",
"path":"65030",
"origin":"incomplete",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"home-spine1.donatas.net",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"selectionReason":"Neighbor IP",
"pathFrom":"external",
"prefix":"192.168.3.0",
"prefixLen":24,
"network":"192.168.3.0\/24",
"version":9,
"metric":0,
"weight":0,
"peerId":"192.168.0.2",
"path":"65030",
"origin":"incomplete",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"home-spine1.donatas.net",
"afi":"ipv4",
"used":true
}
]
}
] } }
```
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
-rw-r--r-- | bgpd/bgp_route.c | 68 | ||||
-rw-r--r-- | bgpd/bgp_route.h | 8 | ||||
-rw-r--r-- | bgpd/bgp_updgrp_adv.c | 4 | ||||
-rw-r--r-- | bgpd/bgp_vpn.c | 5 |
4 files changed, 62 insertions, 23 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 0f0d0590b..1c2ad7fc7 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8223,8 +8223,8 @@ void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type, } /* Static function to display route. */ -static void route_vty_out_route(const struct prefix *p, struct vty *vty, - json_object *json, bool wide) +static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p, + struct vty *vty, json_object *json, bool wide) { int len = 0; char buf[BUFSIZ]; @@ -8241,6 +8241,7 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty, json_object_int_add(json, "prefixLen", p->prefixlen); prefix2str(p, buf2, PREFIX_STRLEN); json_object_string_add(json, "network", buf2); + json_object_int_add(json, "version", dest->version); } } else if (p->family == AF_ETHERNET) { len = vty_out(vty, "%pFX", p); @@ -8265,6 +8266,7 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty, json_object_int_add(json, "prefixLen", p->prefixlen); prefix2str(p, buf2, PREFIX_STRLEN); json_object_string_add(json, "network", buf2); + json_object_int_add(json, "version", dest->version); } } @@ -8460,11 +8462,11 @@ void route_vty_out(struct vty *vty, const struct prefix *p, if (!json_paths) { /* print prefix and mask */ if (!display) - route_vty_out_route(p, vty, json_path, wide); + route_vty_out_route(path->net, p, vty, json_path, wide); else vty_out(vty, "%*s", (wide ? 45 : 17), " "); } else { - route_vty_out_route(p, vty, json_path, wide); + route_vty_out_route(path->net, p, vty, json_path, wide); } /* @@ -8924,9 +8926,9 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } /* called from terminal list command */ -void route_vty_out_tmp(struct vty *vty, const struct prefix *p, - struct attr *attr, safi_t safi, bool use_json, - json_object *json_ar, bool wide) +void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, + const struct prefix *p, struct attr *attr, safi_t safi, + bool use_json, json_object *json_ar, bool wide) { json_object *json_status = NULL; json_object *json_net = NULL; @@ -8958,7 +8960,7 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p, json_object_string_add(json_net, "network", buff); } } else - route_vty_out_route(p, vty, NULL, wide); + route_vty_out_route(dest, p, vty, NULL, wide); /* Print attribute */ if (attr) { @@ -9106,7 +9108,7 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p, /* print prefix and mask */ if (json == NULL) { if (!display) - route_vty_out_route(p, vty, NULL, false); + route_vty_out_route(path->net, p, vty, NULL, false); else vty_out(vty, "%*s", 17, " "); } @@ -9208,7 +9210,7 @@ void route_vty_out_overlay(struct vty *vty, const struct prefix *p, /* print prefix and mask */ if (!display) - route_vty_out_route(p, vty, json_path, false); + route_vty_out_route(path->net, p, vty, json_path, false); else vty_out(vty, "%*s", 17, " "); @@ -9313,7 +9315,7 @@ static void damp_route_vty_out(struct vty *vty, const struct prefix *p, /* print prefix and mask */ if (!use_json) { if (!display) - route_vty_out_route(p, vty, NULL, false); + route_vty_out_route(path->net, p, vty, NULL, false); else vty_out(vty, "%*s", 17, " "); } @@ -9384,7 +9386,7 @@ static void flap_route_vty_out(struct vty *vty, const struct prefix *p, /* print prefix and mask */ if (!use_json) { if (!display) - route_vty_out_route(p, vty, NULL, false); + route_vty_out_route(path->net, p, vty, NULL, false); else vty_out(vty, "%*s", 17, " "); } @@ -10121,6 +10123,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, ", valid"); } + if (json_paths) + json_object_int_add(json_path, "version", bn->version); + if (path->peer != bgp->peer_self) { if (path->peer->as == path->peer->local_as) { if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) { @@ -10616,6 +10621,13 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, for (; pi; pi = pi->next) { total_count++; + if (type == bgp_show_type_prefix_version) { + uint32_t version = + strtoul(output_arg, NULL, 10); + if (dest->version < version) + continue; + } + if (type == bgp_show_type_rpki) { if (dest_p->family == AF_INET || dest_p->family == AF_INET6) @@ -11892,6 +11904,7 @@ DEFPY (show_ip_bgp_json, |route-filter-v4|route-filter-translated-v6\ |route-filter-translated-v4] [exact-match]\ |rpki <invalid|valid|notfound>\ + |version (1-4294967295)\ ] [json$uj | wide$wide]", SHOW_STR IP_STR @@ -11925,6 +11938,8 @@ DEFPY (show_ip_bgp_json, "A valid path as determined by rpki\n" "A invalid path as determined by rpki\n" "A path that has no rpki data\n" + "Display prefixes with matching version numbers\n" + "Version number and above\n" JSON_STR "Increase table width for longer prefixes\n") { @@ -11935,6 +11950,7 @@ DEFPY (show_ip_bgp_json, int idx = 0; int exact_match = 0; char *community = NULL; + char *prefix_version = NULL; bool first = true; uint8_t show_flags = 0; enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED; @@ -12002,12 +12018,22 @@ DEFPY (show_ip_bgp_json, rpki_target_state = RPKI_INVALID; } + /* Display prefixes with matching version numbers */ + if (argv_find(argv, argc, "version", &idx)) { + sh_type = bgp_show_type_prefix_version; + prefix_version = argv[idx + 1]->arg; + } + if (!all) { /* show bgp: AFI_IP6, show ip bgp: AFI_IP */ if (community) return bgp_show_community(vty, bgp, community, exact_match, afi, safi, show_flags); + else if (prefix_version) + return bgp_show(vty, bgp, afi, safi, sh_type, + prefix_version, show_flags, + rpki_target_state); else return bgp_show(vty, bgp, afi, safi, sh_type, NULL, show_flags, rpki_target_state); @@ -12045,6 +12071,11 @@ DEFPY (show_ip_bgp_json, bgp_show_community(vty, bgp, community, exact_match, afi, safi, show_flags); + else if (prefix_version) + return bgp_show(vty, bgp, afi, safi, + sh_type, prefix_version, + show_flags, + rpki_target_state); else bgp_show(vty, bgp, afi, safi, sh_type, NULL, show_flags, @@ -12077,6 +12108,11 @@ DEFPY (show_ip_bgp_json, bgp_show_community(vty, bgp, community, exact_match, afi, safi, show_flags); + else if (prefix_version) + return bgp_show(vty, bgp, afi, safi, + sh_type, prefix_version, + show_flags, + rpki_target_state); else bgp_show(vty, bgp, afi, safi, sh_type, NULL, show_flags, @@ -13289,7 +13325,7 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, && (route_filtered || ret == RMAP_DENY)) (*filtered_count)++; - route_vty_out_tmp(vty, rn_p, &attr, safi, + route_vty_out_tmp(vty, dest, rn_p, &attr, safi, use_json, json_ar, wide); bgp_attr_undup(&attr, ain->attr); (*output_count)++; @@ -13331,8 +13367,8 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, } } route_vty_out_tmp( - vty, rn_p, &attr, safi, - use_json, json_ar, + vty, dest, rn_p, &attr, + safi, use_json, json_ar, wide); (*output_count)++; } else { @@ -13356,7 +13392,7 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) continue; - route_vty_out_tmp(vty, + route_vty_out_tmp(vty, dest, bgp_dest_get_prefix(dest), pi->attr, safi, use_json, json_ar, wide); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 0a4fd026e..1bf5dcf18 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -58,6 +58,7 @@ enum bgp_show_type { bgp_show_type_damp_neighbor, bgp_show_type_detail, bgp_show_type_rpki, + bgp_show_type_prefix_version, }; enum bgp_show_adj_route_type { @@ -714,9 +715,10 @@ extern void route_vty_out(struct vty *vty, const struct prefix *p, extern void route_vty_out_tag(struct vty *vty, const struct prefix *p, struct bgp_path_info *path, int display, safi_t safi, json_object *json); -extern void route_vty_out_tmp(struct vty *vty, const struct prefix *p, - struct attr *attr, safi_t safi, bool use_json, - json_object *json_ar, bool wide); +extern void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, + const struct prefix *p, struct attr *attr, + safi_t safi, bool use_json, json_object *json_ar, + bool wide); extern void route_vty_out_overlay(struct vty *vty, const struct prefix *p, struct bgp_path_info *path, int display, json_object *json); diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index fb64f010f..bb0c95e32 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -267,7 +267,7 @@ static void subgrp_show_adjq_vty(struct update_subgroup *subgrp, } if ((flags & UPDWALK_FLAGS_ADVQUEUE) && adj->adv && adj->adv->baa) { - route_vty_out_tmp(vty, dest_p, + route_vty_out_tmp(vty, dest, dest_p, adj->adv->baa->attr, SUBGRP_SAFI(subgrp), 0, NULL, false); @@ -275,7 +275,7 @@ static void subgrp_show_adjq_vty(struct update_subgroup *subgrp, } if ((flags & UPDWALK_FLAGS_ADVERTISED) && adj->attr) { - route_vty_out_tmp(vty, dest_p, + route_vty_out_tmp(vty, dest, dest_p, adj->attr, SUBGRP_SAFI(subgrp), 0, NULL, false); diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index cb459ae13..8d2cffbb4 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -229,8 +229,9 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, } rd_header = 0; } - route_vty_out_tmp(vty, bgp_dest_get_prefix(rm), attr, - safi, use_json, json_routes, false); + route_vty_out_tmp(vty, rm, bgp_dest_get_prefix(rm), + attr, safi, use_json, json_routes, + false); output_count++; } |