afi_t afi;
route_map_result_t ret;
struct bgp_redist *red;
+ struct interface *ifp;
/* Make default attribute. */
bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
}
attr.nh_type = nhtype;
attr.nh_ifindex = ifindex;
+ ifp = if_lookup_by_index(ifindex, bgp->vrf_id);
+ if (ifp && if_is_operative(ifp))
+ SET_FLAG(attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE);
+ else
+ UNSET_FLAG(attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE);
attr.med = metric;
attr.distance = distance;
"link-local");
if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
- &attr->mp_nexthop_local)
- != 0)
- && !attr->mp_nexthop_prefer_global)
+ &attr->mp_nexthop_local) !=
+ 0) &&
+ !CHECK_FLAG(attr->nh_flag,
+ BGP_ATTR_NH_MP_PREFER_GLOBAL))
json_object_boolean_true_add(
json_nexthop_ll, "used");
else
} else {
/* Display LL if LL/Global both in table unless
* prefer-global is set */
- if (((attr->mp_nexthop_len
- == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
- && !attr->mp_nexthop_prefer_global)
- || (path->peer->conf_if)) {
+ if (((attr->mp_nexthop_len ==
+ BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) &&
+ !CHECK_FLAG(attr->nh_flag,
+ BGP_ATTR_NH_MP_PREFER_GLOBAL)) ||
+ (path->peer->conf_if)) {
if (path->peer->conf_if) {
len = vty_out(vty, "%s",
path->peer->conf_if);
json_object_boolean_true_add(json_nexthop_ll,
"accessible");
- if (!attr->mp_nexthop_prefer_global)
+ if (!CHECK_FLAG(attr->nh_flag,
+ BGP_ATTR_NH_MP_PREFER_GLOBAL))
json_object_boolean_true_add(json_nexthop_ll,
"used");
else
vty_out(vty, " (%s) %s\n",
inet_ntop(AF_INET6, &attr->mp_nexthop_local,
buf, INET6_ADDRSTRLEN),
- attr->mp_nexthop_prefer_global
+ CHECK_FLAG(attr->nh_flag,
+ BGP_ATTR_NH_MP_PREFER_GLOBAL)
? "(prefer-global)"
: "(used)");
}
bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
+ bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
+ bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
if (output_cum && *output_cum != 0)
header = false;
}
/* Check for 'json detail', where we need header output once per dest */
- if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
- type != bgp_show_type_dampend_paths &&
+ if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
type != bgp_show_type_damp_neighbor &&
type != bgp_show_type_flap_statistics &&
type != bgp_show_type_flap_neighbor)
vty_out(vty, "Default local pref %u, ",
bgp->default_local_pref);
vty_out(vty, "local AS %u\n", bgp->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_routes) {
+ 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 (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
+ else if (!detail_routes)
vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
: BGP_SHOW_HEADER));
header = false;
AFI_IP, safi, use_json,
json_paths);
else {
- if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
+ if (detail_routes || detail_json) {
+ const struct prefix_rd *prd = NULL;
+
+ if (dest->pdest)
+ prd = bgp_rd_from_dest(
+ dest->pdest, safi);
+
+ if (!use_json)
+ route_vty_out_detail_header(
+ vty, bgp, dest,
+ bgp_dest_get_prefix(
+ dest),
+ prd, table->afi, safi,
+ NULL);
+
route_vty_out_detail(
- vty, bgp, dest,
- bgp_dest_get_prefix(dest), pi,
+ vty, bgp, dest, dest_p, pi,
family2afi(dest_p->family),
safi, RPKI_NOT_BEING_USED,
json_paths);
- else
+ } else {
route_vty_out(vty, dest_p, pi, display,
safi, json_paths, wide);
+ }
}
display++;
}
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, bool use_json)
+ enum bgp_show_type type, void *output_arg,
+ uint16_t show_flags)
{
struct bgp_dest *dest, *next;
unsigned long output_cum = 0;
unsigned long json_header_depth = 0;
struct bgp_table *itable;
bool show_msg;
- uint16_t show_flags = 0;
+ bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
show_msg = (!use_json && type == bgp_show_type_normal);
- if (use_json)
- SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
-
for (dest = bgp_table_top(table); dest; dest = next) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
/* use MPLS and ENCAP specific shows until they are merged */
if (safi == SAFI_MPLS_VPN) {
return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
- output_arg, use_json);
+ output_arg, show_flags);
}
if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
|A.B.C.D/M longer-prefixes\
|X:X::X:X/M longer-prefixes\
|optimal-route-reflection [WORD$orr_group_name]\
- ] [json$uj [detail$detail] | wide$wide]",
+ |detail-routes$detail_routes\
+ ] [json$uj [detail$detail_json] | 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"
"Display route and more specific routes\n"
"Display Optimal Route Reflection RR Clients\n"
"ORR Group name\n"
+ "Display detailed version of all routes\n"
JSON_STR
"Display detailed version of JSON output\n"
"Increase table width for longer prefixes\n")
SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
}
- if (detail)
- SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
+ if (detail_json)
+ SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
+
+ if (detail_routes)
+ SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
/* [<ipv4|ipv6> [all]] */
if (all) {
struct bgp *bgp = NULL;
int idx = 0;
bool uj = use_json(argc, argv);
- uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
+ uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
if (uj) {
argc--;