From 53e44d0594c52feca7bd4d2a25a8112656ade4a6 Mon Sep 17 00:00:00 2001 From: rgirada Date: Tue, 1 Sep 2020 04:47:13 -0700 Subject: [PATCH] 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 ] summary-address [detail] [json] Signed-off-by: Rajesh Girada --- ospfd/ospf_vty.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 262 insertions(+), 1 deletion(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index c608613bb1..728fdc8cf1 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -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 ] 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. */ -- 2.39.5