return;
}
+#define FRR_BFD_MAXLEN 10 * 1024
+
+ if (plen > FRR_BFD_MAXLEN) {
+ zlog_debug("%s: client closed, invalid message length: %d",
+ __func__, bcm.bcm_length);
+ control_free(bcs);
+ return;
+ }
+
if (bcm.bcm_ver != BMV_VERSION_1) {
zlog_debug("%s: client closed due bad version: %d", __func__,
bcm.bcm_ver);
{BGP_ATTR_EXT_COMMUNITIES, "EXT_COMMUNITIES"},
{BGP_ATTR_AS4_PATH, "AS4_PATH"},
{BGP_ATTR_AS4_AGGREGATOR, "AS4_AGGREGATOR"},
- {BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT"},
{BGP_ATTR_PMSI_TUNNEL, "PMSI_TUNNEL_ATTRIBUTE"},
{BGP_ATTR_ENCAP, "ENCAP"},
{BGP_ATTR_OTC, "OTC"},
/* Locate VNI hash */
vpn = bgp_evpn_lookup_vni(bgp, vni);
- if (!vpn) {
- if (bgp_debug_zebra(NULL))
- flog_warn(
- EC_BGP_EVPN_VPN_VNI,
- "%u: VNI hash entry for VNI %u not found at DEL",
- bgp->vrf_id, vni);
+ if (!vpn)
return 0;
- }
/* Remove all local EVPN routes and schedule for processing (to
* withdraw from peers).
}
}
+int bgp_evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
+ bool use_json, int detail)
+{
+ json_object *json = NULL;
+
+ if (use_json)
+ json = json_object_new_object();
+
+ evpn_show_all_routes(vty, bgp, type, json, detail);
+
+ if (use_json)
+ vty_json(vty, json);
+ return CMD_SUCCESS;
+}
+
/*
* Display specified VNI (vty handler)
*/
extern int bgp_evpn_cli_parse_type(int *type, struct cmd_token **argv,
int argc);
+extern int bgp_evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
+ bool use_json, int detail);
+
#endif /* _QUAGGA_BGP_EVPN_VTY_H */
1, NULL, NULL);
}
+ if (safi == SAFI_EVPN)
+ return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
+
return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
NULL, NULL, &json_header_depth, show_flags,
rpki_target_state);
struct bgp_table *table, int *header1,
int *header2, json_object *json,
json_object *json_scode,
- json_object *json_ocode, bool wide)
+ json_object *json_ocode, bool wide,
+ bool detail)
{
uint64_t version = table ? table->version : 0;
vty_out(vty, "local AS %u\n",
peer->change_local_as ? peer->change_local_as
: peer->local_as);
- vty_out(vty, BGP_SHOW_SCODE_HEADER);
- vty_out(vty, BGP_SHOW_NCODE_HEADER);
- vty_out(vty, BGP_SHOW_OCODE_HEADER);
- vty_out(vty, BGP_SHOW_RPKI_HEADER);
+ if (!detail) {
+ vty_out(vty, BGP_SHOW_SCODE_HEADER);
+ vty_out(vty, BGP_SHOW_NCODE_HEADER);
+ vty_out(vty, BGP_SHOW_OCODE_HEADER);
+ vty_out(vty, BGP_SHOW_RPKI_HEADER);
+ }
}
*header1 = 0;
}
if (*header2) {
- if (!json)
+ if (!json && !detail)
vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
: BGP_SHOW_HEADER));
*header2 = 0;
struct update_subgroup *subgrp;
struct peer_af *paf;
bool route_filtered;
+ bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
|| (safi == SAFI_EVPN))
? true
: false;
+ int display = 0;
+ json_object *json_net = NULL;
bgp = peer->bgp;
vty_out(vty, "local AS %u\n",
peer->change_local_as ? peer->change_local_as
: peer->local_as);
- vty_out(vty, BGP_SHOW_SCODE_HEADER);
- vty_out(vty, BGP_SHOW_NCODE_HEADER);
- vty_out(vty, BGP_SHOW_OCODE_HEADER);
- vty_out(vty, BGP_SHOW_RPKI_HEADER);
+ if (!detail) {
+ vty_out(vty, BGP_SHOW_SCODE_HEADER);
+ vty_out(vty, BGP_SHOW_NCODE_HEADER);
+ vty_out(vty, BGP_SHOW_OCODE_HEADER);
+ vty_out(vty, BGP_SHOW_RPKI_HEADER);
+ }
vty_out(vty, "Originating default network %s\n\n",
(afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
show_adj_route_header(vty, peer, table, header1,
header2, json, json_scode,
- json_ocode, wide);
+ json_ocode, wide, detail);
if ((safi == SAFI_MPLS_VPN)
|| (safi == SAFI_ENCAP)
&& (route_filtered || ret == RMAP_DENY))
(*filtered_count)++;
- route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
- use_json, json_ar, wide);
+ if (detail) {
+ if (use_json)
+ json_net =
+ json_object_new_object();
+ bgp_show_path_info(
+ NULL /* prefix_rd */, dest, vty,
+ bgp, afi, safi, json_net,
+ BGP_PATH_SHOW_ALL, &display,
+ RPKI_NOT_BEING_USED);
+ if (use_json)
+ json_object_object_addf(
+ json_ar, json_net,
+ "%pFX", rn_p);
+ } else
+ route_vty_out_tmp(vty, dest, rn_p,
+ &attr, safi, use_json,
+ json_ar, wide);
bgp_attr_flush(&attr);
(*output_count)++;
}
if (paf->peer != peer || !adj->attr)
continue;
- show_adj_route_header(vty, peer, table,
- header1, header2,
- json, json_scode,
- json_ocode, wide);
+ show_adj_route_header(
+ vty, peer, table, header1,
+ header2, json, json_scode,
+ json_ocode, wide, detail);
const struct prefix *rn_p =
bgp_dest_get_prefix(dest);
show_rd = false;
}
}
- route_vty_out_tmp(
- vty, dest, rn_p, &attr,
- safi, use_json, json_ar,
- wide);
+ if (detail) {
+ if (use_json)
+ json_net =
+ json_object_new_object();
+ bgp_show_path_info(
+ NULL /* prefix_rd
+ */
+ ,
+ dest, vty, bgp,
+ afi, safi,
+ json_net,
+ BGP_PATH_SHOW_ALL,
+ &display,
+ RPKI_NOT_BEING_USED);
+ if (use_json)
+ json_object_object_addf(
+ json_ar,
+ json_net,
+ "%pFX",
+ rn_p);
+ } else
+ route_vty_out_tmp(
+ vty, dest, rn_p,
+ &attr, safi,
+ use_json,
+ json_ar, wide);
(*output_count)++;
} else {
(*filtered_count)++;
show_adj_route_header(vty, peer, table, header1,
header2, json, json_scode,
- json_ocode, wide);
+ json_ocode, wide, detail);
for (pi = bgp_dest_get_bgp_path_info(dest); pi;
pi = pi->next) {
show_flags);
}
-DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
- show_ip_bgp_instance_neighbor_advertised_route_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [all$all] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map RMAP_NAME$route_map] [json$uj | wide$wide]",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- BGP_AFI_HELP_STR
- BGP_SAFI_WITH_LABEL_HELP_STR
- "Display the entries for all address families\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on BGP configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "Display the received routes from neighbor\n"
- "Display the filtered routes received from neighbor\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n"
- JSON_STR
- "Increase table width for longer prefixes\n")
+DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
+ show_ip_bgp_instance_neighbor_advertised_route_cmd,
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR " [" BGP_SAFI_WITH_LABEL_CMD_STR "]] [all$all] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map RMAP_NAME$route_map] [detail$detail] [json$uj | wide$wide]",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ BGP_INSTANCE_HELP_STR
+ BGP_AFI_HELP_STR
+ BGP_SAFI_WITH_LABEL_HELP_STR
+ "Display the entries for all address families\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Neighbor on BGP configured interface\n"
+ "Display the routes advertised to a BGP neighbor\n"
+ "Display the received routes from neighbor\n"
+ "Display the filtered routes received from neighbor\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n"
+ "Display detailed version of routes\n"
+ JSON_STR
+ "Increase table width for longer prefixes\n")
{
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
struct listnode *node;
struct bgp *abgp;
+ if (detail)
+ SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
+
if (uj) {
argc--;
SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
return CMD_SUCCESS;
}
-DEFUN (show_bgp_vrfs,
+static inline void calc_peers_cfgd_estbd(struct bgp *bgp, int *peers_cfgd,
+ int *peers_estbd)
+{
+ struct peer *peer;
+ struct listnode *node;
+
+ *peers_cfgd = *peers_estbd = 0;
+ for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
+ if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+ continue;
+ (*peers_cfgd)++;
+ if (peer_established(peer))
+ (*peers_estbd)++;
+ }
+}
+
+static void print_bgp_vrfs(struct bgp *bgp, struct vty *vty, json_object *json,
+ const char *type)
+{
+ int peers_cfg, peers_estb;
+
+ calc_peers_cfgd_estbd(bgp, &peers_cfg, &peers_estb);
+
+ if (json) {
+ int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN)
+ ? -1
+ : (int64_t)bgp->vrf_id;
+ json_object_string_add(json, "type", type);
+ json_object_int_add(json, "vrfId", vrf_id_ui);
+ json_object_string_addf(json, "routerId", "%pI4",
+ &bgp->router_id);
+ json_object_int_add(json, "numConfiguredPeers", peers_cfg);
+ json_object_int_add(json, "numEstablishedPeers", peers_estb);
+ json_object_int_add(json, "l3vni", bgp->l3vni);
+ json_object_string_addf(json, "rmac", "%pEA", &bgp->rmac);
+ json_object_string_add(
+ json, "interface",
+ ifindex2ifname(bgp->l3vni_svi_ifindex, bgp->vrf_id));
+ }
+}
+
+static int show_bgp_vrfs_detail_common(struct vty *vty, struct bgp *bgp,
+ json_object *json, const char *name,
+ const char *type, bool use_vrf)
+{
+ int peers_cfg, peers_estb;
+
+ calc_peers_cfgd_estbd(bgp, &peers_cfg, &peers_estb);
+
+ if (use_vrf) {
+ if (json) {
+ print_bgp_vrfs(bgp, vty, json, type);
+ } else {
+ vty_out(vty, "BGP instance %s VRF id %d\n",
+ bgp->name_pretty,
+ bgp->vrf_id == VRF_UNKNOWN ? -1
+ : (int)bgp->vrf_id);
+ vty_out(vty, "Router Id %pI4\n", &bgp->router_id);
+ vty_out(vty,
+ "Num Configured Peers %d, Established %d\n",
+ peers_cfg, peers_estb);
+ if (bgp->l3vni) {
+ vty_out(vty,
+ "L3VNI %u, L3VNI-SVI %s, Router MAC %pEA\n",
+ bgp->l3vni,
+ ifindex2ifname(bgp->l3vni_svi_ifindex,
+ bgp->vrf_id),
+ &bgp->rmac);
+ }
+ }
+ } else {
+ if (json) {
+ print_bgp_vrfs(bgp, vty, json, type);
+ } else {
+ vty_out(vty, "%4s %-5d %-16pI4 %-9u %-10u %-37s\n",
+ type,
+ bgp->vrf_id == VRF_UNKNOWN ? -1
+ : (int)bgp->vrf_id,
+ &bgp->router_id, peers_cfg, peers_estb, name);
+ vty_out(vty, "%11s %-16u %-21pEA %-20s\n", " ",
+ bgp->l3vni, &bgp->rmac,
+ ifindex2ifname(bgp->l3vni_svi_ifindex,
+ bgp->vrf_id));
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_bgp_vrfs,
show_bgp_vrfs_cmd,
- "show [ip] bgp vrfs [json]",
+ "show [ip] bgp vrfs [<VRFNAME$vrf_name>] [json]",
SHOW_STR
IP_STR
BGP_STR
"Show BGP VRFs\n"
+ "Specific VRF name\n"
JSON_STR)
{
- char buf[ETHER_ADDR_STRLEN];
struct list *inst = bm->bgp;
struct listnode *node;
struct bgp *bgp;
bool uj = use_json(argc, argv);
json_object *json = NULL;
json_object *json_vrfs = NULL;
+ json_object *json_vrf = NULL;
int count = 0;
+ const char *name = vrf_name;
+ const char *type;
- if (uj) {
+ if (uj)
json = json_object_new_object();
- json_vrfs = json_object_new_object();
+
+ if (name) {
+ if (strmatch(name, VRF_DEFAULT_NAME)) {
+ bgp = bgp_get_default();
+ type = "DFLT";
+ } else {
+ bgp = bgp_lookup_by_name(name);
+ type = "VRF";
+ }
+ if (!bgp) {
+ if (uj)
+ vty_json(vty, json);
+ else
+ vty_out(vty,
+ "%% Specified BGP instance not found\n");
+
+ return CMD_WARNING;
+ }
+ }
+
+ if (vrf_name) {
+ if (uj)
+ json_vrf = json_object_new_object();
+
+ show_bgp_vrfs_detail_common(vty, bgp, json_vrf, name, type,
+ true);
+
+ if (uj) {
+ json_object_object_add(json, name, json_vrf);
+ vty_json(vty, json);
+ }
+
+ return CMD_SUCCESS;
}
+ if (uj)
+ json_vrfs = json_object_new_object();
+
for (ALL_LIST_ELEMENTS_RO(inst, node, bgp)) {
- const char *name, *type;
- struct peer *peer;
- struct listnode *node2, *nnode2;
- int peers_cfg, peers_estb;
- json_object *json_vrf = NULL;
+ const char *name;
/* Skip Views. */
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
vty_out(vty, "%11s %-16s %-21s %-6s\n", " ",
"L3-VNI", "RouterMAC", "Interface");
}
-
- peers_cfg = peers_estb = 0;
if (uj)
json_vrf = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS(bgp->peer, node2, nnode2, peer)) {
- if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
- continue;
- peers_cfg++;
- if (peer_established(peer))
- peers_estb++;
- }
-
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
name = VRF_DEFAULT_NAME;
type = "DFLT";
type = "VRF";
}
+ show_bgp_vrfs_detail_common(vty, bgp, json_vrf, name, type,
+ false);
- if (uj) {
- int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN)
- ? -1
- : (int64_t)bgp->vrf_id;
- char buf[BUFSIZ] = {0};
-
- json_object_string_add(json_vrf, "type", type);
- json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
- json_object_string_addf(json_vrf, "routerId", "%pI4",
- &bgp->router_id);
- json_object_int_add(json_vrf, "numConfiguredPeers",
- peers_cfg);
- json_object_int_add(json_vrf, "numEstablishedPeers",
- peers_estb);
-
- json_object_int_add(json_vrf, "l3vni", bgp->l3vni);
- json_object_string_add(
- json_vrf, "rmac",
- prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
- json_object_string_add(json_vrf, "interface",
- ifindex2ifname(bgp->l3vni_svi_ifindex,
- bgp->vrf_id));
+ if (uj)
json_object_object_add(json_vrfs, name, json_vrf);
- } else {
- vty_out(vty, "%4s %-5d %-16pI4 %-9u %-10u %-37s\n",
- type,
- bgp->vrf_id == VRF_UNKNOWN ? -1
- : (int)bgp->vrf_id,
- &bgp->router_id, peers_cfg, peers_estb, name);
- vty_out(vty,"%11s %-16u %-21s %-20s\n", " ",
- bgp->l3vni,
- prefix_mac2str(&bgp->rmac, buf, sizeof(buf)),
- ifindex2ifname(bgp->l3vni_svi_ifindex,
- bgp->vrf_id));
- }
}
if (uj) {
json_object_object_add(json, "vrfs", json_vrfs);
-
json_object_int_add(json, "totalVrfs", count);
-
vty_json(vty, json);
} else {
if (count)
#define BGP_ATTR_EXT_COMMUNITIES 16
#define BGP_ATTR_AS4_PATH 17
#define BGP_ATTR_AS4_AGGREGATOR 18
-#define BGP_ATTR_AS_PATHLIMIT 21
#define BGP_ATTR_PMSI_TUNNEL 22
#define BGP_ATTR_ENCAP 23
#define BGP_ATTR_IPV6_EXT_COMMUNITIES 25
.. clicmd:: show bgp [afi] [safi] [all] [wide|json]
+.. clicmd:: show bgp vrfs [<VRFNAME$vrf_name>] [json]
+
+ The command displays all bgp vrf instances basic info like router-id,
+ configured and established neighbors,
+ evpn related basic info like l3vni, router-mac, vxlan-interface.
+ User can get that information as JSON format when ``json`` keyword
+ at the end of cli is presented.
+
+ .. code-block:: frr
+
+ torc-11# show bgp vrfs
+ Type Id routerId #PeersCfg #PeersEstb Name
+ L3-VNI RouterMAC Interface
+ DFLT 0 17.0.0.6 3 3 default
+ 0 00:00:00:00:00:00 unknown
+ VRF 21 17.0.0.6 0 0 sym_1
+ 8888 34:11:12:22:22:01 vlan4034_l3
+ VRF 32 17.0.0.6 0 0 sym_2
+ 8889 34:11:12:22:22:01 vlan4035_l3
+
+ Total number of VRFs (including default): 3
+
.. clicmd:: show bgp [<ipv4|ipv6> <unicast|multicast|vpn|labeled-unicast|flowspec> | l2vpn evpn]
These commands display BGP routes for the specific routing table indicated by
The ``terse`` option can be used in combination with the remote-as, neighbor,
failed and established filters, and with the ``wide`` option as well.
-.. clicmd:: show bgp [afi] [safi] [neighbor [PEER] [routes|advertised-routes|received-routes] [json]
+.. clicmd:: show bgp [afi] [safi] [neighbor [PEER] [routes|advertised-routes|received-routes] [detail] [json]
This command shows information on a specific BGP peer of the relevant
afi and safi selected.
The ``received-routes`` keyword displays all routes belonging to this
address-family (prior to inbound policy) that were received by this peer.
+ If ``detail`` option is specified, the detailed version of all routes
+ will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX``
+ will be used, but for the whole table of received, advertised or filtered
+ prefixes.
+
+ If ``json`` option is specified, output is displayed in JSON format.
+
.. clicmd:: show bgp [<view|vrf> VIEWVRFNAME] [afi] [safi] neighbors PEER received prefix-filter [json]
Display Address Prefix ORFs received from this peer.
If the ``json`` option is specified, output is displayed in JSON format.
-.. clicmd:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [json|wide]
+.. clicmd:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [detail] [json|wide]
Display the routes advertised to a BGP neighbor or received routes
from neighbor or filtered routes received from neighbor based on the
if afi is specified, with ``all`` option, routes will be displayed for
each SAFI in the selcted AFI
+ If ``detail`` option is specified, the detailed version of all routes
+ will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX``
+ will be used, but for the whole table of received, advertised or filtered
+ prefixes.
+
If ``json`` option is specified, output is displayed in JSON format.
.. clicmd:: show [ip] bgp [afi] [safi] [all] detail-routes
Display Information about update-group events in FRR.
Displaying Nexthop Information
---------------------
+------------------------------
.. clicmd:: show [ip] bgp [<view|vrf> VIEWVRFNAME] nexthop ipv4 [A.B.C.D] [detail] [json]
.. clicmd:: show [ip] bgp [<view|vrf> VIEWVRFNAME] nexthop ipv6 [X:X::X:X] [detail] [json]
ip link set eth0 master br10
This completes the necessary configuration for an L2VNI.
+
+Displaying EVPN information
+---------------------------
+
+.. clicmd:: show evpn mac vni (1-16777215) detail [json]
+
+ Display detailed information about MAC addresses for
+ a specified VNI.
\ No newline at end of file
pim_channel_del_oif(
ch->upstream->channel_oil, ifp,
PIM_OIF_FLAG_PROTO_STAR, __func__);
+ pim_channel_del_oif(ch->upstream->channel_oil, ifp,
+ PIM_OIF_FLAG_PROTO_PIM, __func__);
if (!ch->upstream->channel_oil->installed)
pim_upstream_mroute_add(
ch->upstream->channel_oil,
tgen = Topogen(build_topo, module.__name__)
tgen.start_topology()
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version("4.19")
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
vrf_setup_cmds = [
"ip link add name blue type vrf table 11",
"ip link add name red type vrf table 12",
"Test for OSPFv2 convergence"
tgen = get_topogen()
- # Required linux kernel version for this suite to run.
- result = required_linux_kernel_version("4.15")
- if result is not True:
- pytest.skip("Kernel requirements are not met")
-
# iproute2 needs to support VRFs for this suite to run.
if not iproute2_is_vrf_capable():
pytest.skip("Installed iproute2 version does not support VRFs")
hdr, 0, false, ctx) != 1) {
dplane_ctx_fini(&ctx);
stream_pulldown(fnc->ibuf);
- return;
+ /*
+ * Let's continue to read other messages
+ * Even if we ignore this one.
+ */
}
break;
default:
"Tx %s family %s IF %s(%u) Neigh %pIA %s %s flags 0x%x state 0x%x %sext_flags 0x%x",
nl_msg_type_to_str(cmd), nl_family_to_str(family),
dplane_ctx_get_ifname(ctx), dplane_ctx_get_ifindex(ctx),
- ip, link_ip ? "Link " : "MAC ", buf2, flags, state,
+ ip, link_ip ? "Link" : "MAC", buf2, flags, state,
ext ? "ext " : "", ext_flags);
return netlink_neigh_update_msg_encode(
ipaddr2str(link_ip, buf1, sizeof(buf1));
zlog_debug("init neigh ctx %s: ifp %s, %s %s, ip %pIA",
dplane_op2str(op), ifp->name,
- link_family == AF_ETHERNET ? "mac " : "link ",
- buf1, ip);
+ link_family == AF_ETHERNET ? "mac" : "link", buf1,
+ ip);
}
ctx = dplane_ctx_alloc();
json_object_int_add(json_mac, "vlan", vid);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
json_object_string_add(json_mac, "type", "remote");
- json_object_string_addf(json_mac, "remoteVtep", "%pI4",
- &mac->fwd_info.r_vtep_ip);
+ if (mac->es)
+ json_object_string_add(json_mac, "remoteEs",
+ mac->es->esi_str);
+ else
+ json_object_string_addf(
+ json_mac, "remoteVtep", "%pI4",
+ &mac->fwd_info.r_vtep_ip);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
json_object_string_add(json_mac, "type", "auto");
"", mac->loc_seq, mac->rem_seq);
} else {
json_object_string_add(json_mac, "type", "remote");
- json_object_string_addf(json_mac, "remoteVtep", "%pI4",
- &mac->fwd_info.r_vtep_ip);
+ if (mac->es)
+ json_object_string_add(json_mac, "remoteEs",
+ mac->es->esi_str);
+ else
+ json_object_string_addf(
+ json_mac, "remoteVtep", "%pI4",
+ &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);
vni = strtoul(argv[4]->arg, NULL, 10);
zvrf = zebra_vrf_get_evpn();
- zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
+ zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj, false);
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_evpn_mac_vni_detail,
+ show_evpn_mac_vni_detail_cmd,
+ "show evpn mac vni " CMD_VNI_RANGE " detail [json]",
+ SHOW_STR
+ "EVPN\n"
+ "MAC addresses\n"
+ "VXLAN Network Identifier\n"
+ "VNI number\n"
+ "Detailed Information On Each VNI MAC\n"
+ JSON_STR)
+{
+ struct zebra_vrf *zvrf;
+ bool uj = use_json(argc, argv);
+
+ zvrf = zebra_vrf_get_evpn();
+ zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj, true);
return CMD_SUCCESS;
}
install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
+ install_element(VIEW_NODE, &show_evpn_mac_vni_detail_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
* Display MACs for a VNI (VTY command handler).
*/
void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
- vni_t vni, bool use_json)
+ vni_t vni, bool use_json, bool detail)
{
struct zebra_evpn *zevpn;
uint32_t num_macs;
wctx.json = json_mac;
if (!use_json) {
- vty_out(vty,
- "Number of MACs (local and remote) known for this VNI: %u\n",
- num_macs);
- vty_out(vty,
- "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
- vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC", "Type",
- "Flags", "Intf/Remote ES/VTEP", "VLAN", "Seq #'s");
+ if (detail) {
+ vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
+ zevpn->vni, num_macs);
+ } else {
+ vty_out(vty,
+ "Number of MACs (local and remote) known for this VNI: %u\n",
+ num_macs);
+ vty_out(vty,
+ "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
+ vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
+ "Type", "Flags", "Intf/Remote ES/VTEP", "VLAN",
+ "Seq #'s");
+ }
} else
json_object_int_add(json, "numMacs", num_macs);
- hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash, &wctx);
+ if (detail)
+ hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash_detail,
+ &wctx);
+ else
+ hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash,
+ &wctx);
if (use_json) {
json_object_object_add(json, "macs", json_mac);
struct ethaddr *rmac,
bool use_json);
extern void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
- vni_t vni, bool use_json);
+ vni_t vni, bool use_json, bool detail);
extern void zebra_vxlan_print_macs_all_vni(struct vty *vty,
struct zebra_vrf *zvrf,
bool print_dup,