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. */
/* "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. */