mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 06:59:21 +00:00
bgpd: Detail option for nexthop and import-check to display paths
1. Updated "show bgp vrf <vrf-name> nexthop detail" and "show bgp vrf <vrf-name> import-check-table detail" show commands to display paths associated with nexthop. "detail" option was previously unused. 2. Added 'ipv4' and 'ipv6' JSON object under top level JSON. 3. Removed the "nexthops" JSON object which was under the top level JSON object 4. Renamed "ifname" to "interfaceName" 5. Renamed "gates" JSON obejct to "nexthops" 6. Changed "flags" JSON array to JSON object and changed the flags from string to boolean 7. "lastUpdate" will display only epoch time for "detail" option JSON output: r4# show bgp vrf default nexthop detail json { "ipv4":{ "10.0.7.1":{ "valid":true, "complete":true, "igpMetric":0, "pathCount":3, "peer":"10.0.7.1", "nexthops":[ { "interfaceName":"r4-r2-eth0" } ], "lastUpdate":1672265350, "paths":[ { "afi":"IPv4", "safi":"unicast", "prefix":"11.0.20.2/32", "vrf":"default", "flags":{ "igpChanged":false, "damped":false, "history":false, "bestpath":true, "valid":true, "attrChanged":false, "deterministicMedCheck":false, "deterministicMedSelected":false, "stale":false, "removed":false, "counted":true, "multipath":false, "multipathChanged":false, "ribAttributeChanged":false, "nexthopSelf":false, "linkBandwidthChanged":false, "acceptOwn":false } } ] } } } } Signed-off-by: Pooja Jagadeesh Doijode <pdoijode@nvidia.com>
This commit is contained in:
parent
bf85e4c5f1
commit
8da79d08ad
@ -741,41 +741,41 @@ static void bgp_show_bgp_path_info_flags(uint32_t flags, json_object *json)
|
||||
if (!json)
|
||||
return;
|
||||
|
||||
json_flags = json_object_new_array();
|
||||
if (CHECK_FLAG(flags, BGP_PATH_IGP_CHANGED))
|
||||
json_array_string_add(json_flags, "igpChanged");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_DAMPED))
|
||||
json_array_string_add(json_flags, "damped");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_HISTORY))
|
||||
json_array_string_add(json_flags, "history");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_SELECTED))
|
||||
json_array_string_add(json_flags, "selected");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_VALID))
|
||||
json_array_string_add(json_flags, "valid");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_ATTR_CHANGED))
|
||||
json_array_string_add(json_flags, "attrChanged");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_DMED_CHECK))
|
||||
json_array_string_add(json_flags, "dmedCheck");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_DMED_SELECTED))
|
||||
json_array_string_add(json_flags, "dmedSelected");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_STALE))
|
||||
json_array_string_add(json_flags, "stale");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_REMOVED))
|
||||
json_array_string_add(json_flags, "removed");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_COUNTED))
|
||||
json_array_string_add(json_flags, "counted");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_MULTIPATH))
|
||||
json_array_string_add(json_flags, "multipath");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_MULTIPATH_CHG))
|
||||
json_array_string_add(json_flags, "multipathChanged");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_RIB_ATTR_CHG))
|
||||
json_array_string_add(json_flags, "ribAttributeChanged");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_ANNC_NH_SELF))
|
||||
json_array_string_add(json_flags, "anncNhSelf");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_LINK_BW_CHG))
|
||||
json_array_string_add(json_flags, "linkBandwidthChanged");
|
||||
if (CHECK_FLAG(flags, BGP_PATH_ACCEPT_OWN))
|
||||
json_array_string_add(json_flags, "acceptOwn");
|
||||
json_flags = json_object_new_object();
|
||||
json_object_boolean_add(json_flags, "igpChanged",
|
||||
CHECK_FLAG(flags, BGP_PATH_IGP_CHANGED));
|
||||
json_object_boolean_add(json_flags, "damped",
|
||||
CHECK_FLAG(flags, BGP_PATH_DAMPED));
|
||||
json_object_boolean_add(json_flags, "history",
|
||||
CHECK_FLAG(flags, BGP_PATH_HISTORY));
|
||||
json_object_boolean_add(json_flags, "bestpath",
|
||||
CHECK_FLAG(flags, BGP_PATH_SELECTED));
|
||||
json_object_boolean_add(json_flags, "valid",
|
||||
CHECK_FLAG(flags, BGP_PATH_VALID));
|
||||
json_object_boolean_add(json_flags, "attrChanged",
|
||||
CHECK_FLAG(flags, BGP_PATH_ATTR_CHANGED));
|
||||
json_object_boolean_add(json_flags, "deterministicMedCheck",
|
||||
CHECK_FLAG(flags, BGP_PATH_DMED_CHECK));
|
||||
json_object_boolean_add(json_flags, "deterministicMedSelected",
|
||||
CHECK_FLAG(flags, BGP_PATH_DMED_SELECTED));
|
||||
json_object_boolean_add(json_flags, "stale",
|
||||
CHECK_FLAG(flags, BGP_PATH_STALE));
|
||||
json_object_boolean_add(json_flags, "removed",
|
||||
CHECK_FLAG(flags, BGP_PATH_REMOVED));
|
||||
json_object_boolean_add(json_flags, "counted",
|
||||
CHECK_FLAG(flags, BGP_PATH_COUNTED));
|
||||
json_object_boolean_add(json_flags, "multipath",
|
||||
CHECK_FLAG(flags, BGP_PATH_MULTIPATH));
|
||||
json_object_boolean_add(json_flags, "multipathChanged",
|
||||
CHECK_FLAG(flags, BGP_PATH_MULTIPATH_CHG));
|
||||
json_object_boolean_add(json_flags, "ribAttributeChanged",
|
||||
CHECK_FLAG(flags, BGP_PATH_RIB_ATTR_CHG));
|
||||
json_object_boolean_add(json_flags, "nexthopSelf",
|
||||
CHECK_FLAG(flags, BGP_PATH_ANNC_NH_SELF));
|
||||
json_object_boolean_add(json_flags, "linkBandwidthChanged",
|
||||
CHECK_FLAG(flags, BGP_PATH_LINK_BW_CHG));
|
||||
json_object_boolean_add(json_flags, "acceptOwn",
|
||||
CHECK_FLAG(flags, BGP_PATH_ACCEPT_OWN));
|
||||
json_object_object_add(json, "flags", json_flags);
|
||||
}
|
||||
|
||||
@ -859,7 +859,7 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
|
||||
json_object_string_addf(json_gate, "ip", "%pI6",
|
||||
&nexthop->gate.ipv6);
|
||||
json_object_string_add(
|
||||
json_gate, "ifname",
|
||||
json_gate, "interfaceName",
|
||||
ifindex2ifname(
|
||||
bnc->ifindex ? bnc->ifindex
|
||||
: nexthop->ifindex,
|
||||
@ -871,7 +871,7 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
|
||||
break;
|
||||
case NEXTHOP_TYPE_IFINDEX:
|
||||
json_object_string_add(
|
||||
json_gate, "ifname",
|
||||
json_gate, "interfaceName",
|
||||
ifindex2ifname(
|
||||
bnc->ifindex ? bnc->ifindex
|
||||
: nexthop->ifindex,
|
||||
@ -881,7 +881,7 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
|
||||
json_object_string_addf(json_gate, "ip", "%pI4",
|
||||
&nexthop->gate.ipv4);
|
||||
json_object_string_add(
|
||||
json_gate, "ifname",
|
||||
json_gate, "interfaceName",
|
||||
ifindex2ifname(
|
||||
bnc->ifindex ? bnc->ifindex
|
||||
: nexthop->ifindex,
|
||||
@ -889,11 +889,26 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
|
||||
break;
|
||||
case NEXTHOP_TYPE_BLACKHOLE:
|
||||
json_object_boolean_true_add(json_gate,
|
||||
"isBlackhole");
|
||||
"unreachable");
|
||||
switch (nexthop->bh_type) {
|
||||
case BLACKHOLE_REJECT:
|
||||
json_object_boolean_true_add(json_gate,
|
||||
"reject");
|
||||
break;
|
||||
case BLACKHOLE_ADMINPROHIB:
|
||||
json_object_boolean_true_add(
|
||||
json_gate, "adminProhibited");
|
||||
break;
|
||||
case BLACKHOLE_NULL:
|
||||
json_object_boolean_true_add(
|
||||
json_gate, "blackhole");
|
||||
break;
|
||||
case BLACKHOLE_UNSPEC:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
json_object_boolean_false_add(
|
||||
json_gate, "isValidNexthopType");
|
||||
break;
|
||||
}
|
||||
json_object_array_add(json_gates, json_gate);
|
||||
continue;
|
||||
@ -934,7 +949,7 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
|
||||
}
|
||||
}
|
||||
if (json)
|
||||
json_object_object_add(json, "gates", json_gates);
|
||||
json_object_object_add(json, "nexthops", json_gates);
|
||||
}
|
||||
|
||||
static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
|
||||
@ -1037,12 +1052,16 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
|
||||
}
|
||||
tbuf = time(NULL) - (monotime(NULL) - bnc->last_update);
|
||||
if (json) {
|
||||
json_last_update = json_object_new_object();
|
||||
json_object_int_add(json_last_update, "epoch", tbuf);
|
||||
json_object_string_add(json_last_update, "string",
|
||||
ctime(&tbuf));
|
||||
json_object_object_add(json_nexthop, "lastUpdate",
|
||||
json_last_update);
|
||||
if (!specific) {
|
||||
json_last_update = json_object_new_object();
|
||||
json_object_int_add(json_last_update, "epoch", tbuf);
|
||||
json_object_string_add(json_last_update, "string",
|
||||
ctime(&tbuf));
|
||||
json_object_object_add(json_nexthop, "lastUpdate",
|
||||
json_last_update);
|
||||
} else {
|
||||
json_object_int_add(json_nexthop, "lastUpdate", tbuf);
|
||||
}
|
||||
} else {
|
||||
vty_out(vty, " Last update: %s", ctime(&tbuf));
|
||||
}
|
||||
@ -1055,12 +1074,13 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
|
||||
}
|
||||
|
||||
static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp,
|
||||
bool import_table, json_object *json)
|
||||
bool import_table, json_object *json, afi_t afi,
|
||||
bool detail)
|
||||
{
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
afi_t afi;
|
||||
struct bgp_nexthop_cache_head(*tree)[AFI_MAX];
|
||||
json_object *json_nexthops = NULL;
|
||||
json_object *json_afi = NULL;
|
||||
bool found = false;
|
||||
|
||||
if (!json) {
|
||||
if (import_table)
|
||||
@ -1072,24 +1092,41 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp,
|
||||
tree = &bgp->import_check_table;
|
||||
else
|
||||
tree = &bgp->nexthop_cache_table;
|
||||
if (json)
|
||||
json_nexthops = json_object_new_object();
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc)
|
||||
bgp_show_nexthop(vty, bgp, bnc, false, json_nexthops);
|
||||
|
||||
if (afi == AFI_IP || afi == AFI_IP6) {
|
||||
if (json)
|
||||
json_afi = json_object_new_object();
|
||||
frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc) {
|
||||
bgp_show_nexthop(vty, bgp, bnc, detail, json_afi);
|
||||
found = true;
|
||||
}
|
||||
if (found && json)
|
||||
json_object_object_add(
|
||||
json, (afi == AFI_IP) ? "ipv4" : "ipv6",
|
||||
json_afi);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
if (json && (afi == AFI_IP || afi == AFI_IP6))
|
||||
json_afi = json_object_new_object();
|
||||
frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc)
|
||||
bgp_show_nexthop(vty, bgp, bnc, detail, json_afi);
|
||||
if (json && (afi == AFI_IP || afi == AFI_IP6))
|
||||
json_object_object_add(
|
||||
json, (afi == AFI_IP) ? "ipv4" : "ipv6",
|
||||
json_afi);
|
||||
}
|
||||
if (json)
|
||||
json_object_object_add(json, "nexthops", json_nexthops);
|
||||
}
|
||||
|
||||
static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
|
||||
const char *nhopip_str, bool import_table,
|
||||
json_object *json)
|
||||
json_object *json, afi_t afi, bool detail)
|
||||
{
|
||||
struct bgp *bgp;
|
||||
json_object *json_nexthops = NULL;
|
||||
|
||||
if (name)
|
||||
if (name && strcmp(name, VRF_DEFAULT_NAME) != 0)
|
||||
bgp = bgp_lookup_by_name(name);
|
||||
else
|
||||
bgp = bgp_get_default();
|
||||
@ -1104,6 +1141,7 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
|
||||
struct bgp_nexthop_cache_head (*tree)[AFI_MAX];
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
bool found = false;
|
||||
json_object *json_afi = NULL;
|
||||
|
||||
if (!str2prefix(nhopip_str, &nhop)) {
|
||||
if (!json)
|
||||
@ -1113,27 +1151,32 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
|
||||
tree = import_table ? &bgp->import_check_table
|
||||
: &bgp->nexthop_cache_table;
|
||||
if (json)
|
||||
json_nexthops = json_object_new_object();
|
||||
json_afi = json_object_new_object();
|
||||
frr_each (bgp_nexthop_cache, &(*tree)[family2afi(nhop.family)],
|
||||
bnc) {
|
||||
if (prefix_cmp(&bnc->prefix, &nhop))
|
||||
continue;
|
||||
bgp_show_nexthop(vty, bgp, bnc, true, json_nexthops);
|
||||
bgp_show_nexthop(vty, bgp, bnc, true, json_afi);
|
||||
found = true;
|
||||
}
|
||||
if (json)
|
||||
json_object_object_add(json, "nexthops", json_nexthops);
|
||||
json_object_object_add(
|
||||
json,
|
||||
(family2afi(nhop.family) == AFI_IP) ? "ipv4"
|
||||
: "ipv6",
|
||||
json_afi);
|
||||
if (!found && !json)
|
||||
vty_out(vty, "nexthop %s does not have entry\n",
|
||||
nhopip_str);
|
||||
} else
|
||||
bgp_show_nexthops(vty, bgp, import_table, json);
|
||||
bgp_show_nexthops(vty, bgp, import_table, json, afi, detail);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void bgp_show_all_instances_nexthops_vty(struct vty *vty,
|
||||
json_object *json)
|
||||
json_object *json, afi_t afi,
|
||||
bool detail)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct bgp *bgp;
|
||||
@ -1149,7 +1192,7 @@ static void bgp_show_all_instances_nexthops_vty(struct vty *vty,
|
||||
else
|
||||
vty_out(vty, "\nInstance %s:\n", inst_name);
|
||||
|
||||
bgp_show_nexthops(vty, bgp, false, json_instance);
|
||||
bgp_show_nexthops(vty, bgp, false, json_instance, afi, detail);
|
||||
|
||||
if (json)
|
||||
json_object_object_add(json, inst_name, json_instance);
|
||||
@ -1176,6 +1219,7 @@ DEFUN (show_ip_bgp_nexthop,
|
||||
char *nhop_ip = NULL;
|
||||
json_object *json = NULL;
|
||||
bool uj = use_json(argc, argv);
|
||||
bool detail = false;
|
||||
|
||||
if (uj)
|
||||
json = json_object_new_object();
|
||||
@ -1188,7 +1232,11 @@ DEFUN (show_ip_bgp_nexthop,
|
||||
|| argv_find(argv, argc, "X:X::X:X", &nh_idx))
|
||||
nhop_ip = argv[nh_idx]->arg;
|
||||
|
||||
rc = show_ip_bgp_nexthop_table(vty, vrf, nhop_ip, false, json);
|
||||
if (argv_find(argv, argc, "detail", &idx))
|
||||
detail = true;
|
||||
|
||||
rc = show_ip_bgp_nexthop_table(vty, vrf, nhop_ip, false, json,
|
||||
AFI_UNSPEC, detail);
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
@ -1211,6 +1259,7 @@ DEFUN (show_ip_bgp_import_check,
|
||||
char *vrf = NULL;
|
||||
json_object *json = NULL;
|
||||
bool uj = use_json(argc, argv);
|
||||
bool detail = false;
|
||||
|
||||
if (uj)
|
||||
json = json_object_new_object();
|
||||
@ -1219,7 +1268,11 @@ DEFUN (show_ip_bgp_import_check,
|
||||
|| argv_find(argv, argc, "vrf", &idx))
|
||||
vrf = argv[++idx]->arg;
|
||||
|
||||
rc = show_ip_bgp_nexthop_table(vty, vrf, NULL, true, json);
|
||||
if (argv_find(argv, argc, "detail", &idx))
|
||||
detail = true;
|
||||
|
||||
rc = show_ip_bgp_nexthop_table(vty, vrf, NULL, true, json, AFI_UNSPEC,
|
||||
detail);
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
@ -1238,11 +1291,19 @@ DEFUN (show_ip_bgp_instance_all_nexthop,
|
||||
{
|
||||
json_object *json = NULL;
|
||||
bool uj = use_json(argc, argv);
|
||||
int idx = 0;
|
||||
afi_t afi = AFI_UNSPEC;
|
||||
bool detail = false;
|
||||
|
||||
if (uj)
|
||||
json = json_object_new_object();
|
||||
|
||||
bgp_show_all_instances_nexthops_vty(vty, json);
|
||||
argv_find_and_parse_afi(argv, argc, &idx, &afi);
|
||||
|
||||
if (argv_find(argv, argc, "detail", &idx))
|
||||
detail = true;
|
||||
|
||||
bgp_show_all_instances_nexthops_vty(vty, json, afi, detail);
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
|
Loading…
Reference in New Issue
Block a user