mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 03:27:25 +00:00
zebra: include backup nexthops in nhe/nhg show output
Include backup nexthops (if any) in the output of 'show nexthop-group xxx'. Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
parent
0328a5bd0d
commit
eeafa8cd43
@ -1024,13 +1024,116 @@ DEFUN (ip_nht_default_route,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper that prints out a nexthop in an nhe/nhg
|
||||||
|
*/
|
||||||
|
static void show_nhg_nh_helper(struct vty *vty, const struct nexthop *nexthop)
|
||||||
|
{
|
||||||
|
char buf[SRCDEST2STR_BUFFER];
|
||||||
|
|
||||||
|
switch (nexthop->type) {
|
||||||
|
case NEXTHOP_TYPE_IPV4:
|
||||||
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
|
vty_out(vty, " %s", inet_ntoa(nexthop->gate.ipv4));
|
||||||
|
if (nexthop->ifindex)
|
||||||
|
vty_out(vty, ", %s",
|
||||||
|
ifindex2ifname(nexthop->ifindex,
|
||||||
|
nexthop->vrf_id));
|
||||||
|
break;
|
||||||
|
case NEXTHOP_TYPE_IPV6:
|
||||||
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||||
|
vty_out(vty, " %s",
|
||||||
|
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
|
||||||
|
sizeof(buf)));
|
||||||
|
if (nexthop->ifindex)
|
||||||
|
vty_out(vty, ", %s",
|
||||||
|
ifindex2ifname(nexthop->ifindex,
|
||||||
|
nexthop->vrf_id));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NEXTHOP_TYPE_IFINDEX:
|
||||||
|
vty_out(vty, " directly connected %s",
|
||||||
|
ifindex2ifname(nexthop->ifindex,
|
||||||
|
nexthop->vrf_id));
|
||||||
|
break;
|
||||||
|
case NEXTHOP_TYPE_BLACKHOLE:
|
||||||
|
vty_out(vty, " unreachable");
|
||||||
|
switch (nexthop->bh_type) {
|
||||||
|
case BLACKHOLE_REJECT:
|
||||||
|
vty_out(vty, " (ICMP unreachable)");
|
||||||
|
break;
|
||||||
|
case BLACKHOLE_ADMINPROHIB:
|
||||||
|
vty_out(vty, " (ICMP admin-prohibited)");
|
||||||
|
break;
|
||||||
|
case BLACKHOLE_NULL:
|
||||||
|
vty_out(vty, " (blackhole)");
|
||||||
|
break;
|
||||||
|
case BLACKHOLE_UNSPEC:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
|
||||||
|
|
||||||
|
if (vrf)
|
||||||
|
vty_out(vty, " (vrf %s)", vrf->name);
|
||||||
|
else
|
||||||
|
vty_out(vty, " (vrf UNKNOWN)");
|
||||||
|
|
||||||
|
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
||||||
|
vty_out(vty, " inactive");
|
||||||
|
|
||||||
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
||||||
|
vty_out(vty, " onlink");
|
||||||
|
|
||||||
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
|
vty_out(vty, " (recursive)");
|
||||||
|
|
||||||
|
switch (nexthop->type) {
|
||||||
|
case NEXTHOP_TYPE_IPV4:
|
||||||
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
|
if (nexthop->src.ipv4.s_addr) {
|
||||||
|
if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
|
||||||
|
sizeof(buf)))
|
||||||
|
vty_out(vty, ", src %s", buf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NEXTHOP_TYPE_IPV6:
|
||||||
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||||
|
if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
|
||||||
|
if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
|
||||||
|
sizeof(buf)))
|
||||||
|
vty_out(vty, ", src %s", buf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Label information */
|
||||||
|
if (nexthop->nh_label && nexthop->nh_label->num_labels) {
|
||||||
|
vty_out(vty, ", label %s",
|
||||||
|
mpls_label2str(nexthop->nh_label->num_labels,
|
||||||
|
nexthop->nh_label->label, buf,
|
||||||
|
sizeof(buf), 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nexthop->weight)
|
||||||
|
vty_out(vty, ", weight %u", nexthop->weight);
|
||||||
|
|
||||||
|
vty_out(vty, "\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe)
|
static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe)
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop = NULL;
|
struct nexthop *nexthop = NULL;
|
||||||
struct nhg_connected *rb_node_dep = NULL;
|
struct nhg_connected *rb_node_dep = NULL;
|
||||||
char buf[SRCDEST2STR_BUFFER];
|
|
||||||
|
|
||||||
struct vrf *nhe_vrf = vrf_lookup_by_id(nhe->vrf_id);
|
struct vrf *nhe_vrf = vrf_lookup_by_id(nhe->vrf_id);
|
||||||
|
struct nexthop_group *backup_nhg;
|
||||||
|
|
||||||
vty_out(vty, "ID: %u\n", nhe->id);
|
vty_out(vty, "ID: %u\n", nhe->id);
|
||||||
vty_out(vty, " RefCnt: %d\n", nhe->refcnt);
|
vty_out(vty, " RefCnt: %d\n", nhe->refcnt);
|
||||||
@ -1062,6 +1165,7 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe)
|
|||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Output nexthops */
|
||||||
for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
|
for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
|
||||||
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
vty_out(vty, " ");
|
vty_out(vty, " ");
|
||||||
@ -1069,100 +1173,23 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe)
|
|||||||
/* Make recursive nexthops a bit more clear */
|
/* Make recursive nexthops a bit more clear */
|
||||||
vty_out(vty, " ");
|
vty_out(vty, " ");
|
||||||
|
|
||||||
switch (nexthop->type) {
|
show_nhg_nh_helper(vty, nexthop);
|
||||||
case NEXTHOP_TYPE_IPV4:
|
}
|
||||||
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
||||||
vty_out(vty, " %s", inet_ntoa(nexthop->gate.ipv4));
|
|
||||||
if (nexthop->ifindex)
|
|
||||||
vty_out(vty, ", %s",
|
|
||||||
ifindex2ifname(nexthop->ifindex,
|
|
||||||
nexthop->vrf_id));
|
|
||||||
break;
|
|
||||||
case NEXTHOP_TYPE_IPV6:
|
|
||||||
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
||||||
vty_out(vty, " %s",
|
|
||||||
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
|
|
||||||
sizeof(buf)));
|
|
||||||
if (nexthop->ifindex)
|
|
||||||
vty_out(vty, ", %s",
|
|
||||||
ifindex2ifname(nexthop->ifindex,
|
|
||||||
nexthop->vrf_id));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NEXTHOP_TYPE_IFINDEX:
|
/* Output backup nexthops (if any) */
|
||||||
vty_out(vty, " directly connected %s",
|
backup_nhg = zebra_nhg_get_backup_nhg(nhe);
|
||||||
ifindex2ifname(nexthop->ifindex,
|
if (backup_nhg) {
|
||||||
nexthop->vrf_id));
|
vty_out(vty, " Backups:\n");
|
||||||
break;
|
|
||||||
case NEXTHOP_TYPE_BLACKHOLE:
|
for (ALL_NEXTHOPS_PTR(backup_nhg, nexthop)) {
|
||||||
vty_out(vty, " unreachable");
|
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
switch (nexthop->bh_type) {
|
vty_out(vty, " ");
|
||||||
case BLACKHOLE_REJECT:
|
else
|
||||||
vty_out(vty, " (ICMP unreachable)");
|
/* Make recursive nexthops a bit more clear */
|
||||||
break;
|
vty_out(vty, " ");
|
||||||
case BLACKHOLE_ADMINPROHIB:
|
|
||||||
vty_out(vty, " (ICMP admin-prohibited)");
|
show_nhg_nh_helper(vty, nexthop);
|
||||||
break;
|
|
||||||
case BLACKHOLE_NULL:
|
|
||||||
vty_out(vty, " (blackhole)");
|
|
||||||
break;
|
|
||||||
case BLACKHOLE_UNSPEC:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
|
|
||||||
|
|
||||||
if (vrf)
|
|
||||||
vty_out(vty, " (vrf %s)", vrf->name);
|
|
||||||
else
|
|
||||||
vty_out(vty, " (vrf UNKNOWN)");
|
|
||||||
|
|
||||||
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
|
||||||
vty_out(vty, " inactive");
|
|
||||||
|
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
|
||||||
vty_out(vty, " onlink");
|
|
||||||
|
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
|
||||||
vty_out(vty, " (recursive)");
|
|
||||||
|
|
||||||
switch (nexthop->type) {
|
|
||||||
case NEXTHOP_TYPE_IPV4:
|
|
||||||
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
||||||
if (nexthop->src.ipv4.s_addr) {
|
|
||||||
if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
|
|
||||||
sizeof(buf)))
|
|
||||||
vty_out(vty, ", src %s", buf);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NEXTHOP_TYPE_IPV6:
|
|
||||||
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
||||||
if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
|
|
||||||
if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
|
|
||||||
sizeof(buf)))
|
|
||||||
vty_out(vty, ", src %s", buf);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Label information */
|
|
||||||
if (nexthop->nh_label && nexthop->nh_label->num_labels) {
|
|
||||||
vty_out(vty, ", label %s",
|
|
||||||
mpls_label2str(nexthop->nh_label->num_labels,
|
|
||||||
nexthop->nh_label->label, buf,
|
|
||||||
sizeof(buf), 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nexthop->weight)
|
|
||||||
vty_out(vty, ", weight %u", nexthop->weight);
|
|
||||||
|
|
||||||
vty_out(vty, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zebra_nhg_dependents_is_empty(nhe)) {
|
if (!zebra_nhg_dependents_is_empty(nhe)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user