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:
vivek 2018-08-20 20:00:50 +00:00
parent f07e1c99d6
commit 1a8c5c38aa

View File

@ -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);