]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospfd: OSPF external LSA summarisation show commands
authorrgirada <rgirada@vmware.com>
Tue, 1 Sep 2020 11:47:13 +0000 (04:47 -0700)
committerrgirada <rgirada@vmware.com>
Mon, 2 Nov 2020 06:06:12 +0000 (22:06 -0800)
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>
ospfd/ospf_vty.c

index c608613bb1b2942de812c6280d5a50e3ac27a171..728fdc8cf17a9372db298138f3b99dd92b1dea52 100644 (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. */