mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 15:33:56 +00:00
zebra: Enhancements to EVPN operational commands
Enhance the EVPN MAC and Neighbor cache display to show additional information such as the mobility sequence numbers and the state. Ensure that the neighbor state is set in a couple of places so that the display is correct. Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
This commit is contained in:
parent
f07e1c99d6
commit
1a8c5c38aa
@ -296,47 +296,59 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
|
|||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
char buf1[ETHER_ADDR_STRLEN];
|
char buf1[ETHER_ADDR_STRLEN];
|
||||||
char buf2[INET6_ADDRSTRLEN];
|
char buf2[INET6_ADDRSTRLEN];
|
||||||
|
const char *type_str;
|
||||||
|
const char *state_str;
|
||||||
|
bool flags_present = false;
|
||||||
|
|
||||||
ipaddr2str(&n->ip, buf2, sizeof(buf2));
|
ipaddr2str(&n->ip, buf2, sizeof(buf2));
|
||||||
prefix_mac2str(&n->emac, buf1, sizeof(buf1));
|
prefix_mac2str(&n->emac, buf1, sizeof(buf1));
|
||||||
|
type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ?
|
||||||
|
"local" : "remote";
|
||||||
|
state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
|
||||||
vty = (struct vty *)ctxt;
|
vty = (struct vty *)ctxt;
|
||||||
if (json == NULL) {
|
if (json == NULL) {
|
||||||
vty_out(vty, "IP: %s\n",
|
vty_out(vty, "IP: %s\n",
|
||||||
ipaddr2str(&n->ip, buf2, sizeof(buf2)));
|
ipaddr2str(&n->ip, buf2, sizeof(buf2)));
|
||||||
vty_out(vty, " MAC: %s",
|
vty_out(vty, " Type: %s\n", type_str);
|
||||||
|
vty_out(vty, " State: %s\n", state_str);
|
||||||
|
vty_out(vty, " MAC: %s\n",
|
||||||
prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
|
prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
|
||||||
} else {
|
} else {
|
||||||
json_object_string_add(json, "ip", buf2);
|
json_object_string_add(json, "ip", buf2);
|
||||||
|
json_object_string_add(json, "type", type_str);
|
||||||
|
json_object_string_add(json, "state", state_str);
|
||||||
json_object_string_add(json, "mac", buf1);
|
json_object_string_add(json, "mac", buf1);
|
||||||
}
|
}
|
||||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
|
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
|
||||||
if (json == NULL) {
|
if (json == NULL) {
|
||||||
vty_out(vty, " Remote VTEP: %s",
|
vty_out(vty, " Remote VTEP: %s\n",
|
||||||
inet_ntoa(n->r_vtep_ip));
|
inet_ntoa(n->r_vtep_ip));
|
||||||
} else
|
} else
|
||||||
json_object_string_add(json, "remoteVtep",
|
json_object_string_add(json, "remoteVtep",
|
||||||
inet_ntoa(n->r_vtep_ip));
|
inet_ntoa(n->r_vtep_ip));
|
||||||
}
|
}
|
||||||
if (!json) {
|
|
||||||
vty_out(vty, "\n");
|
|
||||||
vty_out(vty, " State: %s",
|
|
||||||
IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active"
|
|
||||||
: "Inactive");
|
|
||||||
}
|
|
||||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
|
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
|
||||||
if (!json)
|
if (!json) {
|
||||||
vty_out(vty, " Default-gateway");
|
vty_out(vty, " Flags: Default-gateway");
|
||||||
else
|
flags_present = true;
|
||||||
|
} else
|
||||||
json_object_boolean_true_add(json, "defaultGateway");
|
json_object_boolean_true_add(json, "defaultGateway");
|
||||||
}
|
}
|
||||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
|
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
|
||||||
if (!json)
|
if (!json) {
|
||||||
vty_out(vty, " Router");
|
vty_out(vty,
|
||||||
|
flags_present ? " ,Router" : " Flags: Router");
|
||||||
|
flags_present = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (json == NULL) {
|
if (json == NULL) {
|
||||||
vty_out(vty, " Local Seq: %u Remote Seq: %u",
|
if (flags_present)
|
||||||
|
vty_out(vty, "\n");
|
||||||
|
vty_out(vty, " Local Seq: %u Remote Seq: %u\n",
|
||||||
n->loc_seq, n->rem_seq);
|
n->loc_seq, n->rem_seq);
|
||||||
vty_out(vty, "\n");
|
} else {
|
||||||
|
json_object_int_add(json, "localSequence", n->loc_seq);
|
||||||
|
json_object_int_add(json, "remoteSequence", n->rem_seq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,6 +363,7 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
|
|||||||
char buf1[ETHER_ADDR_STRLEN];
|
char buf1[ETHER_ADDR_STRLEN];
|
||||||
char buf2[INET6_ADDRSTRLEN];
|
char buf2[INET6_ADDRSTRLEN];
|
||||||
struct neigh_walk_ctx *wctx = ctxt;
|
struct neigh_walk_ctx *wctx = ctxt;
|
||||||
|
const char *state_str;
|
||||||
|
|
||||||
vty = wctx->vty;
|
vty = wctx->vty;
|
||||||
json_vni = wctx->json;
|
json_vni = wctx->json;
|
||||||
@ -361,55 +374,58 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
|
|||||||
|
|
||||||
prefix_mac2str(&n->emac, buf1, sizeof(buf1));
|
prefix_mac2str(&n->emac, buf1, sizeof(buf1));
|
||||||
ipaddr2str(&n->ip, buf2, sizeof(buf2));
|
ipaddr2str(&n->ip, buf2, sizeof(buf2));
|
||||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
|
state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
|
||||||
&& !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) {
|
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
|
||||||
|
if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
|
||||||
|
return;
|
||||||
|
|
||||||
if (json_vni == NULL) {
|
if (json_vni == NULL) {
|
||||||
vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width,
|
vty_out(vty, "%*s %-6s %-8s %-17s\n",
|
||||||
buf2, "local", buf1);
|
-wctx->addr_width, buf2, "local",
|
||||||
|
state_str, buf1);
|
||||||
} else {
|
} else {
|
||||||
json_object_string_add(json_row, "type", "local");
|
json_object_string_add(json_row, "type", "local");
|
||||||
|
json_object_string_add(json_row, "state", state_str);
|
||||||
json_object_string_add(json_row, "mac", buf1);
|
json_object_string_add(json_row, "mac", buf1);
|
||||||
|
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
|
||||||
|
json_object_boolean_true_add(
|
||||||
|
json_row, "defaultGateway");
|
||||||
|
json_object_int_add(json_row, "localSequence",
|
||||||
|
n->loc_seq);
|
||||||
|
json_object_int_add(json_row, "remoteSequence",
|
||||||
|
n->rem_seq);
|
||||||
}
|
}
|
||||||
wctx->count++;
|
wctx->count++;
|
||||||
} else {
|
} else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
|
||||||
if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) {
|
if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
|
||||||
if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) {
|
!IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))
|
||||||
if (json_vni == NULL) {
|
return;
|
||||||
if (wctx->count == 0)
|
|
||||||
vty_out(vty,
|
if (json_vni == NULL) {
|
||||||
"%*s %-6s %-17s %-21s\n",
|
if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
|
||||||
-wctx->addr_width,
|
(wctx->count == 0))
|
||||||
"Neighbor", "Type",
|
vty_out(vty,
|
||||||
"MAC", "Remote VTEP");
|
"%*s %-6s %-8s %-17s %-21s\n",
|
||||||
vty_out(vty, "%*s %-6s %-17s %-21s\n",
|
-wctx->addr_width, "Neighbor", "Type",
|
||||||
-wctx->addr_width, buf2,
|
"State", "MAC", "Remote VTEP");
|
||||||
"remote", buf1,
|
vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
|
||||||
inet_ntoa(n->r_vtep_ip));
|
-wctx->addr_width, buf2, "remote", state_str,
|
||||||
} else {
|
buf1, inet_ntoa(n->r_vtep_ip));
|
||||||
json_object_string_add(json_row, "type",
|
|
||||||
"remote");
|
|
||||||
json_object_string_add(json_row, "mac",
|
|
||||||
buf1);
|
|
||||||
json_object_string_add(
|
|
||||||
json_row, "remoteVtep",
|
|
||||||
inet_ntoa(n->r_vtep_ip));
|
|
||||||
}
|
|
||||||
wctx->count++;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (json_vni == NULL) {
|
json_object_string_add(json_row, "type", "remote");
|
||||||
vty_out(vty, "%*s %-6s %-17s %-21s\n",
|
json_object_string_add(json_row, "state", state_str);
|
||||||
-wctx->addr_width, buf2, "remote", buf1,
|
json_object_string_add(json_row, "mac", buf1);
|
||||||
inet_ntoa(n->r_vtep_ip));
|
json_object_string_add(json_row, "remoteVtep",
|
||||||
} else {
|
inet_ntoa(n->r_vtep_ip));
|
||||||
json_object_string_add(json_row, "type",
|
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
|
||||||
"remote");
|
json_object_boolean_true_add(json_row,
|
||||||
json_object_string_add(json_row, "mac", buf1);
|
"defaultGateway");
|
||||||
json_object_string_add(json_row, "remoteVtep",
|
json_object_int_add(json_row, "localSequence",
|
||||||
inet_ntoa(n->r_vtep_ip));
|
n->loc_seq);
|
||||||
}
|
json_object_int_add(json_row, "remoteSequence",
|
||||||
wctx->count++;
|
n->rem_seq);
|
||||||
}
|
}
|
||||||
|
wctx->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json_vni)
|
if (json_vni)
|
||||||
@ -462,8 +478,9 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
|
|||||||
hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
|
hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
|
||||||
|
|
||||||
if (json == NULL) {
|
if (json == NULL) {
|
||||||
vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
|
vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
|
||||||
"Type", "MAC", "Remote VTEP");
|
-wctx.addr_width, "IP", "Type",
|
||||||
|
"State", "MAC", "Remote VTEP");
|
||||||
}
|
}
|
||||||
hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
|
hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
|
||||||
|
|
||||||
@ -523,8 +540,6 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
|
|||||||
vty_out(vty, " Remote VTEP: %s\n",
|
vty_out(vty, " Remote VTEP: %s\n",
|
||||||
inet_ntoa(zrmac->fwd_info.r_vtep_ip));
|
inet_ntoa(zrmac->fwd_info.r_vtep_ip));
|
||||||
vty_out(vty, " Refcount: %d\n", rb_host_count(&zrmac->host_rb));
|
vty_out(vty, " Refcount: %d\n", rb_host_count(&zrmac->host_rb));
|
||||||
vty_out(vty, " Local Seq: %u Remote Seq: %u\n",
|
|
||||||
zrmac->loc_seq, zrmac->rem_seq);
|
|
||||||
vty_out(vty, " Prefixes:\n");
|
vty_out(vty, " Prefixes:\n");
|
||||||
RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
|
RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
|
||||||
vty_out(vty, " %s\n",
|
vty_out(vty, " %s\n",
|
||||||
@ -538,6 +553,8 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
|
|||||||
inet_ntoa(zrmac->fwd_info.r_vtep_ip));
|
inet_ntoa(zrmac->fwd_info.r_vtep_ip));
|
||||||
json_object_int_add(json, "refCount",
|
json_object_int_add(json, "refCount",
|
||||||
rb_host_count(&zrmac->host_rb));
|
rb_host_count(&zrmac->host_rb));
|
||||||
|
json_object_int_add(json, "localSequence", zrmac->loc_seq);
|
||||||
|
json_object_int_add(json, "remoteSequence", zrmac->rem_seq);
|
||||||
RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
|
RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
|
||||||
json_object_array_add(
|
json_object_array_add(
|
||||||
json_hosts,
|
json_hosts,
|
||||||
@ -631,13 +648,15 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
|
|||||||
if (json_mac_hdr)
|
if (json_mac_hdr)
|
||||||
json_mac = json_object_new_object();
|
json_mac = json_object_new_object();
|
||||||
|
|
||||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
|
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
|
||||||
&& !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) {
|
|
||||||
struct zebra_ns *zns;
|
struct zebra_ns *zns;
|
||||||
ifindex_t ifindex;
|
ifindex_t ifindex;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
vlanid_t vid;
|
vlanid_t vid;
|
||||||
|
|
||||||
|
if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)
|
||||||
|
return;
|
||||||
|
|
||||||
zns = zebra_ns_lookup(NS_DEFAULT);
|
zns = zebra_ns_lookup(NS_DEFAULT);
|
||||||
ifindex = mac->fwd_info.local.ifindex;
|
ifindex = mac->fwd_info.local.ifindex;
|
||||||
ifp = if_lookup_by_index_per_ns(zns, ifindex);
|
ifp = if_lookup_by_index_per_ns(zns, ifindex);
|
||||||
@ -657,59 +676,46 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
|
|||||||
else
|
else
|
||||||
json_object_int_add(json_mac, "vlan", vid);
|
json_object_int_add(json_mac, "vlan", vid);
|
||||||
}
|
}
|
||||||
if (json_mac_hdr == NULL)
|
if (json_mac_hdr == NULL) {
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
else
|
|
||||||
json_object_object_add(json_mac_hdr, buf1, json_mac);
|
|
||||||
wctx->count++;
|
|
||||||
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
|
|
||||||
if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) {
|
|
||||||
if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
|
|
||||||
&wctx->r_vtep_ip)) {
|
|
||||||
if (wctx->count == 0) {
|
|
||||||
if (json_mac_hdr == NULL) {
|
|
||||||
vty_out(vty, "\nVNI %u\n\n",
|
|
||||||
wctx->zvni->vni);
|
|
||||||
vty_out(vty,
|
|
||||||
"%-17s %-6s %-21s %-5s\n",
|
|
||||||
"MAC", "Type",
|
|
||||||
"Intf/Remote VTEP",
|
|
||||||
"VLAN");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (json_mac_hdr == NULL)
|
|
||||||
vty_out(vty, "%-17s %-6s %-21s\n", buf1,
|
|
||||||
"remote",
|
|
||||||
inet_ntoa(mac->fwd_info
|
|
||||||
.r_vtep_ip));
|
|
||||||
else {
|
|
||||||
json_object_string_add(json_mac, "type",
|
|
||||||
"remote");
|
|
||||||
json_object_string_add(
|
|
||||||
json_mac, "remoteVtep",
|
|
||||||
inet_ntoa(mac->fwd_info
|
|
||||||
.r_vtep_ip));
|
|
||||||
json_object_object_add(json_mac_hdr,
|
|
||||||
buf1, json_mac);
|
|
||||||
}
|
|
||||||
wctx->count++;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (json_mac_hdr == NULL)
|
json_object_int_add(json_mac, "localSequence",
|
||||||
vty_out(vty, "%-17s %-6s %-21s\n", buf1,
|
mac->loc_seq);
|
||||||
"remote",
|
json_object_int_add(json_mac, "remoteSequence",
|
||||||
inet_ntoa(mac->fwd_info.r_vtep_ip));
|
mac->rem_seq);
|
||||||
else {
|
json_object_object_add(json_mac_hdr, buf1, json_mac);
|
||||||
json_object_string_add(json_mac, "type",
|
|
||||||
"remote");
|
|
||||||
json_object_string_add(
|
|
||||||
json_mac, "remoteVtep",
|
|
||||||
inet_ntoa(mac->fwd_info.r_vtep_ip));
|
|
||||||
json_object_object_add(json_mac_hdr, buf1,
|
|
||||||
json_mac);
|
|
||||||
}
|
|
||||||
wctx->count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wctx->count++;
|
||||||
|
|
||||||
|
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
|
||||||
|
|
||||||
|
if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) &&
|
||||||
|
!IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
|
||||||
|
&wctx->r_vtep_ip))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (json_mac_hdr == NULL) {
|
||||||
|
if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) &&
|
||||||
|
(wctx->count == 0)) {
|
||||||
|
vty_out(vty, "\nVNI %u\n\n", wctx->zvni->vni);
|
||||||
|
vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC",
|
||||||
|
"Type", "Intf/Remote VTEP", "VLAN");
|
||||||
|
}
|
||||||
|
vty_out(vty, "%-17s %-6s %-21s\n", buf1, "remote",
|
||||||
|
inet_ntoa(mac->fwd_info.r_vtep_ip));
|
||||||
|
} else {
|
||||||
|
json_object_string_add(json_mac, "type", "remote");
|
||||||
|
json_object_string_add(json_mac, "remoteVtep",
|
||||||
|
inet_ntoa(mac->fwd_info.r_vtep_ip));
|
||||||
|
json_object_object_add(json_mac_hdr, buf1, json_mac);
|
||||||
|
json_object_int_add(json_mac, "localSequence",
|
||||||
|
mac->loc_seq);
|
||||||
|
json_object_int_add(json_mac, "remoteSequence",
|
||||||
|
mac->rem_seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
wctx->count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1794,6 +1800,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
|
|||||||
/* Set "local" forwarding info. */
|
/* Set "local" forwarding info. */
|
||||||
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
|
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
|
||||||
SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
|
SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
|
||||||
|
ZEBRA_NEIGH_SET_ACTIVE(n);
|
||||||
/* Set Router flag (R-bit) */
|
/* Set Router flag (R-bit) */
|
||||||
if (ip->ipa_type == IPADDR_V6)
|
if (ip->ipa_type == IPADDR_V6)
|
||||||
SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
|
SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
|
||||||
@ -4806,8 +4813,9 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
|
|||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"Number of ARPs (local and remote) known for this VNI: %u\n",
|
"Number of ARPs (local and remote) known for this VNI: %u\n",
|
||||||
num_neigh);
|
num_neigh);
|
||||||
vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
|
vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
|
||||||
"Type", "MAC", "Remote VTEP");
|
-wctx.addr_width, "IP", "Type",
|
||||||
|
"State", "MAC", "Remote VTEP");
|
||||||
} else
|
} else
|
||||||
json_object_int_add(json, "numArpNd", num_neigh);
|
json_object_int_add(json, "numArpNd", num_neigh);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user