summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorLou Berger <lberger@labn.net>2017-10-06 15:31:30 +0200
committerGitHub <noreply@github.com>2017-10-06 15:31:30 +0200
commit3782fb37b1c480f2a1c3811fb703bdd5981ca60a (patch)
treecb7a38fec2b8cdeb61c3f12f37da984da956af2c /bgpd
parentMerge pull request #1299 from opensourcerouting/small_fixes (diff)
parentbgpd: Fixup json with RouteDistinguishers (diff)
downloadfrr-3782fb37b1c480f2a1c3811fb703bdd5981ca60a.tar.xz
frr-3782fb37b1c480f2a1c3811fb703bdd5981ca60a.zip
Merge pull request #1295 from donaldsharp/more_1270
More 1270
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_mplsvpn.c291
-rw-r--r--bgpd/bgp_route.c907
-rw-r--r--bgpd/bgp_route.h4
-rw-r--r--bgpd/bgp_vty.c6
4 files changed, 505 insertions, 703 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 694cb1479..472b9d200 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -356,19 +356,6 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
{
struct bgp *bgp;
struct bgp_table *table;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_info *ri;
- int rd_header;
- int header = 1;
- unsigned long output_count = 0;
- unsigned long total_count = 0;
- json_object *json = NULL;
- json_object *json_mroute = NULL;
- json_object *json_nroute = NULL;
- json_object *json_array = NULL;
- json_object *json_scode = NULL;
- json_object *json_ocode = NULL;
bgp = bgp_get_default();
if (bgp == NULL) {
@@ -378,279 +365,31 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
vty_out(vty, "{}\n");
return CMD_WARNING;
}
-
- if (use_json) {
- json_scode = json_object_new_object();
- json_ocode = json_object_new_object();
- json = json_object_new_object();
- json_mroute = json_object_new_object();
- json_nroute = json_object_new_object();
-
- json_object_string_add(json_scode, "suppressed", "s");
- json_object_string_add(json_scode, "damped", "d");
- json_object_string_add(json_scode, "history", "h");
- json_object_string_add(json_scode, "valid", "*");
- json_object_string_add(json_scode, "best", ">");
- json_object_string_add(json_scode, "internal", "i");
-
- json_object_string_add(json_ocode, "igp", "i");
- json_object_string_add(json_ocode, "egp", "e");
- json_object_string_add(json_ocode, "incomplete", "?");
- }
-
- if ((afi != AFI_IP) && (afi != AFI_IP6)) {
- vty_out(vty, "Afi %d not supported\n", afi);
- return CMD_WARNING;
- }
-
- for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
- rn = bgp_route_next(rn)) {
- if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
- continue;
-
- if ((table = rn->info) != NULL) {
- rd_header = 1;
-
- for (rm = bgp_table_top(table); rm;
- rm = bgp_route_next(rm)) {
- total_count++;
- if (use_json)
- json_array = json_object_new_array();
- else
- json_array = NULL;
-
- for (ri = rm->info; ri; ri = ri->next) {
- if (type == bgp_show_type_neighbor) {
- union sockunion *su =
- output_arg;
-
- if (ri->peer->su_remote == NULL
- || !sockunion_same(
- ri->peer->su_remote,
- su))
- continue;
- }
- if (header) {
- if (use_json) {
- if (!tags) {
- json_object_int_add(
- json,
- "bgpTableVersion",
- 0);
- json_object_string_add(
- json,
- "bgpLocalRouterId",
- inet_ntoa(
- bgp->router_id));
- json_object_object_add(
- json,
- "bgpStatusCodes",
- json_scode);
- json_object_object_add(
- json,
- "bgpOriginCodes",
- json_ocode);
- }
- } else {
- if (tags)
- vty_out(vty,
- V4_HEADER_TAG);
- else {
- vty_out(vty,
- "BGP table version is 0, local router ID is %s\n",
- inet_ntoa(
- bgp->router_id));
- vty_out(vty,
- "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
- vty_out(vty,
- "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
- vty_out(vty,
- V4_HEADER);
- }
- }
- header = 0;
- }
-
- if (rd_header) {
- u_int16_t type;
- struct rd_as rd_as;
- struct rd_ip rd_ip = {0};
-#if ENABLE_BGP_VNC
- struct rd_vnc_eth rd_vnc_eth = {
- 0};
-#endif
- u_char *pnt;
-
- pnt = rn->p.u.val;
-
- /* Decode RD type. */
- type = decode_rd_type(pnt);
- /* Decode RD value. */
- if (type == RD_TYPE_AS)
- decode_rd_as(pnt + 2,
- &rd_as);
- else if (type == RD_TYPE_AS4)
- decode_rd_as4(pnt + 2,
- &rd_as);
- else if (type == RD_TYPE_IP)
- decode_rd_ip(pnt + 2,
- &rd_ip);
-#if ENABLE_BGP_VNC
- else if (type
- == RD_TYPE_VNC_ETH)
- decode_rd_vnc_eth(
- pnt,
- &rd_vnc_eth);
-#endif
-
- if (use_json) {
- char buffer[BUFSIZ];
- if (type == RD_TYPE_AS
- || type == RD_TYPE_AS4)
- sprintf(buffer,
- "%u:%d",
- rd_as.as,
- rd_as.val);
- else if (type
- == RD_TYPE_IP)
- sprintf(buffer,
- "%s:%d",
- inet_ntoa(
- rd_ip.ip),
- rd_ip.val);
- json_object_string_add(
- json_nroute,
- "routeDistinguisher",
- buffer);
- } else {
- vty_out(vty,
- "Route Distinguisher: ");
-
- if (type == RD_TYPE_AS
- || type == RD_TYPE_AS4)
- vty_out(vty,
- "%u:%d",
- rd_as.as,
- rd_as.val);
- else if (type
- == RD_TYPE_IP)
- vty_out(vty,
- "%s:%d",
- inet_ntoa(
- rd_ip.ip),
- rd_ip.val);
-#if ENABLE_BGP_VNC
- else if (
- type
- == RD_TYPE_VNC_ETH)
- vty_out(vty,
- "%u:%02x:%02x:%02x:%02x:%02x:%02x",
- rd_vnc_eth
- .local_nve_id,
- rd_vnc_eth
- .macaddr
- .octet[0],
- rd_vnc_eth
- .macaddr
- .octet[1],
- rd_vnc_eth
- .macaddr
- .octet[2],
- rd_vnc_eth
- .macaddr
- .octet[3],
- rd_vnc_eth
- .macaddr
- .octet[4],
- rd_vnc_eth
- .macaddr
- .octet[5]);
-#endif
- vty_out(vty, "\n");
- }
- rd_header = 0;
- }
- if (tags)
- route_vty_out_tag(vty, &rm->p,
- ri, 0,
- SAFI_MPLS_VPN,
- json_array);
- else
- route_vty_out(vty, &rm->p, ri,
- 0, SAFI_MPLS_VPN,
- json_array);
- output_count++;
- }
-
- if (use_json) {
- struct prefix *p;
- char buf_a[BUFSIZ];
- char buf_b[BUFSIZ];
- p = &rm->p;
- sprintf(buf_a, "%s/%d",
- inet_ntop(p->family,
- &p->u.prefix, buf_b,
- BUFSIZ),
- p->prefixlen);
- json_object_object_add(
- json_mroute, buf_a, json_array);
- }
- }
-
- if (use_json) {
- struct prefix *p;
- char buf_a[BUFSIZ];
- char buf_b[BUFSIZ];
- p = &rn->p;
- sprintf(buf_a, "%s/%d",
- inet_ntop(p->family, &p->u.prefix,
- buf_b, BUFSIZ),
- p->prefixlen);
- json_object_object_add(json_nroute, buf_a,
- json_mroute);
- }
- }
- }
-
- if (use_json) {
- json_object_object_add(json, "routes", json_nroute);
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else {
- if (output_count == 0)
- vty_out(vty, "No prefixes displayed, %ld exist\n",
- total_count);
- else
- vty_out(vty,
- "\nDisplayed %ld routes and %ld total paths\n",
- output_count, total_count);
- }
-
- return CMD_SUCCESS;
+ table = bgp->rib[afi][SAFI_MPLS_VPN];
+ return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN,
+ table, prd, type, output_arg, use_json);
}
DEFUN (show_bgp_ip_vpn_all_rd,
show_bgp_ip_vpn_all_rd_cmd,
"show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
SHOW_STR
- IP_STR
BGP_STR
BGP_VPNVX_HELP_STR
"Display VPN NLRI specific information\n"
+ "Display VPN NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
JSON_STR)
{
- int idx_rd = 5;
int ret;
struct prefix_rd prd;
afi_t afi;
int idx = 0;
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
- if (argc >= 7 && argv[idx_rd]->arg) {
- ret = str2prefix_rd(argv[idx_rd]->arg, &prd);
+ if (argv_find(argv, argc, "rd", &idx)) {
+ ret = str2prefix_rd(argv[idx+1]->arg, &prd);
if (!ret) {
vty_out(vty,
"%% Malformed Route Distinguisher\n");
@@ -668,9 +407,21 @@ DEFUN (show_bgp_ip_vpn_all_rd,
return CMD_SUCCESS;
}
+ALIAS(show_bgp_ip_vpn_all_rd,
+ show_bgp_ip_vpn_rd_cmd,
+ "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
+ SHOW_STR
+ BGP_STR
+ BGP_VPNVX_HELP_STR
+ "Display VPN NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
+ JSON_STR)
+
+#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (show_ip_bgp_vpn_rd,
show_ip_bgp_vpn_rd_cmd,
- "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
+ "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
SHOW_STR
IP_STR
BGP_STR
@@ -697,7 +448,6 @@ DEFUN (show_ip_bgp_vpn_rd,
return CMD_SUCCESS;
}
-#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (show_ip_bgp_vpn_all,
show_ip_bgp_vpn_all_cmd,
"show [ip] bgp <vpnv4|vpnv6>",
@@ -1055,8 +805,9 @@ void bgp_mplsvpn_init(void)
install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
- install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
+ install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 3307f8608..762519715 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -6500,246 +6500,258 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
/* Print attribute */
attr = binfo->attr;
- if (attr) {
- /*
- * For ENCAP and EVPN routes, nexthop address family is not
- * neccessarily the same as the prefix address family.
- * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
- * EVPN routes are also exchanged with a MP nexthop. Currently,
- * this
- * is only IPv4, the value will be present in either
- * attr->nexthop or
- * attr->mp_nexthop_global_in
- */
- if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
- char buf[BUFSIZ];
- int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
-
- switch (af) {
- case AF_INET:
- vty_out(vty, "%s",
- inet_ntop(af,
- &attr->mp_nexthop_global_in,
- buf, BUFSIZ));
- break;
- case AF_INET6:
- vty_out(vty, "%s",
- inet_ntop(af, &attr->mp_nexthop_global,
- buf, BUFSIZ));
- break;
- default:
- vty_out(vty, "?");
- break;
- }
- } else if (safi == SAFI_EVPN) {
- if (json_paths) {
- json_nexthop_global = json_object_new_object();
+ if (!attr) {
+ if (json_paths)
+ json_object_array_add(json_paths, json_path);
+ else
+ vty_out(vty, "\n");
- json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
- json_object_string_add(json_nexthop_global,
- "afi", "ipv4");
- json_object_boolean_true_add(
- json_nexthop_global, "used");
- } else
- vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
+ return;
+ }
+
+ /*
+ * For ENCAP and EVPN routes, nexthop address family is not
+ * neccessarily the same as the prefix address family.
+ * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
+ * EVPN routes are also exchanged with a MP nexthop. Currently,
+ * this
+ * is only IPv4, the value will be present in either
+ * attr->nexthop or
+ * attr->mp_nexthop_global_in
+ */
+ if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
+ char buf[BUFSIZ];
+ char nexthop[128];
+ int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
+
+ switch (af) {
+ case AF_INET:
+ sprintf(nexthop, "%s",
+ inet_ntop(af, &attr->mp_nexthop_global_in,
+ buf, BUFSIZ));
+ break;
+ case AF_INET6:
+ sprintf(nexthop, "%s",
+ inet_ntop(af, &attr->mp_nexthop_global,
+ buf, BUFSIZ));
+ break;
+ default:
+ sprintf(nexthop, "?");
+ break;
}
- /* IPv4 Next Hop */
- else if (p->family == AF_INET
- && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
- if (json_paths) {
- json_nexthop_global = json_object_new_object();
- if ((safi == SAFI_MPLS_VPN)
- || (safi == SAFI_EVPN))
- json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(
- attr->mp_nexthop_global_in));
- else
- json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+
+ json_object_string_add(json_nexthop_global,
+ "afi",
+ (af == AF_INET) ?
+ "ip" : "ipv6");
+ json_object_string_add(json_nexthop_global,
+ (af == AF_INET) ?
+ "ip" : "ipv6",
+ nexthop);
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+ } else
+ vty_out(vty, "%s", nexthop);
+ } else if (safi == SAFI_EVPN) {
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+
+ json_object_string_add(json_nexthop_global, "ip",
+ inet_ntoa(attr->nexthop));
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv4");
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+ } else
+ vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
+ }
+ /* IPv4 Next Hop */
+ else if (p->family == AF_INET
+ && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_EVPN))
json_object_string_add(json_nexthop_global,
- "afi", "ipv4");
- json_object_boolean_true_add(
- json_nexthop_global, "used");
- } else {
- if ((safi == SAFI_MPLS_VPN)
- || (safi == SAFI_EVPN))
- vty_out(vty, "%-16s",
- inet_ntoa(
- attr->mp_nexthop_global_in));
- else
- vty_out(vty, "%-16s",
- inet_ntoa(attr->nexthop));
- }
+ "ip",
+ inet_ntoa(attr->mp_nexthop_global_in));
+ else
+ json_object_string_add(json_nexthop_global,
+ "ip",
+ inet_ntoa(attr->nexthop));
+
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv4");
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+ } else {
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_EVPN))
+ vty_out(vty, "%-16s",
+ inet_ntoa(
+ attr->mp_nexthop_global_in));
+ else
+ vty_out(vty, "%-16s",
+ inet_ntoa(attr->nexthop));
}
+ }
- /* IPv6 Next Hop */
- else if (p->family == AF_INET6
- || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
- int len;
- char buf[BUFSIZ];
+ /* IPv6 Next Hop */
+ else if (p->family == AF_INET6
+ || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ int len;
+ char buf[BUFSIZ];
- if (json_paths) {
- json_nexthop_global = json_object_new_object();
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+ json_object_string_add(json_nexthop_global, "ip",
+ inet_ntop(AF_INET6,
+ &attr->mp_nexthop_global, buf,
+ BUFSIZ));
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv6");
+ json_object_string_add(json_nexthop_global,
+ "scope", "global");
+
+ /* We display both LL & GL if both have been
+ * received */
+ if ((attr->mp_nexthop_len == 32)
+ || (binfo->peer->conf_if)) {
+ json_nexthop_ll =
+ json_object_new_object();
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntop(AF_INET6,
- &attr->mp_nexthop_global, buf,
- BUFSIZ));
- json_object_string_add(json_nexthop_global,
+ json_nexthop_ll, "ip",
+ inet_ntop(
+ AF_INET6,
+ &attr->mp_nexthop_local,
+ buf, BUFSIZ));
+ json_object_string_add(json_nexthop_ll,
"afi", "ipv6");
- json_object_string_add(json_nexthop_global,
- "scope", "global");
+ json_object_string_add(json_nexthop_ll,
+ "scope",
+ "link-local");
- /* We display both LL & GL if both have been
- * received */
- if ((attr->mp_nexthop_len == 32)
- || (binfo->peer->conf_if)) {
- json_nexthop_ll =
- json_object_new_object();
- json_object_string_add(
- json_nexthop_ll, "ip",
- inet_ntop(
- AF_INET6,
- &attr->mp_nexthop_local,
- buf, BUFSIZ));
- json_object_string_add(json_nexthop_ll,
- "afi", "ipv6");
- json_object_string_add(json_nexthop_ll,
- "scope",
- "link-local");
-
- if ((IPV6_ADDR_CMP(
- &attr->mp_nexthop_global,
- &attr->mp_nexthop_local)
- != 0)
- && !attr->mp_nexthop_prefer_global)
- json_object_boolean_true_add(
- json_nexthop_ll,
- "used");
- else
- json_object_boolean_true_add(
- json_nexthop_global,
- "used");
- } else
+ if ((IPV6_ADDR_CMP(
+ &attr->mp_nexthop_global,
+ &attr->mp_nexthop_local)
+ != 0)
+ && !attr->mp_nexthop_prefer_global)
json_object_boolean_true_add(
- json_nexthop_global, "used");
- } else {
- /* Display LL if LL/Global both in table unless
- * prefer-global is set */
- if (((attr->mp_nexthop_len == 32)
- && !attr->mp_nexthop_prefer_global)
- || (binfo->peer->conf_if)) {
- if (binfo->peer->conf_if) {
- len = vty_out(
- vty, "%s",
- binfo->peer->conf_if);
- len = 16 - len; /* len of IPv6
- addr + max
- len of def
- ifname */
-
- if (len < 1)
- vty_out(vty, "\n%*s",
- 36, " ");
- else
- vty_out(vty, "%*s", len,
- " ");
- } else {
- len = vty_out(
- vty, "%s",
- inet_ntop(
- AF_INET6,
- &attr->mp_nexthop_local,
- buf, BUFSIZ));
- len = 16 - len;
-
- if (len < 1)
- vty_out(vty, "\n%*s",
- 36, " ");
- else
- vty_out(vty, "%*s", len,
- " ");
- }
+ json_nexthop_ll,
+ "used");
+ else
+ json_object_boolean_true_add(
+ json_nexthop_global,
+ "used");
+ } else
+ json_object_boolean_true_add(
+ json_nexthop_global, "used");
+ } else {
+ /* Display LL if LL/Global both in table unless
+ * prefer-global is set */
+ if (((attr->mp_nexthop_len == 32)
+ && !attr->mp_nexthop_prefer_global)
+ || (binfo->peer->conf_if)) {
+ if (binfo->peer->conf_if) {
+ len = vty_out(
+ vty, "%s",
+ binfo->peer->conf_if);
+ len = 16 - len; /* len of IPv6
+ addr + max
+ len of def
+ ifname */
+
+ if (len < 1)
+ vty_out(vty, "\n%*s",
+ 36, " ");
+ else
+ vty_out(vty, "%*s", len,
+ " ");
} else {
len = vty_out(
vty, "%s",
inet_ntop(
AF_INET6,
- &attr->mp_nexthop_global,
+ &attr->mp_nexthop_local,
buf, BUFSIZ));
len = 16 - len;
if (len < 1)
- vty_out(vty, "\n%*s", 36, " ");
+ vty_out(vty, "\n%*s",
+ 36, " ");
else
- vty_out(vty, "%*s", len, " ");
+ vty_out(vty, "%*s", len,
+ " ");
}
+ } else {
+ len = vty_out(vty, "%s",
+ inet_ntop(AF_INET6,
+ &attr->mp_nexthop_global,
+ buf, BUFSIZ));
+ len = 16 - len;
+
+ if (len < 1)
+ vty_out(vty, "\n%*s", 36, " ");
+ else
+ vty_out(vty, "%*s", len, " ");
}
}
+ }
- /* MED/Metric */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
- if (json_paths)
- json_object_int_add(json_path, "med",
- attr->med);
- else
- vty_out(vty, "%10u", attr->med);
- else if (!json_paths)
- vty_out(vty, " ");
-
- /* Local Pref */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
- if (json_paths)
- json_object_int_add(json_path, "localpref",
- attr->local_pref);
- else
- vty_out(vty, "%7u", attr->local_pref);
- else if (!json_paths)
- vty_out(vty, " ");
+ /* MED/Metric */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
+ if (json_paths)
+ json_object_int_add(json_path, "med",
+ attr->med);
+ else
+ vty_out(vty, "%10u", attr->med);
+ else if (!json_paths)
+ vty_out(vty, " ");
+ /* Local Pref */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
if (json_paths)
- json_object_int_add(json_path, "weight", attr->weight);
+ json_object_int_add(json_path, "localpref",
+ attr->local_pref);
else
- vty_out(vty, "%7u ", attr->weight);
+ vty_out(vty, "%7u", attr->local_pref);
+ else if (!json_paths)
+ vty_out(vty, " ");
- if (json_paths) {
- char buf[BUFSIZ];
- json_object_string_add(json_path, "peerId",
- sockunion2str(&binfo->peer->su,
- buf,
- SU_ADDRSTRLEN));
- }
+ if (json_paths)
+ json_object_int_add(json_path, "weight", attr->weight);
+ else
+ vty_out(vty, "%7u ", attr->weight);
- /* Print aspath */
- if (attr->aspath) {
- if (json_paths)
- json_object_string_add(json_path, "aspath",
- attr->aspath->str);
- else
- aspath_print_vty(vty, "%s", attr->aspath, " ");
- }
+ if (json_paths) {
+ char buf[BUFSIZ];
+ json_object_string_add(json_path, "peerId",
+ sockunion2str(&binfo->peer->su,
+ buf,
+ SU_ADDRSTRLEN));
+ }
- /* Print origin */
- if (json_paths)
- json_object_string_add(
- json_path, "origin",
- bgp_origin_long_str[attr->origin]);
- else
- vty_out(vty, "%s", bgp_origin_str[attr->origin]);
- } else {
+ /* Print aspath */
+ if (attr->aspath) {
if (json_paths)
- json_object_string_add(json_path, "alert",
- "No attributes");
+ json_object_string_add(json_path, "aspath",
+ attr->aspath->str);
else
- vty_out(vty, "No attributes to print\n");
+ aspath_print_vty(vty, "%s", attr->aspath, " ");
}
+ /* Print origin */
+ if (json_paths)
+ json_object_string_add(
+ json_path, "origin",
+ bgp_origin_long_str[attr->origin]);
+ else
+ vty_out(vty, "%s", bgp_origin_str[attr->origin]);
+
if (json_paths) {
if (json_nexthop_global || json_nexthop_ll) {
json_nexthops = json_object_new_array();
@@ -8122,23 +8134,29 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp,
const char *comstr, int exact, afi_t afi,
safi_t safi);
-static int bgp_show_table(struct vty *vty, struct bgp *bgp,
+
+static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, enum bgp_show_type type,
- void *output_arg, u_char use_json)
+ void *output_arg, u_char use_json,
+ char *rd, int is_last,
+ unsigned long *output_cum, unsigned long *total_cum)
{
struct bgp_info *ri;
struct bgp_node *rn;
int header = 1;
int display;
- unsigned long output_count;
- unsigned long total_count;
+ unsigned long output_count = 0;
+ unsigned long total_count = 0;
struct prefix *p;
char buf[BUFSIZ];
char buf2[BUFSIZ];
json_object *json_paths = NULL;
int first = 1;
- if (use_json) {
+ if (output_cum && *output_cum != 0)
+ header = 0;
+
+ if (use_json && header) {
vty_out(vty,
"{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
@@ -8146,252 +8164,290 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
: bgp->name,
table->version, inet_ntoa(bgp->router_id));
+ if (rd)
+ vty_out(vty, " \"routeDistinguishers\" : {");
json_paths = json_object_new_object();
}
- /* This is first entry point, so reset total line. */
- output_count = 0;
- total_count = 0;
+ if (use_json && rd) {
+ vty_out(vty, " \"%s\" : { ", rd);
+ }
/* Start processing of routes. */
- for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
- if (rn->info != NULL) {
- display = 0;
- if (!first && use_json) {
- vty_out(vty, ",");
- }
- if (use_json)
- json_paths = json_object_new_array();
- else
- json_paths = NULL;
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ if (rn->info == NULL)
+ continue;
- for (ri = rn->info; ri; ri = ri->next) {
- total_count++;
- if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor
- || type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor) {
- if (!(ri->extra
- && ri->extra->damp_info))
- continue;
- }
- if (type == bgp_show_type_regexp) {
- regex_t *regex = output_arg;
+ display = 0;
+ if (!first && use_json)
+ vty_out(vty, ",");
+ if (use_json)
+ json_paths = json_object_new_array();
+ else
+ json_paths = NULL;
- if (bgp_regexec(regex, ri->attr->aspath)
- == REG_NOMATCH)
- continue;
- }
- if (type == bgp_show_type_prefix_list) {
- struct prefix_list *plist = output_arg;
+ for (ri = rn->info; ri; ri = ri->next) {
+ total_count++;
+ if (type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor
+ || type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor) {
+ if (!(ri->extra
+ && ri->extra->damp_info))
+ continue;
+ }
+ if (type == bgp_show_type_regexp) {
+ regex_t *regex = output_arg;
- if (prefix_list_apply(plist, &rn->p)
- != PREFIX_PERMIT)
- continue;
- }
- if (type == bgp_show_type_filter_list) {
- struct as_list *as_list = output_arg;
+ if (bgp_regexec(regex, ri->attr->aspath)
+ == REG_NOMATCH)
+ continue;
+ }
+ if (type == bgp_show_type_prefix_list) {
+ struct prefix_list *plist = output_arg;
- if (as_list_apply(as_list,
- ri->attr->aspath)
- != AS_FILTER_PERMIT)
- continue;
- }
- if (type == bgp_show_type_route_map) {
- struct route_map *rmap = output_arg;
- struct bgp_info binfo;
- struct attr dummy_attr;
- int ret;
+ if (prefix_list_apply(plist, &rn->p)
+ != PREFIX_PERMIT)
+ continue;
+ }
+ if (type == bgp_show_type_filter_list) {
+ struct as_list *as_list = output_arg;
- bgp_attr_dup(&dummy_attr, ri->attr);
+ if (as_list_apply(as_list, ri->attr->aspath)
+ != AS_FILTER_PERMIT)
+ continue;
+ }
+ if (type == bgp_show_type_route_map) {
+ struct route_map *rmap = output_arg;
+ struct bgp_info binfo;
+ struct attr dummy_attr;
+ int ret;
- binfo.peer = ri->peer;
- binfo.attr = &dummy_attr;
+ bgp_attr_dup(&dummy_attr, ri->attr);
- ret = route_map_apply(rmap, &rn->p,
- RMAP_BGP, &binfo);
- if (ret == RMAP_DENYMATCH)
- continue;
- }
- if (type == bgp_show_type_neighbor
- || type == bgp_show_type_flap_neighbor
- || type == bgp_show_type_damp_neighbor) {
- union sockunion *su = output_arg;
-
- if (ri->peer == NULL
- || ri->peer->su_remote == NULL
- || !sockunion_same(
- ri->peer->su_remote, su))
- continue;
- }
- if (type == bgp_show_type_cidr_only) {
- u_int32_t destination;
+ binfo.peer = ri->peer;
+ binfo.attr = &dummy_attr;
- destination =
- ntohl(rn->p.u.prefix4.s_addr);
- if (IN_CLASSC(destination)
- && rn->p.prefixlen == 24)
- continue;
- if (IN_CLASSB(destination)
- && rn->p.prefixlen == 16)
- continue;
- if (IN_CLASSA(destination)
- && rn->p.prefixlen == 8)
- continue;
- }
- if (type == bgp_show_type_prefix_longer) {
- struct prefix *p = output_arg;
+ ret = route_map_apply(rmap, &rn->p,
+ RMAP_BGP, &binfo);
+ if (ret == RMAP_DENYMATCH)
+ continue;
+ }
+ if (type == bgp_show_type_neighbor
+ || type == bgp_show_type_flap_neighbor
+ || type == bgp_show_type_damp_neighbor) {
+ union sockunion *su = output_arg;
+
+ if (ri->peer == NULL
+ || ri->peer->su_remote == NULL
+ || !sockunion_same(ri->peer->su_remote,
+ su))
+ continue;
+ }
+ if (type == bgp_show_type_cidr_only) {
+ u_int32_t destination;
- if (!prefix_match(p, &rn->p))
- continue;
- }
- if (type == bgp_show_type_community_all) {
- if (!ri->attr->community)
- continue;
- }
- if (type == bgp_show_type_community) {
- struct community *com = output_arg;
+ destination = ntohl(rn->p.u.prefix4.s_addr);
+ if (IN_CLASSC(destination)
+ && rn->p.prefixlen == 24)
+ continue;
+ if (IN_CLASSB(destination)
+ && rn->p.prefixlen == 16)
+ continue;
+ if (IN_CLASSA(destination)
+ && rn->p.prefixlen == 8)
+ continue;
+ }
+ if (type == bgp_show_type_prefix_longer) {
+ struct prefix *p = output_arg;
- if (!ri->attr->community
- || !community_match(
- ri->attr->community,
- com))
- continue;
- }
- if (type == bgp_show_type_community_exact) {
- struct community *com = output_arg;
+ if (!prefix_match(p, &rn->p))
+ continue;
+ }
+ if (type == bgp_show_type_community_all) {
+ if (!ri->attr->community)
+ continue;
+ }
+ if (type == bgp_show_type_community) {
+ struct community *com = output_arg;
- if (!ri->attr->community
- || !community_cmp(
- ri->attr->community,
- com))
- continue;
- }
- if (type == bgp_show_type_community_list) {
- struct community_list *list =
- output_arg;
+ if (!ri->attr->community
+ || !community_match(ri->attr->community,
+ com))
+ continue;
+ }
+ if (type == bgp_show_type_community_exact) {
+ struct community *com = output_arg;
- if (!community_list_match(
- ri->attr->community, list))
- continue;
- }
- if (type
- == bgp_show_type_community_list_exact) {
- struct community_list *list =
- output_arg;
+ if (!ri->attr->community
+ || !community_cmp(ri->attr->community,
+ com))
+ continue;
+ }
+ if (type == bgp_show_type_community_list) {
+ struct community_list *list = output_arg;
- if (!community_list_exact_match(
- ri->attr->community, list))
- continue;
- }
- if (type == bgp_show_type_lcommunity) {
- struct lcommunity *lcom = output_arg;
+ if (!community_list_match(
+ ri->attr->community, list))
+ continue;
+ }
+ if (type
+ == bgp_show_type_community_list_exact) {
+ struct community_list *list = output_arg;
- if (!ri->attr->lcommunity
- || !lcommunity_match(
- ri->attr->lcommunity,
- lcom))
- continue;
- }
- if (type == bgp_show_type_lcommunity_list) {
- struct community_list *list =
- output_arg;
+ if (!community_list_exact_match(
+ ri->attr->community, list))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity) {
+ struct lcommunity *lcom = output_arg;
- if (!lcommunity_list_match(
- ri->attr->lcommunity, list))
- continue;
- }
- if (type == bgp_show_type_lcommunity_all) {
- if (!ri->attr->lcommunity)
- continue;
- }
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor) {
- if (!CHECK_FLAG(ri->flags,
- BGP_INFO_DAMPED)
- || CHECK_FLAG(ri->flags,
- BGP_INFO_HISTORY))
- continue;
- }
+ if (!ri->attr->lcommunity
+ || !lcommunity_match(ri->attr->lcommunity,
+ lcom))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity_list) {
+ struct community_list *list = output_arg;
- if (!use_json && header) {
- vty_out(vty,
- "BGP table version is %" PRIu64
- ", local router ID is %s\n",
- table->version,
- inet_ntoa(bgp->router_id));
- vty_out(vty, BGP_SHOW_SCODE_HEADER);
- vty_out(vty, BGP_SHOW_OCODE_HEADER);
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- vty_out(vty,
- BGP_SHOW_DAMP_HEADER);
- else if (
- type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor)
- vty_out(vty,
- BGP_SHOW_FLAP_HEADER);
- else
- vty_out(vty, BGP_SHOW_HEADER);
- header = 0;
- }
+ if (!lcommunity_list_match(
+ ri->attr->lcommunity, list))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity_all) {
+ if (!ri->attr->lcommunity)
+ continue;
+ }
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor) {
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_DAMPED)
+ || CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
+ continue;
+ }
+ if (!use_json && header) {
+ vty_out(vty,
+ "BGP table version is %" PRIu64
+ ", local router ID is %s\n",
+ table->version,
+ inet_ntoa(bgp->router_id));
+ vty_out(vty, BGP_SHOW_SCODE_HEADER);
+ vty_out(vty, BGP_SHOW_OCODE_HEADER);
if (type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor)
- damp_route_vty_out(
- vty, &rn->p, ri, display,
- SAFI_UNICAST, use_json,
- json_paths);
- else if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor)
- flap_route_vty_out(
- vty, &rn->p, ri, display,
- SAFI_UNICAST, use_json,
- json_paths);
+ vty_out(vty, BGP_SHOW_DAMP_HEADER);
+ else if (
+ type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor)
+ vty_out(vty, BGP_SHOW_FLAP_HEADER);
else
- route_vty_out(vty, &rn->p, ri, display,
- SAFI_UNICAST, json_paths);
- display++;
+ vty_out(vty, BGP_SHOW_HEADER);
+ header = 0;
}
-
- if (display) {
- output_count++;
- if (use_json) {
- p = &rn->p;
- sprintf(buf2, "%s/%d",
- inet_ntop(p->family,
- &p->u.prefix, buf,
- BUFSIZ),
- p->prefixlen);
- vty_out(vty, "\"%s\": ", buf2);
- vty_out(vty, "%s",
- json_object_to_json_string(
- json_paths));
- json_object_free(json_paths);
- first = 0;
- }
+ if (rd != NULL && !display && !output_count) {
+ if (!use_json)
+ vty_out(vty,
+ "Route Distinguisher: %s\n",
+ rd);
}
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor)
+ damp_route_vty_out(vty, &rn->p, ri, display,
+ safi, use_json,
+ json_paths);
+ else if (type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor)
+ flap_route_vty_out(vty, &rn->p, ri, display,
+ safi, use_json,
+ json_paths);
+ else
+ route_vty_out(vty, &rn->p, ri, display,
+ safi, json_paths);
+ display++;
}
+ if (display) {
+ output_count++;
+ if (!use_json)
+ continue;
+
+ p = &rn->p;
+ sprintf(buf2, "%s/%d",
+ inet_ntop(p->family, &p->u.prefix,
+ buf, BUFSIZ),
+ p->prefixlen);
+ vty_out(vty, "\"%s\": ", buf2);
+ vty_out(vty, "%s",
+ json_object_to_json_string(json_paths));
+ json_object_free(json_paths);
+ first = 0;
+ }
+ }
+
+ if (output_cum) {
+ output_count += *output_cum;
+ *output_cum = output_count;
+ }
+ if (total_cum) {
+ total_count += *total_cum;
+ *total_cum = total_count;
+ }
if (use_json) {
json_object_free(json_paths);
- vty_out(vty, " } }\n");
+ if (is_last)
+ vty_out(vty, " } }\n");
+ else
+ vty_out(vty, " }, ");
} else {
- /* No route is displayed */
- if (output_count == 0) {
- if (type == bgp_show_type_normal)
+ if (is_last) {
+ /* No route is displayed */
+ if (output_count == 0) {
+ if (type == bgp_show_type_normal)
+ vty_out(vty,
+ "No BGP prefixes displayed, %ld exist\n",
+ total_count);
+ } else
vty_out(vty,
- "No BGP prefixes displayed, %ld exist\n",
- total_count);
- } else
- vty_out(vty,
- "\nDisplayed %ld routes and %ld total paths\n",
- output_count, total_count);
+ "\nDisplayed %ld routes and %ld total paths\n",
+ output_count, total_count);
+ }
}
return CMD_SUCCESS;
}
+int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
+ struct bgp_table *table, struct prefix_rd *prd_match,
+ enum bgp_show_type type, void *output_arg,
+ u_char use_json)
+{
+ struct bgp_node *rn, *next;
+ unsigned long output_cum = 0;
+ unsigned long total_cum = 0;
+
+ for (rn = bgp_table_top(table); rn; rn = next) {
+ next = bgp_route_next(rn);
+ if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
+ continue;
+ if (rn->info != NULL) {
+ struct prefix_rd prd;
+ char rd[BUFSIZ];
+
+ memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
+ if (prefix_rd2str(&prd, rd, BUFSIZ) == NULL)
+ sprintf(rd,
+ "Unknown Type: %u",
+ decode_rd_type(prd.val));
+ bgp_show_table(vty, bgp, safi, rn->info, type,
+ output_arg, use_json,
+ rd, next == NULL,
+ &output_cum, &total_cum);
+ }
+ }
+ if (use_json)
+ vty_out(vty, " } }");
+ return CMD_SUCCESS;
+}
static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
enum bgp_show_type type, void *output_arg, u_char use_json)
{
@@ -8409,18 +8465,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
return CMD_WARNING;
}
+ table = bgp->rib[afi][safi];
/* use MPLS and ENCAP specific shows until they are merged */
if (safi == SAFI_MPLS_VPN) {
- return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg, 0,
- use_json);
+ return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
+ output_arg, use_json);
}
/* labeled-unicast routes live in the unicast table */
else if (safi == SAFI_LABELED_UNICAST)
safi = SAFI_UNICAST;
- table = bgp->rib[afi][safi];
-
- return bgp_show_table(vty, bgp, table, type, output_arg, use_json);
+ return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
+ NULL, 1, NULL, NULL);
}
static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
@@ -9090,12 +9146,7 @@ DEFUN (show_ip_bgp_json,
return bgp_show(vty, bgp, afi, safi,
bgp_show_type_community_all, NULL, uj);
}
-
- if (safi == SAFI_MPLS_VPN)
- return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
- NULL, 0, uj);
- else
- return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
+ return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
}
DEFUN (show_ip_bgp_route,
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 6caa1c893..6fbeed896 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -442,4 +442,8 @@ extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct prefix *p, struct bgp_info *binfo,
afi_t afi, safi_t safi,
json_object *json_paths);
+extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
+ struct bgp_table *table, struct prefix_rd *prd,
+ enum bgp_show_type type, void *output_arg,
+ u_char use_json);
#endif /* _QUAGGA_BGP_ROUTE_H */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 4ddb49982..355d1037b 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9868,17 +9868,13 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
/* "show [ip] bgp neighbors" commands. */
DEFUN (show_ip_bgp_neighbors,
show_ip_bgp_neighbors_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|vpnv4 <all|rd ASN:NN_OR_IP-ADDRESS:NN>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
"Address Family\n"
"Address Family\n"
- "Address Family\n"
- "Display information about all VPNv4 NLRIs\n"
- "Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"