ospfd: OSPF external LSA summarisation show commands

Description:
	The below show command introduced to diplay all configured
	summary addresss information along with matching corresponding
	external route information.

	show ip ospf [vrf <NAME|all>] summary-address [detail] [json]

Signed-off-by: Rajesh Girada <rgirada@vmware.com>
This commit is contained in:
rgirada 2020-09-01 04:47:13 -07:00
parent 423e71c45a
commit 53e44d0594

View File

@ -10554,6 +10554,265 @@ static const char *const ospf_abr_type_str[] = {
static const char *const ospf_shortcut_mode_str[] = {
"default", "enable", "disable"
};
static int ospf_vty_external_rt_walkcb(struct hash_bucket *backet,
void *arg)
{
struct external_info *ei = backet->data;
struct vty *vty = (struct vty *)arg;
static unsigned int count;
vty_out(vty, "%-4pI4/%d, ", &ei->p.prefix, ei->p.prefixlen);
count++;
if (count % 5 == 0)
vty_out(vty, "\n");
if (OSPF_EXTERNAL_RT_COUNT(ei->aggr_route) == count)
count = 0;
return HASHWALK_CONTINUE;
}
static int ospf_json_external_rt_walkcb(struct hash_bucket *backet,
void *arg)
{
struct external_info *ei = backet->data;
struct json_object *json = (struct json_object *)arg;
char buf[PREFIX2STR_BUFFER];
char exnalbuf[20];
static unsigned int count;
prefix2str(&ei->p, buf, sizeof(buf));
snprintf(exnalbuf, 20, "Exnl Addr-%d", count);
json_object_string_add(json, exnalbuf, buf);
count++;
if (OSPF_EXTERNAL_RT_COUNT(ei->aggr_route) == count)
count = 0;
return HASHWALK_CONTINUE;
}
static int ospf_show_summary_address(struct vty *vty, struct ospf *ospf,
uint8_t use_vrf, json_object *json,
bool uj, bool detail)
{
struct route_node *rn;
json_object *json_vrf = NULL;
int mtype = 0;
int mval = 0;
static char header[] =
"Summary-address Metric-type Metric Tag External_Rt_count\n";
mtype = metric_type(ospf, 0, ospf->instance);
mval = metric_value(ospf, 0, ospf->instance);
if (!uj)
vty_out(vty, "%s\n", header);
if (uj) {
if (use_vrf)
json_vrf = json_object_new_object();
else
json_vrf = json;
}
if (ospf->instance) {
if (uj)
json_object_int_add(json, "ospfInstance",
ospf->instance);
else
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
if (!uj)
vty_out(vty, "aggregation delay interval :%d(in seconds)\n\n",
ospf->aggr_delay_interval);
else
json_object_int_add(json_vrf, "aggregation delay interval",
ospf->aggr_delay_interval);
for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn))
if (rn->info) {
struct ospf_external_aggr_rt *aggr = rn->info;
json_object *json_aggr = NULL;
char buf[PREFIX2STR_BUFFER];
prefix2str(&aggr->p, buf, sizeof(buf));
if (uj) {
json_aggr = json_object_new_object();
json_object_object_add(json_vrf, buf,
json_aggr);
json_object_string_add(json_aggr,
"Summary address", buf);
json_object_string_add(
json_aggr, "Metric-type",
(mtype == EXTERNAL_METRIC_TYPE_1)
? "E1"
: "E2");
json_object_int_add(json_aggr, "Metric", mval);
json_object_int_add(json_aggr, "Tag",
aggr->tag);
json_object_int_add(
json_aggr, "External route count",
OSPF_EXTERNAL_RT_COUNT(aggr));
if (OSPF_EXTERNAL_RT_COUNT(aggr) && detail) {
hash_walk(
aggr->match_extnl_hash,
ospf_json_external_rt_walkcb,
json_aggr);
}
} else {
vty_out(vty, "%-20s", buf);
(mtype == EXTERNAL_METRIC_TYPE_1)
? vty_out(vty, "%-16s", "E1")
: vty_out(vty, "%-16s", "E2");
vty_out(vty, "%-11d", mval);
vty_out(vty, "%-12u", aggr->tag);
vty_out(vty, "%-5ld\n",
OSPF_EXTERNAL_RT_COUNT(aggr));
if (OSPF_EXTERNAL_RT_COUNT(aggr) && detail) {
vty_out(vty,
"Matched External routes:\n");
hash_walk(
aggr->match_extnl_hash,
ospf_vty_external_rt_walkcb,
vty);
vty_out(vty, "\n");
}
vty_out(vty, "\n");
}
}
if (uj) {
if (use_vrf) {
if (ospf->vrf_id == VRF_DEFAULT)
json_object_object_add(json, "default",
json_vrf);
else
json_object_object_add(json, ospf->name,
json_vrf);
}
} else
vty_out(vty, "\n");
return CMD_SUCCESS;
}
DEFUN (show_ip_ospf_external_aggregator,
show_ip_ospf_external_aggregator_cmd,
"show ip ospf [vrf <NAME|all>] summary-address [detail] [json]",
SHOW_STR IP_STR
"OSPF information\n"
VRF_CMD_HELP_STR
"All VRFs\n"
"Show external summary addresses\n"
"Detailed informtion\n"
JSON_STR)
{
char *vrf_name = NULL;
bool all_vrf = false;
int ret = CMD_SUCCESS;
int idx_vrf = 0;
int idx = 0;
uint8_t use_vrf = 0;
bool uj = use_json(argc, argv);
struct ospf *ospf = NULL;
json_object *json = NULL;
struct listnode *node = NULL;
int inst = 0;
bool detail = false;
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (argv_find(argv, argc, "detail", &idx))
detail = true;
if (uj)
json = json_object_new_object();
/* vrf input is provided */
if (vrf_name) {
use_vrf = 1;
if (all_vrf) {
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
if (!ospf->oi_running)
continue;
ret = ospf_show_summary_address(
vty, ospf, use_vrf, json, uj, detail);
}
if (uj) {
vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
}
return ret;
}
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
if (ospf == NULL || !ospf->oi_running) {
if (uj) {
vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
} else
vty_out(vty, "%% OSPF instance not found\n");
return CMD_SUCCESS;
}
ret = ospf_show_summary_address(vty, ospf, use_vrf, json, uj,
detail);
} else {
/* Default Vrf */
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL || !ospf->oi_running) {
if (uj) {
vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
} else
vty_out(vty, "%% OSPF instance not found\n");
return CMD_SUCCESS;
}
ospf_show_summary_address(vty, ospf, use_vrf, json, uj, detail);
}
if (uj) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
}
return CMD_SUCCESS;
}
static const char *const ospf_int_type_str[] = {
"unknown", /* should never be used. */
@ -11456,8 +11715,10 @@ void ospf_vty_show_init(void)
/* "show ip ospf gr-helper details" command */
install_element(VIEW_NODE, &show_ip_ospf_gr_helper_cmd);
}
/* "show ip ospf summary-address" command */
install_element(VIEW_NODE, &show_ip_ospf_external_aggregator_cmd);
}
static int config_write_interface(struct vty *vty);
/* ospfd's interface node. */