1 /* OSPF VTY interface.
2  * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
3  * Copyright (C) 2000 Toshiaki Takada
4  *
5  * This file is part of GNU Zebra.
6  *
7  * GNU Zebra is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2, or (at your option) any
10  * later version.
11  *
12  * GNU Zebra is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; see the file COPYING; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <zebra.h>
23 #include <string.h>
24 
25 #include "monotime.h"
26 #include "memory.h"
27 #include "thread.h"
28 #include "prefix.h"
29 #include "table.h"
30 #include "vty.h"
31 #include "command.h"
32 #include "plist.h"
33 #include "log.h"
34 #include "zclient.h"
35 #include <lib/json.h>
36 #include "defaults.h"
37 
38 #include "ospfd/ospfd.h"
39 #include "ospfd/ospf_asbr.h"
40 #include "ospfd/ospf_lsa.h"
41 #include "ospfd/ospf_lsdb.h"
42 #include "ospfd/ospf_ism.h"
43 #include "ospfd/ospf_interface.h"
44 #include "ospfd/ospf_nsm.h"
45 #include "ospfd/ospf_neighbor.h"
46 #include "ospfd/ospf_flood.h"
47 #include "ospfd/ospf_abr.h"
48 #include "ospfd/ospf_spf.h"
49 #include "ospfd/ospf_route.h"
50 #include "ospfd/ospf_zebra.h"
51 /*#include "ospfd/ospf_routemap.h" */
52 #include "ospfd/ospf_vty.h"
53 #include "ospfd/ospf_dump.h"
54 #include "ospfd/ospf_bfd.h"
55 
56 FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES,
57 	{ .val_bool = true, .match_profile = "datacenter", },
58 	{ .val_bool = false },
59 )
60 
61 static const char *const ospf_network_type_str[] = {
62 	"Null",	"POINTOPOINT", "BROADCAST", "NBMA", "POINTOMULTIPOINT",
63 	"VIRTUALLINK", "LOOPBACK"};
64 
65 /* Utility functions. */
str2area_id(const char * str,struct in_addr * area_id,int * area_id_fmt)66 int str2area_id(const char *str, struct in_addr *area_id, int *area_id_fmt)
67 {
68 	char *ep;
69 
70 	area_id->s_addr = htonl(strtoul(str, &ep, 10));
71 	if (*ep && !inet_aton(str, area_id))
72 		return -1;
73 
74 	*area_id_fmt =
75 		*ep ? OSPF_AREA_ID_FMT_DOTTEDQUAD : OSPF_AREA_ID_FMT_DECIMAL;
76 
77 	return 0;
78 }
79 
area_id2str(char * buf,int length,struct in_addr * area_id,int area_id_fmt)80 static void area_id2str(char *buf, int length, struct in_addr *area_id,
81 			int area_id_fmt)
82 {
83 	if (area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD)
84 		inet_ntop(AF_INET, area_id, buf, length);
85 	else
86 		snprintf(buf, length, "%lu",
87 			 (unsigned long)ntohl(area_id->s_addr));
88 }
89 
str2metric(const char * str,int * metric)90 static int str2metric(const char *str, int *metric)
91 {
92 	/* Sanity check. */
93 	if (str == NULL)
94 		return 0;
95 
96 	*metric = strtol(str, NULL, 10);
97 	if (*metric < 0 || *metric > 16777214) {
98 		/* vty_out (vty, "OSPF metric value is invalid\n"); */
99 		return 0;
100 	}
101 
102 	return 1;
103 }
104 
str2metric_type(const char * str,int * metric_type)105 static int str2metric_type(const char *str, int *metric_type)
106 {
107 	/* Sanity check. */
108 	if (str == NULL)
109 		return 0;
110 
111 	if (strncmp(str, "1", 1) == 0)
112 		*metric_type = EXTERNAL_METRIC_TYPE_1;
113 	else if (strncmp(str, "2", 1) == 0)
114 		*metric_type = EXTERNAL_METRIC_TYPE_2;
115 	else
116 		return 0;
117 
118 	return 1;
119 }
120 
ospf_oi_count(struct interface * ifp)121 int ospf_oi_count(struct interface *ifp)
122 {
123 	struct route_node *rn;
124 	int i = 0;
125 
126 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
127 		if (rn->info)
128 			i++;
129 
130 	return i;
131 }
132 
133 #define OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)             \
134 	if (argv_find(argv, argc, "vrf", &idx_vrf)) {                          \
135 		vrf_name = argv[idx_vrf + 1]->arg;                             \
136 		all_vrf = strmatch(vrf_name, "all");                           \
137 	}
138 
ospf_cmd_lookup_ospf(struct vty * vty,struct cmd_token * argv[],const int argc,uint32_t enable,unsigned short * instance)139 static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty,
140 					 struct cmd_token *argv[],
141 					 const int argc, uint32_t enable,
142 					 unsigned short *instance)
143 {
144 	struct ospf *ospf = NULL;
145 	int idx_vrf = 0, idx_inst = 0;
146 	const char *vrf_name = NULL;
147 	bool created = false;
148 
149 	*instance = 0;
150 	if (argv_find(argv, argc, "(1-65535)", &idx_inst))
151 		*instance = strtoul(argv[idx_inst]->arg, NULL, 10);
152 
153 	if (argv_find(argv, argc, "vrf", &idx_vrf)) {
154 		vrf_name = argv[idx_vrf + 1]->arg;
155 		if (vrf_name == NULL || strmatch(vrf_name, VRF_DEFAULT_NAME))
156 			vrf_name = NULL;
157 		if (enable) {
158 			/* Allocate VRF aware instance */
159 			ospf = ospf_get(*instance, vrf_name, &created);
160 		} else {
161 			ospf = ospf_lookup_by_inst_name(*instance, vrf_name);
162 		}
163 	} else {
164 		if (enable) {
165 			ospf = ospf_get(*instance, NULL, &created);
166 		} else {
167 			ospf = ospf_lookup_instance(*instance);
168 		}
169 	}
170 
171 	if (created) {
172 		if (DFLT_OSPF_LOG_ADJACENCY_CHANGES)
173 			SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
174 	}
175 
176 	return ospf;
177 }
178 
ospf_show_vrf_name(struct ospf * ospf,struct vty * vty,json_object * json,uint8_t use_vrf)179 static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty,
180 			       json_object *json, uint8_t use_vrf)
181 {
182 	if (use_vrf) {
183 		if (json) {
184 			if (ospf->vrf_id == VRF_DEFAULT)
185 				json_object_string_add(json, "vrfName",
186 						       "default");
187 			else
188 				json_object_string_add(json, "vrfName",
189 						       ospf->name);
190 			json_object_int_add(json, "vrfId", ospf->vrf_id);
191 		} else {
192 			if (ospf->vrf_id == VRF_DEFAULT)
193 				vty_out(vty, "VRF Name: %s\n", "default");
194 			else if (ospf->name)
195 				vty_out(vty, "VRF Name: %s\n", ospf->name);
196 		}
197 	}
198 }
199 
200 #ifndef VTYSH_EXTRACT_PL
201 #include "ospfd/ospf_vty_clippy.c"
202 #endif
203 
204 DEFUN_NOSH (router_ospf,
205        router_ospf_cmd,
206        "router ospf [{(1-65535)|vrf NAME}]",
207        "Enable a routing process\n"
208        "Start OSPF configuration\n"
209        "Instance ID\n"
210        VRF_CMD_HELP_STR)
211 {
212 	struct ospf *ospf = NULL;
213 	int ret = CMD_SUCCESS;
214 	unsigned short instance = 0;
215 
216 	ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance);
217 	if (!ospf)
218 		return CMD_WARNING_CONFIG_FAILED;
219 
220 	/* The following logic to set the vty qobj index is in place to be able
221 	   to ignore the commands which dont belong to this instance. */
222 	if (ospf->instance != instance) {
223 		VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
224 		ret = CMD_NOT_MY_INSTANCE;
225 	} else {
226 		if (IS_DEBUG_OSPF_EVENT)
227 			zlog_debug(
228 				"Config command 'router ospf %d' received, vrf %s id %u oi_running %u",
229 				instance, ospf->name ? ospf->name : "NIL",
230 				ospf->vrf_id, ospf->oi_running);
231 		VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
232 	}
233 
234 	return ret;
235 }
236 
237 DEFUN (no_router_ospf,
238        no_router_ospf_cmd,
239        "no router ospf [{(1-65535)|vrf NAME}]",
240        NO_STR
241        "Enable a routing process\n"
242        "Start OSPF configuration\n"
243        "Instance ID\n"
244        VRF_CMD_HELP_STR)
245 {
246 	struct ospf *ospf;
247 	unsigned short instance = 0;
248 
249 	ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 0, &instance);
250 	if (ospf == NULL) {
251 		if (instance)
252 			return CMD_NOT_MY_INSTANCE;
253 		else
254 			return CMD_WARNING;
255 	}
256 	ospf_finish(ospf);
257 
258 	return CMD_SUCCESS;
259 }
260 
261 
262 DEFPY (ospf_router_id,
263        ospf_router_id_cmd,
264        "ospf router-id A.B.C.D",
265        "OSPF specific commands\n"
266        "router-id for the OSPF process\n"
267        "OSPF router-id in IP address format\n")
268 {
269 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
270 
271 	struct listnode *node;
272 	struct ospf_area *area;
273 
274 	ospf->router_id_static = router_id;
275 
276 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
277 		if (area->full_nbrs) {
278 			vty_out(vty,
279 				"For this router-id change to take effect, save config and restart ospfd\n");
280 			return CMD_SUCCESS;
281 		}
282 
283 	ospf_router_id_update(ospf);
284 
285 	return CMD_SUCCESS;
286 }
287 
288 DEFUN_HIDDEN (ospf_router_id_old,
289               ospf_router_id_old_cmd,
290               "router-id A.B.C.D",
291               "router-id for the OSPF process\n"
292               "OSPF router-id in IP address format\n")
293 {
294 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
295 	int idx_ipv4 = 1;
296 	struct listnode *node;
297 	struct ospf_area *area;
298 	struct in_addr router_id;
299 	int ret;
300 
301 	ret = inet_aton(argv[idx_ipv4]->arg, &router_id);
302 	if (!ret) {
303 		vty_out(vty, "Please specify Router ID by A.B.C.D\n");
304 		return CMD_WARNING_CONFIG_FAILED;
305 	}
306 
307 	ospf->router_id_static = router_id;
308 
309 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
310 		if (area->full_nbrs) {
311 			vty_out(vty,
312 				"For this router-id change to take effect, save config and restart ospfd\n");
313 			return CMD_SUCCESS;
314 		}
315 
316 	ospf_router_id_update(ospf);
317 
318 	return CMD_SUCCESS;
319 }
320 
321 DEFPY (no_ospf_router_id,
322        no_ospf_router_id_cmd,
323        "no ospf router-id [A.B.C.D]",
324        NO_STR
325        "OSPF specific commands\n"
326        "router-id for the OSPF process\n"
327        "OSPF router-id in IP address format\n")
328 {
329 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
330 	struct listnode *node;
331 	struct ospf_area *area;
332 
333 	if (router_id_str) {
334 		if (!IPV4_ADDR_SAME(&ospf->router_id_static, &router_id)) {
335 			vty_out(vty, "%% OSPF router-id doesn't match\n");
336 			return CMD_WARNING_CONFIG_FAILED;
337 		}
338 	}
339 
340 	ospf->router_id_static.s_addr = 0;
341 
342 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
343 		if (area->full_nbrs) {
344 			vty_out(vty,
345 				"For this router-id change to take effect, save config and restart ospfd\n");
346 			return CMD_SUCCESS;
347 		}
348 
349 	ospf_router_id_update(ospf);
350 
351 	return CMD_SUCCESS;
352 }
353 
354 
ospf_passive_interface_default(struct ospf * ospf,uint8_t newval)355 static void ospf_passive_interface_default(struct ospf *ospf, uint8_t newval)
356 {
357 	struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
358 	struct listnode *ln;
359 	struct interface *ifp;
360 	struct ospf_interface *oi;
361 
362 	ospf->passive_interface_default = newval;
363 
364 	FOR_ALL_INTERFACES (vrf, ifp) {
365 		if (ifp && OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
366 						    passive_interface))
367 			UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), passive_interface);
368 	}
369 	for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, ln, oi)) {
370 		if (OSPF_IF_PARAM_CONFIGURED(oi->params, passive_interface))
371 			UNSET_IF_PARAM(oi->params, passive_interface);
372 		/* update multicast memberships */
373 		ospf_if_set_multicast(oi);
374 	}
375 }
376 
ospf_passive_interface_update_addr(struct ospf * ospf,struct interface * ifp,struct ospf_if_params * params,uint8_t value,struct in_addr addr)377 static void ospf_passive_interface_update_addr(struct ospf *ospf,
378 					       struct interface *ifp,
379 					       struct ospf_if_params *params,
380 					       uint8_t value,
381 					       struct in_addr addr)
382 {
383 	uint8_t dflt;
384 
385 	params->passive_interface = value;
386 	if (params != IF_DEF_PARAMS(ifp)) {
387 		if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
388 					     passive_interface))
389 			dflt = IF_DEF_PARAMS(ifp)->passive_interface;
390 		else
391 			dflt = ospf->passive_interface_default;
392 
393 		if (value != dflt)
394 			SET_IF_PARAM(params, passive_interface);
395 		else
396 			UNSET_IF_PARAM(params, passive_interface);
397 
398 		ospf_free_if_params(ifp, addr);
399 		ospf_if_update_params(ifp, addr);
400 	}
401 }
402 
ospf_passive_interface_update(struct ospf * ospf,struct interface * ifp,struct ospf_if_params * params,uint8_t value)403 static void ospf_passive_interface_update(struct ospf *ospf,
404 					  struct interface *ifp,
405 					  struct ospf_if_params *params,
406 					  uint8_t value)
407 {
408 	params->passive_interface = value;
409 	if (params == IF_DEF_PARAMS(ifp)) {
410 		if (value != ospf->passive_interface_default)
411 			SET_IF_PARAM(params, passive_interface);
412 		else
413 			UNSET_IF_PARAM(params, passive_interface);
414 	}
415 }
416 
417 DEFUN (ospf_passive_interface,
418        ospf_passive_interface_addr_cmd,
419        "passive-interface <IFNAME [A.B.C.D]|default>",
420        "Suppress routing updates on an interface\n"
421        "Interface's name\n"
422        "IPv4 address\n"
423        "Suppress routing updates on interfaces by default\n")
424 {
425 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
426 	int idx_ipv4 = 2;
427 	struct interface *ifp = NULL;
428 	struct in_addr addr = {.s_addr = INADDR_ANY};
429 	int ret;
430 	struct ospf_if_params *params;
431 	struct route_node *rn;
432 
433 	if (strmatch(argv[1]->text, "default")) {
434 		ospf_passive_interface_default(ospf, OSPF_IF_PASSIVE);
435 		return CMD_SUCCESS;
436 	}
437 	if (ospf->vrf_id != VRF_UNKNOWN)
438 		ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id);
439 
440 	if (ifp == NULL) {
441 		vty_out(vty, "interface %s not found.\n", (char *)argv[1]->arg);
442 		return CMD_WARNING_CONFIG_FAILED;
443 	}
444 
445 	params = IF_DEF_PARAMS(ifp);
446 
447 	if (argc == 3) {
448 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
449 		if (!ret) {
450 			vty_out(vty,
451 				"Please specify interface address by A.B.C.D\n");
452 			return CMD_WARNING_CONFIG_FAILED;
453 		}
454 
455 		params = ospf_get_if_params(ifp, addr);
456 		ospf_if_update_params(ifp, addr);
457 		ospf_passive_interface_update_addr(ospf, ifp, params,
458 						   OSPF_IF_PASSIVE, addr);
459 	}
460 
461 	ospf_passive_interface_update(ospf, ifp, params, OSPF_IF_PASSIVE);
462 
463 	/* XXX We should call ospf_if_set_multicast on exactly those
464 	 * interfaces for which the passive property changed.  It is too much
465 	 * work to determine this set, so we do this for every interface.
466 	 * This is safe and reasonable because ospf_if_set_multicast uses a
467 	 * record of joined groups to avoid systems calls if the desired
468 	 * memberships match the current memership.
469 	 */
470 
471 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
472 		struct ospf_interface *oi = rn->info;
473 
474 		if (oi && (OSPF_IF_PARAM(oi, passive_interface)
475 			   == OSPF_IF_PASSIVE))
476 			ospf_if_set_multicast(oi);
477 	}
478 	/*
479 	 * XXX It is not clear what state transitions the interface needs to
480 	 * undergo when going from active to passive.  Fixing this will
481 	 * require precise identification of interfaces having such a
482 	 * transition.
483 	 */
484 
485 	return CMD_SUCCESS;
486 }
487 
488 DEFUN (no_ospf_passive_interface,
489        no_ospf_passive_interface_addr_cmd,
490        "no passive-interface <IFNAME [A.B.C.D]|default>",
491        NO_STR
492        "Allow routing updates on an interface\n"
493        "Interface's name\n"
494        "IPv4 address\n"
495        "Allow routing updates on interfaces by default\n")
496 {
497 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
498 	int idx_ipv4 = 3;
499 	struct interface *ifp = NULL;
500 	struct in_addr addr = {.s_addr = INADDR_ANY};
501 	struct ospf_if_params *params;
502 	int ret;
503 	struct route_node *rn;
504 
505 	if (strmatch(argv[2]->text, "default")) {
506 		ospf_passive_interface_default(ospf, OSPF_IF_ACTIVE);
507 		return CMD_SUCCESS;
508 	}
509 
510 	if (ospf->vrf_id != VRF_UNKNOWN)
511 		ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id);
512 
513 	if (ifp == NULL) {
514 		vty_out(vty, "interface %s not found.\n", (char *)argv[2]->arg);
515 		return CMD_WARNING_CONFIG_FAILED;
516 	}
517 
518 	params = IF_DEF_PARAMS(ifp);
519 
520 	if (argc == 4) {
521 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
522 		if (!ret) {
523 			vty_out(vty,
524 				"Please specify interface address by A.B.C.D\n");
525 			return CMD_WARNING_CONFIG_FAILED;
526 		}
527 
528 		params = ospf_lookup_if_params(ifp, addr);
529 		if (params == NULL)
530 			return CMD_SUCCESS;
531 		ospf_passive_interface_update_addr(ospf, ifp, params,
532 						   OSPF_IF_ACTIVE, addr);
533 	}
534 	ospf_passive_interface_update(ospf, ifp, params, OSPF_IF_ACTIVE);
535 
536 	/* XXX We should call ospf_if_set_multicast on exactly those
537 	 * interfaces for which the passive property changed.  It is too much
538 	 * work to determine this set, so we do this for every interface.
539 	 * This is safe and reasonable because ospf_if_set_multicast uses a
540 	 * record of joined groups to avoid systems calls if the desired
541 	 * memberships match the current memership.
542 	 */
543 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
544 		struct ospf_interface *oi = rn->info;
545 
546 		if (oi
547 		    && (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_ACTIVE))
548 			ospf_if_set_multicast(oi);
549 	}
550 
551 	return CMD_SUCCESS;
552 }
553 
554 
555 DEFUN (ospf_network_area,
556        ospf_network_area_cmd,
557        "network A.B.C.D/M area <A.B.C.D|(0-4294967295)>",
558        "Enable routing on an IP network\n"
559        "OSPF network prefix\n"
560        "Set the OSPF area ID\n"
561        "OSPF area ID in IP address format\n"
562        "OSPF area ID as a decimal value\n")
563 {
564 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
565 	int idx_ipv4_prefixlen = 1;
566 	int idx_ipv4_number = 3;
567 	struct prefix_ipv4 p;
568 	struct in_addr area_id;
569 	int ret, format;
570 
571 	if (ospf->instance) {
572 		vty_out(vty,
573 			"The network command is not supported in multi-instance ospf\n");
574 		return CMD_WARNING_CONFIG_FAILED;
575 	}
576 
577 	if (ospf->if_ospf_cli_count > 0) {
578 		vty_out(vty,
579 			"Please remove all ip ospf area x.x.x.x commands first.\n");
580 		if (IS_DEBUG_OSPF_EVENT)
581 			zlog_debug(
582 				"%s ospf vrf %s num of %u ip osp area x config",
583 				__func__, ospf->name ? ospf->name : "NIL",
584 				ospf->if_ospf_cli_count);
585 		return CMD_WARNING_CONFIG_FAILED;
586 	}
587 
588 	/* Get network prefix and Area ID. */
589 	str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
590 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
591 
592 	ret = ospf_network_set(ospf, &p, area_id, format);
593 	if (ret == 0) {
594 		vty_out(vty, "There is already same network statement.\n");
595 		return CMD_WARNING_CONFIG_FAILED;
596 	}
597 
598 	return CMD_SUCCESS;
599 }
600 
601 DEFUN (no_ospf_network_area,
602        no_ospf_network_area_cmd,
603        "no network A.B.C.D/M area <A.B.C.D|(0-4294967295)>",
604        NO_STR
605        "Enable routing on an IP network\n"
606        "OSPF network prefix\n"
607        "Set the OSPF area ID\n"
608        "OSPF area ID in IP address format\n"
609        "OSPF area ID as a decimal value\n")
610 {
611 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
612 	int idx_ipv4_prefixlen = 2;
613 	int idx_ipv4_number = 4;
614 	struct prefix_ipv4 p;
615 	struct in_addr area_id;
616 	int ret, format;
617 
618 	if (ospf->instance) {
619 		vty_out(vty,
620 			"The network command is not supported in multi-instance ospf\n");
621 		return CMD_WARNING_CONFIG_FAILED;
622 	}
623 
624 	/* Get network prefix and Area ID. */
625 	str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
626 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
627 
628 	ret = ospf_network_unset(ospf, &p, area_id);
629 	if (ret == 0) {
630 		vty_out(vty,
631 			"Can't find specified network area configuration.\n");
632 		return CMD_WARNING_CONFIG_FAILED;
633 	}
634 
635 	return CMD_SUCCESS;
636 }
637 
638 DEFUN (ospf_area_range,
639        ospf_area_range_cmd,
640        "area <A.B.C.D|(0-4294967295)> range A.B.C.D/M [advertise [cost (0-16777215)]]",
641        "OSPF area parameters\n"
642        "OSPF area ID in IP address format\n"
643        "OSPF area ID as a decimal value\n"
644        "Summarize routes matching address/mask (border routers only)\n"
645        "Area range prefix\n"
646        "Advertise this range (default)\n"
647        "User specified metric for this range\n"
648        "Advertised metric for this range\n")
649 {
650 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
651 	int idx_ipv4_number = 1;
652 	int idx_ipv4_prefixlen = 3;
653 	int idx_cost = 6;
654 	struct prefix_ipv4 p;
655 	struct in_addr area_id;
656 	int format;
657 	uint32_t cost;
658 
659 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
660 	str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
661 
662 	ospf_area_range_set(ospf, area_id, &p, OSPF_AREA_RANGE_ADVERTISE);
663 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
664 				     format);
665 	if (argc > 5) {
666 		cost = strtoul(argv[idx_cost]->arg, NULL, 10);
667 		ospf_area_range_cost_set(ospf, area_id, &p, cost);
668 	}
669 
670 	return CMD_SUCCESS;
671 }
672 
673 DEFUN (ospf_area_range_cost,
674        ospf_area_range_cost_cmd,
675        "area <A.B.C.D|(0-4294967295)> range A.B.C.D/M cost (0-16777215)",
676        "OSPF area parameters\n"
677        "OSPF area ID in IP address format\n"
678        "OSPF area ID as a decimal value\n"
679        "Summarize routes matching address/mask (border routers only)\n"
680        "Area range prefix\n"
681        "User specified metric for this range\n"
682        "Advertised metric for this range\n")
683 {
684 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
685 	int idx_ipv4_number = 1;
686 	int idx_ipv4_prefixlen = 3;
687 	int idx_cost = 5;
688 	struct prefix_ipv4 p;
689 	struct in_addr area_id;
690 	int format;
691 	uint32_t cost;
692 
693 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
694 	str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
695 
696 	ospf_area_range_set(ospf, area_id, &p, OSPF_AREA_RANGE_ADVERTISE);
697 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
698 				     format);
699 
700 	cost = strtoul(argv[idx_cost]->arg, NULL, 10);
701 	ospf_area_range_cost_set(ospf, area_id, &p, cost);
702 
703 	return CMD_SUCCESS;
704 }
705 
706 DEFUN (ospf_area_range_not_advertise,
707        ospf_area_range_not_advertise_cmd,
708        "area <A.B.C.D|(0-4294967295)> range A.B.C.D/M not-advertise",
709        "OSPF area parameters\n"
710        "OSPF area ID in IP address format\n"
711        "OSPF area ID as a decimal value\n"
712        "Summarize routes matching address/mask (border routers only)\n"
713        "Area range prefix\n"
714        "DoNotAdvertise this range\n")
715 {
716 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
717 	int idx_ipv4_number = 1;
718 	int idx_ipv4_prefixlen = 3;
719 	struct prefix_ipv4 p;
720 	struct in_addr area_id;
721 	int format;
722 
723 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
724 	str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
725 
726 	ospf_area_range_set(ospf, area_id, &p, 0);
727 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
728 				     format);
729 	ospf_area_range_substitute_unset(ospf, area_id, &p);
730 
731 	return CMD_SUCCESS;
732 }
733 
734 DEFUN (no_ospf_area_range,
735        no_ospf_area_range_cmd,
736        "no area <A.B.C.D|(0-4294967295)> range A.B.C.D/M [<cost (0-16777215)|advertise [cost (0-16777215)]|not-advertise>]",
737        NO_STR
738        "OSPF area parameters\n"
739        "OSPF area ID in IP address format\n"
740        "OSPF area ID as a decimal value\n"
741        "Summarize routes matching address/mask (border routers only)\n"
742        "Area range prefix\n"
743        "User specified metric for this range\n"
744        "Advertised metric for this range\n"
745        "Advertise this range (default)\n"
746        "User specified metric for this range\n"
747        "Advertised metric for this range\n"
748        "DoNotAdvertise this range\n")
749 {
750 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
751 	int idx_ipv4_number = 2;
752 	int idx_ipv4_prefixlen = 4;
753 	struct prefix_ipv4 p;
754 	struct in_addr area_id;
755 	int format;
756 
757 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
758 	str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
759 
760 	ospf_area_range_unset(ospf, area_id, &p);
761 
762 	return CMD_SUCCESS;
763 }
764 
765 DEFUN (ospf_area_range_substitute,
766        ospf_area_range_substitute_cmd,
767        "area <A.B.C.D|(0-4294967295)> range A.B.C.D/M substitute A.B.C.D/M",
768        "OSPF area parameters\n"
769        "OSPF area ID in IP address format\n"
770        "OSPF area ID as a decimal value\n"
771        "Summarize routes matching address/mask (border routers only)\n"
772        "Area range prefix\n"
773        "Announce area range as another prefix\n"
774        "Network prefix to be announced instead of range\n")
775 {
776 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
777 	int idx_ipv4_number = 1;
778 	int idx_ipv4_prefixlen = 3;
779 	int idx_ipv4_prefixlen_2 = 5;
780 	struct prefix_ipv4 p, s;
781 	struct in_addr area_id;
782 	int format;
783 
784 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
785 	str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
786 	str2prefix_ipv4(argv[idx_ipv4_prefixlen_2]->arg, &s);
787 
788 	ospf_area_range_substitute_set(ospf, area_id, &p, &s);
789 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
790 				     format);
791 
792 	return CMD_SUCCESS;
793 }
794 
795 DEFUN (no_ospf_area_range_substitute,
796        no_ospf_area_range_substitute_cmd,
797        "no area <A.B.C.D|(0-4294967295)> range A.B.C.D/M substitute A.B.C.D/M",
798        NO_STR
799        "OSPF area parameters\n"
800        "OSPF area ID in IP address format\n"
801        "OSPF area ID as a decimal value\n"
802        "Summarize routes matching address/mask (border routers only)\n"
803        "Area range prefix\n"
804        "Announce area range as another prefix\n"
805        "Network prefix to be announced instead of range\n")
806 {
807 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
808 	int idx_ipv4_number = 2;
809 	int idx_ipv4_prefixlen = 4;
810 	int idx_ipv4_prefixlen_2 = 6;
811 	struct prefix_ipv4 p, s;
812 	struct in_addr area_id;
813 	int format;
814 
815 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
816 	str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
817 	str2prefix_ipv4(argv[idx_ipv4_prefixlen_2]->arg, &s);
818 
819 	ospf_area_range_substitute_unset(ospf, area_id, &p);
820 
821 	return CMD_SUCCESS;
822 }
823 
824 
825 /* Command Handler Logic in VLink stuff is delicate!!
826 
827 	ALTER AT YOUR OWN RISK!!!!
828 
829 	Various dummy values are used to represent 'NoChange' state for
830 	VLink configuration NOT being changed by a VLink command, and
831 	special syntax is used within the command strings so that the
832 	typed in command verbs can be seen in the configuration command
833 	bacckend handler.  This is to drastically reduce the verbeage
834 	required to coe up with a reasonably compatible Cisco VLink command
835 
836 	- Matthew Grant <grantma@anathoth.gen.nz>
837 	Wed, 21 Feb 2001 15:13:52 +1300
838  */
839 
840 /* Configuration data for virtual links
841  */
842 struct ospf_vl_config_data {
843 	struct vty *vty;	/* vty stuff */
844 	struct in_addr area_id; /* area ID from command line */
845 	int area_id_fmt;	/* command line area ID format */
846 	struct in_addr vl_peer; /* command line vl_peer */
847 	int auth_type;		/* Authehntication type, if given */
848 	char *auth_key;		/* simple password if present */
849 	int crypto_key_id;      /* Cryptographic key ID */
850 	char *md5_key;		/* MD5 authentication key */
851 	int hello_interval;     /* Obvious what these are... */
852 	int retransmit_interval;
853 	int transmit_delay;
854 	int dead_interval;
855 };
856 
ospf_vl_config_data_init(struct ospf_vl_config_data * vl_config,struct vty * vty)857 static void ospf_vl_config_data_init(struct ospf_vl_config_data *vl_config,
858 				     struct vty *vty)
859 {
860 	memset(vl_config, 0, sizeof(struct ospf_vl_config_data));
861 	vl_config->auth_type = OSPF_AUTH_CMD_NOTSEEN;
862 	vl_config->vty = vty;
863 }
864 
865 static struct ospf_vl_data *
ospf_find_vl_data(struct ospf * ospf,struct ospf_vl_config_data * vl_config)866 ospf_find_vl_data(struct ospf *ospf, struct ospf_vl_config_data *vl_config)
867 {
868 	struct ospf_area *area;
869 	struct ospf_vl_data *vl_data;
870 	struct vty *vty;
871 	struct in_addr area_id;
872 
873 	vty = vl_config->vty;
874 	area_id = vl_config->area_id;
875 
876 	if (area_id.s_addr == OSPF_AREA_BACKBONE) {
877 		vty_out(vty,
878 			"Configuring VLs over the backbone is not allowed\n");
879 		return NULL;
880 	}
881 	area = ospf_area_get(ospf, area_id);
882 	ospf_area_display_format_set(ospf, area, vl_config->area_id_fmt);
883 
884 	if (area->external_routing != OSPF_AREA_DEFAULT) {
885 		if (vl_config->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD)
886 			vty_out(vty, "Area %s is %s\n", inet_ntoa(area_id),
887 				area->external_routing == OSPF_AREA_NSSA
888 					? "nssa"
889 					: "stub");
890 		else
891 			vty_out(vty, "Area %ld is %s\n",
892 				(unsigned long)ntohl(area_id.s_addr),
893 				area->external_routing == OSPF_AREA_NSSA
894 					? "nssa"
895 					: "stub");
896 		return NULL;
897 	}
898 
899 	if ((vl_data = ospf_vl_lookup(ospf, area, vl_config->vl_peer))
900 	    == NULL) {
901 		vl_data = ospf_vl_data_new(area, vl_config->vl_peer);
902 		if (vl_data->vl_oi == NULL) {
903 			vl_data->vl_oi = ospf_vl_new(ospf, vl_data);
904 			ospf_vl_add(ospf, vl_data);
905 			ospf_spf_calculate_schedule(ospf,
906 						    SPF_FLAG_CONFIG_CHANGE);
907 		}
908 	}
909 	return vl_data;
910 }
911 
912 
ospf_vl_set_security(struct ospf_vl_data * vl_data,struct ospf_vl_config_data * vl_config)913 static int ospf_vl_set_security(struct ospf_vl_data *vl_data,
914 				struct ospf_vl_config_data *vl_config)
915 {
916 	struct crypt_key *ck;
917 	struct vty *vty;
918 	struct interface *ifp = vl_data->vl_oi->ifp;
919 
920 	vty = vl_config->vty;
921 
922 	if (vl_config->auth_type != OSPF_AUTH_CMD_NOTSEEN) {
923 		SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type);
924 		IF_DEF_PARAMS(ifp)->auth_type = vl_config->auth_type;
925 	}
926 
927 	if (vl_config->auth_key) {
928 		memset(IF_DEF_PARAMS(ifp)->auth_simple, 0,
929 		       OSPF_AUTH_SIMPLE_SIZE + 1);
930 		strlcpy((char *)IF_DEF_PARAMS(ifp)->auth_simple,
931 			vl_config->auth_key,
932 			sizeof(IF_DEF_PARAMS(ifp)->auth_simple));
933 	} else if (vl_config->md5_key) {
934 		if (ospf_crypt_key_lookup(IF_DEF_PARAMS(ifp)->auth_crypt,
935 					  vl_config->crypto_key_id)
936 		    != NULL) {
937 			vty_out(vty, "OSPF: Key %d already exists\n",
938 				vl_config->crypto_key_id);
939 			return CMD_WARNING;
940 		}
941 		ck = ospf_crypt_key_new();
942 		ck->key_id = vl_config->crypto_key_id;
943 		memset(ck->auth_key, 0, OSPF_AUTH_MD5_SIZE + 1);
944 		strlcpy((char *)ck->auth_key, vl_config->md5_key,
945 			sizeof(ck->auth_key));
946 
947 		ospf_crypt_key_add(IF_DEF_PARAMS(ifp)->auth_crypt, ck);
948 	} else if (vl_config->crypto_key_id != 0) {
949 		/* Delete a key */
950 
951 		if (ospf_crypt_key_lookup(IF_DEF_PARAMS(ifp)->auth_crypt,
952 					  vl_config->crypto_key_id)
953 		    == NULL) {
954 			vty_out(vty, "OSPF: Key %d does not exist\n",
955 				vl_config->crypto_key_id);
956 			return CMD_WARNING_CONFIG_FAILED;
957 		}
958 
959 		ospf_crypt_key_delete(IF_DEF_PARAMS(ifp)->auth_crypt,
960 				      vl_config->crypto_key_id);
961 	}
962 
963 	return CMD_SUCCESS;
964 }
965 
ospf_vl_set_timers(struct ospf_vl_data * vl_data,struct ospf_vl_config_data * vl_config)966 static int ospf_vl_set_timers(struct ospf_vl_data *vl_data,
967 			      struct ospf_vl_config_data *vl_config)
968 {
969 	struct interface *ifp = vl_data->vl_oi->ifp;
970 	/* Virtual Link data initialised to defaults, so only set
971 	   if a value given */
972 	if (vl_config->hello_interval) {
973 		SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello);
974 		IF_DEF_PARAMS(ifp)->v_hello = vl_config->hello_interval;
975 	}
976 
977 	if (vl_config->dead_interval) {
978 		SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait);
979 		IF_DEF_PARAMS(ifp)->v_wait = vl_config->dead_interval;
980 	}
981 
982 	if (vl_config->retransmit_interval) {
983 		SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_interval);
984 		IF_DEF_PARAMS(ifp)->retransmit_interval =
985 			vl_config->retransmit_interval;
986 	}
987 
988 	if (vl_config->transmit_delay) {
989 		SET_IF_PARAM(IF_DEF_PARAMS(ifp), transmit_delay);
990 		IF_DEF_PARAMS(ifp)->transmit_delay = vl_config->transmit_delay;
991 	}
992 
993 	return CMD_SUCCESS;
994 }
995 
996 
997 /* The business end of all of the above */
ospf_vl_set(struct ospf * ospf,struct ospf_vl_config_data * vl_config)998 static int ospf_vl_set(struct ospf *ospf, struct ospf_vl_config_data *vl_config)
999 {
1000 	struct ospf_vl_data *vl_data;
1001 	int ret;
1002 
1003 	vl_data = ospf_find_vl_data(ospf, vl_config);
1004 	if (!vl_data)
1005 		return CMD_WARNING_CONFIG_FAILED;
1006 
1007 	/* Process this one first as it can have a fatal result, which can
1008 	   only logically occur if the virtual link exists already
1009 	   Thus a command error does not result in a change to the
1010 	   running configuration such as unexpectedly altered timer
1011 	   values etc.*/
1012 	ret = ospf_vl_set_security(vl_data, vl_config);
1013 	if (ret != CMD_SUCCESS)
1014 		return ret;
1015 
1016 	/* Set any time based parameters, these area already range checked */
1017 
1018 	ret = ospf_vl_set_timers(vl_data, vl_config);
1019 	if (ret != CMD_SUCCESS)
1020 		return ret;
1021 
1022 	return CMD_SUCCESS;
1023 }
1024 
1025 /* This stuff exists to make specifying all the alias commands A LOT simpler
1026  */
1027 #define VLINK_HELPSTR_IPADDR                                                   \
1028 	"OSPF area parameters\n"                                               \
1029 	"OSPF area ID in IP address format\n"                                  \
1030 	"OSPF area ID as a decimal value\n"                                    \
1031 	"Configure a virtual link\n"                                           \
1032 	"Router ID of the remote ABR\n"
1033 
1034 #define VLINK_HELPSTR_AUTHTYPE_SIMPLE                                          \
1035 	"Enable authentication on this virtual link\n"                         \
1036 	"dummy string \n"
1037 
1038 #define VLINK_HELPSTR_AUTHTYPE_ALL                                             \
1039 	VLINK_HELPSTR_AUTHTYPE_SIMPLE                                          \
1040 	"Use null authentication\n"                                            \
1041 	"Use message-digest authentication\n"
1042 
1043 #define VLINK_HELPSTR_TIME_PARAM                                               \
1044 	"Time between HELLO packets\n"                                         \
1045 	"Seconds\n"                                                            \
1046 	"Time between retransmitting lost link state advertisements\n"         \
1047 	"Seconds\n"                                                            \
1048 	"Link state transmit delay\n"                                          \
1049 	"Seconds\n"                                                            \
1050 	"Interval time after which a neighbor is declared down\n"              \
1051 	"Seconds\n"
1052 
1053 #define VLINK_HELPSTR_AUTH_SIMPLE                                              \
1054 	"Authentication password (key)\n"                                      \
1055 	"The OSPF password (key)\n"
1056 
1057 #define VLINK_HELPSTR_AUTH_MD5                                                 \
1058 	"Message digest authentication password (key)\n"                       \
1059 	"Key ID\n"                                                             \
1060 	"Use MD5 algorithm\n"                                                  \
1061 	"The OSPF password (key)\n"
1062 
1063 DEFUN (ospf_area_vlink,
1064        ospf_area_vlink_cmd,
1065        "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
1066        VLINK_HELPSTR_IPADDR
1067        "Enable authentication on this virtual link\n"
1068        "Use message-digest authentication\n"
1069        "Use null authentication\n"
1070        VLINK_HELPSTR_AUTH_MD5
1071        VLINK_HELPSTR_AUTH_SIMPLE)
1072 {
1073 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1074 	int idx_ipv4_number = 1;
1075 	int idx_ipv4 = 3;
1076 	struct ospf_vl_config_data vl_config;
1077 	char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1];
1078 	char md5_key[OSPF_AUTH_MD5_SIZE + 1];
1079 	int ret;
1080 	int idx = 0;
1081 
1082 	ospf_vl_config_data_init(&vl_config, vty);
1083 
1084 	/* Read off first 2 parameters and check them */
1085 	ret = str2area_id(argv[idx_ipv4_number]->arg, &vl_config.area_id,
1086 			  &vl_config.area_id_fmt);
1087 	if (ret < 0) {
1088 		vty_out(vty, "OSPF area ID is invalid\n");
1089 		return CMD_WARNING_CONFIG_FAILED;
1090 	}
1091 
1092 	ret = inet_aton(argv[idx_ipv4]->arg, &vl_config.vl_peer);
1093 	if (!ret) {
1094 		vty_out(vty, "Please specify valid Router ID as a.b.c.d\n");
1095 		return CMD_WARNING_CONFIG_FAILED;
1096 	}
1097 
1098 	if (argc <= 4) {
1099 		/* Thats all folks! - BUGS B. strikes again!!!*/
1100 
1101 		return ospf_vl_set(ospf, &vl_config);
1102 	}
1103 
1104 	if (argv_find(argv, argc, "authentication", &idx)) {
1105 		/* authentication  - this option can only occur
1106 		at start of command line */
1107 		vl_config.auth_type = OSPF_AUTH_SIMPLE;
1108 	}
1109 
1110 	if (argv_find(argv, argc, "message-digest", &idx)) {
1111 		/* authentication message-digest */
1112 		vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
1113 	} else if (argv_find(argv, argc, "null", &idx)) {
1114 		/* "authentication null" */
1115 		vl_config.auth_type = OSPF_AUTH_NULL;
1116 	}
1117 
1118 	if (argv_find(argv, argc, "message-digest-key", &idx)) {
1119 		vl_config.md5_key = NULL;
1120 		vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10);
1121 		if (vl_config.crypto_key_id < 0)
1122 			return CMD_WARNING_CONFIG_FAILED;
1123 
1124 		strlcpy(md5_key, argv[idx + 3]->arg, sizeof(md5_key));
1125 		vl_config.md5_key = md5_key;
1126 	}
1127 
1128 	if (argv_find(argv, argc, "authentication-key", &idx)) {
1129 		strlcpy(auth_key, argv[idx + 1]->arg, sizeof(auth_key));
1130 		vl_config.auth_key = auth_key;
1131 	}
1132 
1133 	/* Action configuration */
1134 
1135 	return ospf_vl_set(ospf, &vl_config);
1136 }
1137 
1138 DEFUN (no_ospf_area_vlink,
1139        no_ospf_area_vlink_cmd,
1140        "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
1141        NO_STR
1142        VLINK_HELPSTR_IPADDR
1143        "Enable authentication on this virtual link\n"
1144        "Use message-digest authentication\n"
1145        "Use null authentication\n"
1146        VLINK_HELPSTR_AUTH_MD5
1147        VLINK_HELPSTR_AUTH_SIMPLE)
1148 {
1149 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1150 	int idx_ipv4_number = 2;
1151 	int idx_ipv4 = 4;
1152 	struct ospf_area *area;
1153 	struct ospf_vl_config_data vl_config;
1154 	struct ospf_vl_data *vl_data = NULL;
1155 	char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1];
1156 	int idx = 0;
1157 	int ret, format;
1158 
1159 	ospf_vl_config_data_init(&vl_config, vty);
1160 
1161 	ret = str2area_id(argv[idx_ipv4_number]->arg, &vl_config.area_id,
1162 			  &format);
1163 	if (ret < 0) {
1164 		vty_out(vty, "OSPF area ID is invalid\n");
1165 		return CMD_WARNING_CONFIG_FAILED;
1166 	}
1167 
1168 	area = ospf_area_lookup_by_area_id(ospf, vl_config.area_id);
1169 	if (!area) {
1170 		vty_out(vty, "Area does not exist\n");
1171 		return CMD_WARNING_CONFIG_FAILED;
1172 	}
1173 
1174 	ret = inet_aton(argv[idx_ipv4]->arg, &vl_config.vl_peer);
1175 	if (!ret) {
1176 		vty_out(vty, "Please specify valid Router ID as a.b.c.d\n");
1177 		return CMD_WARNING_CONFIG_FAILED;
1178 	}
1179 
1180 	vl_data = ospf_vl_lookup(ospf, area, vl_config.vl_peer);
1181 	if (!vl_data) {
1182 		vty_out(vty, "Virtual link does not exist\n");
1183 		return CMD_WARNING_CONFIG_FAILED;
1184 	}
1185 
1186 	if (argc <= 5) {
1187 		/* Basic VLink no command */
1188 		/* Thats all folks! - BUGS B. strikes again!!!*/
1189 		ospf_vl_delete(ospf, vl_data);
1190 		ospf_area_check_free(ospf, vl_config.area_id);
1191 		return CMD_SUCCESS;
1192 	}
1193 
1194 	/* If we are down here, we are reseting parameters */
1195 	/* Deal with other parameters */
1196 
1197 	if (argv_find(argv, argc, "authentication", &idx)) {
1198 		/* authentication  - this option can only occur
1199 		at start of command line */
1200 		vl_config.auth_type = OSPF_AUTH_NOTSET;
1201 	}
1202 
1203 	if (argv_find(argv, argc, "message-digest-key", &idx)) {
1204 		vl_config.md5_key = NULL;
1205 		vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10);
1206 		if (vl_config.crypto_key_id < 0)
1207 			return CMD_WARNING_CONFIG_FAILED;
1208 	}
1209 
1210 	if (argv_find(argv, argc, "authentication-key", &idx)) {
1211 		/* Reset authentication-key to 0 */
1212 		memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
1213 		vl_config.auth_key = auth_key;
1214 	}
1215 
1216 	/* Action configuration */
1217 
1218 	return ospf_vl_set(ospf, &vl_config);
1219 }
1220 
1221 DEFUN (ospf_area_vlink_intervals,
1222        ospf_area_vlink_intervals_cmd,
1223        "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|transmit-delay (1-65535)|dead-interval (1-65535)}",
1224        VLINK_HELPSTR_IPADDR
1225        VLINK_HELPSTR_TIME_PARAM)
1226 {
1227 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1228 	struct ospf_vl_config_data vl_config;
1229 	int ret = 0;
1230 
1231 	ospf_vl_config_data_init(&vl_config, vty);
1232 
1233 	char *area_id = argv[1]->arg;
1234 	char *router_id = argv[3]->arg;
1235 
1236 	ret = str2area_id(area_id, &vl_config.area_id, &vl_config.area_id_fmt);
1237 	if (ret < 0) {
1238 		vty_out(vty, "OSPF area ID is invalid\n");
1239 		return CMD_WARNING_CONFIG_FAILED;
1240 	}
1241 
1242 	ret = inet_aton(router_id, &vl_config.vl_peer);
1243 	if (!ret) {
1244 		vty_out(vty, "Please specify valid Router ID as a.b.c.d\n");
1245 		return CMD_WARNING_CONFIG_FAILED;
1246 	}
1247 
1248 	for (int idx = 4; idx < argc; idx++) {
1249 		if (strmatch(argv[idx]->text, "hello-interval"))
1250 			vl_config.hello_interval =
1251 				strtol(argv[++idx]->arg, NULL, 10);
1252 		else if (strmatch(argv[idx]->text, "retransmit-interval"))
1253 			vl_config.retransmit_interval =
1254 				strtol(argv[++idx]->arg, NULL, 10);
1255 		else if (strmatch(argv[idx]->text, "transmit-delay"))
1256 			vl_config.transmit_delay =
1257 				strtol(argv[++idx]->arg, NULL, 10);
1258 		else if (strmatch(argv[idx]->text, "dead-interval"))
1259 			vl_config.dead_interval =
1260 				strtol(argv[++idx]->arg, NULL, 10);
1261 	}
1262 
1263 	/* Action configuration */
1264 	return ospf_vl_set(ospf, &vl_config);
1265 }
1266 
1267 DEFUN (no_ospf_area_vlink_intervals,
1268        no_ospf_area_vlink_intervals_cmd,
1269        "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|transmit-delay (1-65535)|dead-interval (1-65535)}",
1270        NO_STR
1271        VLINK_HELPSTR_IPADDR
1272        VLINK_HELPSTR_TIME_PARAM)
1273 {
1274 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1275 	struct ospf_vl_config_data vl_config;
1276 	int ret = 0;
1277 
1278 	ospf_vl_config_data_init(&vl_config, vty);
1279 
1280 	char *area_id = argv[2]->arg;
1281 	char *router_id = argv[4]->arg;
1282 
1283 	ret = str2area_id(area_id, &vl_config.area_id, &vl_config.area_id_fmt);
1284 	if (ret < 0) {
1285 		vty_out(vty, "OSPF area ID is invalid\n");
1286 		return CMD_WARNING_CONFIG_FAILED;
1287 	}
1288 
1289 	ret = inet_aton(router_id, &vl_config.vl_peer);
1290 	if (!ret) {
1291 		vty_out(vty, "Please specify valid Router ID as a.b.c.d\n");
1292 		return CMD_WARNING_CONFIG_FAILED;
1293 	}
1294 
1295 	for (int idx = 5; idx < argc; idx++) {
1296 		if (strmatch(argv[idx]->text, "hello-interval"))
1297 			vl_config.hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
1298 		else if (strmatch(argv[idx]->text, "retransmit-interval"))
1299 			vl_config.retransmit_interval =
1300 				OSPF_RETRANSMIT_INTERVAL_DEFAULT;
1301 		else if (strmatch(argv[idx]->text, "transmit-delay"))
1302 			vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
1303 		else if (strmatch(argv[idx]->text, "dead-interval"))
1304 			vl_config.dead_interval =
1305 				OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
1306 	}
1307 
1308 	/* Action configuration */
1309 	return ospf_vl_set(ospf, &vl_config);
1310 }
1311 
1312 DEFUN (ospf_area_shortcut,
1313        ospf_area_shortcut_cmd,
1314        "area <A.B.C.D|(0-4294967295)> shortcut <default|enable|disable>",
1315        "OSPF area parameters\n"
1316        "OSPF area ID in IP address format\n"
1317        "OSPF area ID as a decimal value\n"
1318        "Configure the area's shortcutting mode\n"
1319        "Set default shortcutting behavior\n"
1320        "Enable shortcutting through the area\n"
1321        "Disable shortcutting through the area\n")
1322 {
1323 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1324 	int idx_ipv4_number = 1;
1325 	int idx_enable_disable = 3;
1326 	struct ospf_area *area;
1327 	struct in_addr area_id;
1328 	int mode;
1329 	int format;
1330 
1331 	VTY_GET_OSPF_AREA_ID_NO_BB("shortcut", area_id, format,
1332 				   argv[idx_ipv4_number]->arg);
1333 
1334 	area = ospf_area_get(ospf, area_id);
1335 	ospf_area_display_format_set(ospf, area, format);
1336 
1337 	if (strncmp(argv[idx_enable_disable]->arg, "de", 2) == 0)
1338 		mode = OSPF_SHORTCUT_DEFAULT;
1339 	else if (strncmp(argv[idx_enable_disable]->arg, "di", 2) == 0)
1340 		mode = OSPF_SHORTCUT_DISABLE;
1341 	else if (strncmp(argv[idx_enable_disable]->arg, "e", 1) == 0)
1342 		mode = OSPF_SHORTCUT_ENABLE;
1343 	else
1344 		return CMD_WARNING_CONFIG_FAILED;
1345 
1346 	ospf_area_shortcut_set(ospf, area, mode);
1347 
1348 	if (ospf->abr_type != OSPF_ABR_SHORTCUT)
1349 		vty_out(vty,
1350 			"Shortcut area setting will take effect only when the router is configured as Shortcut ABR\n");
1351 
1352 	return CMD_SUCCESS;
1353 }
1354 
1355 DEFUN (no_ospf_area_shortcut,
1356        no_ospf_area_shortcut_cmd,
1357        "no area <A.B.C.D|(0-4294967295)> shortcut <enable|disable>",
1358        NO_STR
1359        "OSPF area parameters\n"
1360        "OSPF area ID in IP address format\n"
1361        "OSPF area ID as a decimal value\n"
1362        "Deconfigure the area's shortcutting mode\n"
1363        "Deconfigure enabled shortcutting through the area\n"
1364        "Deconfigure disabled shortcutting through the area\n")
1365 {
1366 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1367 	int idx_ipv4_number = 2;
1368 	struct ospf_area *area;
1369 	struct in_addr area_id;
1370 	int format;
1371 
1372 	VTY_GET_OSPF_AREA_ID_NO_BB("shortcut", area_id, format,
1373 				   argv[idx_ipv4_number]->arg);
1374 
1375 	area = ospf_area_lookup_by_area_id(ospf, area_id);
1376 	if (!area)
1377 		return CMD_SUCCESS;
1378 
1379 	ospf_area_shortcut_unset(ospf, area);
1380 
1381 	return CMD_SUCCESS;
1382 }
1383 
1384 
1385 DEFUN (ospf_area_stub,
1386        ospf_area_stub_cmd,
1387        "area <A.B.C.D|(0-4294967295)> stub",
1388        "OSPF area parameters\n"
1389        "OSPF area ID in IP address format\n"
1390        "OSPF area ID as a decimal value\n"
1391        "Configure OSPF area as stub\n")
1392 {
1393 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1394 	int idx_ipv4_number = 1;
1395 	struct in_addr area_id;
1396 	int ret, format;
1397 
1398 	VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format,
1399 				   argv[idx_ipv4_number]->arg);
1400 
1401 	ret = ospf_area_stub_set(ospf, area_id);
1402 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
1403 				     format);
1404 	if (ret == 0) {
1405 		vty_out(vty,
1406 			"First deconfigure all virtual link through this area\n");
1407 		return CMD_WARNING_CONFIG_FAILED;
1408 	}
1409 
1410 	/* Flush the external LSAs from the specified area */
1411 	ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA);
1412 	ospf_area_no_summary_unset(ospf, area_id);
1413 
1414 	return CMD_SUCCESS;
1415 }
1416 
1417 DEFUN (ospf_area_stub_no_summary,
1418        ospf_area_stub_no_summary_cmd,
1419        "area <A.B.C.D|(0-4294967295)> stub no-summary",
1420        "OSPF stub parameters\n"
1421        "OSPF area ID in IP address format\n"
1422        "OSPF area ID as a decimal value\n"
1423        "Configure OSPF area as stub\n"
1424        "Do not inject inter-area routes into stub\n")
1425 {
1426 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1427 	int idx_ipv4_number = 1;
1428 	struct in_addr area_id;
1429 	int ret, format;
1430 
1431 	VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format,
1432 				   argv[idx_ipv4_number]->arg);
1433 
1434 	ret = ospf_area_stub_set(ospf, area_id);
1435 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
1436 				     format);
1437 	if (ret == 0) {
1438 		vty_out(vty,
1439 			"%% Area cannot be stub as it contains a virtual link\n");
1440 		return CMD_WARNING_CONFIG_FAILED;
1441 	}
1442 
1443 	ospf_area_no_summary_set(ospf, area_id);
1444 
1445 	return CMD_SUCCESS;
1446 }
1447 
1448 DEFUN (no_ospf_area_stub,
1449        no_ospf_area_stub_cmd,
1450        "no area <A.B.C.D|(0-4294967295)> stub",
1451        NO_STR
1452        "OSPF area parameters\n"
1453        "OSPF area ID in IP address format\n"
1454        "OSPF area ID as a decimal value\n"
1455        "Configure OSPF area as stub\n")
1456 {
1457 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1458 	int idx_ipv4_number = 2;
1459 	struct in_addr area_id;
1460 	int format;
1461 
1462 	VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format,
1463 				   argv[idx_ipv4_number]->arg);
1464 
1465 	ospf_area_stub_unset(ospf, area_id);
1466 	ospf_area_no_summary_unset(ospf, area_id);
1467 
1468 	return CMD_SUCCESS;
1469 }
1470 
1471 DEFUN (no_ospf_area_stub_no_summary,
1472        no_ospf_area_stub_no_summary_cmd,
1473        "no area <A.B.C.D|(0-4294967295)> stub no-summary",
1474        NO_STR
1475        "OSPF area parameters\n"
1476        "OSPF area ID in IP address format\n"
1477        "OSPF area ID as a decimal value\n"
1478        "Configure OSPF area as stub\n"
1479        "Do not inject inter-area routes into area\n")
1480 {
1481 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1482 	int idx_ipv4_number = 2;
1483 	struct in_addr area_id;
1484 	int format;
1485 
1486 	VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format,
1487 				   argv[idx_ipv4_number]->arg);
1488 	ospf_area_no_summary_unset(ospf, area_id);
1489 
1490 	return CMD_SUCCESS;
1491 }
1492 
ospf_area_nssa_cmd_handler(struct vty * vty,int argc,struct cmd_token ** argv,int cfg_nosum,int nosum)1493 static int ospf_area_nssa_cmd_handler(struct vty *vty, int argc,
1494 				      struct cmd_token **argv, int cfg_nosum,
1495 				      int nosum)
1496 {
1497 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1498 	struct in_addr area_id;
1499 	int ret, format;
1500 
1501 	VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format, argv[1]->arg);
1502 
1503 	ret = ospf_area_nssa_set(ospf, area_id);
1504 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
1505 				     format);
1506 	if (ret == 0) {
1507 		vty_out(vty,
1508 			"%% Area cannot be nssa as it contains a virtual link\n");
1509 		return CMD_WARNING_CONFIG_FAILED;
1510 	}
1511 
1512 	if (argc > 3) {
1513 		if (strncmp(argv[3]->text, "translate-c", 11) == 0)
1514 			ospf_area_nssa_translator_role_set(
1515 				ospf, area_id, OSPF_NSSA_ROLE_CANDIDATE);
1516 		else if (strncmp(argv[3]->text, "translate-n", 11) == 0)
1517 			ospf_area_nssa_translator_role_set(
1518 				ospf, area_id, OSPF_NSSA_ROLE_NEVER);
1519 		else if (strncmp(argv[3]->text, "translate-a", 11) == 0)
1520 			ospf_area_nssa_translator_role_set(
1521 				ospf, area_id, OSPF_NSSA_ROLE_ALWAYS);
1522 	} else {
1523 		ospf_area_nssa_translator_role_set(ospf, area_id,
1524 						   OSPF_NSSA_ROLE_CANDIDATE);
1525 	}
1526 
1527 	if (cfg_nosum) {
1528 		if (nosum)
1529 			ospf_area_no_summary_set(ospf, area_id);
1530 		else
1531 			ospf_area_no_summary_unset(ospf, area_id);
1532 	}
1533 
1534 	/* Flush the external LSA for the specified area */
1535 	ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA);
1536 	ospf_schedule_abr_task(ospf);
1537 
1538 	return CMD_SUCCESS;
1539 }
1540 
1541 
1542 DEFUN (ospf_area_nssa_translate,
1543        ospf_area_nssa_translate_cmd,
1544        "area <A.B.C.D|(0-4294967295)> nssa <translate-candidate|translate-never|translate-always>",
1545        "OSPF area parameters\n"
1546        "OSPF area ID in IP address format\n"
1547        "OSPF area ID as a decimal value\n"
1548        "Configure OSPF area as nssa\n"
1549        "Configure NSSA-ABR for translate election (default)\n"
1550        "Configure NSSA-ABR to never translate\n"
1551        "Configure NSSA-ABR to always translate\n")
1552 {
1553 	return ospf_area_nssa_cmd_handler(vty, argc, argv, 0, 0);
1554 }
1555 
1556 DEFUN (ospf_area_nssa,
1557        ospf_area_nssa_cmd,
1558        "area <A.B.C.D|(0-4294967295)> nssa",
1559        "OSPF area parameters\n"
1560        "OSPF area ID in IP address format\n"
1561        "OSPF area ID as a decimal value\n"
1562        "Configure OSPF area as nssa\n")
1563 {
1564 	return ospf_area_nssa_cmd_handler(vty, argc, argv, 0, 0);
1565 }
1566 
1567 DEFUN (ospf_area_nssa_no_summary,
1568        ospf_area_nssa_no_summary_cmd,
1569        "area <A.B.C.D|(0-4294967295)> nssa no-summary",
1570        "OSPF area parameters\n"
1571        "OSPF area ID in IP address format\n"
1572        "OSPF area ID as a decimal value\n"
1573        "Configure OSPF area as nssa\n"
1574        "Do not inject inter-area routes into nssa\n")
1575 {
1576 	int idx_ipv4_number = 1;
1577 	struct in_addr area_id;
1578 	int format;
1579 
1580 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1581 	VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format,
1582 				   argv[idx_ipv4_number]->arg);
1583 
1584 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
1585 				     format);
1586 	ospf_area_nssa_no_summary_set(ospf, area_id);
1587 
1588 	ospf_schedule_abr_task(ospf);
1589 
1590 	return CMD_SUCCESS;
1591 }
1592 
1593 DEFUN (no_ospf_area_nssa_no_summary,
1594        no_ospf_area_nssa_no_summary_cmd,
1595        "no area <A.B.C.D|(0-4294967295)> nssa no-summary",
1596        NO_STR
1597        "OSPF area parameters\n"
1598        "OSPF area ID in IP address format\n"
1599        "OSPF area ID as a decimal value\n"
1600        "Configure OSPF area as nssa\n"
1601        "Do not inject inter-area routes into nssa\n")
1602 {
1603 	int idx_ipv4_number = 2;
1604 	struct in_addr area_id;
1605 	int format;
1606 
1607 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1608 
1609 	VTY_GET_OSPF_AREA_ID_NO_BB("nssa", area_id, format,
1610 				   argv[idx_ipv4_number]->arg);
1611 
1612 	ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
1613 				     format);
1614 	ospf_area_no_summary_unset(ospf, area_id);
1615 
1616 	ospf_schedule_abr_task(ospf);
1617 
1618 	return CMD_SUCCESS;
1619 }
1620 
1621 DEFUN (no_ospf_area_nssa,
1622        no_ospf_area_nssa_cmd,
1623        "no area <A.B.C.D|(0-4294967295)> nssa [<translate-candidate|translate-never|translate-always>]",
1624        NO_STR
1625        "OSPF area parameters\n"
1626        "OSPF area ID in IP address format\n"
1627        "OSPF area ID as a decimal value\n"
1628        "Configure OSPF area as nssa\n"
1629        "Configure NSSA-ABR for translate election (default)\n"
1630        "Configure NSSA-ABR to never translate\n"
1631        "Configure NSSA-ABR to always translate\n")
1632 {
1633 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1634 	int idx_ipv4_number = 2;
1635 	struct in_addr area_id;
1636 	int format;
1637 
1638 	VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format,
1639 				   argv[idx_ipv4_number]->arg);
1640 
1641 	/* Flush the NSSA LSA for the specified area */
1642 	ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_NSSA_LSA);
1643 	ospf_area_nssa_unset(ospf, area_id, argc);
1644 
1645 	ospf_schedule_abr_task(ospf);
1646 
1647 	return CMD_SUCCESS;
1648 }
1649 
1650 
1651 DEFUN (ospf_area_default_cost,
1652        ospf_area_default_cost_cmd,
1653        "area <A.B.C.D|(0-4294967295)> default-cost (0-16777215)",
1654        "OSPF area parameters\n"
1655        "OSPF area ID in IP address format\n"
1656        "OSPF area ID as a decimal value\n"
1657        "Set the summary-default cost of a NSSA or stub area\n"
1658        "Stub's advertised default summary cost\n")
1659 {
1660 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1661 	int idx_ipv4_number = 1;
1662 	int idx_number = 3;
1663 	struct ospf_area *area;
1664 	struct in_addr area_id;
1665 	uint32_t cost;
1666 	int format;
1667 	struct prefix_ipv4 p;
1668 
1669 	VTY_GET_OSPF_AREA_ID_NO_BB("default-cost", area_id, format,
1670 				   argv[idx_ipv4_number]->arg);
1671 	cost = strtoul(argv[idx_number]->arg, NULL, 10);
1672 
1673 	area = ospf_area_get(ospf, area_id);
1674 	ospf_area_display_format_set(ospf, area, format);
1675 
1676 	if (area->external_routing == OSPF_AREA_DEFAULT) {
1677 		vty_out(vty, "The area is neither stub, nor NSSA\n");
1678 		return CMD_WARNING_CONFIG_FAILED;
1679 	}
1680 
1681 	area->default_cost = cost;
1682 
1683 	p.family = AF_INET;
1684 	p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
1685 	p.prefixlen = 0;
1686 	if (IS_DEBUG_OSPF_EVENT)
1687 		zlog_debug(
1688 			"ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %s",
1689 			inet_ntoa(area->area_id));
1690 	ospf_abr_announce_network_to_area(&p, area->default_cost, area);
1691 
1692 	return CMD_SUCCESS;
1693 }
1694 
1695 DEFUN (no_ospf_area_default_cost,
1696        no_ospf_area_default_cost_cmd,
1697        "no area <A.B.C.D|(0-4294967295)> default-cost (0-16777215)",
1698        NO_STR
1699        "OSPF area parameters\n"
1700        "OSPF area ID in IP address format\n"
1701        "OSPF area ID as a decimal value\n"
1702        "Set the summary-default cost of a NSSA or stub area\n"
1703        "Stub's advertised default summary cost\n")
1704 {
1705 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1706 	int idx_ipv4_number = 2;
1707 	struct ospf_area *area;
1708 	struct in_addr area_id;
1709 	int format;
1710 	struct prefix_ipv4 p;
1711 
1712 	VTY_GET_OSPF_AREA_ID_NO_BB("default-cost", area_id, format,
1713 				   argv[idx_ipv4_number]->arg);
1714 
1715 	area = ospf_area_lookup_by_area_id(ospf, area_id);
1716 	if (area == NULL)
1717 		return CMD_SUCCESS;
1718 
1719 	if (area->external_routing == OSPF_AREA_DEFAULT) {
1720 		vty_out(vty, "The area is neither stub, nor NSSA\n");
1721 		return CMD_WARNING_CONFIG_FAILED;
1722 	}
1723 
1724 	area->default_cost = 1;
1725 
1726 	p.family = AF_INET;
1727 	p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
1728 	p.prefixlen = 0;
1729 	if (IS_DEBUG_OSPF_EVENT)
1730 		zlog_debug(
1731 			"ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %s",
1732 			inet_ntoa(area->area_id));
1733 	ospf_abr_announce_network_to_area(&p, area->default_cost, area);
1734 
1735 
1736 	ospf_area_check_free(ospf, area_id);
1737 
1738 	return CMD_SUCCESS;
1739 }
1740 
1741 DEFUN (ospf_area_export_list,
1742        ospf_area_export_list_cmd,
1743        "area <A.B.C.D|(0-4294967295)> export-list NAME",
1744        "OSPF area parameters\n"
1745        "OSPF area ID in IP address format\n"
1746        "OSPF area ID as a decimal value\n"
1747        "Set the filter for networks announced to other areas\n"
1748        "Name of the access-list\n")
1749 {
1750 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1751 	int idx_ipv4_number = 1;
1752 	struct ospf_area *area;
1753 	struct in_addr area_id;
1754 	int format;
1755 
1756 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
1757 
1758 	area = ospf_area_get(ospf, area_id);
1759 	ospf_area_display_format_set(ospf, area, format);
1760 	ospf_area_export_list_set(ospf, area, argv[3]->arg);
1761 
1762 	return CMD_SUCCESS;
1763 }
1764 
1765 DEFUN (no_ospf_area_export_list,
1766        no_ospf_area_export_list_cmd,
1767        "no area <A.B.C.D|(0-4294967295)> export-list NAME",
1768        NO_STR
1769        "OSPF area parameters\n"
1770        "OSPF area ID in IP address format\n"
1771        "OSPF area ID as a decimal value\n"
1772        "Unset the filter for networks announced to other areas\n"
1773        "Name of the access-list\n")
1774 {
1775 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1776 	int idx_ipv4_number = 2;
1777 	struct ospf_area *area;
1778 	struct in_addr area_id;
1779 	int format;
1780 
1781 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
1782 
1783 	area = ospf_area_lookup_by_area_id(ospf, area_id);
1784 	if (area == NULL)
1785 		return CMD_SUCCESS;
1786 
1787 	ospf_area_export_list_unset(ospf, area);
1788 
1789 	return CMD_SUCCESS;
1790 }
1791 
1792 
1793 DEFUN (ospf_area_import_list,
1794        ospf_area_import_list_cmd,
1795        "area <A.B.C.D|(0-4294967295)> import-list NAME",
1796        "OSPF area parameters\n"
1797        "OSPF area ID in IP address format\n"
1798        "OSPF area ID as a decimal value\n"
1799        "Set the filter for networks from other areas announced to the specified one\n"
1800        "Name of the access-list\n")
1801 {
1802 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1803 	int idx_ipv4_number = 1;
1804 	struct ospf_area *area;
1805 	struct in_addr area_id;
1806 	int format;
1807 
1808 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
1809 
1810 	area = ospf_area_get(ospf, area_id);
1811 	ospf_area_display_format_set(ospf, area, format);
1812 	ospf_area_import_list_set(ospf, area, argv[3]->arg);
1813 
1814 	return CMD_SUCCESS;
1815 }
1816 
1817 DEFUN (no_ospf_area_import_list,
1818        no_ospf_area_import_list_cmd,
1819        "no area <A.B.C.D|(0-4294967295)> import-list NAME",
1820        NO_STR
1821        "OSPF area parameters\n"
1822        "OSPF area ID in IP address format\n"
1823        "OSPF area ID as a decimal value\n"
1824        "Unset the filter for networks announced to other areas\n"
1825        "Name of the access-list\n")
1826 {
1827 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1828 	int idx_ipv4_number = 2;
1829 	struct ospf_area *area;
1830 	struct in_addr area_id;
1831 	int format;
1832 
1833 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
1834 
1835 	area = ospf_area_lookup_by_area_id(ospf, area_id);
1836 	if (area == NULL)
1837 		return CMD_SUCCESS;
1838 
1839 	ospf_area_import_list_unset(ospf, area);
1840 
1841 	return CMD_SUCCESS;
1842 }
1843 
1844 DEFUN (ospf_area_filter_list,
1845        ospf_area_filter_list_cmd,
1846        "area <A.B.C.D|(0-4294967295)> filter-list prefix WORD <in|out>",
1847        "OSPF area parameters\n"
1848        "OSPF area ID in IP address format\n"
1849        "OSPF area ID as a decimal value\n"
1850        "Filter networks between OSPF areas\n"
1851        "Filter prefixes between OSPF areas\n"
1852        "Name of an IP prefix-list\n"
1853        "Filter networks sent to this area\n"
1854        "Filter networks sent from this area\n")
1855 {
1856 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1857 	int idx_ipv4_number = 1;
1858 	int idx_word = 4;
1859 	int idx_in_out = 5;
1860 	struct ospf_area *area;
1861 	struct in_addr area_id;
1862 	struct prefix_list *plist;
1863 	int format;
1864 
1865 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
1866 
1867 	area = ospf_area_get(ospf, area_id);
1868 	ospf_area_display_format_set(ospf, area, format);
1869 	plist = prefix_list_lookup(AFI_IP, argv[idx_word]->arg);
1870 	if (strncmp(argv[idx_in_out]->arg, "in", 2) == 0) {
1871 		PREFIX_LIST_IN(area) = plist;
1872 		if (PREFIX_NAME_IN(area))
1873 			free(PREFIX_NAME_IN(area));
1874 
1875 		PREFIX_NAME_IN(area) = strdup(argv[idx_word]->arg);
1876 		ospf_schedule_abr_task(ospf);
1877 	} else {
1878 		PREFIX_LIST_OUT(area) = plist;
1879 		if (PREFIX_NAME_OUT(area))
1880 			free(PREFIX_NAME_OUT(area));
1881 
1882 		PREFIX_NAME_OUT(area) = strdup(argv[idx_word]->arg);
1883 		ospf_schedule_abr_task(ospf);
1884 	}
1885 
1886 	return CMD_SUCCESS;
1887 }
1888 
1889 DEFUN (no_ospf_area_filter_list,
1890        no_ospf_area_filter_list_cmd,
1891        "no area <A.B.C.D|(0-4294967295)> filter-list prefix WORD <in|out>",
1892        NO_STR
1893        "OSPF area parameters\n"
1894        "OSPF area ID in IP address format\n"
1895        "OSPF area ID as a decimal value\n"
1896        "Filter networks between OSPF areas\n"
1897        "Filter prefixes between OSPF areas\n"
1898        "Name of an IP prefix-list\n"
1899        "Filter networks sent to this area\n"
1900        "Filter networks sent from this area\n")
1901 {
1902 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1903 	int idx_ipv4_number = 2;
1904 	int idx_word = 5;
1905 	int idx_in_out = 6;
1906 	struct ospf_area *area;
1907 	struct in_addr area_id;
1908 	int format;
1909 
1910 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
1911 
1912 	if ((area = ospf_area_lookup_by_area_id(ospf, area_id)) == NULL)
1913 		return CMD_SUCCESS;
1914 
1915 	if (strncmp(argv[idx_in_out]->arg, "in", 2) == 0) {
1916 		if (PREFIX_NAME_IN(area))
1917 			if (strcmp(PREFIX_NAME_IN(area), argv[idx_word]->arg)
1918 			    != 0)
1919 				return CMD_SUCCESS;
1920 
1921 		PREFIX_LIST_IN(area) = NULL;
1922 		if (PREFIX_NAME_IN(area))
1923 			free(PREFIX_NAME_IN(area));
1924 
1925 		PREFIX_NAME_IN(area) = NULL;
1926 
1927 		ospf_schedule_abr_task(ospf);
1928 	} else {
1929 		if (PREFIX_NAME_OUT(area))
1930 			if (strcmp(PREFIX_NAME_OUT(area), argv[idx_word]->arg)
1931 			    != 0)
1932 				return CMD_SUCCESS;
1933 
1934 		PREFIX_LIST_OUT(area) = NULL;
1935 		if (PREFIX_NAME_OUT(area))
1936 			free(PREFIX_NAME_OUT(area));
1937 
1938 		PREFIX_NAME_OUT(area) = NULL;
1939 
1940 		ospf_schedule_abr_task(ospf);
1941 	}
1942 
1943 	return CMD_SUCCESS;
1944 }
1945 
1946 
1947 DEFUN (ospf_area_authentication_message_digest,
1948        ospf_area_authentication_message_digest_cmd,
1949        "[no] area <A.B.C.D|(0-4294967295)> authentication message-digest",
1950        NO_STR
1951        "OSPF area parameters\n"
1952        "OSPF area ID in IP address format\n"
1953        "OSPF area ID as a decimal value\n"
1954        "Enable authentication\n"
1955        "Use message-digest authentication\n")
1956 {
1957 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1958 	int idx = 0;
1959 	struct ospf_area *area;
1960 	struct in_addr area_id;
1961 	int format;
1962 
1963 	argv_find(argv, argc, "area", &idx);
1964 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx + 1]->arg);
1965 
1966 	area = ospf_area_get(ospf, area_id);
1967 	ospf_area_display_format_set(ospf, area, format);
1968 	area->auth_type = strmatch(argv[0]->text, "no")
1969 				  ? OSPF_AUTH_NULL
1970 				  : OSPF_AUTH_CRYPTOGRAPHIC;
1971 
1972 	return CMD_SUCCESS;
1973 }
1974 
1975 DEFUN (ospf_area_authentication,
1976        ospf_area_authentication_cmd,
1977        "area <A.B.C.D|(0-4294967295)> authentication",
1978        "OSPF area parameters\n"
1979        "OSPF area ID in IP address format\n"
1980        "OSPF area ID as a decimal value\n"
1981        "Enable authentication\n")
1982 {
1983 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
1984 	int idx_ipv4_number = 1;
1985 	struct ospf_area *area;
1986 	struct in_addr area_id;
1987 	int format;
1988 
1989 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
1990 
1991 	area = ospf_area_get(ospf, area_id);
1992 	ospf_area_display_format_set(ospf, area, format);
1993 	area->auth_type = OSPF_AUTH_SIMPLE;
1994 
1995 	return CMD_SUCCESS;
1996 }
1997 
1998 DEFUN (no_ospf_area_authentication,
1999        no_ospf_area_authentication_cmd,
2000        "no area <A.B.C.D|(0-4294967295)> authentication",
2001        NO_STR
2002        "OSPF area parameters\n"
2003        "OSPF area ID in IP address format\n"
2004        "OSPF area ID as a decimal value\n"
2005        "Enable authentication\n")
2006 {
2007 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2008 	int idx_ipv4_number = 2;
2009 	struct ospf_area *area;
2010 	struct in_addr area_id;
2011 	int format;
2012 
2013 	VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
2014 
2015 	area = ospf_area_lookup_by_area_id(ospf, area_id);
2016 	if (area == NULL)
2017 		return CMD_SUCCESS;
2018 
2019 	area->auth_type = OSPF_AUTH_NULL;
2020 
2021 	ospf_area_check_free(ospf, area_id);
2022 
2023 	return CMD_SUCCESS;
2024 }
2025 
2026 
2027 DEFUN (ospf_abr_type,
2028        ospf_abr_type_cmd,
2029        "ospf abr-type <cisco|ibm|shortcut|standard>",
2030        "OSPF specific commands\n"
2031        "Set OSPF ABR type\n"
2032        "Alternative ABR, cisco implementation\n"
2033        "Alternative ABR, IBM implementation\n"
2034        "Shortcut ABR\n"
2035        "Standard behavior (RFC2328)\n")
2036 {
2037 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2038 	int idx_vendor = 2;
2039 	uint8_t abr_type = OSPF_ABR_UNKNOWN;
2040 
2041 	if (strncmp(argv[idx_vendor]->arg, "c", 1) == 0)
2042 		abr_type = OSPF_ABR_CISCO;
2043 	else if (strncmp(argv[idx_vendor]->arg, "i", 1) == 0)
2044 		abr_type = OSPF_ABR_IBM;
2045 	else if (strncmp(argv[idx_vendor]->arg, "sh", 2) == 0)
2046 		abr_type = OSPF_ABR_SHORTCUT;
2047 	else if (strncmp(argv[idx_vendor]->arg, "st", 2) == 0)
2048 		abr_type = OSPF_ABR_STAND;
2049 	else
2050 		return CMD_WARNING_CONFIG_FAILED;
2051 
2052 	/* If ABR type value is changed, schedule ABR task. */
2053 	if (ospf->abr_type != abr_type) {
2054 		ospf->abr_type = abr_type;
2055 		ospf_schedule_abr_task(ospf);
2056 	}
2057 
2058 	return CMD_SUCCESS;
2059 }
2060 
2061 DEFUN (no_ospf_abr_type,
2062        no_ospf_abr_type_cmd,
2063        "no ospf abr-type <cisco|ibm|shortcut|standard>",
2064        NO_STR
2065        "OSPF specific commands\n"
2066        "Set OSPF ABR type\n"
2067        "Alternative ABR, cisco implementation\n"
2068        "Alternative ABR, IBM implementation\n"
2069        "Shortcut ABR\n"
2070        "Standard ABR\n")
2071 {
2072 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2073 	int idx_vendor = 3;
2074 	uint8_t abr_type = OSPF_ABR_UNKNOWN;
2075 
2076 	if (strncmp(argv[idx_vendor]->arg, "c", 1) == 0)
2077 		abr_type = OSPF_ABR_CISCO;
2078 	else if (strncmp(argv[idx_vendor]->arg, "i", 1) == 0)
2079 		abr_type = OSPF_ABR_IBM;
2080 	else if (strncmp(argv[idx_vendor]->arg, "sh", 2) == 0)
2081 		abr_type = OSPF_ABR_SHORTCUT;
2082 	else if (strncmp(argv[idx_vendor]->arg, "st", 2) == 0)
2083 		abr_type = OSPF_ABR_STAND;
2084 	else
2085 		return CMD_WARNING_CONFIG_FAILED;
2086 
2087 	/* If ABR type value is changed, schedule ABR task. */
2088 	if (ospf->abr_type == abr_type) {
2089 		ospf->abr_type = OSPF_ABR_DEFAULT;
2090 		ospf_schedule_abr_task(ospf);
2091 	}
2092 
2093 	return CMD_SUCCESS;
2094 }
2095 
2096 DEFUN (ospf_log_adjacency_changes,
2097        ospf_log_adjacency_changes_cmd,
2098        "log-adjacency-changes",
2099        "Log changes in adjacency state\n")
2100 {
2101 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2102 
2103 	SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
2104 	UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
2105 	return CMD_SUCCESS;
2106 }
2107 
2108 DEFUN (ospf_log_adjacency_changes_detail,
2109        ospf_log_adjacency_changes_detail_cmd,
2110        "log-adjacency-changes detail",
2111        "Log changes in adjacency state\n"
2112        "Log all state changes\n")
2113 {
2114 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2115 
2116 	SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
2117 	SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
2118 	return CMD_SUCCESS;
2119 }
2120 
2121 DEFUN (no_ospf_log_adjacency_changes,
2122        no_ospf_log_adjacency_changes_cmd,
2123        "no log-adjacency-changes",
2124        NO_STR
2125        "Log changes in adjacency state\n")
2126 {
2127 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2128 
2129 	UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
2130 	UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
2131 	return CMD_SUCCESS;
2132 }
2133 
2134 DEFUN (no_ospf_log_adjacency_changes_detail,
2135        no_ospf_log_adjacency_changes_detail_cmd,
2136        "no log-adjacency-changes detail",
2137        NO_STR
2138        "Log changes in adjacency state\n"
2139        "Log all state changes\n")
2140 {
2141 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2142 
2143 	UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
2144 	return CMD_SUCCESS;
2145 }
2146 
2147 DEFUN (ospf_compatible_rfc1583,
2148        ospf_compatible_rfc1583_cmd,
2149        "compatible rfc1583",
2150        "OSPF compatibility list\n"
2151        "compatible with RFC 1583\n")
2152 {
2153 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2154 
2155 	if (!CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) {
2156 		SET_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE);
2157 		ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE);
2158 	}
2159 	return CMD_SUCCESS;
2160 }
2161 
2162 DEFUN (no_ospf_compatible_rfc1583,
2163        no_ospf_compatible_rfc1583_cmd,
2164        "no compatible rfc1583",
2165        NO_STR
2166        "OSPF compatibility list\n"
2167        "compatible with RFC 1583\n")
2168 {
2169 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2170 
2171 	if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) {
2172 		UNSET_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE);
2173 		ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE);
2174 	}
2175 	return CMD_SUCCESS;
2176 }
2177 
2178 ALIAS(ospf_compatible_rfc1583, ospf_rfc1583_flag_cmd,
2179       "ospf rfc1583compatibility",
2180       "OSPF specific commands\n"
2181       "Enable the RFC1583Compatibility flag\n")
2182 
2183 ALIAS(no_ospf_compatible_rfc1583, no_ospf_rfc1583_flag_cmd,
2184       "no ospf rfc1583compatibility", NO_STR
2185       "OSPF specific commands\n"
2186       "Disable the RFC1583Compatibility flag\n")
2187 
ospf_timers_spf_set(struct vty * vty,unsigned int delay,unsigned int hold,unsigned int max)2188 static int ospf_timers_spf_set(struct vty *vty, unsigned int delay,
2189 			       unsigned int hold, unsigned int max)
2190 {
2191 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2192 
2193 	ospf->spf_delay = delay;
2194 	ospf->spf_holdtime = hold;
2195 	ospf->spf_max_holdtime = max;
2196 
2197 	return CMD_SUCCESS;
2198 }
2199 
2200 DEFUN (ospf_timers_min_ls_interval,
2201        ospf_timers_min_ls_interval_cmd,
2202        "timers throttle lsa all (0-5000)",
2203        "Adjust routing timers\n"
2204        "Throttling adaptive timer\n"
2205        "LSA delay between transmissions\n"
2206        "All LSA types\n"
2207        "Delay (msec) between sending LSAs\n")
2208 {
2209 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2210 	int idx_number = 4;
2211 	unsigned int interval;
2212 
2213 	if (argc < 5) {
2214 		vty_out(vty, "Insufficient arguments\n");
2215 		return CMD_WARNING_CONFIG_FAILED;
2216 	}
2217 
2218 	interval = strtoul(argv[idx_number]->arg, NULL, 10);
2219 
2220 	ospf->min_ls_interval = interval;
2221 
2222 	return CMD_SUCCESS;
2223 }
2224 
2225 DEFUN (no_ospf_timers_min_ls_interval,
2226        no_ospf_timers_min_ls_interval_cmd,
2227        "no timers throttle lsa all [(0-5000)]",
2228        NO_STR
2229        "Adjust routing timers\n"
2230        "Throttling adaptive timer\n"
2231        "LSA delay between transmissions\n"
2232        "All LSA types\n"
2233        "Delay (msec) between sending LSAs\n")
2234 {
2235 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2236 	ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL;
2237 
2238 	return CMD_SUCCESS;
2239 }
2240 
2241 DEFUN (ospf_timers_throttle_spf,
2242        ospf_timers_throttle_spf_cmd,
2243        "timers throttle spf (0-600000) (0-600000) (0-600000)",
2244        "Adjust routing timers\n"
2245        "Throttling adaptive timer\n"
2246        "OSPF SPF timers\n"
2247        "Delay (msec) from first change received till SPF calculation\n"
2248        "Initial hold time (msec) between consecutive SPF calculations\n"
2249        "Maximum hold time (msec)\n")
2250 {
2251 	int idx_number = 3;
2252 	int idx_number_2 = 4;
2253 	int idx_number_3 = 5;
2254 	unsigned int delay, hold, max;
2255 
2256 	if (argc < 6) {
2257 		vty_out(vty, "Insufficient arguments\n");
2258 		return CMD_WARNING_CONFIG_FAILED;
2259 	}
2260 
2261 	delay = strtoul(argv[idx_number]->arg, NULL, 10);
2262 	hold = strtoul(argv[idx_number_2]->arg, NULL, 10);
2263 	max = strtoul(argv[idx_number_3]->arg, NULL, 10);
2264 
2265 	return ospf_timers_spf_set(vty, delay, hold, max);
2266 }
2267 
2268 DEFUN (no_ospf_timers_throttle_spf,
2269        no_ospf_timers_throttle_spf_cmd,
2270        "no timers throttle spf [(0-600000)(0-600000)(0-600000)]",
2271        NO_STR
2272        "Adjust routing timers\n"
2273        "Throttling adaptive timer\n"
2274        "OSPF SPF timers\n"
2275        "Delay (msec) from first change received till SPF calculation\n"
2276        "Initial hold time (msec) between consecutive SPF calculations\n"
2277        "Maximum hold time (msec)\n")
2278 {
2279 	return ospf_timers_spf_set(vty, OSPF_SPF_DELAY_DEFAULT,
2280 				   OSPF_SPF_HOLDTIME_DEFAULT,
2281 				   OSPF_SPF_MAX_HOLDTIME_DEFAULT);
2282 }
2283 
2284 
2285 DEFUN (ospf_timers_lsa_min_arrival,
2286        ospf_timers_lsa_min_arrival_cmd,
2287        "timers lsa min-arrival (0-600000)",
2288        "Adjust routing timers\n"
2289        "OSPF LSA timers\n"
2290        "Minimum delay in receiving new version of a LSA\n"
2291        "Delay in milliseconds\n")
2292 {
2293 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2294 	ospf->min_ls_arrival = strtoul(argv[argc - 1]->arg, NULL, 10);
2295 	return CMD_SUCCESS;
2296 }
2297 
2298 DEFUN (no_ospf_timers_lsa_min_arrival,
2299        no_ospf_timers_lsa_min_arrival_cmd,
2300        "no timers lsa min-arrival [(0-600000)]",
2301        NO_STR
2302        "Adjust routing timers\n"
2303        "OSPF LSA timers\n"
2304        "Minimum delay in receiving new version of a LSA\n"
2305        "Delay in milliseconds\n")
2306 {
2307 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2308 	unsigned int minarrival;
2309 
2310 	if (argc > 4) {
2311 		minarrival = strtoul(argv[argc - 1]->arg, NULL, 10);
2312 
2313 		if (ospf->min_ls_arrival != minarrival
2314 		    || minarrival == OSPF_MIN_LS_ARRIVAL)
2315 			return CMD_SUCCESS;
2316 	}
2317 
2318 	ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
2319 
2320 	return CMD_SUCCESS;
2321 }
2322 
2323 DEFUN (ospf_neighbor,
2324        ospf_neighbor_cmd,
2325        "neighbor A.B.C.D [priority (0-255) [poll-interval (1-65535)]]",
2326        NEIGHBOR_STR
2327        "Neighbor IP address\n"
2328        "Neighbor Priority\n"
2329        "Priority\n"
2330        "Dead Neighbor Polling interval\n"
2331        "Seconds\n")
2332 {
2333 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2334 	int idx_ipv4 = 1;
2335 	int idx_pri = 3;
2336 	int idx_poll = 5;
2337 	struct in_addr nbr_addr;
2338 	unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
2339 	unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT;
2340 
2341 	if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) {
2342 		vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
2343 		return CMD_WARNING_CONFIG_FAILED;
2344 	}
2345 
2346 	if (argc > 2)
2347 		priority = strtoul(argv[idx_pri]->arg, NULL, 10);
2348 
2349 	if (argc > 4)
2350 		interval = strtoul(argv[idx_poll]->arg, NULL, 10);
2351 
2352 	ospf_nbr_nbma_set(ospf, nbr_addr);
2353 
2354 	if (argc > 2)
2355 		ospf_nbr_nbma_priority_set(ospf, nbr_addr, priority);
2356 
2357 	if (argc > 4)
2358 		ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval);
2359 
2360 	return CMD_SUCCESS;
2361 }
2362 
2363 DEFUN (ospf_neighbor_poll_interval,
2364        ospf_neighbor_poll_interval_cmd,
2365        "neighbor A.B.C.D poll-interval (1-65535) [priority (0-255)]",
2366        NEIGHBOR_STR
2367        "Neighbor IP address\n"
2368        "Dead Neighbor Polling interval\n"
2369        "Seconds\n"
2370        "OSPF priority of non-broadcast neighbor\n"
2371        "Priority\n")
2372 {
2373 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2374 	int idx_ipv4 = 1;
2375 	int idx_poll = 3;
2376 	int idx_pri = 5;
2377 	struct in_addr nbr_addr;
2378 	unsigned int priority;
2379 	unsigned int interval;
2380 
2381 	if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) {
2382 		vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
2383 		return CMD_WARNING_CONFIG_FAILED;
2384 	}
2385 
2386 	interval = strtoul(argv[idx_poll]->arg, NULL, 10);
2387 
2388 	priority = argc > 4 ? strtoul(argv[idx_pri]->arg, NULL, 10)
2389 			    : OSPF_NEIGHBOR_PRIORITY_DEFAULT;
2390 
2391 	ospf_nbr_nbma_set(ospf, nbr_addr);
2392 	ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval);
2393 
2394 	if (argc > 4)
2395 		ospf_nbr_nbma_priority_set(ospf, nbr_addr, priority);
2396 
2397 	return CMD_SUCCESS;
2398 }
2399 
2400 DEFUN (no_ospf_neighbor,
2401        no_ospf_neighbor_cmd,
2402        "no neighbor A.B.C.D [priority (0-255) [poll-interval (1-65525)]]",
2403        NO_STR
2404        NEIGHBOR_STR
2405        "Neighbor IP address\n"
2406        "Neighbor Priority\n"
2407        "Priority\n"
2408        "Dead Neighbor Polling interval\n"
2409        "Seconds\n")
2410 {
2411 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2412 	int idx_ipv4 = 2;
2413 	struct in_addr nbr_addr;
2414 
2415 	if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) {
2416 		vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
2417 		return CMD_WARNING_CONFIG_FAILED;
2418 	}
2419 
2420 	(void)ospf_nbr_nbma_unset(ospf, nbr_addr);
2421 
2422 	return CMD_SUCCESS;
2423 }
2424 
2425 DEFUN (no_ospf_neighbor_poll,
2426        no_ospf_neighbor_poll_cmd,
2427        "no neighbor A.B.C.D poll-interval (1-65535) [priority (0-255)]",
2428        NO_STR
2429        NEIGHBOR_STR
2430        "Neighbor IP address\n"
2431        "Dead Neighbor Polling interval\n"
2432        "Seconds\n"
2433        "Neighbor Priority\n"
2434        "Priority\n")
2435 {
2436 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2437 	int idx_ipv4 = 2;
2438 	struct in_addr nbr_addr;
2439 
2440 	if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) {
2441 		vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
2442 		return CMD_WARNING_CONFIG_FAILED;
2443 	}
2444 
2445 	(void)ospf_nbr_nbma_unset(ospf, nbr_addr);
2446 
2447 	return CMD_SUCCESS;
2448 }
2449 
2450 DEFUN (ospf_refresh_timer,
2451        ospf_refresh_timer_cmd,
2452        "refresh timer (10-1800)",
2453        "Adjust refresh parameters\n"
2454        "Set refresh timer\n"
2455        "Timer value in seconds\n")
2456 {
2457 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2458 	int idx_number = 2;
2459 	unsigned int interval;
2460 
2461 	interval = strtoul(argv[idx_number]->arg, NULL, 10);
2462 	interval = (interval / OSPF_LSA_REFRESHER_GRANULARITY)
2463 		   * OSPF_LSA_REFRESHER_GRANULARITY;
2464 
2465 	ospf_timers_refresh_set(ospf, interval);
2466 
2467 	return CMD_SUCCESS;
2468 }
2469 
2470 DEFUN (no_ospf_refresh_timer,
2471        no_ospf_refresh_timer_val_cmd,
2472        "no refresh timer [(10-1800)]",
2473        NO_STR
2474        "Adjust refresh parameters\n"
2475        "Unset refresh timer\n"
2476        "Timer value in seconds\n")
2477 {
2478 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2479 	int idx_number = 3;
2480 	unsigned int interval;
2481 
2482 	if (argc == 1) {
2483 		interval = strtoul(argv[idx_number]->arg, NULL, 10);
2484 
2485 		if (ospf->lsa_refresh_interval != interval
2486 		    || interval == OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
2487 			return CMD_SUCCESS;
2488 	}
2489 
2490 	ospf_timers_refresh_unset(ospf);
2491 
2492 	return CMD_SUCCESS;
2493 }
2494 
2495 
2496 DEFUN (ospf_auto_cost_reference_bandwidth,
2497        ospf_auto_cost_reference_bandwidth_cmd,
2498        "auto-cost reference-bandwidth (1-4294967)",
2499        "Calculate OSPF interface cost according to bandwidth\n"
2500        "Use reference bandwidth method to assign OSPF cost\n"
2501        "The reference bandwidth in terms of Mbits per second\n")
2502 {
2503 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2504 	struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
2505 	int idx_number = 2;
2506 	uint32_t refbw;
2507 	struct interface *ifp;
2508 
2509 	refbw = strtol(argv[idx_number]->arg, NULL, 10);
2510 	if (refbw < 1 || refbw > 4294967) {
2511 		vty_out(vty, "reference-bandwidth value is invalid\n");
2512 		return CMD_WARNING_CONFIG_FAILED;
2513 	}
2514 
2515 	/* If reference bandwidth is changed. */
2516 	if ((refbw) == ospf->ref_bandwidth)
2517 		return CMD_SUCCESS;
2518 
2519 	ospf->ref_bandwidth = refbw;
2520 	FOR_ALL_INTERFACES (vrf, ifp)
2521 		ospf_if_recalculate_output_cost(ifp);
2522 
2523 	return CMD_SUCCESS;
2524 }
2525 
2526 DEFUN (no_ospf_auto_cost_reference_bandwidth,
2527        no_ospf_auto_cost_reference_bandwidth_cmd,
2528        "no auto-cost reference-bandwidth [(1-4294967)]",
2529        NO_STR
2530        "Calculate OSPF interface cost according to bandwidth\n"
2531        "Use reference bandwidth method to assign OSPF cost\n"
2532        "The reference bandwidth in terms of Mbits per second\n")
2533 {
2534 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2535 	struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
2536 	struct interface *ifp;
2537 
2538 	if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH)
2539 		return CMD_SUCCESS;
2540 
2541 	ospf->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
2542 	vty_out(vty, "%% OSPF: Reference bandwidth is changed.\n");
2543 	vty_out(vty,
2544 		"        Please ensure reference bandwidth is consistent across all routers\n");
2545 
2546 	FOR_ALL_INTERFACES (vrf, ifp)
2547 		ospf_if_recalculate_output_cost(ifp);
2548 
2549 	return CMD_SUCCESS;
2550 }
2551 
2552 DEFUN (ospf_write_multiplier,
2553        ospf_write_multiplier_cmd,
2554        "ospf write-multiplier (1-100)",
2555        "OSPF specific commands\n"
2556        "Write multiplier\n"
2557        "Maximum number of interface serviced per write\n")
2558 {
2559 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2560 	int idx_number;
2561 	uint32_t write_oi_count;
2562 
2563 	if (argc == 3)
2564 		idx_number = 2;
2565 	else
2566 		idx_number = 1;
2567 
2568 	write_oi_count = strtol(argv[idx_number]->arg, NULL, 10);
2569 	if (write_oi_count < 1 || write_oi_count > 100) {
2570 		vty_out(vty, "write-multiplier value is invalid\n");
2571 		return CMD_WARNING_CONFIG_FAILED;
2572 	}
2573 
2574 	ospf->write_oi_count = write_oi_count;
2575 	return CMD_SUCCESS;
2576 }
2577 
2578 ALIAS(ospf_write_multiplier, write_multiplier_cmd, "write-multiplier (1-100)",
2579       "Write multiplier\n"
2580       "Maximum number of interface serviced per write\n")
2581 
2582 DEFUN (no_ospf_write_multiplier,
2583        no_ospf_write_multiplier_cmd,
2584        "no ospf write-multiplier (1-100)",
2585        NO_STR
2586        "OSPF specific commands\n"
2587        "Write multiplier\n"
2588        "Maximum number of interface serviced per write\n")
2589 {
2590 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
2591 
2592 	ospf->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
2593 	return CMD_SUCCESS;
2594 }
2595 
2596 ALIAS(no_ospf_write_multiplier, no_write_multiplier_cmd,
2597       "no write-multiplier (1-100)", NO_STR
2598       "Write multiplier\n"
2599       "Maximum number of interface serviced per write\n")
2600 
2601 static const char *const ospf_abr_type_descr_str[] = {
2602 	"Unknown", "Standard (RFC2328)", "Alternative IBM",
2603 	"Alternative Cisco", "Alternative Shortcut"
2604 };
2605 
2606 static const char *const ospf_shortcut_mode_descr_str[] = {
2607 	"Default", "Enabled", "Disabled"
2608 };
2609 
show_ip_ospf_area(struct vty * vty,struct ospf_area * area,json_object * json_areas,bool use_json)2610 static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area,
2611 			      json_object *json_areas, bool use_json)
2612 {
2613 	json_object *json_area = NULL;
2614 
2615 	if (use_json)
2616 		json_area = json_object_new_object();
2617 
2618 	/* Show Area ID. */
2619 	if (!use_json)
2620 		vty_out(vty, " Area ID: %s", inet_ntoa(area->area_id));
2621 
2622 	/* Show Area type/mode. */
2623 	if (OSPF_IS_AREA_BACKBONE(area)) {
2624 		if (use_json)
2625 			json_object_boolean_true_add(json_area, "backbone");
2626 		else
2627 			vty_out(vty, " (Backbone)\n");
2628 	} else {
2629 		if (use_json) {
2630 			if (area->external_routing == OSPF_AREA_STUB) {
2631 				if (area->no_summary)
2632 					json_object_boolean_true_add(
2633 						json_area, "stubNoSummary");
2634 				if (area->shortcut_configured)
2635 					json_object_boolean_true_add(
2636 						json_area, "stubShortcut");
2637 			} else if (area->external_routing == OSPF_AREA_NSSA) {
2638 				if (area->no_summary)
2639 					json_object_boolean_true_add(
2640 						json_area, "nssaNoSummary");
2641 				if (area->shortcut_configured)
2642 					json_object_boolean_true_add(
2643 						json_area, "nssaShortcut");
2644 			}
2645 
2646 			json_object_string_add(
2647 				json_area, "shortcuttingMode",
2648 				ospf_shortcut_mode_descr_str
2649 					[area->shortcut_configured]);
2650 			if (area->shortcut_capability)
2651 				json_object_boolean_true_add(json_area,
2652 							     "sBitConcensus");
2653 		} else {
2654 			if (area->external_routing == OSPF_AREA_STUB)
2655 				vty_out(vty, " (Stub%s%s)",
2656 					area->no_summary ? ", no summary" : "",
2657 					area->shortcut_configured ? "; " : "");
2658 			else if (area->external_routing == OSPF_AREA_NSSA)
2659 				vty_out(vty, " (NSSA%s%s)",
2660 					area->no_summary ? ", no summary" : "",
2661 					area->shortcut_configured ? "; " : "");
2662 
2663 			vty_out(vty, "\n");
2664 			vty_out(vty, "   Shortcutting mode: %s",
2665 				ospf_shortcut_mode_descr_str
2666 					[area->shortcut_configured]);
2667 			vty_out(vty, ", S-bit consensus: %s\n",
2668 				area->shortcut_capability ? "ok" : "no");
2669 		}
2670 	}
2671 
2672 	/* Show number of interfaces */
2673 	if (use_json) {
2674 		json_object_int_add(json_area, "areaIfTotalCounter",
2675 				    listcount(area->oiflist));
2676 		json_object_int_add(json_area, "areaIfActiveCounter",
2677 				    area->act_ints);
2678 	} else
2679 		vty_out(vty,
2680 			"   Number of interfaces in this area: Total: %d, Active: %d\n",
2681 			listcount(area->oiflist), area->act_ints);
2682 
2683 	if (area->external_routing == OSPF_AREA_NSSA) {
2684 		if (use_json) {
2685 			json_object_boolean_true_add(json_area, "nssa");
2686 			if (!IS_OSPF_ABR(area->ospf))
2687 				json_object_boolean_false_add(json_area, "abr");
2688 			else if (area->NSSATranslatorState) {
2689 				json_object_boolean_true_add(json_area, "abr");
2690 				if (area->NSSATranslatorRole
2691 				    == OSPF_NSSA_ROLE_CANDIDATE)
2692 					json_object_boolean_true_add(
2693 						json_area,
2694 						"nssaTranslatorElected");
2695 				else if (area->NSSATranslatorRole
2696 					 == OSPF_NSSA_ROLE_ALWAYS)
2697 					json_object_boolean_true_add(
2698 						json_area,
2699 						"nssaTranslatorAlways");
2700 			} else {
2701 				json_object_boolean_true_add(json_area, "abr");
2702 				if (area->NSSATranslatorRole
2703 				    == OSPF_NSSA_ROLE_CANDIDATE)
2704 					json_object_boolean_false_add(
2705 						json_area,
2706 						"nssaTranslatorElected");
2707 				else
2708 					json_object_boolean_true_add(
2709 						json_area,
2710 						"nssaTranslatorNever");
2711 			}
2712 		} else {
2713 			vty_out(vty,
2714 				"   It is an NSSA configuration. \n   Elected NSSA/ABR performs type-7/type-5 LSA translation. \n");
2715 			if (!IS_OSPF_ABR(area->ospf))
2716 				vty_out(vty,
2717 					"   It is not ABR, therefore not Translator. \n");
2718 			else if (area->NSSATranslatorState) {
2719 				vty_out(vty, "   We are an ABR and ");
2720 				if (area->NSSATranslatorRole
2721 				    == OSPF_NSSA_ROLE_CANDIDATE)
2722 					vty_out(vty,
2723 						"the NSSA Elected Translator. \n");
2724 				else if (area->NSSATranslatorRole
2725 					 == OSPF_NSSA_ROLE_ALWAYS)
2726 					vty_out(vty,
2727 						"always an NSSA Translator. \n");
2728 			} else {
2729 				vty_out(vty, "   We are an ABR, but ");
2730 				if (area->NSSATranslatorRole
2731 				    == OSPF_NSSA_ROLE_CANDIDATE)
2732 					vty_out(vty,
2733 						"not the NSSA Elected Translator. \n");
2734 				else
2735 					vty_out(vty,
2736 						"never an NSSA Translator. \n");
2737 			}
2738 		}
2739 	}
2740 
2741 	/* Stub-router state for this area */
2742 	if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) {
2743 		char timebuf[OSPF_TIME_DUMP_SIZE];
2744 
2745 		if (use_json) {
2746 			json_object_boolean_true_add(
2747 				json_area, "originStubMaxDistRouterLsa");
2748 			if (CHECK_FLAG(area->stub_router_state,
2749 				       OSPF_AREA_ADMIN_STUB_ROUTED))
2750 				json_object_boolean_true_add(
2751 					json_area, "indefiniteActiveAdmin");
2752 			if (area->t_stub_router) {
2753 				long time_store;
2754 				time_store =
2755 					monotime_until(
2756 						&area->t_stub_router->u.sands,
2757 						NULL)
2758 					/ 1000LL;
2759 				json_object_int_add(
2760 					json_area,
2761 					"activeStartupRemainderMsecs",
2762 					time_store);
2763 			}
2764 		} else {
2765 			vty_out(vty,
2766 				"   Originating stub / maximum-distance Router-LSA\n");
2767 			if (CHECK_FLAG(area->stub_router_state,
2768 				       OSPF_AREA_ADMIN_STUB_ROUTED))
2769 				vty_out(vty,
2770 					"     Administratively activated (indefinitely)\n");
2771 			if (area->t_stub_router)
2772 				vty_out(vty,
2773 					"     Active from startup, %s remaining\n",
2774 					ospf_timer_dump(area->t_stub_router,
2775 							timebuf,
2776 							sizeof(timebuf)));
2777 		}
2778 	}
2779 
2780 	if (use_json) {
2781 		/* Show number of fully adjacent neighbors. */
2782 		json_object_int_add(json_area, "nbrFullAdjacentCounter",
2783 				    area->full_nbrs);
2784 
2785 		/* Show authentication type. */
2786 		if (area->auth_type == OSPF_AUTH_NULL)
2787 			json_object_string_add(json_area, "authentication",
2788 					       "authenticationNone");
2789 		else if (area->auth_type == OSPF_AUTH_SIMPLE)
2790 			json_object_string_add(json_area, "authentication",
2791 					       "authenticationSimplePassword");
2792 		else if (area->auth_type == OSPF_AUTH_CRYPTOGRAPHIC)
2793 			json_object_string_add(json_area, "authentication",
2794 					       "authenticationMessageDigest");
2795 
2796 		if (!OSPF_IS_AREA_BACKBONE(area))
2797 			json_object_int_add(json_area,
2798 					    "virtualAdjacenciesPassingCounter",
2799 					    area->full_vls);
2800 
2801 		/* Show SPF calculation times. */
2802 		json_object_int_add(json_area, "spfExecutedCounter",
2803 				    area->spf_calculation);
2804 		json_object_int_add(json_area, "lsaNumber", area->lsdb->total);
2805 		json_object_int_add(
2806 			json_area, "lsaRouterNumber",
2807 			ospf_lsdb_count(area->lsdb, OSPF_ROUTER_LSA));
2808 		json_object_int_add(
2809 			json_area, "lsaRouterChecksum",
2810 			ospf_lsdb_checksum(area->lsdb, OSPF_ROUTER_LSA));
2811 		json_object_int_add(
2812 			json_area, "lsaNetworkNumber",
2813 			ospf_lsdb_count(area->lsdb, OSPF_NETWORK_LSA));
2814 		json_object_int_add(
2815 			json_area, "lsaNetworkChecksum",
2816 			ospf_lsdb_checksum(area->lsdb, OSPF_NETWORK_LSA));
2817 		json_object_int_add(
2818 			json_area, "lsaSummaryNumber",
2819 			ospf_lsdb_count(area->lsdb, OSPF_SUMMARY_LSA));
2820 		json_object_int_add(
2821 			json_area, "lsaSummaryChecksum",
2822 			ospf_lsdb_checksum(area->lsdb, OSPF_SUMMARY_LSA));
2823 		json_object_int_add(
2824 			json_area, "lsaAsbrNumber",
2825 			ospf_lsdb_count(area->lsdb, OSPF_ASBR_SUMMARY_LSA));
2826 		json_object_int_add(
2827 			json_area, "lsaAsbrChecksum",
2828 			ospf_lsdb_checksum(area->lsdb, OSPF_ASBR_SUMMARY_LSA));
2829 		json_object_int_add(
2830 			json_area, "lsaNssaNumber",
2831 			ospf_lsdb_count(area->lsdb, OSPF_AS_NSSA_LSA));
2832 		json_object_int_add(
2833 			json_area, "lsaNssaChecksum",
2834 			ospf_lsdb_checksum(area->lsdb, OSPF_AS_NSSA_LSA));
2835 	} else {
2836 		/* Show number of fully adjacent neighbors. */
2837 		vty_out(vty,
2838 			"   Number of fully adjacent neighbors in this area: %d\n",
2839 			area->full_nbrs);
2840 
2841 		/* Show authentication type. */
2842 		vty_out(vty, "   Area has ");
2843 		if (area->auth_type == OSPF_AUTH_NULL)
2844 			vty_out(vty, "no authentication\n");
2845 		else if (area->auth_type == OSPF_AUTH_SIMPLE)
2846 			vty_out(vty, "simple password authentication\n");
2847 		else if (area->auth_type == OSPF_AUTH_CRYPTOGRAPHIC)
2848 			vty_out(vty, "message digest authentication\n");
2849 
2850 		if (!OSPF_IS_AREA_BACKBONE(area))
2851 			vty_out(vty,
2852 				"   Number of full virtual adjacencies going through this area: %d\n",
2853 				area->full_vls);
2854 
2855 		/* Show SPF calculation times. */
2856 		vty_out(vty, "   SPF algorithm executed %d times\n",
2857 			area->spf_calculation);
2858 
2859 		/* Show number of LSA. */
2860 		vty_out(vty, "   Number of LSA %ld\n", area->lsdb->total);
2861 		vty_out(vty,
2862 			"   Number of router LSA %ld. Checksum Sum 0x%08x\n",
2863 			ospf_lsdb_count(area->lsdb, OSPF_ROUTER_LSA),
2864 			ospf_lsdb_checksum(area->lsdb, OSPF_ROUTER_LSA));
2865 		vty_out(vty,
2866 			"   Number of network LSA %ld. Checksum Sum 0x%08x\n",
2867 			ospf_lsdb_count(area->lsdb, OSPF_NETWORK_LSA),
2868 			ospf_lsdb_checksum(area->lsdb, OSPF_NETWORK_LSA));
2869 		vty_out(vty,
2870 			"   Number of summary LSA %ld. Checksum Sum 0x%08x\n",
2871 			ospf_lsdb_count(area->lsdb, OSPF_SUMMARY_LSA),
2872 			ospf_lsdb_checksum(area->lsdb, OSPF_SUMMARY_LSA));
2873 		vty_out(vty,
2874 			"   Number of ASBR summary LSA %ld. Checksum Sum 0x%08x\n",
2875 			ospf_lsdb_count(area->lsdb, OSPF_ASBR_SUMMARY_LSA),
2876 			ospf_lsdb_checksum(area->lsdb, OSPF_ASBR_SUMMARY_LSA));
2877 		vty_out(vty, "   Number of NSSA LSA %ld. Checksum Sum 0x%08x\n",
2878 			ospf_lsdb_count(area->lsdb, OSPF_AS_NSSA_LSA),
2879 			ospf_lsdb_checksum(area->lsdb, OSPF_AS_NSSA_LSA));
2880 	}
2881 
2882 	if (use_json) {
2883 		json_object_int_add(
2884 			json_area, "lsaOpaqueLinkNumber",
2885 			ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_LINK_LSA));
2886 		json_object_int_add(
2887 			json_area, "lsaOpaqueLinkChecksum",
2888 			ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_LINK_LSA));
2889 		json_object_int_add(
2890 			json_area, "lsaOpaqueAreaNumber",
2891 			ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_AREA_LSA));
2892 		json_object_int_add(
2893 			json_area, "lsaOpaqueAreaChecksum",
2894 			ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_AREA_LSA));
2895 	} else {
2896 		vty_out(vty,
2897 			"   Number of opaque link LSA %ld. Checksum Sum 0x%08x\n",
2898 			ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_LINK_LSA),
2899 			ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_LINK_LSA));
2900 		vty_out(vty,
2901 			"   Number of opaque area LSA %ld. Checksum Sum 0x%08x\n",
2902 			ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_AREA_LSA),
2903 			ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_AREA_LSA));
2904 	}
2905 
2906 	if (use_json)
2907 		json_object_object_add(json_areas, inet_ntoa(area->area_id),
2908 				       json_area);
2909 	else
2910 		vty_out(vty, "\n");
2911 }
2912 
show_ip_ospf_common(struct vty * vty,struct ospf * ospf,json_object * json,uint8_t use_vrf)2913 static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
2914 			       json_object *json, uint8_t use_vrf)
2915 {
2916 	struct listnode *node, *nnode;
2917 	struct ospf_area *area;
2918 	struct timeval result;
2919 	char timebuf[OSPF_TIME_DUMP_SIZE];
2920 	json_object *json_vrf = NULL;
2921 	json_object *json_areas = NULL;
2922 
2923 	if (json) {
2924 		if (use_vrf)
2925 			json_vrf = json_object_new_object();
2926 		else
2927 			json_vrf = json;
2928 		json_areas = json_object_new_object();
2929 	}
2930 
2931 	if (ospf->instance) {
2932 		if (json) {
2933 			json_object_int_add(json, "ospfInstance",
2934 					    ospf->instance);
2935 		} else {
2936 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
2937 		}
2938 	}
2939 
2940 	ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
2941 
2942 	/* Show Router ID. */
2943 	if (json) {
2944 		json_object_string_add(json_vrf, "routerId",
2945 				       inet_ntoa(ospf->router_id));
2946 	} else {
2947 		vty_out(vty, " OSPF Routing Process, Router ID: %s\n",
2948 			inet_ntoa(ospf->router_id));
2949 	}
2950 
2951 	/* Graceful shutdown */
2952 	if (ospf->t_deferred_shutdown) {
2953 		if (json) {
2954 			long time_store;
2955 			time_store =
2956 				monotime_until(
2957 					&ospf->t_deferred_shutdown->u.sands,
2958 					NULL)
2959 				/ 1000LL;
2960 			json_object_int_add(json_vrf, "deferredShutdownMsecs",
2961 					    time_store);
2962 		} else {
2963 			vty_out(vty,
2964 				" Deferred shutdown in progress, %s remaining\n",
2965 				ospf_timer_dump(ospf->t_deferred_shutdown,
2966 						timebuf, sizeof(timebuf)));
2967 		}
2968 	}
2969 
2970 	/* Show capability. */
2971 	if (json) {
2972 		json_object_boolean_true_add(json_vrf, "tosRoutesOnly");
2973 		json_object_boolean_true_add(json_vrf, "rfc2328Conform");
2974 		if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) {
2975 			json_object_boolean_true_add(json_vrf,
2976 						     "rfc1583Compatibility");
2977 		}
2978 	} else {
2979 		vty_out(vty, " Supports only single TOS (TOS0) routes\n");
2980 		vty_out(vty, " This implementation conforms to RFC2328\n");
2981 		vty_out(vty, " RFC1583Compatibility flag is %s\n",
2982 			CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)
2983 				? "enabled"
2984 				: "disabled");
2985 	}
2986 
2987 	if (json) {
2988 		if (CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) {
2989 			json_object_boolean_true_add(json_vrf, "opaqueCapable");
2990 		}
2991 	} else {
2992 		vty_out(vty, " OpaqueCapability flag is %s\n",
2993 			CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)
2994 				? "enabled"
2995 				: "disabled");
2996 	}
2997 
2998 	/* Show stub-router configuration */
2999 	if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED
3000 	    || ospf->stub_router_shutdown_time
3001 		       != OSPF_STUB_ROUTER_UNCONFIGURED) {
3002 		if (json) {
3003 			json_object_boolean_true_add(json_vrf,
3004 						     "stubAdvertisement");
3005 			if (ospf->stub_router_startup_time
3006 			    != OSPF_STUB_ROUTER_UNCONFIGURED)
3007 				json_object_int_add(
3008 					json_vrf, "postStartEnabledSecs",
3009 					ospf->stub_router_startup_time);
3010 			if (ospf->stub_router_shutdown_time
3011 			    != OSPF_STUB_ROUTER_UNCONFIGURED)
3012 				json_object_int_add(
3013 					json_vrf, "preShutdownEnabledSecs",
3014 					ospf->stub_router_shutdown_time);
3015 		} else {
3016 			vty_out(vty,
3017 				" Stub router advertisement is configured\n");
3018 			if (ospf->stub_router_startup_time
3019 			    != OSPF_STUB_ROUTER_UNCONFIGURED)
3020 				vty_out(vty,
3021 					"   Enabled for %us after start-up\n",
3022 					ospf->stub_router_startup_time);
3023 			if (ospf->stub_router_shutdown_time
3024 			    != OSPF_STUB_ROUTER_UNCONFIGURED)
3025 				vty_out(vty,
3026 					"   Enabled for %us prior to full shutdown\n",
3027 					ospf->stub_router_shutdown_time);
3028 		}
3029 	}
3030 
3031 	/* Show SPF timers. */
3032 	if (json) {
3033 		json_object_int_add(json_vrf, "spfScheduleDelayMsecs",
3034 				    ospf->spf_delay);
3035 		json_object_int_add(json_vrf, "holdtimeMinMsecs",
3036 				    ospf->spf_holdtime);
3037 		json_object_int_add(json_vrf, "holdtimeMaxMsecs",
3038 				    ospf->spf_max_holdtime);
3039 		json_object_int_add(json_vrf, "holdtimeMultplier",
3040 				    ospf->spf_hold_multiplier);
3041 	} else {
3042 		vty_out(vty,
3043 			" Initial SPF scheduling delay %d millisec(s)\n"
3044 			" Minimum hold time between consecutive SPFs %d millisec(s)\n"
3045 			" Maximum hold time between consecutive SPFs %d millisec(s)\n"
3046 			" Hold time multiplier is currently %d\n",
3047 			ospf->spf_delay, ospf->spf_holdtime,
3048 			ospf->spf_max_holdtime, ospf->spf_hold_multiplier);
3049 	}
3050 
3051 	if (json) {
3052 		if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) {
3053 			long time_store = 0;
3054 
3055 			time_store =
3056 				monotime_since(&ospf->ts_spf, NULL) / 1000LL;
3057 			json_object_int_add(json_vrf, "spfLastExecutedMsecs",
3058 					    time_store);
3059 
3060 			time_store = (1000 * ospf->ts_spf_duration.tv_sec)
3061 				     + (ospf->ts_spf_duration.tv_usec / 1000);
3062 			json_object_int_add(json_vrf, "spfLastDurationMsecs",
3063 					    time_store);
3064 		} else
3065 			json_object_boolean_true_add(json_vrf, "spfHasNotRun");
3066 	} else {
3067 		vty_out(vty, " SPF algorithm ");
3068 		if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) {
3069 			monotime_since(&ospf->ts_spf, &result);
3070 			vty_out(vty, "last executed %s ago\n",
3071 				ospf_timeval_dump(&result, timebuf,
3072 						  sizeof(timebuf)));
3073 			vty_out(vty, " Last SPF duration %s\n",
3074 				ospf_timeval_dump(&ospf->ts_spf_duration,
3075 						  timebuf, sizeof(timebuf)));
3076 		} else
3077 			vty_out(vty, "has not been run\n");
3078 	}
3079 
3080 	if (json) {
3081 		if (ospf->t_spf_calc) {
3082 			long time_store;
3083 			time_store =
3084 				monotime_until(&ospf->t_spf_calc->u.sands, NULL)
3085 				/ 1000LL;
3086 			json_object_int_add(json_vrf, "spfTimerDueInMsecs",
3087 					    time_store);
3088 		}
3089 
3090 		json_object_int_add(json_vrf, "lsaMinIntervalMsecs",
3091 				    ospf->min_ls_interval);
3092 		json_object_int_add(json_vrf, "lsaMinArrivalMsecs",
3093 				    ospf->min_ls_arrival);
3094 		/* Show write multiplier values */
3095 		json_object_int_add(json_vrf, "writeMultiplier",
3096 				    ospf->write_oi_count);
3097 		/* Show refresh parameters. */
3098 		json_object_int_add(json_vrf, "refreshTimerMsecs",
3099 				    ospf->lsa_refresh_interval * 1000);
3100 	} else {
3101 		vty_out(vty, " SPF timer %s%s\n",
3102 			(ospf->t_spf_calc ? "due in " : "is "),
3103 			ospf_timer_dump(ospf->t_spf_calc, timebuf,
3104 					sizeof(timebuf)));
3105 
3106 		vty_out(vty, " LSA minimum interval %d msecs\n",
3107 			ospf->min_ls_interval);
3108 		vty_out(vty, " LSA minimum arrival %d msecs\n",
3109 			ospf->min_ls_arrival);
3110 
3111 		/* Show write multiplier values */
3112 		vty_out(vty, " Write Multiplier set to %d \n",
3113 			ospf->write_oi_count);
3114 
3115 		/* Show refresh parameters. */
3116 		vty_out(vty, " Refresh timer %d secs\n",
3117 			ospf->lsa_refresh_interval);
3118 	}
3119 
3120 	/* Show ABR/ASBR flags. */
3121 	if (CHECK_FLAG(ospf->flags, OSPF_FLAG_ABR)) {
3122 		if (json)
3123 			json_object_string_add(
3124 				json_vrf, "abrType",
3125 				ospf_abr_type_descr_str[ospf->abr_type]);
3126 		else
3127 			vty_out(vty,
3128 				" This router is an ABR, ABR type is: %s\n",
3129 				ospf_abr_type_descr_str[ospf->abr_type]);
3130 	}
3131 	if (CHECK_FLAG(ospf->flags, OSPF_FLAG_ASBR)) {
3132 		if (json)
3133 			json_object_string_add(
3134 				json_vrf, "asbrRouter",
3135 				"injectingExternalRoutingInformation");
3136 		else
3137 			vty_out(vty,
3138 				" This router is an ASBR (injecting external routing information)\n");
3139 	}
3140 
3141 	/* Show Number of AS-external-LSAs. */
3142 	if (json) {
3143 		json_object_int_add(
3144 			json_vrf, "lsaExternalCounter",
3145 			ospf_lsdb_count(ospf->lsdb, OSPF_AS_EXTERNAL_LSA));
3146 		json_object_int_add(
3147 			json_vrf, "lsaExternalChecksum",
3148 			ospf_lsdb_checksum(ospf->lsdb, OSPF_AS_EXTERNAL_LSA));
3149 	} else {
3150 		vty_out(vty,
3151 			" Number of external LSA %ld. Checksum Sum 0x%08x\n",
3152 			ospf_lsdb_count(ospf->lsdb, OSPF_AS_EXTERNAL_LSA),
3153 			ospf_lsdb_checksum(ospf->lsdb, OSPF_AS_EXTERNAL_LSA));
3154 	}
3155 
3156 	if (json) {
3157 		json_object_int_add(
3158 			json_vrf, "lsaAsopaqueCounter",
3159 			ospf_lsdb_count(ospf->lsdb, OSPF_OPAQUE_AS_LSA));
3160 		json_object_int_add(
3161 			json_vrf, "lsaAsOpaqueChecksum",
3162 			ospf_lsdb_checksum(ospf->lsdb, OSPF_OPAQUE_AS_LSA));
3163 	} else {
3164 		vty_out(vty,
3165 			" Number of opaque AS LSA %ld. Checksum Sum 0x%08x\n",
3166 			ospf_lsdb_count(ospf->lsdb, OSPF_OPAQUE_AS_LSA),
3167 			ospf_lsdb_checksum(ospf->lsdb, OSPF_OPAQUE_AS_LSA));
3168 	}
3169 
3170 	/* Show number of areas attached. */
3171 	if (json)
3172 		json_object_int_add(json_vrf, "attachedAreaCounter",
3173 				    listcount(ospf->areas));
3174 	else
3175 		vty_out(vty, " Number of areas attached to this router: %d\n",
3176 			listcount(ospf->areas));
3177 
3178 	if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
3179 		if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) {
3180 			if (json)
3181 				json_object_boolean_true_add(
3182 					json_vrf, "adjacencyChangesLoggedAll");
3183 			else
3184 				vty_out(vty,
3185 					" All adjacency changes are logged\n");
3186 		} else {
3187 			if (json)
3188 				json_object_boolean_true_add(
3189 					json_vrf, "adjacencyChangesLogged");
3190 			else
3191 				vty_out(vty, " Adjacency changes are logged\n");
3192 		}
3193 	}
3194 	/* Show each area status. */
3195 	for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
3196 		show_ip_ospf_area(vty, area, json_areas, json ? 1 : 0);
3197 
3198 	if (json) {
3199 		if (use_vrf) {
3200 			json_object_object_add(json_vrf, "areas", json_areas);
3201 			if (ospf->vrf_id == VRF_DEFAULT)
3202 				json_object_object_add(json, "default",
3203 						       json_vrf);
3204 			else
3205 				json_object_object_add(json, ospf->name,
3206 						       json_vrf);
3207 		} else {
3208 			json_object_object_add(json, "areas", json_areas);
3209 		}
3210 	} else
3211 		vty_out(vty, "\n");
3212 
3213 	return CMD_SUCCESS;
3214 }
3215 
3216 DEFUN (show_ip_ospf,
3217        show_ip_ospf_cmd,
3218        "show ip ospf [vrf <NAME|all>] [json]",
3219        SHOW_STR
3220        IP_STR
3221        "OSPF information\n"
3222        VRF_CMD_HELP_STR
3223        "All VRFs\n"
3224        JSON_STR)
3225 {
3226 	struct ospf *ospf;
3227 	bool uj = use_json(argc, argv);
3228 	struct listnode *node = NULL;
3229 	char *vrf_name = NULL;
3230 	bool all_vrf = false;
3231 	int ret = CMD_SUCCESS;
3232 	int inst = 0;
3233 	int idx_vrf = 0;
3234 	json_object *json = NULL;
3235 	uint8_t use_vrf = 0;
3236 
3237 	if (listcount(om->ospf) == 0)
3238 		return CMD_SUCCESS;
3239 
3240 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
3241 
3242 	if (uj)
3243 		json = json_object_new_object();
3244 
3245 	/* vrf input is provided could be all or specific vrf*/
3246 	if (vrf_name) {
3247 		bool ospf_output = false;
3248 
3249 		use_vrf = 1;
3250 
3251 		if (all_vrf) {
3252 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
3253 				if (!ospf->oi_running)
3254 					continue;
3255 				ospf_output = true;
3256 				ret = show_ip_ospf_common(vty, ospf, json,
3257 							  use_vrf);
3258 			}
3259 			if (uj) {
3260 				vty_out(vty, "%s\n",
3261 					json_object_to_json_string_ext(
3262 						json, JSON_C_TO_STRING_PRETTY));
3263 				json_object_free(json);
3264 			} else if (!ospf_output)
3265 				vty_out(vty, "%% OSPF instance not found\n");
3266 			return ret;
3267 		}
3268 		ospf = ospf_lookup_by_inst_name(inst, vrf_name);
3269 		if ((ospf == NULL) || !ospf->oi_running) {
3270 			if (uj) {
3271 				vty_out(vty, "%s\n",
3272 					json_object_to_json_string_ext(
3273 						json, JSON_C_TO_STRING_PRETTY));
3274 				json_object_free(json);
3275 			} else
3276 				vty_out(vty, "%% OSPF instance not found\n");
3277 
3278 			return CMD_SUCCESS;
3279 		}
3280 	} else {
3281 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
3282 		/* Display default ospf (instance 0) info */
3283 		if (ospf == NULL || !ospf->oi_running) {
3284 			if (uj) {
3285 				vty_out(vty, "%s\n",
3286 					json_object_to_json_string_ext(
3287 						json, JSON_C_TO_STRING_PRETTY));
3288 				json_object_free(json);
3289 			} else
3290 				vty_out(vty, "%% OSPF instance not found\n");
3291 
3292 			return CMD_SUCCESS;
3293 		}
3294 	}
3295 
3296 	if (ospf) {
3297 		show_ip_ospf_common(vty, ospf, json, use_vrf);
3298 		if (uj)
3299 			vty_out(vty, "%s\n",
3300 				json_object_to_json_string_ext(
3301 					json, JSON_C_TO_STRING_PRETTY));
3302 	}
3303 
3304 	if (uj)
3305 		json_object_free(json);
3306 
3307 	return ret;
3308 }
3309 
3310 DEFUN (show_ip_ospf_instance,
3311        show_ip_ospf_instance_cmd,
3312        "show ip ospf (1-65535) [json]",
3313        SHOW_STR
3314        IP_STR
3315        "OSPF information\n"
3316        "Instance ID\n"
3317        JSON_STR)
3318 {
3319 	int idx_number = 3;
3320 	struct ospf *ospf;
3321 	unsigned short instance = 0;
3322 	bool uj = use_json(argc, argv);
3323 	int ret = CMD_SUCCESS;
3324 	json_object *json = NULL;
3325 
3326 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
3327 	ospf = ospf_lookup_instance(instance);
3328 	if (ospf == NULL)
3329 		return CMD_NOT_MY_INSTANCE;
3330 
3331 	if (!ospf->oi_running)
3332 		return CMD_SUCCESS;
3333 
3334 	if (uj)
3335 		json = json_object_new_object();
3336 
3337 	ret = show_ip_ospf_common(vty, ospf, json, 0);
3338 
3339 	if (uj) {
3340 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
3341 					     json, JSON_C_TO_STRING_PRETTY));
3342 		json_object_free(json);
3343 	}
3344 
3345 	return ret;
3346 }
3347 
show_ip_ospf_interface_sub(struct vty * vty,struct ospf * ospf,struct interface * ifp,json_object * json_interface_sub,bool use_json)3348 static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
3349 				       struct interface *ifp,
3350 				       json_object *json_interface_sub,
3351 				       bool use_json)
3352 {
3353 	int is_up;
3354 	struct ospf_neighbor *nbr;
3355 	struct route_node *rn;
3356 	uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed;
3357 
3358 	/* Is interface up? */
3359 	if (use_json) {
3360 		is_up = if_is_operative(ifp);
3361 		if (is_up)
3362 			json_object_boolean_true_add(json_interface_sub,
3363 						     "ifUp");
3364 		else
3365 			json_object_boolean_false_add(json_interface_sub,
3366 						      "ifDown");
3367 
3368 		json_object_int_add(json_interface_sub, "ifIndex",
3369 				    ifp->ifindex);
3370 		json_object_int_add(json_interface_sub, "mtuBytes", ifp->mtu);
3371 		json_object_int_add(json_interface_sub, "bandwidthMbit",
3372 				    bandwidth);
3373 		json_object_string_add(json_interface_sub, "ifFlags",
3374 				       if_flag_dump(ifp->flags));
3375 	} else {
3376 		vty_out(vty, "%s is %s\n", ifp->name,
3377 			((is_up = if_is_operative(ifp)) ? "up" : "down"));
3378 		vty_out(vty, "  ifindex %u, MTU %u bytes, BW %u Mbit %s\n",
3379 			ifp->ifindex, ifp->mtu, bandwidth,
3380 			if_flag_dump(ifp->flags));
3381 	}
3382 
3383 	/* Is interface OSPF enabled? */
3384 	if (use_json) {
3385 		if (ospf_oi_count(ifp) == 0) {
3386 			json_object_boolean_false_add(json_interface_sub,
3387 						      "ospfEnabled");
3388 			return;
3389 		} else if (!is_up) {
3390 			json_object_boolean_false_add(json_interface_sub,
3391 						      "ospfRunning");
3392 			return;
3393 		} else
3394 			json_object_boolean_true_add(json_interface_sub,
3395 						     "ospfEnabled");
3396 	} else {
3397 		if (ospf_oi_count(ifp) == 0) {
3398 			vty_out(vty, "  OSPF not enabled on this interface\n");
3399 			return;
3400 		} else if (!is_up) {
3401 			vty_out(vty,
3402 				"  OSPF is enabled, but not running on this interface\n");
3403 			return;
3404 		}
3405 	}
3406 
3407 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
3408 		struct ospf_interface *oi = rn->info;
3409 
3410 		if (oi == NULL)
3411 			continue;
3412 
3413 		if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) {
3414 			if (use_json)
3415 				json_object_boolean_true_add(json_interface_sub,
3416 							     "ifUnnumbered");
3417 			else
3418 				vty_out(vty, "  This interface is UNNUMBERED,");
3419 		} else {
3420 			struct in_addr dest;
3421 			const char *dstr;
3422 
3423 			/* Show OSPF interface information. */
3424 			if (use_json) {
3425 				json_object_string_add(
3426 					json_interface_sub, "ipAddress",
3427 					inet_ntoa(oi->address->u.prefix4));
3428 				json_object_int_add(json_interface_sub,
3429 						    "ipAddressPrefixlen",
3430 						    oi->address->prefixlen);
3431 			} else
3432 				vty_out(vty, "  Internet Address %s/%d,",
3433 					inet_ntoa(oi->address->u.prefix4),
3434 					oi->address->prefixlen);
3435 
3436 			/* For Vlinks, showing the peer address is
3437 			 * probably more informative than the local
3438 			 * interface that is being used */
3439 			if (oi->type == OSPF_IFTYPE_VIRTUALLINK) {
3440 				dstr = "Peer";
3441 				dest = oi->vl_data->peer_addr;
3442 			} else if (CONNECTED_PEER(oi->connected)
3443 					 && oi->connected->destination) {
3444 				dstr = "Peer";
3445 				dest = oi->connected->destination->u.prefix4;
3446 			} else {
3447 				dstr = "Broadcast";
3448 				dest.s_addr = ipv4_broadcast_addr(
3449 						oi->connected->address->u.prefix4.s_addr,
3450 						oi->connected->address->prefixlen);
3451 			}
3452 
3453 			if (use_json) {
3454 				json_object_string_add(
3455 					json_interface_sub,
3456 					"ospfIfType", dstr);
3457 				if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3458 					json_object_string_add(
3459 						json_interface_sub,
3460 						"vlinkPeer",
3461 						inet_ntoa(dest));
3462 				else
3463 					json_object_string_add(
3464 						json_interface_sub,
3465 						"localIfUsed",
3466 						inet_ntoa(dest));
3467 			} else
3468 				vty_out(vty, " %s %s,", dstr,
3469 					inet_ntoa(dest));
3470 		}
3471 		if (use_json) {
3472 			json_object_string_add(json_interface_sub, "area",
3473 					       ospf_area_desc_string(oi->area));
3474 			if (OSPF_IF_PARAM(oi, mtu_ignore))
3475 				json_object_boolean_true_add(
3476 					json_interface_sub,
3477 					"mtuMismatchDetect");
3478 			json_object_string_add(json_interface_sub, "routerId",
3479 					       inet_ntoa(ospf->router_id));
3480 			json_object_string_add(json_interface_sub,
3481 					       "networkType",
3482 					       ospf_network_type_str[oi->type]);
3483 			json_object_int_add(json_interface_sub, "cost",
3484 					    oi->output_cost);
3485 			json_object_int_add(
3486 				json_interface_sub, "transmitDelaySecs",
3487 				OSPF_IF_PARAM(oi, transmit_delay));
3488 			json_object_string_add(json_interface_sub, "state",
3489 					       lookup_msg(ospf_ism_state_msg,
3490 							  oi->state, NULL));
3491 			json_object_int_add(json_interface_sub, "priority",
3492 					    PRIORITY(oi));
3493 		} else {
3494 			vty_out(vty, " Area %s\n",
3495 				ospf_area_desc_string(oi->area));
3496 
3497 			vty_out(vty, "  MTU mismatch detection: %s\n",
3498 				OSPF_IF_PARAM(oi, mtu_ignore) ? "disabled"
3499 							      : "enabled");
3500 
3501 			vty_out(vty,
3502 				"  Router ID %s, Network Type %s, Cost: %d\n",
3503 				inet_ntoa(ospf->router_id),
3504 				ospf_network_type_str[oi->type],
3505 				oi->output_cost);
3506 
3507 			vty_out(vty,
3508 				"  Transmit Delay is %d sec, State %s, Priority %d\n",
3509 				OSPF_IF_PARAM(oi, transmit_delay),
3510 				lookup_msg(ospf_ism_state_msg, oi->state, NULL),
3511 				PRIORITY(oi));
3512 		}
3513 
3514 		/* Show DR information. */
3515 		if (DR(oi).s_addr == INADDR_ANY) {
3516 			if (!use_json)
3517 				vty_out(vty,
3518 					"  No backup designated router on this network\n");
3519 		} else {
3520 			nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &BDR(oi));
3521 			if (nbr == NULL) {
3522 				if (!use_json)
3523 					vty_out(vty,
3524 						"  No backup designated router on this network\n");
3525 			} else {
3526 				if (use_json) {
3527 					json_object_string_add(
3528 						json_interface_sub, "bdrId",
3529 						inet_ntoa(nbr->router_id));
3530 					json_object_string_add(
3531 						json_interface_sub,
3532 						"bdrAddress",
3533 						inet_ntoa(nbr->address.u
3534 								  .prefix4));
3535 				} else {
3536 					vty_out(vty,
3537 						"  Backup Designated Router (ID) %s,",
3538 						inet_ntoa(nbr->router_id));
3539 					vty_out(vty, " Interface Address %s\n",
3540 						inet_ntoa(nbr->address.u
3541 								  .prefix4));
3542 				}
3543 			}
3544 		}
3545 
3546 		/* Next network-LSA sequence number we'll use, if we're elected
3547 		 * DR */
3548 		if (oi->params
3549 		    && ntohl(oi->params->network_lsa_seqnum)
3550 			       != OSPF_INITIAL_SEQUENCE_NUMBER) {
3551 			if (use_json)
3552 				json_object_int_add(
3553 					json_interface_sub,
3554 					"networkLsaSequence",
3555 					ntohl(oi->params->network_lsa_seqnum));
3556 			else
3557 				vty_out(vty,
3558 					"  Saved Network-LSA sequence number 0x%x\n",
3559 					ntohl(oi->params->network_lsa_seqnum));
3560 		}
3561 
3562 		if (use_json) {
3563 			if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
3564 			    || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) {
3565 				if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
3566 					json_object_boolean_true_add(
3567 						json_interface_sub,
3568 						"mcastMemberOspfAllRouters");
3569 				if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
3570 					json_object_boolean_true_add(
3571 						json_interface_sub,
3572 						"mcastMemberOspfDesignatedRouters");
3573 			}
3574 		} else {
3575 			vty_out(vty, "  Multicast group memberships:");
3576 			if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
3577 			    || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) {
3578 				if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
3579 					vty_out(vty, " OSPFAllRouters");
3580 				if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
3581 					vty_out(vty, " OSPFDesignatedRouters");
3582 			} else
3583 				vty_out(vty, " <None>");
3584 			vty_out(vty, "\n");
3585 		}
3586 
3587 		if (use_json) {
3588 			if (OSPF_IF_PARAM(oi, fast_hello) == 0)
3589 				json_object_int_add(
3590 					json_interface_sub, "timerMsecs",
3591 					OSPF_IF_PARAM(oi, v_hello) * 1000);
3592 			else
3593 				json_object_int_add(
3594 					json_interface_sub, "timerMsecs",
3595 					1000 / OSPF_IF_PARAM(oi, fast_hello));
3596 			json_object_int_add(json_interface_sub,
3597 					    "timerDeadSecs",
3598 					    OSPF_IF_PARAM(oi, v_wait));
3599 			json_object_int_add(json_interface_sub,
3600 					    "timerWaitSecs",
3601 					    OSPF_IF_PARAM(oi, v_wait));
3602 			json_object_int_add(
3603 				json_interface_sub, "timerRetransmitSecs",
3604 				OSPF_IF_PARAM(oi, retransmit_interval));
3605 		} else {
3606 			vty_out(vty, "  Timer intervals configured,");
3607 			vty_out(vty, " Hello ");
3608 			if (OSPF_IF_PARAM(oi, fast_hello) == 0)
3609 				vty_out(vty, "%ds,",
3610 					OSPF_IF_PARAM(oi, v_hello));
3611 			else
3612 				vty_out(vty, "%dms,",
3613 					1000 / OSPF_IF_PARAM(oi, fast_hello));
3614 			vty_out(vty, " Dead %ds, Wait %ds, Retransmit %d\n",
3615 				OSPF_IF_PARAM(oi, v_wait),
3616 				OSPF_IF_PARAM(oi, v_wait),
3617 				OSPF_IF_PARAM(oi, retransmit_interval));
3618 		}
3619 
3620 		if (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE) {
3621 			char timebuf[OSPF_TIME_DUMP_SIZE];
3622 			if (use_json) {
3623 				long time_store = 0;
3624 				if (oi->t_hello)
3625 					time_store =
3626 						monotime_until(
3627 							&oi->t_hello->u.sands,
3628 							NULL)
3629 						/ 1000LL;
3630 				json_object_int_add(json_interface_sub,
3631 						    "timerHelloInMsecs",
3632 						    time_store);
3633 			} else
3634 				vty_out(vty, "    Hello due in %s\n",
3635 					ospf_timer_dump(oi->t_hello, timebuf,
3636 							sizeof(timebuf)));
3637 		} else /* passive-interface is set */
3638 		{
3639 			if (use_json)
3640 				json_object_boolean_true_add(
3641 					json_interface_sub,
3642 					"timerPassiveIface");
3643 			else
3644 				vty_out(vty,
3645 					"    No Hellos (Passive interface)\n");
3646 		}
3647 
3648 		if (use_json) {
3649 			json_object_int_add(json_interface_sub, "nbrCount",
3650 					    ospf_nbr_count(oi, 0));
3651 			json_object_int_add(json_interface_sub,
3652 					    "nbrAdjacentCount",
3653 					    ospf_nbr_count(oi, NSM_Full));
3654 		} else
3655 			vty_out(vty,
3656 				"  Neighbor Count is %d, Adjacent neighbor count is %d\n",
3657 				ospf_nbr_count(oi, 0),
3658 				ospf_nbr_count(oi, NSM_Full));
3659 		ospf_bfd_interface_show(vty, ifp, json_interface_sub, use_json);
3660 	}
3661 }
3662 
show_ip_ospf_interface_common(struct vty * vty,struct ospf * ospf,char * intf_name,uint8_t use_vrf,json_object * json,bool use_json)3663 static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
3664 					 char *intf_name, uint8_t use_vrf,
3665 					 json_object *json, bool use_json)
3666 {
3667 	struct interface *ifp;
3668 	struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
3669 	json_object *json_vrf = NULL;
3670 	json_object *json_interface_sub = NULL, *json_interface = NULL;
3671 
3672 	if (use_json) {
3673 		if (use_vrf)
3674 			json_vrf = json_object_new_object();
3675 		else
3676 			json_vrf = json;
3677 		json_interface = json_object_new_object();
3678 	}
3679 
3680 	if (ospf->instance) {
3681 		if (use_json)
3682 			json_object_int_add(json, "ospfInstance",
3683 					    ospf->instance);
3684 		else
3685 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
3686 	}
3687 
3688 	ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
3689 
3690 	if (intf_name == NULL) {
3691 		/* Show All Interfaces.*/
3692 		FOR_ALL_INTERFACES (vrf, ifp) {
3693 			if (ospf_oi_count(ifp)) {
3694 				if (use_json) {
3695 					json_interface_sub =
3696 						json_object_new_object();
3697 				}
3698 				show_ip_ospf_interface_sub(vty, ospf, ifp,
3699 							   json_interface_sub,
3700 							   use_json);
3701 
3702 				if (use_json) {
3703 					json_object_object_add(
3704 						json_interface, ifp->name,
3705 						json_interface_sub);
3706 				}
3707 			}
3708 		}
3709 		if (use_json)
3710 			json_object_object_add(json_vrf, "interfaces",
3711 					       json_interface);
3712 	} else {
3713 		/* Interface name is specified. */
3714 		ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
3715 		if (ifp == NULL) {
3716 			if (use_json)
3717 				json_object_boolean_true_add(json_vrf,
3718 							     "noSuchIface");
3719 			else
3720 				vty_out(vty, "No such interface name\n");
3721 		} else {
3722 			if (use_json) {
3723 				json_interface_sub = json_object_new_object();
3724 				json_interface = json_object_new_object();
3725 			}
3726 
3727 			show_ip_ospf_interface_sub(
3728 				vty, ospf, ifp, json_interface_sub, use_json);
3729 
3730 			if (use_json) {
3731 				json_object_object_add(json_interface,
3732 						       ifp->name,
3733 						       json_interface_sub);
3734 				json_object_object_add(json_vrf, "interfaces",
3735 						       json_interface);
3736 			}
3737 		}
3738 	}
3739 
3740 	if (use_json) {
3741 		if (use_vrf) {
3742 			if (ospf->vrf_id == VRF_DEFAULT)
3743 				json_object_object_add(json, "default",
3744 						       json_vrf);
3745 			else
3746 				json_object_object_add(json, ospf->name,
3747 						       json_vrf);
3748 		}
3749 	} else
3750 		vty_out(vty, "\n");
3751 
3752 	return CMD_SUCCESS;
3753 }
3754 
show_ip_ospf_interface_traffic_sub(struct vty * vty,struct ospf_interface * oi,json_object * json_interface_sub,bool use_json)3755 static void show_ip_ospf_interface_traffic_sub(struct vty *vty,
3756 					       struct ospf_interface *oi,
3757 					       json_object *json_interface_sub,
3758 					       bool use_json)
3759 {
3760 	if (use_json) {
3761 		json_object_int_add(json_interface_sub, "ifIndex",
3762 				    oi->ifp->ifindex);
3763 		json_object_int_add(json_interface_sub, "helloIn",
3764 				    oi->hello_in);
3765 		json_object_int_add(json_interface_sub, "helloOut",
3766 				    oi->hello_out);
3767 		json_object_int_add(json_interface_sub, "dbDescIn",
3768 				    oi->db_desc_in);
3769 		json_object_int_add(json_interface_sub, "dbDescOut",
3770 				    oi->db_desc_out);
3771 		json_object_int_add(json_interface_sub, "lsReqIn",
3772 				    oi->ls_req_in);
3773 		json_object_int_add(json_interface_sub, "lsReqOut",
3774 				    oi->ls_req_out);
3775 		json_object_int_add(json_interface_sub, "lsUpdIn",
3776 				    oi->ls_upd_in);
3777 		json_object_int_add(json_interface_sub, "lsUpdOut",
3778 				    oi->ls_upd_out);
3779 		json_object_int_add(json_interface_sub, "lsAckIn",
3780 				    oi->ls_ack_in);
3781 		json_object_int_add(json_interface_sub, "lsAckOut",
3782 				    oi->ls_ack_out);
3783 	} else {
3784 		vty_out(vty,
3785 			"%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
3786 			oi->ifp->name, oi->hello_in, oi->hello_out,
3787 			oi->db_desc_in, oi->db_desc_out, oi->ls_req_in,
3788 			oi->ls_req_out, oi->ls_upd_in, oi->ls_upd_out,
3789 			oi->ls_ack_in, oi->ls_ack_out);
3790 	}
3791 }
3792 
3793 /* OSPFv2 Packet Counters */
show_ip_ospf_interface_traffic_common(struct vty * vty,struct ospf * ospf,char * intf_name,json_object * json,int display_once,uint8_t use_vrf,bool use_json)3794 static int show_ip_ospf_interface_traffic_common(
3795 	struct vty *vty, struct ospf *ospf, char *intf_name, json_object *json,
3796 	int display_once, uint8_t use_vrf, bool use_json)
3797 {
3798 	struct vrf *vrf = NULL;
3799 	struct interface *ifp = NULL;
3800 	json_object *json_vrf = NULL;
3801 	json_object *json_interface_sub = NULL;
3802 
3803 	if (!use_json && !display_once) {
3804 		vty_out(vty, "\n");
3805 		vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
3806 			"    HELLO", "    DB-Desc", "   LS-Req", "   LS-Update",
3807 			"   LS-Ack");
3808 		vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
3809 			"      Rx/Tx", "     Rx/Tx", "    Rx/Tx", "    Rx/Tx",
3810 			"    Rx/Tx");
3811 		vty_out(vty,
3812 			"--------------------------------------------------------------------------------------------\n");
3813 	} else if (use_json) {
3814 		if (use_vrf)
3815 			json_vrf = json_object_new_object();
3816 		else
3817 			json_vrf = json;
3818 	}
3819 
3820 	ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
3821 
3822 	if (intf_name == NULL) {
3823 		vrf = vrf_lookup_by_id(ospf->vrf_id);
3824 		FOR_ALL_INTERFACES (vrf, ifp) {
3825 			struct route_node *rn;
3826 			struct ospf_interface *oi;
3827 
3828 			if (ospf_oi_count(ifp) == 0)
3829 				continue;
3830 
3831 			for (rn = route_top(IF_OIFS(ifp)); rn;
3832 			     rn = route_next(rn)) {
3833 				oi = rn->info;
3834 
3835 				if (oi == NULL)
3836 					continue;
3837 
3838 				if (use_json) {
3839 					json_interface_sub =
3840 						json_object_new_object();
3841 				}
3842 
3843 				show_ip_ospf_interface_traffic_sub(
3844 					vty, oi, json_interface_sub, use_json);
3845 				if (use_json) {
3846 					json_object_object_add(
3847 						json_vrf, ifp->name,
3848 						json_interface_sub);
3849 				}
3850 			}
3851 		}
3852 	} else {
3853 		/* Interface name is specified. */
3854 		ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
3855 		if (ifp != NULL) {
3856 			struct route_node *rn;
3857 			struct ospf_interface *oi;
3858 
3859 			if (ospf_oi_count(ifp) == 0) {
3860 				vty_out(vty,
3861 					"  OSPF not enabled on this interface %s\n",
3862 					ifp->name);
3863 				return CMD_SUCCESS;
3864 			}
3865 
3866 			for (rn = route_top(IF_OIFS(ifp)); rn;
3867 			     rn = route_next(rn)) {
3868 				oi = rn->info;
3869 
3870 				if (use_json) {
3871 					json_interface_sub =
3872 						json_object_new_object();
3873 				}
3874 
3875 				show_ip_ospf_interface_traffic_sub(
3876 					vty, oi, json_interface_sub, use_json);
3877 				if (use_json) {
3878 					json_object_object_add(
3879 						json_vrf, ifp->name,
3880 						json_interface_sub);
3881 				}
3882 			}
3883 		}
3884 	}
3885 
3886 	if (use_json) {
3887 		if (use_vrf) {
3888 			if (ospf->vrf_id == VRF_DEFAULT)
3889 				json_object_object_add(json, "default",
3890 						       json_vrf);
3891 			else
3892 				json_object_object_add(json, ospf->name,
3893 						       json_vrf);
3894 		}
3895 	} else
3896 		vty_out(vty, "\n");
3897 
3898 	return CMD_SUCCESS;
3899 }
3900 
3901 DEFUN (show_ip_ospf_interface,
3902        show_ip_ospf_interface_cmd,
3903        "show ip ospf [vrf <NAME|all>] interface [INTERFACE] [json]",
3904        SHOW_STR
3905        IP_STR
3906        "OSPF information\n"
3907        VRF_CMD_HELP_STR
3908        "All VRFs\n"
3909        "Interface information\n"
3910        "Interface name\n"
3911        JSON_STR)
3912 {
3913 	struct ospf *ospf;
3914 	bool uj = use_json(argc, argv);
3915 	struct listnode *node = NULL;
3916 	char *vrf_name = NULL, *intf_name = NULL;
3917 	bool all_vrf = false;
3918 	int ret = CMD_SUCCESS;
3919 	int inst = 0;
3920 	int idx_vrf = 0, idx_intf = 0;
3921 	uint8_t use_vrf = 0;
3922 	json_object *json = NULL;
3923 
3924 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
3925 
3926 	if (argv_find(argv, argc, "INTERFACE", &idx_intf))
3927 		intf_name = argv[idx_intf]->arg;
3928 
3929 	if (uj)
3930 		json = json_object_new_object();
3931 
3932 	/* vrf input is provided could be all or specific vrf*/
3933 	if (vrf_name) {
3934 		use_vrf = 1;
3935 		if (all_vrf) {
3936 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
3937 				if (!ospf->oi_running)
3938 					continue;
3939 				ret = show_ip_ospf_interface_common(
3940 					vty, ospf, intf_name, use_vrf, json,
3941 					uj);
3942 			}
3943 
3944 			if (uj) {
3945 				vty_out(vty, "%s\n",
3946 					json_object_to_json_string_ext(
3947 						json, JSON_C_TO_STRING_PRETTY));
3948 				json_object_free(json);
3949 			} else if (!ospf)
3950 				vty_out(vty, "%% OSPF instance not found\n");
3951 
3952 			return ret;
3953 		}
3954 		ospf = ospf_lookup_by_inst_name(inst, vrf_name);
3955 		if (ospf == NULL || !ospf->oi_running) {
3956 			if (uj) {
3957 				vty_out(vty, "%s\n",
3958 					json_object_to_json_string_ext(
3959 						json, JSON_C_TO_STRING_PRETTY));
3960 				json_object_free(json);
3961 			} else
3962 				vty_out(vty, "%% OSPF instance not found\n");
3963 
3964 			return CMD_SUCCESS;
3965 		}
3966 		ret = show_ip_ospf_interface_common(vty, ospf, intf_name,
3967 						    use_vrf, json, uj);
3968 
3969 	} else {
3970 		/* Display default ospf (instance 0) info */
3971 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
3972 		if (ospf == NULL || !ospf->oi_running) {
3973 			if (uj) {
3974 				vty_out(vty, "%s\n",
3975 					json_object_to_json_string_ext(
3976 						json, JSON_C_TO_STRING_PRETTY));
3977 				json_object_free(json);
3978 			} else
3979 				vty_out(vty, "%% OSPF instance not found\n");
3980 
3981 			return CMD_SUCCESS;
3982 		}
3983 		ret = show_ip_ospf_interface_common(vty, ospf, intf_name,
3984 						    use_vrf, json, uj);
3985 	}
3986 
3987 	if (uj) {
3988 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
3989 					     json, JSON_C_TO_STRING_PRETTY));
3990 		json_object_free(json);
3991 	}
3992 
3993 	return ret;
3994 }
3995 
3996 DEFUN (show_ip_ospf_instance_interface,
3997        show_ip_ospf_instance_interface_cmd,
3998        "show ip ospf (1-65535) interface [INTERFACE] [json]",
3999        SHOW_STR
4000        IP_STR
4001        "OSPF information\n"
4002        "Instance ID\n"
4003        "Interface information\n"
4004        "Interface name\n"
4005        JSON_STR)
4006 {
4007 	int idx_number = 3;
4008 	int idx_intf = 0;
4009 	struct ospf *ospf;
4010 	unsigned short instance = 0;
4011 	bool uj = use_json(argc, argv);
4012 	char *intf_name = NULL;
4013 	int ret = CMD_SUCCESS;
4014 	json_object *json = NULL;
4015 
4016 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
4017 	ospf = ospf_lookup_instance(instance);
4018 	if (ospf == NULL)
4019 		return CMD_NOT_MY_INSTANCE;
4020 
4021 	if (!ospf->oi_running)
4022 		return CMD_SUCCESS;
4023 
4024 	if (uj)
4025 		json = json_object_new_object();
4026 
4027 	if (argv_find(argv, argc, "INTERFACE", &idx_intf))
4028 		intf_name = argv[idx_intf]->arg;
4029 
4030 	ret = show_ip_ospf_interface_common(vty, ospf, intf_name, 0, json, uj);
4031 
4032 	if (uj) {
4033 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
4034 					     json, JSON_C_TO_STRING_PRETTY));
4035 		json_object_free(json);
4036 	}
4037 
4038 	return ret;
4039 }
4040 
4041 DEFUN (show_ip_ospf_interface_traffic,
4042        show_ip_ospf_interface_traffic_cmd,
4043        "show ip ospf [vrf <NAME|all>] interface traffic [INTERFACE] [json]",
4044        SHOW_STR
4045        IP_STR
4046        "OSPF information\n"
4047        VRF_CMD_HELP_STR
4048        "All VRFs\n"
4049        "Interface information\n"
4050        "Protocol Packet counters\n"
4051        "Interface name\n"
4052        JSON_STR)
4053 {
4054 	struct ospf *ospf = NULL;
4055 	struct listnode *node = NULL;
4056 	char *vrf_name = NULL, *intf_name = NULL;
4057 	bool all_vrf = false;
4058 	int inst = 0;
4059 	int idx_vrf = 0, idx_intf = 0;
4060 	bool uj = use_json(argc, argv);
4061 	json_object *json = NULL;
4062 	int ret = CMD_SUCCESS;
4063 	int display_once = 0;
4064 	uint8_t use_vrf = 0;
4065 
4066 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
4067 
4068 	if (argv_find(argv, argc, "INTERFACE", &idx_intf))
4069 		intf_name = argv[idx_intf]->arg;
4070 
4071 	if (uj)
4072 		json = json_object_new_object();
4073 
4074 	if (vrf_name) {
4075 		use_vrf = 1;
4076 		if (all_vrf) {
4077 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
4078 				if (!ospf->oi_running)
4079 					continue;
4080 
4081 				ret = show_ip_ospf_interface_traffic_common(
4082 					vty, ospf, intf_name, json,
4083 					display_once, use_vrf, uj);
4084 				display_once = 1;
4085 			}
4086 
4087 			if (uj) {
4088 				vty_out(vty, "%s\n",
4089 					json_object_to_json_string_ext(
4090 						json, JSON_C_TO_STRING_PRETTY));
4091 				json_object_free(json);
4092 			}
4093 
4094 			return ret;
4095 		}
4096 		ospf = ospf_lookup_by_inst_name(inst, vrf_name);
4097 		if (ospf == NULL || !ospf->oi_running) {
4098 			if (uj)
4099 				json_object_free(json);
4100 			return CMD_SUCCESS;
4101 		}
4102 
4103 		ret = show_ip_ospf_interface_traffic_common(
4104 			vty, ospf, intf_name, json, display_once, use_vrf, uj);
4105 	} else {
4106 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
4107 		if (ospf == NULL || !ospf->oi_running) {
4108 			if (uj)
4109 				json_object_free(json);
4110 			return CMD_SUCCESS;
4111 		}
4112 
4113 		ret = show_ip_ospf_interface_traffic_common(
4114 			vty, ospf, intf_name, json, display_once, use_vrf, uj);
4115 	}
4116 
4117 	if (uj) {
4118 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
4119 					     json, JSON_C_TO_STRING_PRETTY));
4120 		json_object_free(json);
4121 	}
4122 
4123 	return ret;
4124 }
4125 
4126 
show_ip_ospf_neighbour_header(struct vty * vty)4127 static void show_ip_ospf_neighbour_header(struct vty *vty)
4128 {
4129 	vty_out(vty, "\n%-15s %3s %-15s %9s %-15s %-32s %5s %5s %5s\n",
4130 		"Neighbor ID", "Pri", "State", "Dead Time", "Address",
4131 		"Interface", "RXmtL", "RqstL", "DBsmL");
4132 }
4133 
show_ip_ospf_neighbor_sub(struct vty * vty,struct ospf_interface * oi,json_object * json,bool use_json)4134 static void show_ip_ospf_neighbor_sub(struct vty *vty,
4135 				      struct ospf_interface *oi,
4136 				      json_object *json, bool use_json)
4137 {
4138 	struct route_node *rn;
4139 	struct ospf_neighbor *nbr, *prev_nbr = NULL;
4140 	char msgbuf[16];
4141 	char timebuf[OSPF_TIME_DUMP_SIZE];
4142 	json_object *json_neighbor = NULL, *json_neigh_array = NULL;
4143 
4144 	for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
4145 		if ((nbr = rn->info)) {
4146 			/* Do not show myself. */
4147 			if (nbr == oi->nbr_self)
4148 				continue;
4149 			/* Down state is not shown. */
4150 			if (nbr->state == NSM_Down)
4151 				continue;
4152 			if (use_json) {
4153 				char neigh_str[INET_ADDRSTRLEN];
4154 
4155 				if (prev_nbr
4156 				    && !IPV4_ADDR_SAME(&prev_nbr->src,
4157 						       &nbr->src)) {
4158 					/* Start new neigh list */
4159 					json_neigh_array = NULL;
4160 				}
4161 
4162 				if (nbr->state == NSM_Attempt
4163 				    && nbr->router_id.s_addr == INADDR_ANY)
4164 					strlcpy(neigh_str, "neighbor",
4165 						sizeof(neigh_str));
4166 				else
4167 					strlcpy(neigh_str,
4168 						inet_ntoa(nbr->router_id),
4169 						sizeof(neigh_str));
4170 
4171 				json_object_object_get_ex(json, neigh_str,
4172 							  &json_neigh_array);
4173 
4174 				if (!json_neigh_array) {
4175 					json_neigh_array =
4176 						json_object_new_array();
4177 					json_object_object_add(
4178 						json, neigh_str,
4179 						json_neigh_array);
4180 				}
4181 
4182 				json_neighbor = json_object_new_object();
4183 
4184 				ospf_nbr_state_message(nbr, msgbuf, 16);
4185 
4186 				long time_store;
4187 
4188 				time_store =
4189 					monotime_until(
4190 						&nbr->t_inactivity->u.sands,
4191 						NULL)
4192 					/ 1000LL;
4193 
4194 				json_object_int_add(json_neighbor, "priority",
4195 						    nbr->priority);
4196 				json_object_string_add(json_neighbor, "state",
4197 						       msgbuf);
4198 				json_object_int_add(json_neighbor,
4199 						    "deadTimeMsecs",
4200 						    time_store);
4201 				json_object_string_add(json_neighbor, "address",
4202 						       inet_ntoa(nbr->src));
4203 				json_object_string_add(json_neighbor,
4204 						       "ifaceName",
4205 						       IF_NAME(oi));
4206 				json_object_int_add(
4207 					json_neighbor, "retransmitCounter",
4208 					ospf_ls_retransmit_count(nbr));
4209 				json_object_int_add(json_neighbor,
4210 						    "requestCounter",
4211 						    ospf_ls_request_count(nbr));
4212 				json_object_int_add(json_neighbor,
4213 						    "dbSummaryCounter",
4214 						    ospf_db_summary_count(nbr));
4215 
4216 				json_object_array_add(json_neigh_array,
4217 						      json_neighbor);
4218 			} else {
4219 				ospf_nbr_state_message(nbr, msgbuf, 16);
4220 
4221 				if (nbr->state == NSM_Attempt
4222 				    && nbr->router_id.s_addr == INADDR_ANY)
4223 					vty_out(vty, "%-15s %3d %-15s ", "-",
4224 						nbr->priority, msgbuf);
4225 				else
4226 					vty_out(vty, "%-15s %3d %-15s ",
4227 						inet_ntoa(nbr->router_id),
4228 						nbr->priority, msgbuf);
4229 
4230 				vty_out(vty, "%9s ",
4231 					ospf_timer_dump(nbr->t_inactivity,
4232 							timebuf,
4233 							sizeof(timebuf)));
4234 				vty_out(vty, "%-15s ", inet_ntoa(nbr->src));
4235 				vty_out(vty, "%-32s %5ld %5ld %5d\n",
4236 					IF_NAME(oi),
4237 					ospf_ls_retransmit_count(nbr),
4238 					ospf_ls_request_count(nbr),
4239 					ospf_db_summary_count(nbr));
4240 			}
4241 			prev_nbr = nbr;
4242 		}
4243 	}
4244 }
4245 
show_ip_ospf_neighbor_common(struct vty * vty,struct ospf * ospf,json_object * json,bool use_json,uint8_t use_vrf)4246 static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf,
4247 					json_object *json, bool use_json,
4248 					uint8_t use_vrf)
4249 {
4250 	struct ospf_interface *oi;
4251 	struct listnode *node;
4252 	json_object *json_vrf = NULL;
4253 	json_object *json_nbr_sub = NULL;
4254 
4255 	if (use_json) {
4256 		if (use_vrf)
4257 			json_vrf = json_object_new_object();
4258 		else
4259 			json_vrf = json;
4260 		json_nbr_sub = json_object_new_object();
4261 	}
4262 
4263 	if (ospf->instance) {
4264 		if (use_json)
4265 			json_object_int_add(json, "ospfInstance",
4266 					    ospf->instance);
4267 		else
4268 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
4269 	}
4270 
4271 	ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
4272 	if (!use_json)
4273 		show_ip_ospf_neighbour_header(vty);
4274 
4275 	for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
4276 		if (ospf_interface_neighbor_count(oi) == 0)
4277 			continue;
4278 		show_ip_ospf_neighbor_sub(vty, oi, json_nbr_sub, use_json);
4279 	}
4280 
4281 	if (use_json) {
4282 		json_object_object_add(json_vrf, "neighbors", json_nbr_sub);
4283 		if (use_vrf) {
4284 			if (ospf->vrf_id == VRF_DEFAULT)
4285 				json_object_object_add(json, "default",
4286 						       json_vrf);
4287 			else
4288 				json_object_object_add(json, ospf->name,
4289 						       json_vrf);
4290 		}
4291 	} else
4292 		vty_out(vty, "\n");
4293 
4294 	return CMD_SUCCESS;
4295 }
4296 
4297 DEFUN (show_ip_ospf_neighbor,
4298        show_ip_ospf_neighbor_cmd,
4299        "show ip ospf [vrf <NAME|all>] neighbor [json]",
4300        SHOW_STR
4301        IP_STR
4302        "OSPF information\n"
4303        VRF_CMD_HELP_STR
4304        "All VRFs\n"
4305        "Neighbor list\n"
4306        JSON_STR)
4307 {
4308 	struct ospf *ospf;
4309 	bool uj = use_json(argc, argv);
4310 	struct listnode *node = NULL;
4311 	char *vrf_name = NULL;
4312 	bool all_vrf = false;
4313 	int ret = CMD_SUCCESS;
4314 	int inst = 0;
4315 	int idx_vrf = 0;
4316 	uint8_t use_vrf = 0;
4317 	json_object *json = NULL;
4318 
4319 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
4320 
4321 	if (uj)
4322 		json = json_object_new_object();
4323 
4324 	/* vrf input is provided could be all or specific vrf*/
4325 	if (vrf_name) {
4326 		use_vrf = 1;
4327 		if (all_vrf) {
4328 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
4329 				if (!ospf->oi_running)
4330 					continue;
4331 				ret = show_ip_ospf_neighbor_common(
4332 					vty, ospf, json, uj, use_vrf);
4333 			}
4334 
4335 			if (uj) {
4336 				vty_out(vty, "%s\n",
4337 					json_object_to_json_string_ext(
4338 						json, JSON_C_TO_STRING_PRETTY));
4339 				json_object_free(json);
4340 			} else if (!ospf)
4341 				vty_out(vty, "OSPF instance not found\n");
4342 
4343 			return ret;
4344 		}
4345 
4346 		ospf = ospf_lookup_by_inst_name(inst, vrf_name);
4347 		if (ospf == NULL || !ospf->oi_running) {
4348 			if (uj) {
4349 				vty_out(vty, "%s\n",
4350 					json_object_to_json_string_ext(
4351 						json, JSON_C_TO_STRING_PRETTY));
4352 				json_object_free(json);
4353 			} else
4354 				vty_out(vty, "%% OSPF instance not found\n");
4355 
4356 			return CMD_SUCCESS;
4357 		}
4358 	} else {
4359 		/* Display default ospf (instance 0) info */
4360 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
4361 		if (ospf == NULL || !ospf->oi_running) {
4362 			if (uj) {
4363 				vty_out(vty, "%s\n",
4364 					json_object_to_json_string_ext(
4365 						json, JSON_C_TO_STRING_PRETTY));
4366 				json_object_free(json);
4367 			} else
4368 				vty_out(vty, "%% OSPF instance not found\n");
4369 
4370 			return CMD_SUCCESS;
4371 		}
4372 	}
4373 
4374 	if (ospf) {
4375 		ret = show_ip_ospf_neighbor_common(vty, ospf, json, uj,
4376 						   use_vrf);
4377 
4378 		if (uj) {
4379 			vty_out(vty, "%s\n",
4380 				json_object_to_json_string_ext(
4381 					json, JSON_C_TO_STRING_PRETTY));
4382 		}
4383 	}
4384 
4385 	if (uj)
4386 		json_object_free(json);
4387 
4388 	return ret;
4389 }
4390 
4391 
4392 DEFUN (show_ip_ospf_instance_neighbor,
4393        show_ip_ospf_instance_neighbor_cmd,
4394        "show ip ospf (1-65535) neighbor [json]",
4395        SHOW_STR
4396        IP_STR
4397        "OSPF information\n"
4398        "Instance ID\n"
4399        "Neighbor list\n"
4400        JSON_STR)
4401 {
4402 	int idx_number = 3;
4403 	struct ospf *ospf;
4404 	unsigned short instance = 0;
4405 	bool uj = use_json(argc, argv);
4406 	json_object *json = NULL;
4407 	int ret = CMD_SUCCESS;
4408 
4409 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
4410 	ospf = ospf_lookup_instance(instance);
4411 	if (ospf == NULL)
4412 		return CMD_NOT_MY_INSTANCE;
4413 
4414 	if (!ospf->oi_running)
4415 		return CMD_SUCCESS;
4416 
4417 	if (uj)
4418 		json = json_object_new_object();
4419 
4420 	ret = show_ip_ospf_neighbor_common(vty, ospf, json, uj, 0);
4421 
4422 	if (uj) {
4423 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
4424 					     json, JSON_C_TO_STRING_PRETTY));
4425 		json_object_free(json);
4426 	}
4427 
4428 	return ret;
4429 }
4430 
show_ip_ospf_neighbor_all_common(struct vty * vty,struct ospf * ospf,json_object * json,bool use_json,uint8_t use_vrf)4431 static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
4432 					    json_object *json, bool use_json,
4433 					    uint8_t use_vrf)
4434 {
4435 	struct listnode *node;
4436 	struct ospf_interface *oi;
4437 	json_object *json_vrf = NULL;
4438 	json_object *json_neighbor_sub = NULL;
4439 
4440 	if (use_json) {
4441 		if (use_vrf)
4442 			json_vrf = json_object_new_object();
4443 		else
4444 			json_vrf = json;
4445 		json_neighbor_sub = json_object_new_object();
4446 	}
4447 
4448 	ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
4449 	if (!use_json)
4450 		show_ip_ospf_neighbour_header(vty);
4451 
4452 	if (ospf->instance) {
4453 		if (use_json)
4454 			json_object_int_add(json_vrf, "ospfInstance",
4455 					    ospf->instance);
4456 		else
4457 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
4458 	}
4459 
4460 	for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
4461 		struct listnode *nbr_node;
4462 		struct ospf_nbr_nbma *nbr_nbma;
4463 
4464 		show_ip_ospf_neighbor_sub(vty, oi, json_vrf, use_json);
4465 
4466 		/* print Down neighbor status */
4467 		for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, nbr_node, nbr_nbma)) {
4468 			if (nbr_nbma->nbr == NULL
4469 			    || nbr_nbma->nbr->state == NSM_Down) {
4470 				if (use_json) {
4471 					json_object_int_add(json_neighbor_sub,
4472 							    "nbrNbmaPriority",
4473 							    nbr_nbma->priority);
4474 					json_object_boolean_true_add(
4475 						json_neighbor_sub,
4476 						"nbrNbmaDown");
4477 					json_object_string_add(
4478 						json_neighbor_sub,
4479 						"nbrNbmaIfaceName",
4480 						IF_NAME(oi));
4481 					json_object_int_add(
4482 						json_neighbor_sub,
4483 						"nbrNbmaRetransmitCounter", 0);
4484 					json_object_int_add(
4485 						json_neighbor_sub,
4486 						"nbrNbmaRequestCounter", 0);
4487 					json_object_int_add(
4488 						json_neighbor_sub,
4489 						"nbrNbmaDbSummaryCounter", 0);
4490 					json_object_object_add(
4491 						json_vrf,
4492 						inet_ntoa(nbr_nbma->addr),
4493 						json_neighbor_sub);
4494 				} else {
4495 					vty_out(vty, "%-15s %3d %-15s %9s ",
4496 						"-", nbr_nbma->priority, "Down",
4497 						"-");
4498 					vty_out(vty,
4499 						"%-32s %-20s %5d %5d %5d\n",
4500 						inet_ntoa(nbr_nbma->addr),
4501 						IF_NAME(oi), 0, 0, 0);
4502 				}
4503 			}
4504 		}
4505 	}
4506 
4507 	if (use_json) {
4508 		if (use_vrf) {
4509 			if (ospf->vrf_id == VRF_DEFAULT)
4510 				json_object_object_add(json, "default",
4511 						       json_vrf);
4512 			else
4513 				json_object_object_add(json, ospf->name,
4514 						       json_vrf);
4515 		}
4516 	} else
4517 		vty_out(vty, "\n");
4518 
4519 	return CMD_SUCCESS;
4520 }
4521 
4522 DEFUN (show_ip_ospf_neighbor_all,
4523        show_ip_ospf_neighbor_all_cmd,
4524        "show ip ospf [vrf <NAME|all>] neighbor all [json]",
4525        SHOW_STR
4526        IP_STR
4527        "OSPF information\n"
4528        VRF_CMD_HELP_STR
4529        "All VRFs\n"
4530        "Neighbor list\n"
4531        "include down status neighbor\n"
4532        JSON_STR)
4533 {
4534 	struct ospf *ospf;
4535 	bool uj = use_json(argc, argv);
4536 	struct listnode *node = NULL;
4537 	char *vrf_name = NULL;
4538 	bool all_vrf = false;
4539 	int ret = CMD_SUCCESS;
4540 	int inst = 0;
4541 	int idx_vrf = 0;
4542 	uint8_t use_vrf = 0;
4543 	json_object *json = NULL;
4544 
4545 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
4546 
4547 	if (uj)
4548 		json = json_object_new_object();
4549 
4550 	/* vrf input is provided could be all or specific vrf*/
4551 	if (vrf_name) {
4552 		use_vrf = 1;
4553 		if (all_vrf) {
4554 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
4555 				if (!ospf->oi_running)
4556 					continue;
4557 				ret = show_ip_ospf_neighbor_all_common(
4558 					vty, ospf, json, uj, use_vrf);
4559 			}
4560 
4561 			if (uj) {
4562 				vty_out(vty, "%s\n",
4563 					json_object_to_json_string_ext(
4564 						json, JSON_C_TO_STRING_PRETTY));
4565 				json_object_free(json);
4566 			}
4567 
4568 			return ret;
4569 		}
4570 
4571 		ospf = ospf_lookup_by_inst_name(inst, vrf_name);
4572 		if (ospf == NULL || !ospf->oi_running) {
4573 			if (uj)
4574 				json_object_free(json);
4575 			return CMD_SUCCESS;
4576 		}
4577 	} else {
4578 		/* Display default ospf (instance 0) info */
4579 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
4580 		if (ospf == NULL || !ospf->oi_running) {
4581 			if (uj)
4582 				json_object_free(json);
4583 			return CMD_SUCCESS;
4584 		}
4585 	}
4586 
4587 	if (ospf) {
4588 		ret = show_ip_ospf_neighbor_all_common(vty, ospf, json, uj,
4589 						       use_vrf);
4590 		if (uj) {
4591 			vty_out(vty, "%s\n",
4592 				json_object_to_json_string_ext(
4593 					json, JSON_C_TO_STRING_PRETTY));
4594 		}
4595 	}
4596 
4597 	if (uj)
4598 		json_object_free(json);
4599 
4600 	return ret;
4601 }
4602 
4603 DEFUN (show_ip_ospf_instance_neighbor_all,
4604        show_ip_ospf_instance_neighbor_all_cmd,
4605        "show ip ospf (1-65535) neighbor all [json]",
4606        SHOW_STR
4607        IP_STR
4608        "OSPF information\n"
4609        "Instance ID\n"
4610        "Neighbor list\n"
4611        "include down status neighbor\n"
4612        JSON_STR)
4613 {
4614 	int idx_number = 3;
4615 	struct ospf *ospf;
4616 	unsigned short instance = 0;
4617 	bool uj = use_json(argc, argv);
4618 	json_object *json = NULL;
4619 	int ret = CMD_SUCCESS;
4620 
4621 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
4622 	ospf = ospf_lookup_instance(instance);
4623 	if (ospf == NULL)
4624 		return CMD_NOT_MY_INSTANCE;
4625 
4626 	if (!ospf->oi_running)
4627 		return CMD_SUCCESS;
4628 	if (uj)
4629 		json = json_object_new_object();
4630 
4631 	ret = show_ip_ospf_neighbor_all_common(vty, ospf, json, uj, 0);
4632 
4633 	if (uj) {
4634 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
4635 					     json, JSON_C_TO_STRING_PRETTY));
4636 		json_object_free(json);
4637 	}
4638 
4639 	return ret;
4640 }
4641 
show_ip_ospf_neighbor_int_common(struct vty * vty,struct ospf * ospf,int arg_base,struct cmd_token ** argv,bool use_json,uint8_t use_vrf)4642 static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
4643 					    int arg_base,
4644 					    struct cmd_token **argv,
4645 					    bool use_json, uint8_t use_vrf)
4646 {
4647 	struct interface *ifp;
4648 	struct route_node *rn;
4649 	json_object *json = NULL;
4650 
4651 	if (use_json)
4652 		json = json_object_new_object();
4653 
4654 	if (ospf->instance) {
4655 		if (use_json)
4656 			json_object_int_add(json, "ospfInstance",
4657 					    ospf->instance);
4658 		else
4659 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
4660 	}
4661 
4662 	ospf_show_vrf_name(ospf, vty, json, use_vrf);
4663 
4664 	ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
4665 	if (!ifp) {
4666 		if (use_json)
4667 			json_object_boolean_true_add(json, "noSuchIface");
4668 		else
4669 			vty_out(vty, "No such interface.\n");
4670 		return CMD_WARNING;
4671 	}
4672 
4673 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
4674 		struct ospf_interface *oi = rn->info;
4675 
4676 		if (oi == NULL)
4677 			continue;
4678 
4679 		show_ip_ospf_neighbor_sub(vty, oi, json, use_json);
4680 	}
4681 
4682 	if (use_json) {
4683 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
4684 					     json, JSON_C_TO_STRING_PRETTY));
4685 		json_object_free(json);
4686 	} else
4687 		vty_out(vty, "\n");
4688 
4689 	return CMD_SUCCESS;
4690 }
4691 
4692 DEFUN (show_ip_ospf_neighbor_int,
4693        show_ip_ospf_neighbor_int_cmd,
4694        "show ip ospf [vrf <NAME>] neighbor IFNAME [json]",
4695        SHOW_STR
4696        IP_STR
4697        "OSPF information\n"
4698        VRF_CMD_HELP_STR
4699        "Neighbor list\n"
4700        "Interface name\n"
4701        JSON_STR)
4702 {
4703 	struct ospf *ospf;
4704 	int idx_ifname = 0;
4705 	int idx_vrf = 0;
4706 	bool uj = use_json(argc, argv);
4707 	int ret = CMD_SUCCESS;
4708 	struct interface *ifp = NULL;
4709 	char *vrf_name = NULL;
4710 	vrf_id_t vrf_id = VRF_DEFAULT;
4711 	struct vrf *vrf = NULL;
4712 
4713 	if (argv_find(argv, argc, "vrf", &idx_vrf))
4714 		vrf_name = argv[idx_vrf + 1]->arg;
4715 	if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
4716 		vrf_name = NULL;
4717 	if (vrf_name) {
4718 		vrf = vrf_lookup_by_name(vrf_name);
4719 		if (vrf)
4720 			vrf_id = vrf->vrf_id;
4721 	}
4722 	ospf = ospf_lookup_by_vrf_id(vrf_id);
4723 
4724 	if (!ospf || !ospf->oi_running)
4725 		return ret;
4726 
4727 	if (!uj)
4728 		show_ip_ospf_neighbour_header(vty);
4729 
4730 	argv_find(argv, argc, "IFNAME", &idx_ifname);
4731 
4732 	ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
4733 	if (!ifp)
4734 		return ret;
4735 
4736 	ret = show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname,
4737 					       argv, uj, 0);
4738 	return ret;
4739 }
4740 
4741 DEFUN (show_ip_ospf_instance_neighbor_int,
4742        show_ip_ospf_instance_neighbor_int_cmd,
4743        "show ip ospf (1-65535) neighbor IFNAME [json]",
4744        SHOW_STR
4745        IP_STR
4746        "OSPF information\n"
4747        "Instance ID\n"
4748        "Neighbor list\n"
4749        "Interface name\n"
4750        JSON_STR)
4751 {
4752 	int idx_number = 3;
4753 	int idx_ifname = 5;
4754 	struct ospf *ospf;
4755 	unsigned short instance = 0;
4756 	bool uj = use_json(argc, argv);
4757 
4758 	if (!uj)
4759 		show_ip_ospf_neighbour_header(vty);
4760 
4761 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
4762 	ospf = ospf_lookup_instance(instance);
4763 	if (ospf == NULL)
4764 		return CMD_NOT_MY_INSTANCE;
4765 
4766 	if (!ospf->oi_running)
4767 		return CMD_SUCCESS;
4768 
4769 	if (!uj)
4770 		show_ip_ospf_neighbour_header(vty);
4771 
4772 	return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj,
4773 						0);
4774 }
4775 
show_ip_ospf_nbr_nbma_detail_sub(struct vty * vty,struct ospf_interface * oi,struct ospf_nbr_nbma * nbr_nbma,bool use_json,json_object * json)4776 static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
4777 					     struct ospf_interface *oi,
4778 					     struct ospf_nbr_nbma *nbr_nbma,
4779 					     bool use_json, json_object *json)
4780 {
4781 	char timebuf[OSPF_TIME_DUMP_SIZE];
4782 	json_object *json_sub = NULL;
4783 
4784 	if (use_json)
4785 		json_sub = json_object_new_object();
4786 	else /* Show neighbor ID. */
4787 		vty_out(vty, " Neighbor %s,", "-");
4788 
4789 	/* Show interface address. */
4790 	if (use_json)
4791 		json_object_string_add(json_sub, "ifaceAddress",
4792 				       inet_ntoa(nbr_nbma->addr));
4793 	else
4794 		vty_out(vty, " interface address %s\n",
4795 			inet_ntoa(nbr_nbma->addr));
4796 
4797 	/* Show Area ID. */
4798 	if (use_json) {
4799 		json_object_string_add(json_sub, "areaId",
4800 				       ospf_area_desc_string(oi->area));
4801 		json_object_string_add(json_sub, "iface", IF_NAME(oi));
4802 	} else
4803 		vty_out(vty, "    In the area %s via interface %s\n",
4804 			ospf_area_desc_string(oi->area), IF_NAME(oi));
4805 
4806 	/* Show neighbor priority and state. */
4807 	if (use_json) {
4808 		json_object_int_add(json_sub, "nbrPriority",
4809 				    nbr_nbma->priority);
4810 		json_object_string_add(json_sub, "nbrState", "down");
4811 	} else
4812 		vty_out(vty, "    Neighbor priority is %d, State is %s,",
4813 			nbr_nbma->priority, "Down");
4814 
4815 	/* Show state changes. */
4816 	if (use_json)
4817 		json_object_int_add(json_sub, "stateChangeCounter",
4818 				    nbr_nbma->state_change);
4819 	else
4820 		vty_out(vty, " %d state changes\n", nbr_nbma->state_change);
4821 
4822 	/* Show PollInterval */
4823 	if (use_json)
4824 		json_object_int_add(json_sub, "pollInterval", nbr_nbma->v_poll);
4825 	else
4826 		vty_out(vty, "    Poll interval %d\n", nbr_nbma->v_poll);
4827 
4828 	/* Show poll-interval timer. */
4829 	if (nbr_nbma->t_poll) {
4830 		if (use_json) {
4831 			long time_store;
4832 			time_store = monotime_until(&nbr_nbma->t_poll->u.sands,
4833 						    NULL) / 1000LL;
4834 			json_object_int_add(json_sub,
4835 					    "pollIntervalTimerDueMsec",
4836 					    time_store);
4837 		} else
4838 			vty_out(vty, "    Poll timer due in %s\n",
4839 				ospf_timer_dump(nbr_nbma->t_poll, timebuf,
4840 						sizeof(timebuf)));
4841 	}
4842 
4843 	/* Show poll-interval timer thread. */
4844 	if (use_json) {
4845 		if (nbr_nbma->t_poll != NULL)
4846 			json_object_string_add(json_sub,
4847 					       "pollIntervalTimerThread", "on");
4848 	} else
4849 		vty_out(vty, "    Thread Poll Timer %s\n",
4850 			nbr_nbma->t_poll != NULL ? "on" : "off");
4851 
4852 	if (use_json)
4853 		json_object_object_add(json, "noNbrId", json_sub);
4854 }
4855 
show_ip_ospf_neighbor_detail_sub(struct vty * vty,struct ospf_interface * oi,struct ospf_neighbor * nbr,struct ospf_neighbor * prev_nbr,json_object * json,bool use_json)4856 static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
4857 					     struct ospf_interface *oi,
4858 					     struct ospf_neighbor *nbr,
4859 					     struct ospf_neighbor *prev_nbr,
4860 					     json_object *json, bool use_json)
4861 {
4862 	char timebuf[OSPF_TIME_DUMP_SIZE];
4863 	json_object *json_neigh = NULL, *json_neigh_array = NULL;
4864 	char neigh_str[INET_ADDRSTRLEN] = {0};
4865 
4866 	if (use_json) {
4867 		if (prev_nbr &&
4868 		    !IPV4_ADDR_SAME(&prev_nbr->src, &nbr->src)) {
4869 			json_neigh_array = NULL;
4870 		}
4871 
4872 		if (nbr->state == NSM_Attempt
4873 		    && nbr->router_id.s_addr == INADDR_ANY)
4874 			strlcpy(neigh_str, "noNbrId", sizeof(neigh_str));
4875 		else
4876 			strlcpy(neigh_str, inet_ntoa(nbr->router_id),
4877 				sizeof(neigh_str));
4878 
4879 		json_object_object_get_ex(json, neigh_str, &json_neigh_array);
4880 
4881 		if (!json_neigh_array) {
4882 			json_neigh_array = json_object_new_array();
4883 			json_object_object_add(json, neigh_str,
4884 					       json_neigh_array);
4885 		}
4886 
4887 		json_neigh = json_object_new_object();
4888 
4889 	} else {
4890 		/* Show neighbor ID. */
4891 		if (nbr->state == NSM_Attempt
4892 		    && nbr->router_id.s_addr == INADDR_ANY)
4893 			vty_out(vty, " Neighbor %s,", "-");
4894 		else
4895 			vty_out(vty, " Neighbor %s,",
4896 				inet_ntoa(nbr->router_id));
4897 	}
4898 
4899 	/* Show interface address. */
4900 	if (use_json)
4901 		json_object_string_add(json_neigh, "ifaceAddress",
4902 				       inet_ntoa(nbr->address.u.prefix4));
4903 	else
4904 		vty_out(vty, " interface address %s\n",
4905 			inet_ntoa(nbr->address.u.prefix4));
4906 
4907 	/* Show Area ID. */
4908 	if (use_json) {
4909 		json_object_string_add(json_neigh, "areaId",
4910 				       ospf_area_desc_string(oi->area));
4911 		json_object_string_add(json_neigh, "ifaceName", oi->ifp->name);
4912 	} else
4913 		vty_out(vty, "    In the area %s via interface %s\n",
4914 			ospf_area_desc_string(oi->area), oi->ifp->name);
4915 
4916 	/* Show neighbor priority and state. */
4917 	if (use_json) {
4918 		json_object_int_add(json_neigh, "nbrPriority", nbr->priority);
4919 		json_object_string_add(
4920 			json_neigh, "nbrState",
4921 			lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
4922 	} else
4923 		vty_out(vty, "    Neighbor priority is %d, State is %s,",
4924 			nbr->priority,
4925 			lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
4926 
4927 	/* Show state changes. */
4928 	if (use_json)
4929 		json_object_int_add(json_neigh, "stateChangeCounter",
4930 				    nbr->state_change);
4931 	else
4932 		vty_out(vty, " %d state changes\n", nbr->state_change);
4933 
4934 	if (nbr->ts_last_progress.tv_sec || nbr->ts_last_progress.tv_usec) {
4935 		struct timeval res;
4936 		long time_store;
4937 
4938 		time_store =
4939 			monotime_since(&nbr->ts_last_progress, &res) / 1000LL;
4940 		if (use_json) {
4941 			json_object_int_add(json_neigh, "lastPrgrsvChangeMsec",
4942 					    time_store);
4943 		} else {
4944 			vty_out(vty,
4945 				"    Most recent state change statistics:\n");
4946 			vty_out(vty, "      Progressive change %s ago\n",
4947 				ospf_timeval_dump(&res, timebuf,
4948 						  sizeof(timebuf)));
4949 		}
4950 	}
4951 
4952 	if (nbr->ts_last_regress.tv_sec || nbr->ts_last_regress.tv_usec) {
4953 		struct timeval res;
4954 		long time_store;
4955 
4956 		time_store =
4957 			monotime_since(&nbr->ts_last_regress, &res) / 1000LL;
4958 		if (use_json) {
4959 			json_object_int_add(json_neigh,
4960 					    "lastRegressiveChangeMsec",
4961 					    time_store);
4962 			if (nbr->last_regress_str)
4963 				json_object_string_add(
4964 					json_neigh,
4965 					"lastRegressiveChangeReason",
4966 					nbr->last_regress_str);
4967 		} else {
4968 			vty_out(vty,
4969 				"      Regressive change %s ago, due to %s\n",
4970 				ospf_timeval_dump(&res, timebuf,
4971 						  sizeof(timebuf)),
4972 				(nbr->last_regress_str ? nbr->last_regress_str
4973 						       : "??"));
4974 		}
4975 	}
4976 
4977 	/* Show Designated Rotuer ID. */
4978 	if (use_json)
4979 		json_object_string_add(json_neigh, "routerDesignatedId",
4980 				       inet_ntoa(nbr->d_router));
4981 	else
4982 		vty_out(vty, "    DR is %s,", inet_ntoa(nbr->d_router));
4983 
4984 	/* Show Backup Designated Rotuer ID. */
4985 	if (use_json)
4986 		json_object_string_add(json_neigh, "routerDesignatedBackupId",
4987 				       inet_ntoa(nbr->bd_router));
4988 	else
4989 		vty_out(vty, " BDR is %s\n", inet_ntoa(nbr->bd_router));
4990 
4991 	/* Show options. */
4992 	if (use_json) {
4993 		json_object_int_add(json_neigh, "optionsCounter", nbr->options);
4994 		json_object_string_add(json_neigh, "optionsList",
4995 				       ospf_options_dump(nbr->options));
4996 	} else
4997 		vty_out(vty, "    Options %d %s\n", nbr->options,
4998 			ospf_options_dump(nbr->options));
4999 
5000 	/* Show Router Dead interval timer. */
5001 	if (use_json) {
5002 		if (nbr->t_inactivity) {
5003 			long time_store;
5004 			time_store = monotime_until(&nbr->t_inactivity->u.sands,
5005 						    NULL)
5006 				     / 1000LL;
5007 			json_object_int_add(json_neigh,
5008 					    "routerDeadIntervalTimerDueMsec",
5009 					    time_store);
5010 		} else
5011 			json_object_int_add(
5012 				json_neigh,
5013 				"routerDeadIntervalTimerDueMsec", -1);
5014 	} else
5015 		vty_out(vty, "    Dead timer due in %s\n",
5016 			ospf_timer_dump(nbr->t_inactivity, timebuf,
5017 					sizeof(timebuf)));
5018 
5019 	/* Show Database Summary list. */
5020 	if (use_json)
5021 		json_object_int_add(json_neigh, "databaseSummaryListCounter",
5022 				    ospf_db_summary_count(nbr));
5023 	else
5024 		vty_out(vty, "    Database Summary List %d\n",
5025 			ospf_db_summary_count(nbr));
5026 
5027 	/* Show Link State Request list. */
5028 	if (use_json)
5029 		json_object_int_add(json_neigh, "linkStateRequestListCounter",
5030 				    ospf_ls_request_count(nbr));
5031 	else
5032 		vty_out(vty, "    Link State Request List %ld\n",
5033 			ospf_ls_request_count(nbr));
5034 
5035 	/* Show Link State Retransmission list. */
5036 	if (use_json)
5037 		json_object_int_add(json_neigh,
5038 				    "linkStateRetransmissionListCounter",
5039 				    ospf_ls_retransmit_count(nbr));
5040 	else
5041 		vty_out(vty, "    Link State Retransmission List %ld\n",
5042 			ospf_ls_retransmit_count(nbr));
5043 
5044 	/* Show inactivity timer thread. */
5045 	if (use_json) {
5046 		if (nbr->t_inactivity != NULL)
5047 			json_object_string_add(json_neigh,
5048 					       "threadInactivityTimer", "on");
5049 	} else
5050 		vty_out(vty, "    Thread Inactivity Timer %s\n",
5051 			nbr->t_inactivity != NULL ? "on" : "off");
5052 
5053 	/* Show Database Description retransmission thread. */
5054 	if (use_json) {
5055 		if (nbr->t_db_desc != NULL)
5056 			json_object_string_add(
5057 				json_neigh,
5058 				"threadDatabaseDescriptionRetransmission",
5059 				"on");
5060 	} else
5061 		vty_out(vty,
5062 			"    Thread Database Description Retransmision %s\n",
5063 			nbr->t_db_desc != NULL ? "on" : "off");
5064 
5065 	/* Show Link State Request Retransmission thread. */
5066 	if (use_json) {
5067 		if (nbr->t_ls_req != NULL)
5068 			json_object_string_add(
5069 				json_neigh,
5070 				"threadLinkStateRequestRetransmission", "on");
5071 	} else
5072 		vty_out(vty,
5073 			"    Thread Link State Request Retransmission %s\n",
5074 			nbr->t_ls_req != NULL ? "on" : "off");
5075 
5076 	/* Show Link State Update Retransmission thread. */
5077 	if (use_json) {
5078 		if (nbr->t_ls_upd != NULL)
5079 			json_object_string_add(
5080 				json_neigh,
5081 				"threadLinkStateUpdateRetransmission",
5082 				"on");
5083 	} else
5084 		vty_out(vty,
5085 			"    Thread Link State Update Retransmission %s\n\n",
5086 			nbr->t_ls_upd != NULL ? "on" : "off");
5087 
5088 	ospf_bfd_show_info(vty, nbr->bfd_info, json_neigh, use_json, 0);
5089 
5090 	if (use_json)
5091 		json_object_array_add(json_neigh_array, json_neigh);
5092 
5093 }
5094 
show_ip_ospf_neighbor_id_common(struct vty * vty,struct ospf * ospf,struct in_addr * router_id,bool use_json,uint8_t use_vrf)5095 static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
5096 					   struct in_addr *router_id,
5097 					   bool use_json, uint8_t use_vrf)
5098 {
5099 	struct listnode *node;
5100 	struct ospf_neighbor *nbr;
5101 	struct ospf_interface *oi;
5102 	json_object *json = NULL;
5103 
5104 	if (use_json)
5105 		json = json_object_new_object();
5106 
5107 	if (ospf->instance) {
5108 		if (use_json)
5109 			json_object_int_add(json, "ospfInstance",
5110 					    ospf->instance);
5111 		else
5112 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
5113 	}
5114 
5115 	ospf_show_vrf_name(ospf, vty, json, use_vrf);
5116 
5117 	for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
5118 		if ((nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, router_id))) {
5119 			show_ip_ospf_neighbor_detail_sub(vty, oi, nbr, NULL,
5120 							 json, use_json);
5121 		}
5122 	}
5123 
5124 	if (use_json) {
5125 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
5126 					     json, JSON_C_TO_STRING_PRETTY));
5127 		json_object_free(json);
5128 	} else
5129 		vty_out(vty, "\n");
5130 
5131 	return CMD_SUCCESS;
5132 }
5133 
5134 DEFPY (show_ip_ospf_neighbor_id,
5135        show_ip_ospf_neighbor_id_cmd,
5136        "show ip ospf neighbor A.B.C.D$router_id [json$json]",
5137        SHOW_STR
5138        IP_STR
5139        "OSPF information\n"
5140        "Neighbor list\n"
5141        "Neighbor ID\n"
5142        JSON_STR)
5143 {
5144 	struct ospf *ospf;
5145 	struct listnode *node;
5146 	int ret = CMD_SUCCESS;
5147 
5148 	for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
5149 		if (!ospf->oi_running)
5150 			continue;
5151 		ret = show_ip_ospf_neighbor_id_common(vty, ospf, &router_id,
5152 						      !!json, 0);
5153 	}
5154 
5155 	return ret;
5156 }
5157 
5158 DEFPY (show_ip_ospf_instance_neighbor_id,
5159        show_ip_ospf_instance_neighbor_id_cmd,
5160        "show ip ospf (1-65535)$instance neighbor A.B.C.D$router_id [json$json]",
5161        SHOW_STR
5162        IP_STR
5163        "OSPF information\n"
5164        "Instance ID\n"
5165        "Neighbor list\n"
5166        "Neighbor ID\n"
5167        JSON_STR)
5168 {
5169 	struct ospf *ospf;
5170 
5171 	ospf = ospf_lookup_instance(instance);
5172 	if (ospf == NULL)
5173 		return CMD_NOT_MY_INSTANCE;
5174 
5175 	if (!ospf->oi_running)
5176 		return CMD_SUCCESS;
5177 
5178 	return show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, !!json,
5179 					       0);
5180 }
5181 
show_ip_ospf_neighbor_detail_common(struct vty * vty,struct ospf * ospf,json_object * json,bool use_json,uint8_t use_vrf)5182 static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
5183 					       struct ospf *ospf,
5184 					       json_object *json, bool use_json,
5185 					       uint8_t use_vrf)
5186 {
5187 	struct ospf_interface *oi;
5188 	struct listnode *node;
5189 	json_object *json_vrf = NULL;
5190 	json_object *json_nbr_sub = NULL;
5191 
5192 	if (use_json) {
5193 		if (use_vrf)
5194 			json_vrf = json_object_new_object();
5195 		else
5196 			json_vrf = json;
5197 
5198 		json_nbr_sub = json_object_new_object();
5199 	}
5200 
5201 	if (ospf->instance) {
5202 		if (use_json)
5203 			json_object_int_add(json, "ospfInstance",
5204 					    ospf->instance);
5205 		else
5206 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
5207 	}
5208 
5209 	ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
5210 
5211 	for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
5212 		struct route_node *rn;
5213 		struct ospf_neighbor *nbr, *prev_nbr = NULL;
5214 
5215 		for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
5216 			if ((nbr = rn->info)) {
5217 				if (nbr != oi->nbr_self) {
5218 					if (nbr->state != NSM_Down) {
5219 						show_ip_ospf_neighbor_detail_sub(
5220 							vty, oi, nbr, prev_nbr,
5221 							json_nbr_sub, use_json);
5222 					}
5223 				}
5224 				prev_nbr = nbr;
5225 			}
5226 		}
5227 	}
5228 
5229 	if (use_json) {
5230 		json_object_object_add(json_vrf, "neighbors",
5231 				       json_nbr_sub);
5232 		if (use_vrf) {
5233 			if (ospf->vrf_id == VRF_DEFAULT)
5234 				json_object_object_add(json, "default",
5235 						       json_vrf);
5236 			else
5237 				json_object_object_add(json, ospf->name,
5238 						       json_vrf);
5239 		}
5240 	} else
5241 		vty_out(vty, "\n");
5242 
5243 	return CMD_SUCCESS;
5244 }
5245 
5246 DEFUN (show_ip_ospf_neighbor_detail,
5247        show_ip_ospf_neighbor_detail_cmd,
5248        "show ip ospf [vrf <NAME|all>] neighbor detail [json]",
5249        SHOW_STR
5250        IP_STR
5251        "OSPF information\n"
5252        VRF_CMD_HELP_STR
5253        "All VRFs\n"
5254        "Neighbor list\n"
5255        "detail of all neighbors\n"
5256        JSON_STR)
5257 {
5258 	struct ospf *ospf;
5259 	bool uj = use_json(argc, argv);
5260 	struct listnode *node = NULL;
5261 	char *vrf_name = NULL;
5262 	bool all_vrf = false;
5263 	int ret = CMD_SUCCESS;
5264 	int inst = 0;
5265 	int idx_vrf = 0;
5266 	uint8_t use_vrf = 0;
5267 	json_object *json = NULL;
5268 
5269 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
5270 
5271 	if (uj)
5272 		json = json_object_new_object();
5273 
5274 	/* vrf input is provided could be all or specific vrf*/
5275 	if (vrf_name) {
5276 		use_vrf = 1;
5277 		if (all_vrf) {
5278 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
5279 				if (!ospf->oi_running)
5280 					continue;
5281 				ret = show_ip_ospf_neighbor_detail_common(
5282 					vty, ospf, json, uj, use_vrf);
5283 			}
5284 			if (uj) {
5285 				vty_out(vty, "%s\n",
5286 					json_object_to_json_string_ext(
5287 						json, JSON_C_TO_STRING_PRETTY));
5288 				json_object_free(json);
5289 			}
5290 
5291 			return ret;
5292 		}
5293 		ospf = ospf_lookup_by_inst_name(inst, vrf_name);
5294 		if (ospf == NULL || !ospf->oi_running) {
5295 			if (uj)
5296 				json_object_free(json);
5297 			return CMD_SUCCESS;
5298 		}
5299 	} else {
5300 		/* Display default ospf (instance 0) info */
5301 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
5302 		if (ospf == NULL || !ospf->oi_running) {
5303 			if (uj)
5304 				json_object_free(json);
5305 			return CMD_SUCCESS;
5306 		}
5307 	}
5308 
5309 	if (ospf) {
5310 		ret = show_ip_ospf_neighbor_detail_common(vty, ospf, json, uj,
5311 							  use_vrf);
5312 		if (uj) {
5313 			vty_out(vty, "%s\n",
5314 				json_object_to_json_string_ext(
5315 					json, JSON_C_TO_STRING_PRETTY));
5316 		}
5317 	}
5318 
5319 	if (uj)
5320 		json_object_free(json);
5321 
5322 	return ret;
5323 }
5324 
5325 DEFUN (show_ip_ospf_instance_neighbor_detail,
5326        show_ip_ospf_instance_neighbor_detail_cmd,
5327        "show ip ospf (1-65535) neighbor detail [json]",
5328        SHOW_STR
5329        IP_STR
5330        "OSPF information\n"
5331        "Instance ID\n"
5332        "Neighbor list\n"
5333        "detail of all neighbors\n"
5334        JSON_STR)
5335 {
5336 	int idx_number = 3;
5337 	struct ospf *ospf;
5338 	unsigned short instance = 0;
5339 	bool uj = use_json(argc, argv);
5340 	json_object *json = NULL;
5341 	int ret = CMD_SUCCESS;
5342 
5343 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
5344 	ospf = ospf_lookup_instance(instance);
5345 	if (ospf == NULL)
5346 		return CMD_NOT_MY_INSTANCE;
5347 
5348 	if (!ospf->oi_running)
5349 		return CMD_SUCCESS;
5350 
5351 	if (uj)
5352 		json = json_object_new_object();
5353 
5354 	ret = show_ip_ospf_neighbor_detail_common(vty, ospf, json, uj, 0);
5355 
5356 	if (uj) {
5357 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
5358 					     json, JSON_C_TO_STRING_PRETTY));
5359 		json_object_free(json);
5360 	}
5361 
5362 	return ret;
5363 }
5364 
show_ip_ospf_neighbor_detail_all_common(struct vty * vty,struct ospf * ospf,json_object * json,bool use_json,uint8_t use_vrf)5365 static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty,
5366 						   struct ospf *ospf,
5367 						   json_object *json,
5368 						   bool use_json,
5369 						   uint8_t use_vrf)
5370 {
5371 	struct listnode *node;
5372 	struct ospf_interface *oi;
5373 	json_object *json_vrf = NULL;
5374 
5375 	if (use_json) {
5376 		if (use_vrf)
5377 			json_vrf = json_object_new_object();
5378 		else
5379 			json_vrf = json;
5380 	}
5381 
5382 	if (ospf->instance) {
5383 		if (use_json)
5384 			json_object_int_add(json, "ospfInstance",
5385 					    ospf->instance);
5386 		else
5387 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
5388 	}
5389 
5390 	ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
5391 
5392 	for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
5393 		struct route_node *rn;
5394 		struct ospf_neighbor *nbr, *prev_nbr = NULL;
5395 		struct ospf_nbr_nbma *nbr_nbma;
5396 
5397 		for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
5398 			if ((nbr = rn->info)) {
5399 				if (nbr != oi->nbr_self)
5400 					if (nbr->state != NSM_Down)
5401 						show_ip_ospf_neighbor_detail_sub(
5402 							vty, oi, rn->info,
5403 							prev_nbr,
5404 							json_vrf, use_json);
5405 				prev_nbr = nbr;
5406 			}
5407 		}
5408 
5409 		if (oi->type == OSPF_IFTYPE_NBMA) {
5410 			struct listnode *nd;
5411 
5412 			for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, nd, nbr_nbma)) {
5413 				if (nbr_nbma->nbr == NULL
5414 				    || nbr_nbma->nbr->state == NSM_Down)
5415 					show_ip_ospf_nbr_nbma_detail_sub(
5416 						vty, oi, nbr_nbma, use_json,
5417 						json_vrf);
5418 			}
5419 		}
5420 	}
5421 
5422 	if (use_json) {
5423 		if (use_vrf) {
5424 			if (ospf->vrf_id == VRF_DEFAULT)
5425 				json_object_object_add(json, "default",
5426 						       json_vrf);
5427 			else
5428 				json_object_object_add(json, ospf->name,
5429 						       json_vrf);
5430 		}
5431 	} else {
5432 		vty_out(vty, "\n");
5433 	}
5434 
5435 	return CMD_SUCCESS;
5436 }
5437 
5438 DEFUN (show_ip_ospf_neighbor_detail_all,
5439        show_ip_ospf_neighbor_detail_all_cmd,
5440        "show ip ospf [vrf <NAME|all>] neighbor detail all [json]",
5441        SHOW_STR
5442        IP_STR
5443        "OSPF information\n"
5444        VRF_CMD_HELP_STR
5445        "All VRFs\n"
5446        "Neighbor list\n"
5447        "detail of all neighbors\n"
5448        "include down status neighbor\n"
5449        JSON_STR)
5450 {
5451 	struct ospf *ospf;
5452 	bool uj = use_json(argc, argv);
5453 	struct listnode *node = NULL;
5454 	char *vrf_name = NULL;
5455 	bool all_vrf = false;
5456 	int ret = CMD_SUCCESS;
5457 	int inst = 0;
5458 	int idx_vrf = 0;
5459 	uint8_t use_vrf = 0;
5460 	json_object *json = NULL;
5461 
5462 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
5463 
5464 	if (uj)
5465 		json = json_object_new_object();
5466 
5467 	/* vrf input is provided could be all or specific vrf*/
5468 	if (vrf_name) {
5469 		use_vrf = 1;
5470 		if (all_vrf) {
5471 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
5472 				if (!ospf->oi_running)
5473 					continue;
5474 				ret = show_ip_ospf_neighbor_detail_all_common(
5475 					vty, ospf, json, uj, use_vrf);
5476 			}
5477 
5478 			if (uj) {
5479 				vty_out(vty, "%s\n",
5480 					json_object_to_json_string_ext(
5481 						json, JSON_C_TO_STRING_PRETTY));
5482 				json_object_free(json);
5483 			}
5484 
5485 			return ret;
5486 		}
5487 		ospf = ospf_lookup_by_inst_name(inst, vrf_name);
5488 		if (ospf == NULL || !ospf->oi_running) {
5489 			if (uj)
5490 				json_object_free(json);
5491 			return CMD_SUCCESS;
5492 		}
5493 	} else {
5494 		/* Display default ospf (instance 0) info */
5495 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
5496 		if (ospf == NULL || !ospf->oi_running) {
5497 			if (uj)
5498 				json_object_free(json);
5499 			return CMD_SUCCESS;
5500 		}
5501 	}
5502 
5503 	if (ospf) {
5504 		ret = show_ip_ospf_neighbor_detail_all_common(vty, ospf, json,
5505 							      uj, use_vrf);
5506 		if (uj) {
5507 			vty_out(vty, "%s\n",
5508 				json_object_to_json_string_ext(
5509 					json, JSON_C_TO_STRING_PRETTY));
5510 		}
5511 	}
5512 
5513 	if (uj)
5514 		json_object_free(json);
5515 
5516 	return ret;
5517 }
5518 
5519 DEFUN (show_ip_ospf_instance_neighbor_detail_all,
5520        show_ip_ospf_instance_neighbor_detail_all_cmd,
5521        "show ip ospf (1-65535) neighbor detail all [json]",
5522        SHOW_STR
5523        IP_STR
5524        "OSPF information\n"
5525        "Instance ID\n"
5526        "Neighbor list\n"
5527        "detail of all neighbors\n"
5528        "include down status neighbor\n"
5529        JSON_STR)
5530 {
5531 	int idx_number = 3;
5532 	struct ospf *ospf;
5533 	unsigned short instance = 0;
5534 	bool uj = use_json(argc, argv);
5535 	json_object *json = NULL;
5536 	int ret = CMD_SUCCESS;
5537 
5538 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
5539 	ospf = ospf_lookup_instance(instance);
5540 	if (ospf == NULL)
5541 		return CMD_NOT_MY_INSTANCE;
5542 
5543 	if (!ospf->oi_running)
5544 		return CMD_SUCCESS;
5545 
5546 	if (uj)
5547 		json = json_object_new_object();
5548 
5549 	ret = show_ip_ospf_neighbor_detail_all_common(vty, ospf, json, uj, 0);
5550 
5551 	if (uj) {
5552 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
5553 					     json, JSON_C_TO_STRING_PRETTY));
5554 		json_object_free(json);
5555 	}
5556 
5557 	return ret;
5558 }
5559 
show_ip_ospf_neighbor_int_detail_common(struct vty * vty,struct ospf * ospf,int arg_base,struct cmd_token ** argv,bool use_json)5560 static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
5561 						   struct ospf *ospf,
5562 						   int arg_base,
5563 						   struct cmd_token **argv,
5564 						   bool use_json)
5565 {
5566 	struct ospf_interface *oi;
5567 	struct interface *ifp;
5568 	struct route_node *rn, *nrn;
5569 	struct ospf_neighbor *nbr;
5570 	json_object *json = NULL;
5571 
5572 	if (use_json)
5573 		json = json_object_new_object();
5574 
5575 	if (ospf->instance) {
5576 		if (use_json)
5577 			json_object_int_add(json, "ospfInstance",
5578 					    ospf->instance);
5579 		else
5580 			vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
5581 	}
5582 
5583 	ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
5584 	if (!ifp) {
5585 		if (!use_json)
5586 			vty_out(vty, "No such interface.\n");
5587 		else {
5588 			vty_out(vty, "{}\n");
5589 			json_object_free(json);
5590 		}
5591 		return CMD_WARNING;
5592 	}
5593 
5594 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
5595 		if ((oi = rn->info)) {
5596 			for (nrn = route_top(oi->nbrs); nrn;
5597 			     nrn = route_next(nrn)) {
5598 				if ((nbr = nrn->info)) {
5599 					if (nbr != oi->nbr_self) {
5600 						if (nbr->state != NSM_Down)
5601 							show_ip_ospf_neighbor_detail_sub(
5602 								vty, oi, nbr,
5603 								NULL,
5604 								json, use_json);
5605 					}
5606 				}
5607 			}
5608 		}
5609 	}
5610 
5611 	if (use_json) {
5612 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
5613 					     json, JSON_C_TO_STRING_PRETTY));
5614 		json_object_free(json);
5615 	} else
5616 		vty_out(vty, "\n");
5617 
5618 	return CMD_SUCCESS;
5619 }
5620 
5621 DEFUN (show_ip_ospf_neighbor_int_detail,
5622        show_ip_ospf_neighbor_int_detail_cmd,
5623        "show ip ospf neighbor IFNAME detail [json]",
5624        SHOW_STR
5625        IP_STR
5626        "OSPF information\n"
5627        "Neighbor list\n"
5628        "Interface name\n"
5629        "detail of all neighbors\n"
5630        JSON_STR)
5631 {
5632 	struct ospf *ospf;
5633 	bool uj = use_json(argc, argv);
5634 	struct listnode *node = NULL;
5635 	int ret = CMD_SUCCESS;
5636 	bool ospf_output = false;
5637 
5638 	for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
5639 		if (!ospf->oi_running)
5640 			continue;
5641 		ospf_output = true;
5642 		ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 4,
5643 							      argv, uj);
5644 	}
5645 
5646 	if (!ospf_output)
5647 		vty_out(vty, "%% OSPF instance not found\n");
5648 
5649 	return ret;
5650 }
5651 
5652 DEFUN (show_ip_ospf_instance_neighbor_int_detail,
5653        show_ip_ospf_instance_neighbor_int_detail_cmd,
5654        "show ip ospf (1-65535) neighbor IFNAME detail [json]",
5655        SHOW_STR
5656        IP_STR
5657        "OSPF information\n"
5658        "Instance ID\n"
5659        "Neighbor list\n"
5660        "Interface name\n"
5661        "detail of all neighbors\n"
5662        JSON_STR)
5663 {
5664 	int idx_number = 3;
5665 	int idx_ifname = 5;
5666 	struct ospf *ospf;
5667 	unsigned short instance = 0;
5668 	bool uj = use_json(argc, argv);
5669 
5670 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
5671 	ospf = ospf_lookup_instance(instance);
5672 	if (ospf == NULL)
5673 		return CMD_NOT_MY_INSTANCE;
5674 
5675 	if (!ospf->oi_running)
5676 		return CMD_SUCCESS;
5677 
5678 	return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname,
5679 						       argv, uj);
5680 }
5681 
5682 /* Show functions */
show_lsa_summary(struct vty * vty,struct ospf_lsa * lsa,int self)5683 static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self)
5684 {
5685 	struct router_lsa *rl;
5686 	struct summary_lsa *sl;
5687 	struct as_external_lsa *asel;
5688 	struct prefix_ipv4 p;
5689 
5690 	if (lsa != NULL)
5691 		/* If self option is set, check LSA self flag. */
5692 		if (self == 0 || IS_LSA_SELF(lsa)) {
5693 			/* LSA common part show. */
5694 			vty_out(vty, "%-15s ", inet_ntoa(lsa->data->id));
5695 			vty_out(vty, "%-15s %4d 0x%08lx 0x%04x",
5696 				inet_ntoa(lsa->data->adv_router), LS_AGE(lsa),
5697 				(unsigned long)ntohl(lsa->data->ls_seqnum),
5698 				ntohs(lsa->data->checksum));
5699 			/* LSA specific part show. */
5700 			switch (lsa->data->type) {
5701 			case OSPF_ROUTER_LSA:
5702 				rl = (struct router_lsa *)lsa->data;
5703 				vty_out(vty, " %-d", ntohs(rl->links));
5704 				break;
5705 			case OSPF_SUMMARY_LSA:
5706 				sl = (struct summary_lsa *)lsa->data;
5707 
5708 				p.family = AF_INET;
5709 				p.prefix = sl->header.id;
5710 				p.prefixlen = ip_masklen(sl->mask);
5711 				apply_mask_ipv4(&p);
5712 
5713 				vty_out(vty, " %s/%d", inet_ntoa(p.prefix),
5714 					p.prefixlen);
5715 				break;
5716 			case OSPF_AS_EXTERNAL_LSA:
5717 			case OSPF_AS_NSSA_LSA:
5718 				asel = (struct as_external_lsa *)lsa->data;
5719 
5720 				p.family = AF_INET;
5721 				p.prefix = asel->header.id;
5722 				p.prefixlen = ip_masklen(asel->mask);
5723 				apply_mask_ipv4(&p);
5724 
5725 				vty_out(vty, " %s %s/%d [0x%lx]",
5726 					IS_EXTERNAL_METRIC(asel->e[0].tos)
5727 						? "E2"
5728 						: "E1",
5729 					inet_ntoa(p.prefix), p.prefixlen,
5730 					(unsigned long)ntohl(
5731 						asel->e[0].route_tag));
5732 				break;
5733 			case OSPF_NETWORK_LSA:
5734 			case OSPF_ASBR_SUMMARY_LSA:
5735 			case OSPF_OPAQUE_LINK_LSA:
5736 			case OSPF_OPAQUE_AREA_LSA:
5737 			case OSPF_OPAQUE_AS_LSA:
5738 			default:
5739 				break;
5740 			}
5741 			vty_out(vty, "\n");
5742 		}
5743 
5744 	return 0;
5745 }
5746 
5747 static const char *const show_database_desc[] = {
5748 	"unknown",
5749 	"Router Link States",
5750 	"Net Link States",
5751 	"Summary Link States",
5752 	"ASBR-Summary Link States",
5753 	"AS External Link States",
5754 	"Group Membership LSA",
5755 	"NSSA-external Link States",
5756 	"Type-8 LSA",
5757 	"Link-Local Opaque-LSA",
5758 	"Area-Local Opaque-LSA",
5759 	"AS-external Opaque-LSA",
5760 };
5761 
5762 static const char *const show_database_header[] = {
5763 	"",
5764 	"Link ID         ADV Router      Age  Seq#       CkSum  Link count",
5765 	"Link ID         ADV Router      Age  Seq#       CkSum",
5766 	"Link ID         ADV Router      Age  Seq#       CkSum  Route",
5767 	"Link ID         ADV Router      Age  Seq#       CkSum",
5768 	"Link ID         ADV Router      Age  Seq#       CkSum  Route",
5769 	" --- header for Group Member ----",
5770 	"Link ID         ADV Router      Age  Seq#       CkSum  Route",
5771 	" --- type-8 ---",
5772 	"Opaque-Type/Id  ADV Router      Age  Seq#       CkSum",
5773 	"Opaque-Type/Id  ADV Router      Age  Seq#       CkSum",
5774 	"Opaque-Type/Id  ADV Router      Age  Seq#       CkSum",
5775 };
5776 
show_ip_ospf_database_header(struct vty * vty,struct ospf_lsa * lsa)5777 static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa)
5778 {
5779 	struct router_lsa *rlsa = (struct router_lsa *)lsa->data;
5780 
5781 	vty_out(vty, "  LS age: %d\n", LS_AGE(lsa));
5782 	vty_out(vty, "  Options: 0x%-2x : %s\n", lsa->data->options,
5783 		ospf_options_dump(lsa->data->options));
5784 	vty_out(vty, "  LS Flags: 0x%-2x %s\n", lsa->flags,
5785 		((lsa->flags & OSPF_LSA_LOCAL_XLT) ? "(Translated from Type-7)"
5786 						   : ""));
5787 
5788 	if (lsa->data->type == OSPF_ROUTER_LSA) {
5789 		vty_out(vty, "  Flags: 0x%x", rlsa->flags);
5790 
5791 		if (rlsa->flags)
5792 			vty_out(vty, " :%s%s%s%s",
5793 				IS_ROUTER_LSA_BORDER(rlsa) ? " ABR" : "",
5794 				IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR" : "",
5795 				IS_ROUTER_LSA_VIRTUAL(rlsa) ? " VL-endpoint"
5796 							    : "",
5797 				IS_ROUTER_LSA_SHORTCUT(rlsa) ? " Shortcut"
5798 							     : "");
5799 
5800 		vty_out(vty, "\n");
5801 	}
5802 	vty_out(vty, "  LS Type: %s\n",
5803 		lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL));
5804 	vty_out(vty, "  Link State ID: %s %s\n", inet_ntoa(lsa->data->id),
5805 		lookup_msg(ospf_link_state_id_type_msg, lsa->data->type, NULL));
5806 	vty_out(vty, "  Advertising Router: %s\n",
5807 		inet_ntoa(lsa->data->adv_router));
5808 	vty_out(vty, "  LS Seq Number: %08lx\n",
5809 		(unsigned long)ntohl(lsa->data->ls_seqnum));
5810 	vty_out(vty, "  Checksum: 0x%04x\n", ntohs(lsa->data->checksum));
5811 	vty_out(vty, "  Length: %d\n\n", ntohs(lsa->data->length));
5812 }
5813 
5814 static const char *const link_type_desc[] = {
5815 	"(null)",
5816 	"another Router (point-to-point)",
5817 	"a Transit Network",
5818 	"Stub Network",
5819 	"a Virtual Link",
5820 };
5821 
5822 static const char *const link_id_desc[] = {
5823 	"(null)", "Neighboring Router ID", "Designated Router address",
5824 	"Net",    "Neighboring Router ID",
5825 };
5826 
5827 static const char *const link_data_desc[] = {
5828 	"(null)",       "Router Interface address", "Router Interface address",
5829 	"Network Mask", "Router Interface address",
5830 };
5831 
5832 /* Show router-LSA each Link information. */
show_ip_ospf_database_router_links(struct vty * vty,struct router_lsa * rl)5833 static void show_ip_ospf_database_router_links(struct vty *vty,
5834 					       struct router_lsa *rl)
5835 {
5836 	int len, type;
5837 	unsigned int i;
5838 
5839 	len = ntohs(rl->header.length) - 4;
5840 	for (i = 0; i < ntohs(rl->links) && len > 0; len -= 12, i++) {
5841 		type = rl->link[i].type;
5842 
5843 		vty_out(vty, "    Link connected to: %s\n",
5844 			link_type_desc[type]);
5845 		vty_out(vty, "     (Link ID) %s: %s\n", link_id_desc[type],
5846 			inet_ntoa(rl->link[i].link_id));
5847 		vty_out(vty, "     (Link Data) %s: %s\n", link_data_desc[type],
5848 			inet_ntoa(rl->link[i].link_data));
5849 		vty_out(vty, "      Number of TOS metrics: 0\n");
5850 		vty_out(vty, "       TOS 0 Metric: %d\n",
5851 			ntohs(rl->link[i].metric));
5852 		vty_out(vty, "\n");
5853 	}
5854 }
5855 
5856 /* Show router-LSA detail information. */
show_router_lsa_detail(struct vty * vty,struct ospf_lsa * lsa)5857 static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
5858 {
5859 	if (lsa != NULL) {
5860 		struct router_lsa *rl = (struct router_lsa *)lsa->data;
5861 
5862 		show_ip_ospf_database_header(vty, lsa);
5863 
5864 		vty_out(vty, "   Number of Links: %d\n\n", ntohs(rl->links));
5865 
5866 		show_ip_ospf_database_router_links(vty, rl);
5867 		vty_out(vty, "\n");
5868 	}
5869 
5870 	return 0;
5871 }
5872 
5873 /* Show network-LSA detail information. */
show_network_lsa_detail(struct vty * vty,struct ospf_lsa * lsa)5874 static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
5875 {
5876 	int length, i;
5877 
5878 	if (lsa != NULL) {
5879 		struct network_lsa *nl = (struct network_lsa *)lsa->data;
5880 
5881 		show_ip_ospf_database_header(vty, lsa);
5882 
5883 		vty_out(vty, "  Network Mask: /%d\n", ip_masklen(nl->mask));
5884 
5885 		length = ntohs(lsa->data->length) - OSPF_LSA_HEADER_SIZE - 4;
5886 
5887 		for (i = 0; length > 0; i++, length -= 4)
5888 			vty_out(vty, "        Attached Router: %s\n",
5889 				inet_ntoa(nl->routers[i]));
5890 
5891 		vty_out(vty, "\n");
5892 	}
5893 
5894 	return 0;
5895 }
5896 
5897 /* Show summary-LSA detail information. */
show_summary_lsa_detail(struct vty * vty,struct ospf_lsa * lsa)5898 static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
5899 {
5900 	if (lsa != NULL) {
5901 		struct summary_lsa *sl = (struct summary_lsa *)lsa->data;
5902 
5903 		show_ip_ospf_database_header(vty, lsa);
5904 
5905 		vty_out(vty, "  Network Mask: /%d\n", ip_masklen(sl->mask));
5906 		vty_out(vty, "        TOS: 0  Metric: %d\n",
5907 			GET_METRIC(sl->metric));
5908 		vty_out(vty, "\n");
5909 	}
5910 
5911 	return 0;
5912 }
5913 
5914 /* Show summary-ASBR-LSA detail information. */
show_summary_asbr_lsa_detail(struct vty * vty,struct ospf_lsa * lsa)5915 static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
5916 {
5917 	if (lsa != NULL) {
5918 		struct summary_lsa *sl = (struct summary_lsa *)lsa->data;
5919 
5920 		show_ip_ospf_database_header(vty, lsa);
5921 
5922 		vty_out(vty, "  Network Mask: /%d\n", ip_masklen(sl->mask));
5923 		vty_out(vty, "        TOS: 0  Metric: %d\n",
5924 			GET_METRIC(sl->metric));
5925 		vty_out(vty, "\n");
5926 	}
5927 
5928 	return 0;
5929 }
5930 
5931 /* Show AS-external-LSA detail information. */
show_as_external_lsa_detail(struct vty * vty,struct ospf_lsa * lsa)5932 static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
5933 {
5934 	if (lsa != NULL) {
5935 		struct as_external_lsa *al =
5936 			(struct as_external_lsa *)lsa->data;
5937 
5938 		show_ip_ospf_database_header(vty, lsa);
5939 
5940 		vty_out(vty, "  Network Mask: /%d\n", ip_masklen(al->mask));
5941 		vty_out(vty, "        Metric Type: %s\n",
5942 			IS_EXTERNAL_METRIC(al->e[0].tos)
5943 				? "2 (Larger than any link state path)"
5944 				: "1");
5945 		vty_out(vty, "        TOS: 0\n");
5946 		vty_out(vty, "        Metric: %d\n",
5947 			GET_METRIC(al->e[0].metric));
5948 		vty_out(vty, "        Forward Address: %s\n",
5949 			inet_ntoa(al->e[0].fwd_addr));
5950 
5951 		vty_out(vty,
5952 			"        External Route Tag: %" ROUTE_TAG_PRI "\n\n",
5953 			(route_tag_t)ntohl(al->e[0].route_tag));
5954 	}
5955 
5956 	return 0;
5957 }
5958 #if 0
5959 static int
5960 show_as_external_lsa_stdvty (struct ospf_lsa *lsa)
5961 {
5962   struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
5963 
5964   /* show_ip_ospf_database_header (vty, lsa); */
5965 
5966   zlog_debug( "  Network Mask: /%d%s",
5967 	     ip_masklen (al->mask), "\n");
5968   zlog_debug( "        Metric Type: %s%s",
5969 	     IS_EXTERNAL_METRIC (al->e[0].tos) ?
5970 	     "2 (Larger than any link state path)" : "1", "\n");
5971   zlog_debug( "        TOS: 0%s", "\n");
5972   zlog_debug( "        Metric: %d%s",
5973 	     GET_METRIC (al->e[0].metric), "\n");
5974   zlog_debug( "        Forward Address: %s%s",
5975 	     inet_ntoa (al->e[0].fwd_addr), "\n");
5976 
5977   zlog_debug( "        External Route Tag: %"ROUTE_TAG_PRI"%s%s",
5978 	     (route_tag_t)ntohl (al->e[0].route_tag), "\n", "\n");
5979 
5980   return 0;
5981 }
5982 #endif
5983 /* Show AS-NSSA-LSA detail information. */
show_as_nssa_lsa_detail(struct vty * vty,struct ospf_lsa * lsa)5984 static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
5985 {
5986 	if (lsa != NULL) {
5987 		struct as_external_lsa *al =
5988 			(struct as_external_lsa *)lsa->data;
5989 
5990 		show_ip_ospf_database_header(vty, lsa);
5991 
5992 		vty_out(vty, "  Network Mask: /%d\n", ip_masklen(al->mask));
5993 		vty_out(vty, "        Metric Type: %s\n",
5994 			IS_EXTERNAL_METRIC(al->e[0].tos)
5995 				? "2 (Larger than any link state path)"
5996 				: "1");
5997 		vty_out(vty, "        TOS: 0\n");
5998 		vty_out(vty, "        Metric: %d\n",
5999 			GET_METRIC(al->e[0].metric));
6000 		vty_out(vty, "        NSSA: Forward Address: %s\n",
6001 			inet_ntoa(al->e[0].fwd_addr));
6002 
6003 		vty_out(vty,
6004 			"        External Route Tag: %" ROUTE_TAG_PRI "\n\n",
6005 			(route_tag_t)ntohl(al->e[0].route_tag));
6006 	}
6007 
6008 	return 0;
6009 }
6010 
show_func_dummy(struct vty * vty,struct ospf_lsa * lsa)6011 static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa)
6012 {
6013 	return 0;
6014 }
6015 
show_opaque_lsa_detail(struct vty * vty,struct ospf_lsa * lsa)6016 static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
6017 {
6018 	if (lsa != NULL) {
6019 		show_ip_ospf_database_header(vty, lsa);
6020 		show_opaque_info_detail(vty, lsa);
6021 
6022 		vty_out(vty, "\n");
6023 	}
6024 	return 0;
6025 }
6026 
6027 int (*const show_function[])(struct vty *, struct ospf_lsa *) = {
6028 	NULL,
6029 	show_router_lsa_detail,
6030 	show_network_lsa_detail,
6031 	show_summary_lsa_detail,
6032 	show_summary_asbr_lsa_detail,
6033 	show_as_external_lsa_detail,
6034 	show_func_dummy,
6035 	show_as_nssa_lsa_detail, /* almost same as external */
6036 	NULL,			 /* type-8 */
6037 	show_opaque_lsa_detail,
6038 	show_opaque_lsa_detail,
6039 	show_opaque_lsa_detail,
6040 };
6041 
show_lsa_prefix_set(struct vty * vty,struct prefix_ls * lp,struct in_addr * id,struct in_addr * adv_router)6042 static void show_lsa_prefix_set(struct vty *vty, struct prefix_ls *lp,
6043 				struct in_addr *id, struct in_addr *adv_router)
6044 {
6045 	memset(lp, 0, sizeof(struct prefix_ls));
6046 	lp->family = 0;
6047 	if (id == NULL)
6048 		lp->prefixlen = 0;
6049 	else if (adv_router == NULL) {
6050 		lp->prefixlen = 32;
6051 		lp->id = *id;
6052 	} else {
6053 		lp->prefixlen = 64;
6054 		lp->id = *id;
6055 		lp->adv_router = *adv_router;
6056 	}
6057 }
6058 
show_lsa_detail_proc(struct vty * vty,struct route_table * rt,struct in_addr * id,struct in_addr * adv_router)6059 static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt,
6060 				 struct in_addr *id, struct in_addr *adv_router)
6061 {
6062 	struct prefix_ls lp;
6063 	struct route_node *rn, *start;
6064 	struct ospf_lsa *lsa;
6065 
6066 	show_lsa_prefix_set(vty, &lp, id, adv_router);
6067 	start = route_node_get(rt, (struct prefix *)&lp);
6068 	if (start) {
6069 		route_lock_node(start);
6070 		for (rn = start; rn; rn = route_next_until(rn, start))
6071 			if ((lsa = rn->info)) {
6072 				if (show_function[lsa->data->type] != NULL)
6073 					show_function[lsa->data->type](vty,
6074 								       lsa);
6075 			}
6076 		route_unlock_node(start);
6077 	}
6078 }
6079 
6080 /* Show detail LSA information
6081    -- if id is NULL then show all LSAs. */
show_lsa_detail(struct vty * vty,struct ospf * ospf,int type,struct in_addr * id,struct in_addr * adv_router)6082 static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type,
6083 			    struct in_addr *id, struct in_addr *adv_router)
6084 {
6085 	struct listnode *node;
6086 	struct ospf_area *area;
6087 
6088 	switch (type) {
6089 	case OSPF_AS_EXTERNAL_LSA:
6090 	case OSPF_OPAQUE_AS_LSA:
6091 		vty_out(vty, "                %s \n\n",
6092 			show_database_desc[type]);
6093 		show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router);
6094 		break;
6095 	default:
6096 		for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
6097 			vty_out(vty, "\n                %s (Area %s)\n\n",
6098 				show_database_desc[type],
6099 				ospf_area_desc_string(area));
6100 			show_lsa_detail_proc(vty, AREA_LSDB(area, type), id,
6101 					     adv_router);
6102 		}
6103 		break;
6104 	}
6105 }
6106 
show_lsa_detail_adv_router_proc(struct vty * vty,struct route_table * rt,struct in_addr * adv_router)6107 static void show_lsa_detail_adv_router_proc(struct vty *vty,
6108 					    struct route_table *rt,
6109 					    struct in_addr *adv_router)
6110 {
6111 	struct route_node *rn;
6112 	struct ospf_lsa *lsa;
6113 
6114 	for (rn = route_top(rt); rn; rn = route_next(rn))
6115 		if ((lsa = rn->info))
6116 			if (IPV4_ADDR_SAME(adv_router,
6117 					   &lsa->data->adv_router)) {
6118 				if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
6119 					continue;
6120 				if (show_function[lsa->data->type] != NULL)
6121 					show_function[lsa->data->type](vty,
6122 								       lsa);
6123 			}
6124 }
6125 
6126 /* Show detail LSA information. */
show_lsa_detail_adv_router(struct vty * vty,struct ospf * ospf,int type,struct in_addr * adv_router)6127 static void show_lsa_detail_adv_router(struct vty *vty, struct ospf *ospf,
6128 				       int type, struct in_addr *adv_router)
6129 {
6130 	struct listnode *node;
6131 	struct ospf_area *area;
6132 
6133 	switch (type) {
6134 	case OSPF_AS_EXTERNAL_LSA:
6135 	case OSPF_OPAQUE_AS_LSA:
6136 		vty_out(vty, "                %s \n\n",
6137 			show_database_desc[type]);
6138 		show_lsa_detail_adv_router_proc(vty, AS_LSDB(ospf, type),
6139 						adv_router);
6140 		break;
6141 	default:
6142 		for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
6143 			vty_out(vty, "\n                %s (Area %s)\n\n",
6144 				show_database_desc[type],
6145 				ospf_area_desc_string(area));
6146 			show_lsa_detail_adv_router_proc(
6147 				vty, AREA_LSDB(area, type), adv_router);
6148 		}
6149 		break;
6150 	}
6151 }
6152 
show_ip_ospf_database_summary(struct vty * vty,struct ospf * ospf,int self)6153 static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf,
6154 					  int self)
6155 {
6156 	struct ospf_lsa *lsa;
6157 	struct route_node *rn;
6158 	struct ospf_area *area;
6159 	struct listnode *node;
6160 	int type;
6161 
6162 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
6163 		for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) {
6164 			switch (type) {
6165 			case OSPF_AS_EXTERNAL_LSA:
6166 			case OSPF_OPAQUE_AS_LSA:
6167 				continue;
6168 			default:
6169 				break;
6170 			}
6171 			if (ospf_lsdb_count_self(area->lsdb, type) > 0
6172 			    || (!self
6173 				&& ospf_lsdb_count(area->lsdb, type) > 0)) {
6174 				vty_out(vty, "                %s (Area %s)\n\n",
6175 					show_database_desc[type],
6176 					ospf_area_desc_string(area));
6177 				vty_out(vty, "%s\n",
6178 					show_database_header[type]);
6179 
6180 				LSDB_LOOP (AREA_LSDB(area, type), rn, lsa)
6181 					show_lsa_summary(vty, lsa, self);
6182 
6183 				vty_out(vty, "\n");
6184 			}
6185 		}
6186 	}
6187 
6188 	for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) {
6189 		switch (type) {
6190 		case OSPF_AS_EXTERNAL_LSA:
6191 		case OSPF_OPAQUE_AS_LSA:
6192 			break;
6193 		default:
6194 			continue;
6195 		}
6196 		if (ospf_lsdb_count_self(ospf->lsdb, type)
6197 		    || (!self && ospf_lsdb_count(ospf->lsdb, type))) {
6198 			vty_out(vty, "                %s\n\n",
6199 				show_database_desc[type]);
6200 			vty_out(vty, "%s\n", show_database_header[type]);
6201 
6202 			LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa)
6203 				show_lsa_summary(vty, lsa, self);
6204 
6205 			vty_out(vty, "\n");
6206 		}
6207 	}
6208 
6209 	vty_out(vty, "\n");
6210 }
6211 
show_ip_ospf_database_maxage(struct vty * vty,struct ospf * ospf)6212 static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf)
6213 {
6214 	struct route_node *rn;
6215 
6216 	vty_out(vty, "\n                MaxAge Link States:\n\n");
6217 
6218 	for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
6219 		struct ospf_lsa *lsa;
6220 
6221 		if ((lsa = rn->info) != NULL) {
6222 			vty_out(vty, "Link type: %d\n", lsa->data->type);
6223 			vty_out(vty, "Link State ID: %s\n",
6224 				inet_ntoa(lsa->data->id));
6225 			vty_out(vty, "Advertising Router: %s\n",
6226 				inet_ntoa(lsa->data->adv_router));
6227 			vty_out(vty, "LSA lock count: %d\n", lsa->lock);
6228 			vty_out(vty, "\n");
6229 		}
6230 	}
6231 }
6232 
6233 #define OSPF_LSA_TYPE_NSSA_DESC      "NSSA external link state\n"
6234 #define OSPF_LSA_TYPE_NSSA_CMD_STR   "|nssa-external"
6235 
6236 #define OSPF_LSA_TYPE_OPAQUE_LINK_DESC "Link local Opaque-LSA\n"
6237 #define OSPF_LSA_TYPE_OPAQUE_AREA_DESC "Link area Opaque-LSA\n"
6238 #define OSPF_LSA_TYPE_OPAQUE_AS_DESC   "Link AS Opaque-LSA\n"
6239 #define OSPF_LSA_TYPE_OPAQUE_CMD_STR   "|opaque-link|opaque-area|opaque-as"
6240 
6241 #define OSPF_LSA_TYPES_DESC                                                    \
6242 	"ASBR summary link states\n"                                           \
6243 	"External link states\n"                                               \
6244 	"Network link states\n"                                                \
6245 	"Router link states\n"                                                 \
6246 	"Network summary link states\n" OSPF_LSA_TYPE_NSSA_DESC                \
6247 		OSPF_LSA_TYPE_OPAQUE_LINK_DESC OSPF_LSA_TYPE_OPAQUE_AREA_DESC  \
6248 			OSPF_LSA_TYPE_OPAQUE_AS_DESC
6249 
show_ip_ospf_database_common(struct vty * vty,struct ospf * ospf,int arg_base,int argc,struct cmd_token ** argv,uint8_t use_vrf)6250 static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
6251 					int arg_base, int argc,
6252 					struct cmd_token **argv,
6253 					uint8_t use_vrf)
6254 {
6255 	int idx_type = 4;
6256 	int type, ret;
6257 	struct in_addr id, adv_router;
6258 
6259 	if (ospf->instance)
6260 		vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance);
6261 
6262 	ospf_show_vrf_name(ospf, vty, NULL, use_vrf);
6263 
6264 	vty_out(vty, "\n       OSPF Router with ID (%s)\n\n",
6265 		inet_ntoa(ospf->router_id));
6266 
6267 	/* Show all LSA. */
6268 	if (argc == arg_base + 4) {
6269 		show_ip_ospf_database_summary(vty, ospf, 0);
6270 		return CMD_SUCCESS;
6271 	}
6272 
6273 	/* Set database type to show. */
6274 	if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0)
6275 		type = OSPF_ROUTER_LSA;
6276 	else if (strncmp(argv[arg_base + idx_type]->text, "ne", 2) == 0)
6277 		type = OSPF_NETWORK_LSA;
6278 	else if (strncmp(argv[arg_base + idx_type]->text, "ns", 2) == 0)
6279 		type = OSPF_AS_NSSA_LSA;
6280 	else if (strncmp(argv[arg_base + idx_type]->text, "su", 2) == 0)
6281 		type = OSPF_SUMMARY_LSA;
6282 	else if (strncmp(argv[arg_base + idx_type]->text, "a", 1) == 0)
6283 		type = OSPF_ASBR_SUMMARY_LSA;
6284 	else if (strncmp(argv[arg_base + idx_type]->text, "e", 1) == 0)
6285 		type = OSPF_AS_EXTERNAL_LSA;
6286 	else if (strncmp(argv[arg_base + idx_type]->text, "se", 2) == 0) {
6287 		show_ip_ospf_database_summary(vty, ospf, 1);
6288 		return CMD_SUCCESS;
6289 	} else if (strncmp(argv[arg_base + idx_type]->text, "m", 1) == 0) {
6290 		show_ip_ospf_database_maxage(vty, ospf);
6291 		return CMD_SUCCESS;
6292 	} else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0)
6293 		type = OSPF_OPAQUE_LINK_LSA;
6294 	else if (strncmp(argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0)
6295 		type = OSPF_OPAQUE_AREA_LSA;
6296 	else if (strncmp(argv[arg_base + idx_type]->text, "opaque-as", 9) == 0)
6297 		type = OSPF_OPAQUE_AS_LSA;
6298 	else
6299 		return CMD_WARNING;
6300 
6301 	/* `show ip ospf database LSA'. */
6302 	if (argc == arg_base + 5)
6303 		show_lsa_detail(vty, ospf, type, NULL, NULL);
6304 	else if (argc >= arg_base + 6) {
6305 		ret = inet_aton(argv[arg_base + 5]->arg, &id);
6306 		if (!ret)
6307 			return CMD_WARNING;
6308 
6309 		/* `show ip ospf database LSA ID'. */
6310 		if (argc == arg_base + 6)
6311 			show_lsa_detail(vty, ospf, type, &id, NULL);
6312 		/* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */
6313 		else if (argc == arg_base + 7) {
6314 			if (strncmp(argv[arg_base + 6]->text, "s", 1) == 0)
6315 				adv_router = ospf->router_id;
6316 			else {
6317 				ret = inet_aton(argv[arg_base + 7]->arg,
6318 						&adv_router);
6319 				if (!ret)
6320 					return CMD_WARNING;
6321 			}
6322 			show_lsa_detail(vty, ospf, type, &id, &adv_router);
6323 		}
6324 	}
6325 
6326 	return CMD_SUCCESS;
6327 }
6328 
6329 DEFUN (show_ip_ospf_database_max,
6330        show_ip_ospf_database_max_cmd,
6331        "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>",
6332        SHOW_STR
6333        IP_STR
6334        "OSPF information\n"
6335        VRF_CMD_HELP_STR
6336        "All VRFs\n"
6337        "Database summary\n"
6338        "LSAs in MaxAge list\n"
6339        "Self-originated link states\n")
6340 {
6341 	struct ospf *ospf = NULL;
6342 	struct listnode *node = NULL;
6343 	char *vrf_name = NULL;
6344 	bool all_vrf = false;
6345 	int ret = CMD_SUCCESS;
6346 	int inst = 0;
6347 	int idx_vrf = 0;
6348 	uint8_t use_vrf = 0;
6349 
6350 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
6351 
6352 	if (vrf_name) {
6353 		bool ospf_output = false;
6354 
6355 		use_vrf = 1;
6356 
6357 		if (all_vrf) {
6358 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
6359 				if (!ospf->oi_running)
6360 					continue;
6361 				ospf_output = true;
6362 				ret = show_ip_ospf_database_common(
6363 					vty, ospf, idx_vrf ? 2 : 0, argc, argv,
6364 					use_vrf);
6365 			}
6366 
6367 			if (!ospf_output)
6368 				vty_out(vty, "%% OSPF instance not found\n");
6369 		} else {
6370 			ospf = ospf_lookup_by_inst_name(inst, vrf_name);
6371 			if (ospf == NULL || !ospf->oi_running) {
6372 				vty_out(vty, "%% OSPF instance not found\n");
6373 				return CMD_SUCCESS;
6374 			}
6375 			ret = (show_ip_ospf_database_common(
6376 				vty, ospf, idx_vrf ? 2 : 0, argc, argv,
6377 				use_vrf));
6378 		}
6379 	} else {
6380 		/* Display default ospf (instance 0) info */
6381 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
6382 		if (ospf == NULL || !ospf->oi_running) {
6383 			vty_out(vty, "%% OSPF instance not found\n");
6384 			return CMD_SUCCESS;
6385 		}
6386 
6387 		ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv,
6388 						   use_vrf);
6389 	}
6390 
6391 	return ret;
6392 }
6393 
6394 DEFUN (show_ip_ospf_instance_database,
6395        show_ip_ospf_instance_database_cmd,
6396        "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
6397        SHOW_STR
6398        IP_STR
6399        "OSPF information\n"
6400        "Instance ID\n"
6401        VRF_CMD_HELP_STR
6402        "Database summary\n"
6403         OSPF_LSA_TYPES_DESC
6404        "Link State ID (as an IP address)\n"
6405        "Self-originated link states\n"
6406        "Advertising Router link states\n"
6407        "Advertising Router (as an IP address)\n")
6408 {
6409 	struct ospf *ospf;
6410 	unsigned short instance = 0;
6411 	struct listnode *node = NULL;
6412 	char *vrf_name = NULL;
6413 	bool all_vrf = false;
6414 	int ret = CMD_SUCCESS;
6415 	int inst = 0;
6416 	int idx = 0;
6417 	uint8_t use_vrf = 0;
6418 
6419 	if (argv_find(argv, argc, "(1-65535)", &idx)) {
6420 		instance = strtoul(argv[idx]->arg, NULL, 10);
6421 		ospf = ospf_lookup_instance(instance);
6422 		if (ospf == NULL)
6423 			return CMD_NOT_MY_INSTANCE;
6424 		if (!ospf->oi_running)
6425 			return CMD_SUCCESS;
6426 
6427 		return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0,
6428 						     argc, argv, use_vrf));
6429 	} else if (argv_find(argv, argc, "vrf", &idx)) {
6430 		vrf_name = argv[++idx]->arg;
6431 		all_vrf = strmatch(vrf_name, "all");
6432 	}
6433 
6434 	if (vrf_name) {
6435 		use_vrf = 1;
6436 		if (all_vrf) {
6437 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
6438 				if (!ospf->oi_running)
6439 					continue;
6440 				ret = (show_ip_ospf_database_common(
6441 					vty, ospf, idx ? 2 : 0, argc, argv,
6442 					use_vrf));
6443 			}
6444 		} else {
6445 			ospf = ospf_lookup_by_inst_name(inst, vrf_name);
6446 			if ((ospf == NULL) || !ospf->oi_running) {
6447 				vty_out(vty, "%% OSPF instance not found\n");
6448 				return CMD_SUCCESS;
6449 			}
6450 
6451 			ret = (show_ip_ospf_database_common(
6452 				vty, ospf, idx ? 2 : 0, argc, argv, use_vrf));
6453 		}
6454 	} else {
6455 		/* Display default ospf (instance 0) info */
6456 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
6457 		if (ospf == NULL || !ospf->oi_running) {
6458 			vty_out(vty, "%% OSPF instance not found\n");
6459 			return CMD_SUCCESS;
6460 		}
6461 
6462 		ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv,
6463 						    use_vrf));
6464 	}
6465 
6466 	return ret;
6467 }
6468 
6469 DEFUN (show_ip_ospf_instance_database_max,
6470        show_ip_ospf_instance_database_max_cmd,
6471        "show ip ospf (1-65535) database <max-age|self-originate>",
6472        SHOW_STR
6473        IP_STR
6474        "OSPF information\n"
6475        "Instance ID\n"
6476        "Database summary\n"
6477        "LSAs in MaxAge list\n"
6478        "Self-originated link states\n")
6479 {
6480 	int idx_number = 3;
6481 	struct ospf *ospf;
6482 	unsigned short instance = 0;
6483 
6484 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
6485 
6486 	ospf = ospf_lookup_instance(instance);
6487 	if (ospf == NULL)
6488 		return CMD_NOT_MY_INSTANCE;
6489 
6490 	if (!ospf->oi_running) {
6491 		vty_out(vty, "%% OSPF instance not found\n");
6492 		return CMD_SUCCESS;
6493 	}
6494 
6495 	return show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0);
6496 }
6497 
6498 
show_ip_ospf_database_type_adv_router_common(struct vty * vty,struct ospf * ospf,int arg_base,int argc,struct cmd_token ** argv,uint8_t use_vrf)6499 static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
6500 							struct ospf *ospf,
6501 							int arg_base, int argc,
6502 							struct cmd_token **argv,
6503 							uint8_t use_vrf)
6504 {
6505 	int idx_type = 4;
6506 	int type, ret;
6507 	struct in_addr adv_router;
6508 
6509 	if (ospf->instance)
6510 		vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance);
6511 
6512 	ospf_show_vrf_name(ospf, vty, NULL, use_vrf);
6513 
6514 	vty_out(vty, "\n       OSPF Router with ID (%s)\n\n",
6515 		inet_ntoa(ospf->router_id));
6516 
6517 	/* Set database type to show. */
6518 	if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0)
6519 		type = OSPF_ROUTER_LSA;
6520 	else if (strncmp(argv[arg_base + idx_type]->text, "ne", 2) == 0)
6521 		type = OSPF_NETWORK_LSA;
6522 	else if (strncmp(argv[arg_base + idx_type]->text, "ns", 2) == 0)
6523 		type = OSPF_AS_NSSA_LSA;
6524 	else if (strncmp(argv[arg_base + idx_type]->text, "s", 1) == 0)
6525 		type = OSPF_SUMMARY_LSA;
6526 	else if (strncmp(argv[arg_base + idx_type]->text, "a", 1) == 0)
6527 		type = OSPF_ASBR_SUMMARY_LSA;
6528 	else if (strncmp(argv[arg_base + idx_type]->text, "e", 1) == 0)
6529 		type = OSPF_AS_EXTERNAL_LSA;
6530 	else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0)
6531 		type = OSPF_OPAQUE_LINK_LSA;
6532 	else if (strncmp(argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0)
6533 		type = OSPF_OPAQUE_AREA_LSA;
6534 	else if (strncmp(argv[arg_base + idx_type]->text, "opaque-as", 9) == 0)
6535 		type = OSPF_OPAQUE_AS_LSA;
6536 	else
6537 		return CMD_WARNING;
6538 
6539 	/* `show ip ospf database LSA adv-router ADV_ROUTER'. */
6540 	if (strncmp(argv[arg_base + 5]->text, "s", 1) == 0)
6541 		adv_router = ospf->router_id;
6542 	else {
6543 		ret = inet_aton(argv[arg_base + 6]->arg, &adv_router);
6544 		if (!ret)
6545 			return CMD_WARNING;
6546 	}
6547 
6548 	show_lsa_detail_adv_router(vty, ospf, type, &adv_router);
6549 
6550 	return CMD_SUCCESS;
6551 }
6552 
6553 DEFUN (show_ip_ospf_instance_database_type_adv_router,
6554        show_ip_ospf_instance_database_type_adv_router_cmd,
6555        "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
6556        SHOW_STR
6557        IP_STR
6558        "OSPF information\n"
6559        "Instance ID\n"
6560        VRF_CMD_HELP_STR
6561        "Database summary\n"
6562        OSPF_LSA_TYPES_DESC
6563        "Advertising Router link states\n"
6564        "Advertising Router (as an IP address)\n"
6565        "Self-originated link states\n")
6566 {
6567 	struct ospf *ospf = NULL;
6568 	unsigned short instance = 0;
6569 	struct listnode *node = NULL;
6570 	char *vrf_name = NULL;
6571 	bool all_vrf = false;
6572 	int ret = CMD_SUCCESS;
6573 	int inst = 0;
6574 	int idx = 0, idx_vrf = 0;
6575 	uint8_t use_vrf = 0;
6576 
6577 	if (argv_find(argv, argc, "(1-65535)", &idx)) {
6578 		instance = strtoul(argv[idx]->arg, NULL, 10);
6579 		ospf = ospf_lookup_instance(instance);
6580 		if (ospf == NULL)
6581 			return CMD_NOT_MY_INSTANCE;
6582 		if (!ospf->oi_running) {
6583 			vty_out(vty, "%% OSPF instance not found\n");
6584 			return CMD_SUCCESS;
6585 		}
6586 
6587 		return (show_ip_ospf_database_type_adv_router_common(
6588 			vty, ospf, idx ? 1 : 0, argc, argv, use_vrf));
6589 	}
6590 
6591 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
6592 
6593 	if (vrf_name) {
6594 		bool ospf_output = false;
6595 
6596 		use_vrf = 1;
6597 
6598 		if (all_vrf) {
6599 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
6600 				if (!ospf->oi_running)
6601 					continue;
6602 				ospf_output = true;
6603 				ret = show_ip_ospf_database_type_adv_router_common(
6604 					vty, ospf, 2, argc, argv, use_vrf);
6605 			}
6606 			if (!ospf_output)
6607 				vty_out(vty, "%% OSPF instance not found\n");
6608 		} else {
6609 			ospf = ospf_lookup_by_inst_name(inst, vrf_name);
6610 			if ((ospf == NULL) || !ospf->oi_running) {
6611 				vty_out(vty, "%% OSPF instance not found\n");
6612 				return CMD_SUCCESS;
6613 			}
6614 
6615 			ret = show_ip_ospf_database_type_adv_router_common(
6616 				vty, ospf, 2, argc, argv, use_vrf);
6617 		}
6618 	} else {
6619 		/* Display default ospf (instance 0) info */
6620 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
6621 		if (ospf == NULL || !ospf->oi_running) {
6622 			vty_out(vty, "%% OSPF instance not found\n");
6623 			return CMD_SUCCESS;
6624 		}
6625 
6626 		ret = show_ip_ospf_database_type_adv_router_common(
6627 			vty, ospf, idx ? 1 : 0, argc, argv, use_vrf);
6628 	}
6629 	return ret;
6630 	/*return (show_ip_ospf_database_type_adv_router_common(
6631 		vty, ospf, idx ? 1 : 0, argc, argv));*/
6632 }
6633 
6634 DEFUN (ip_ospf_authentication_args,
6635        ip_ospf_authentication_args_addr_cmd,
6636        "ip ospf authentication <null|message-digest> [A.B.C.D]",
6637        "IP Information\n"
6638        "OSPF interface commands\n"
6639        "Enable authentication on this interface\n"
6640        "Use null authentication\n"
6641        "Use message-digest authentication\n"
6642        "Address of interface\n")
6643 {
6644 	VTY_DECLVAR_CONTEXT(interface, ifp);
6645 	int idx_encryption = 3;
6646 	int idx_ipv4 = 4;
6647 	struct in_addr addr;
6648 	int ret;
6649 	struct ospf_if_params *params;
6650 
6651 	params = IF_DEF_PARAMS(ifp);
6652 
6653 	if (argc == 5) {
6654 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
6655 		if (!ret) {
6656 			vty_out(vty,
6657 				"Please specify interface address by A.B.C.D\n");
6658 			return CMD_WARNING_CONFIG_FAILED;
6659 		}
6660 
6661 		params = ospf_get_if_params(ifp, addr);
6662 		ospf_if_update_params(ifp, addr);
6663 	}
6664 
6665 	/* Handle null authentication */
6666 	if (argv[idx_encryption]->arg[0] == 'n') {
6667 		SET_IF_PARAM(params, auth_type);
6668 		params->auth_type = OSPF_AUTH_NULL;
6669 		return CMD_SUCCESS;
6670 	}
6671 
6672 	/* Handle message-digest authentication */
6673 	if (argv[idx_encryption]->arg[0] == 'm') {
6674 		SET_IF_PARAM(params, auth_type);
6675 		params->auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
6676 		return CMD_SUCCESS;
6677 	}
6678 
6679 	vty_out(vty, "You shouldn't get here!\n");
6680 	return CMD_WARNING_CONFIG_FAILED;
6681 }
6682 
6683 DEFUN (ip_ospf_authentication,
6684        ip_ospf_authentication_addr_cmd,
6685        "ip ospf authentication [A.B.C.D]",
6686        "IP Information\n"
6687        "OSPF interface commands\n"
6688        "Enable authentication on this interface\n"
6689        "Address of interface\n")
6690 {
6691 	VTY_DECLVAR_CONTEXT(interface, ifp);
6692 	int idx_ipv4 = 3;
6693 	struct in_addr addr;
6694 	int ret;
6695 	struct ospf_if_params *params;
6696 
6697 	params = IF_DEF_PARAMS(ifp);
6698 
6699 	if (argc == 4) {
6700 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
6701 		if (!ret) {
6702 			vty_out(vty,
6703 				"Please specify interface address by A.B.C.D\n");
6704 			return CMD_WARNING_CONFIG_FAILED;
6705 		}
6706 
6707 		params = ospf_get_if_params(ifp, addr);
6708 		ospf_if_update_params(ifp, addr);
6709 	}
6710 
6711 	SET_IF_PARAM(params, auth_type);
6712 	params->auth_type = OSPF_AUTH_SIMPLE;
6713 
6714 	return CMD_SUCCESS;
6715 }
6716 
6717 DEFUN (no_ip_ospf_authentication_args,
6718        no_ip_ospf_authentication_args_addr_cmd,
6719        "no ip ospf authentication <null|message-digest> [A.B.C.D]",
6720        NO_STR
6721        "IP Information\n"
6722        "OSPF interface commands\n"
6723        "Enable authentication on this interface\n"
6724        "Use null authentication\n"
6725        "Use message-digest authentication\n"
6726        "Address of interface\n")
6727 {
6728 	VTY_DECLVAR_CONTEXT(interface, ifp);
6729 	int idx_encryption = 4;
6730 	int idx_ipv4 = 5;
6731 	struct in_addr addr;
6732 	int ret;
6733 	struct ospf_if_params *params;
6734 	struct route_node *rn;
6735 	int auth_type;
6736 
6737 	params = IF_DEF_PARAMS(ifp);
6738 
6739 	if (argc == 6) {
6740 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
6741 		if (!ret) {
6742 			vty_out(vty,
6743 				"Please specify interface address by A.B.C.D\n");
6744 			return CMD_WARNING_CONFIG_FAILED;
6745 		}
6746 
6747 		params = ospf_lookup_if_params(ifp, addr);
6748 		if (params == NULL) {
6749 			vty_out(vty, "Ip Address specified is unknown\n");
6750 			return CMD_WARNING_CONFIG_FAILED;
6751 		}
6752 		params->auth_type = OSPF_AUTH_NOTSET;
6753 		UNSET_IF_PARAM(params, auth_type);
6754 		if (params != IF_DEF_PARAMS(ifp)) {
6755 			ospf_free_if_params(ifp, addr);
6756 			ospf_if_update_params(ifp, addr);
6757 		}
6758 	} else {
6759 		if (argv[idx_encryption]->arg[0] == 'n') {
6760 			auth_type = OSPF_AUTH_NULL;
6761 		} else if (argv[idx_encryption]->arg[0] == 'm') {
6762 			auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
6763 		} else {
6764 			vty_out(vty, "Unexpected input encountered\n");
6765 			return CMD_WARNING_CONFIG_FAILED;
6766 		}
6767 		/*
6768 		 * Here we have a case where the user has entered
6769 		 * 'no ip ospf authentication (null | message_digest )'
6770 		 * we need to find if we have any ip addresses underneath it
6771 		 * that
6772 		 * correspond to the associated type.
6773 		 */
6774 		if (params->auth_type == auth_type) {
6775 			params->auth_type = OSPF_AUTH_NOTSET;
6776 			UNSET_IF_PARAM(params, auth_type);
6777 		}
6778 
6779 		for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn;
6780 		     rn = route_next(rn)) {
6781 			if ((params = rn->info)) {
6782 				if (params->auth_type == auth_type) {
6783 					params->auth_type = OSPF_AUTH_NOTSET;
6784 					UNSET_IF_PARAM(params, auth_type);
6785 					if (params != IF_DEF_PARAMS(ifp)) {
6786 						ospf_free_if_params(
6787 							ifp, rn->p.u.prefix4);
6788 						ospf_if_update_params(
6789 							ifp, rn->p.u.prefix4);
6790 					}
6791 				}
6792 			}
6793 		}
6794 	}
6795 
6796 	return CMD_SUCCESS;
6797 }
6798 
6799 DEFUN (no_ip_ospf_authentication,
6800        no_ip_ospf_authentication_addr_cmd,
6801        "no ip ospf authentication [A.B.C.D]",
6802        NO_STR
6803        "IP Information\n"
6804        "OSPF interface commands\n"
6805        "Enable authentication on this interface\n"
6806        "Address of interface\n")
6807 {
6808 	VTY_DECLVAR_CONTEXT(interface, ifp);
6809 	int idx_ipv4 = 4;
6810 	struct in_addr addr;
6811 	int ret;
6812 	struct ospf_if_params *params;
6813 	struct route_node *rn;
6814 
6815 	params = IF_DEF_PARAMS(ifp);
6816 
6817 	if (argc == 5) {
6818 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
6819 		if (!ret) {
6820 			vty_out(vty,
6821 				"Please specify interface address by A.B.C.D\n");
6822 			return CMD_WARNING_CONFIG_FAILED;
6823 		}
6824 
6825 		params = ospf_lookup_if_params(ifp, addr);
6826 		if (params == NULL) {
6827 			vty_out(vty, "Ip Address specified is unknown\n");
6828 			return CMD_WARNING_CONFIG_FAILED;
6829 		}
6830 
6831 		params->auth_type = OSPF_AUTH_NOTSET;
6832 		UNSET_IF_PARAM(params, auth_type);
6833 		if (params != IF_DEF_PARAMS(ifp)) {
6834 			ospf_free_if_params(ifp, addr);
6835 			ospf_if_update_params(ifp, addr);
6836 		}
6837 	} else {
6838 		/*
6839 		 * When a user enters 'no ip ospf authentication'
6840 		 * We should remove all authentication types from
6841 		 * the interface.
6842 		 */
6843 		if ((params->auth_type == OSPF_AUTH_NULL)
6844 		    || (params->auth_type == OSPF_AUTH_CRYPTOGRAPHIC)
6845 		    || (params->auth_type == OSPF_AUTH_SIMPLE)) {
6846 			params->auth_type = OSPF_AUTH_NOTSET;
6847 			UNSET_IF_PARAM(params, auth_type);
6848 		}
6849 
6850 		for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn;
6851 		     rn = route_next(rn)) {
6852 			if ((params = rn->info)) {
6853 
6854 				if ((params->auth_type == OSPF_AUTH_NULL)
6855 				    || (params->auth_type
6856 					== OSPF_AUTH_CRYPTOGRAPHIC)
6857 				    || (params->auth_type
6858 					== OSPF_AUTH_SIMPLE)) {
6859 					params->auth_type = OSPF_AUTH_NOTSET;
6860 					UNSET_IF_PARAM(params, auth_type);
6861 					if (params != IF_DEF_PARAMS(ifp)) {
6862 						ospf_free_if_params(
6863 							ifp, rn->p.u.prefix4);
6864 						ospf_if_update_params(
6865 							ifp, rn->p.u.prefix4);
6866 					}
6867 				}
6868 			}
6869 		}
6870 	}
6871 
6872 	return CMD_SUCCESS;
6873 }
6874 
6875 
6876 DEFUN (ip_ospf_authentication_key,
6877        ip_ospf_authentication_key_addr_cmd,
6878        "ip ospf authentication-key AUTH_KEY [A.B.C.D]",
6879        "IP Information\n"
6880        "OSPF interface commands\n"
6881        "Authentication password (key)\n"
6882        "The OSPF password (key)\n"
6883        "Address of interface\n")
6884 {
6885 	VTY_DECLVAR_CONTEXT(interface, ifp);
6886 	int idx = 0;
6887 	struct in_addr addr;
6888 	struct ospf_if_params *params;
6889 
6890 	params = IF_DEF_PARAMS(ifp);
6891 
6892 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
6893 		if (!inet_aton(argv[idx]->arg, &addr)) {
6894 			vty_out(vty,
6895 				"Please specify interface address by A.B.C.D\n");
6896 			return CMD_WARNING_CONFIG_FAILED;
6897 		}
6898 
6899 		params = ospf_get_if_params(ifp, addr);
6900 		ospf_if_update_params(ifp, addr);
6901 	}
6902 
6903 	strlcpy((char *)params->auth_simple, argv[3]->arg,
6904 		sizeof(params->auth_simple));
6905 	SET_IF_PARAM(params, auth_simple);
6906 
6907 	return CMD_SUCCESS;
6908 }
6909 
6910 DEFUN_HIDDEN (ospf_authentication_key,
6911               ospf_authentication_key_cmd,
6912               "ospf authentication-key AUTH_KEY [A.B.C.D]",
6913               "OSPF interface commands\n"
6914               VLINK_HELPSTR_AUTH_SIMPLE
6915               "Address of interface\n")
6916 {
6917 	return ip_ospf_authentication_key(self, vty, argc, argv);
6918 }
6919 
6920 DEFUN (no_ip_ospf_authentication_key,
6921        no_ip_ospf_authentication_key_authkey_addr_cmd,
6922        "no ip ospf authentication-key [AUTH_KEY [A.B.C.D]]",
6923        NO_STR
6924        "IP Information\n"
6925        "OSPF interface commands\n"
6926        VLINK_HELPSTR_AUTH_SIMPLE
6927        "Address of interface\n")
6928 {
6929 	VTY_DECLVAR_CONTEXT(interface, ifp);
6930 	int idx = 0;
6931 	struct in_addr addr;
6932 	struct ospf_if_params *params;
6933 	params = IF_DEF_PARAMS(ifp);
6934 
6935 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
6936 		if (!inet_aton(argv[idx]->arg, &addr)) {
6937 			vty_out(vty,
6938 				"Please specify interface address by A.B.C.D\n");
6939 			return CMD_WARNING_CONFIG_FAILED;
6940 		}
6941 
6942 		params = ospf_lookup_if_params(ifp, addr);
6943 		if (params == NULL)
6944 			return CMD_SUCCESS;
6945 	}
6946 
6947 	memset(params->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
6948 	UNSET_IF_PARAM(params, auth_simple);
6949 
6950 	if (params != IF_DEF_PARAMS(ifp)) {
6951 		ospf_free_if_params(ifp, addr);
6952 		ospf_if_update_params(ifp, addr);
6953 	}
6954 
6955 	return CMD_SUCCESS;
6956 }
6957 
6958 DEFUN_HIDDEN (no_ospf_authentication_key,
6959               no_ospf_authentication_key_authkey_addr_cmd,
6960               "no ospf authentication-key [AUTH_KEY [A.B.C.D]]",
6961               NO_STR
6962               "OSPF interface commands\n"
6963               VLINK_HELPSTR_AUTH_SIMPLE
6964 	      "Address of interface\n")
6965 {
6966 	return no_ip_ospf_authentication_key(self, vty, argc, argv);
6967 }
6968 
6969 DEFUN (ip_ospf_message_digest_key,
6970        ip_ospf_message_digest_key_cmd,
6971        "ip ospf message-digest-key (1-255) md5 KEY [A.B.C.D]",
6972        "IP Information\n"
6973        "OSPF interface commands\n"
6974        "Message digest authentication password (key)\n"
6975        "Key ID\n"
6976        "Use MD5 algorithm\n"
6977        "The OSPF password (key)\n"
6978        "Address of interface\n")
6979 {
6980 	VTY_DECLVAR_CONTEXT(interface, ifp);
6981 	struct crypt_key *ck;
6982 	uint8_t key_id;
6983 	struct in_addr addr;
6984 	struct ospf_if_params *params;
6985 
6986 	params = IF_DEF_PARAMS(ifp);
6987 	int idx = 0;
6988 
6989 	argv_find(argv, argc, "(1-255)", &idx);
6990 	char *keyid = argv[idx]->arg;
6991 	argv_find(argv, argc, "KEY", &idx);
6992 	char *cryptkey = argv[idx]->arg;
6993 
6994 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
6995 		if (!inet_aton(argv[idx]->arg, &addr)) {
6996 			vty_out(vty,
6997 				"Please specify interface address by A.B.C.D\n");
6998 			return CMD_WARNING_CONFIG_FAILED;
6999 		}
7000 
7001 		params = ospf_get_if_params(ifp, addr);
7002 		ospf_if_update_params(ifp, addr);
7003 	}
7004 
7005 	key_id = strtol(keyid, NULL, 10);
7006 	if (ospf_crypt_key_lookup(params->auth_crypt, key_id) != NULL) {
7007 		vty_out(vty, "OSPF: Key %d already exists\n", key_id);
7008 		return CMD_WARNING;
7009 	}
7010 
7011 	ck = ospf_crypt_key_new();
7012 	ck->key_id = (uint8_t)key_id;
7013 	strlcpy((char *)ck->auth_key, cryptkey, sizeof(ck->auth_key));
7014 
7015 	ospf_crypt_key_add(params->auth_crypt, ck);
7016 	SET_IF_PARAM(params, auth_crypt);
7017 
7018 	return CMD_SUCCESS;
7019 }
7020 
7021 DEFUN_HIDDEN (ospf_message_digest_key,
7022               ospf_message_digest_key_cmd,
7023               "ospf message-digest-key (1-255) md5 KEY [A.B.C.D]",
7024               "OSPF interface commands\n"
7025               "Message digest authentication password (key)\n"
7026               "Key ID\n"
7027               "Use MD5 algorithm\n"
7028               "The OSPF password (key)\n"
7029               "Address of interface\n")
7030 {
7031 	return ip_ospf_message_digest_key(self, vty, argc, argv);
7032 }
7033 
7034 DEFUN (no_ip_ospf_message_digest_key,
7035        no_ip_ospf_message_digest_key_cmd,
7036        "no ip ospf message-digest-key (1-255) [md5 KEY] [A.B.C.D]",
7037         NO_STR
7038        "IP Information\n"
7039        "OSPF interface commands\n"
7040        "Message digest authentication password (key)\n"
7041        "Key ID\n"
7042        "Use MD5 algorithm\n"
7043        "The OSPF password (key)\n"
7044        "Address of interface\n")
7045 {
7046 	VTY_DECLVAR_CONTEXT(interface, ifp);
7047 	int idx = 0;
7048 	struct crypt_key *ck;
7049 	int key_id;
7050 	struct in_addr addr;
7051 	struct ospf_if_params *params;
7052 	params = IF_DEF_PARAMS(ifp);
7053 
7054 	argv_find(argv, argc, "(1-255)", &idx);
7055 	char *keyid = argv[idx]->arg;
7056 
7057 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7058 		if (!inet_aton(argv[idx]->arg, &addr)) {
7059 			vty_out(vty,
7060 				"Please specify interface address by A.B.C.D\n");
7061 			return CMD_WARNING_CONFIG_FAILED;
7062 		}
7063 
7064 		params = ospf_lookup_if_params(ifp, addr);
7065 		if (params == NULL)
7066 			return CMD_SUCCESS;
7067 	}
7068 
7069 	key_id = strtol(keyid, NULL, 10);
7070 	ck = ospf_crypt_key_lookup(params->auth_crypt, key_id);
7071 	if (ck == NULL) {
7072 		vty_out(vty, "OSPF: Key %d does not exist\n", key_id);
7073 		return CMD_WARNING_CONFIG_FAILED;
7074 	}
7075 
7076 	ospf_crypt_key_delete(params->auth_crypt, key_id);
7077 
7078 	if (params != IF_DEF_PARAMS(ifp)) {
7079 		ospf_free_if_params(ifp, addr);
7080 		ospf_if_update_params(ifp, addr);
7081 	}
7082 
7083 	return CMD_SUCCESS;
7084 }
7085 
7086 DEFUN_HIDDEN (no_ospf_message_digest_key,
7087               no_ospf_message_digest_key_cmd,
7088               "no ospf message-digest-key (1-255) [md5 KEY] [A.B.C.D]",
7089               NO_STR
7090               "OSPF interface commands\n"
7091               "Message digest authentication password (key)\n"
7092               "Key ID\n"
7093               "Use MD5 algorithm\n"
7094               "The OSPF password (key)\n"
7095               "Address of interface\n")
7096 {
7097 	return no_ip_ospf_message_digest_key(self, vty, argc, argv);
7098 }
7099 
7100 DEFUN (ip_ospf_cost,
7101        ip_ospf_cost_cmd,
7102        "ip ospf cost (1-65535) [A.B.C.D]",
7103        "IP Information\n"
7104        "OSPF interface commands\n"
7105        "Interface cost\n"
7106        "Cost\n"
7107        "Address of interface\n")
7108 {
7109 	VTY_DECLVAR_CONTEXT(interface, ifp);
7110 	int idx = 0;
7111 	uint32_t cost = OSPF_OUTPUT_COST_DEFAULT;
7112 	struct in_addr addr;
7113 	struct ospf_if_params *params;
7114 	params = IF_DEF_PARAMS(ifp);
7115 
7116 	// get arguments
7117 	char *coststr = NULL, *ifaddr = NULL;
7118 
7119 	argv_find(argv, argc, "(1-65535)", &idx);
7120 	coststr = argv[idx]->arg;
7121 	cost = strtol(coststr, NULL, 10);
7122 
7123 	ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
7124 	if (ifaddr) {
7125 		if (!inet_aton(ifaddr, &addr)) {
7126 			vty_out(vty,
7127 				"Please specify interface address by A.B.C.D\n");
7128 			return CMD_WARNING_CONFIG_FAILED;
7129 		}
7130 
7131 		params = ospf_get_if_params(ifp, addr);
7132 		ospf_if_update_params(ifp, addr);
7133 	}
7134 
7135 	SET_IF_PARAM(params, output_cost_cmd);
7136 	params->output_cost_cmd = cost;
7137 
7138 	ospf_if_recalculate_output_cost(ifp);
7139 
7140 	return CMD_SUCCESS;
7141 }
7142 
7143 DEFUN_HIDDEN (ospf_cost,
7144               ospf_cost_cmd,
7145               "ospf cost (1-65535) [A.B.C.D]",
7146               "OSPF interface commands\n"
7147               "Interface cost\n"
7148               "Cost\n"
7149               "Address of interface\n")
7150 {
7151 	return ip_ospf_cost(self, vty, argc, argv);
7152 }
7153 
7154 DEFUN (no_ip_ospf_cost,
7155        no_ip_ospf_cost_cmd,
7156        "no ip ospf cost [(1-65535)] [A.B.C.D]",
7157        NO_STR
7158        "IP Information\n"
7159        "OSPF interface commands\n"
7160        "Interface cost\n"
7161        "Cost\n"
7162        "Address of interface\n")
7163 {
7164 	VTY_DECLVAR_CONTEXT(interface, ifp);
7165 	int idx = 0;
7166 	struct in_addr addr;
7167 	struct ospf_if_params *params;
7168 
7169 	params = IF_DEF_PARAMS(ifp);
7170 
7171 	// get arguments
7172 	char *ifaddr = NULL;
7173 	ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
7174 
7175 	/* According to the semantics we are mimicking "no ip ospf cost N" is
7176 	 * always treated as "no ip ospf cost" regardless of the actual value
7177 	 * of N already configured for the interface. Thus ignore cost. */
7178 
7179 	if (ifaddr) {
7180 		if (!inet_aton(ifaddr, &addr)) {
7181 			vty_out(vty,
7182 				"Please specify interface address by A.B.C.D\n");
7183 			return CMD_WARNING_CONFIG_FAILED;
7184 		}
7185 
7186 		params = ospf_lookup_if_params(ifp, addr);
7187 		if (params == NULL)
7188 			return CMD_SUCCESS;
7189 	}
7190 
7191 	UNSET_IF_PARAM(params, output_cost_cmd);
7192 
7193 	if (params != IF_DEF_PARAMS(ifp)) {
7194 		ospf_free_if_params(ifp, addr);
7195 		ospf_if_update_params(ifp, addr);
7196 	}
7197 
7198 	ospf_if_recalculate_output_cost(ifp);
7199 
7200 	return CMD_SUCCESS;
7201 }
7202 
7203 DEFUN_HIDDEN (no_ospf_cost,
7204               no_ospf_cost_cmd,
7205               "no ospf cost [(1-65535)] [A.B.C.D]",
7206               NO_STR
7207               "OSPF interface commands\n"
7208               "Interface cost\n"
7209               "Cost\n"
7210               "Address of interface\n")
7211 {
7212 	return no_ip_ospf_cost(self, vty, argc, argv);
7213 }
7214 
ospf_nbr_timer_update(struct ospf_interface * oi)7215 static void ospf_nbr_timer_update(struct ospf_interface *oi)
7216 {
7217 	struct route_node *rn;
7218 	struct ospf_neighbor *nbr;
7219 
7220 	for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
7221 		if ((nbr = rn->info)) {
7222 			nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait);
7223 			nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval);
7224 			nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval);
7225 			nbr->v_ls_upd = OSPF_IF_PARAM(oi, retransmit_interval);
7226 		}
7227 }
7228 
ospf_vty_dead_interval_set(struct vty * vty,const char * interval_str,const char * nbr_str,const char * fast_hello_str)7229 static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str,
7230 				      const char *nbr_str,
7231 				      const char *fast_hello_str)
7232 {
7233 	VTY_DECLVAR_CONTEXT(interface, ifp);
7234 	uint32_t seconds;
7235 	uint8_t hellomult;
7236 	struct in_addr addr;
7237 	int ret;
7238 	struct ospf_if_params *params;
7239 	struct ospf_interface *oi;
7240 	struct route_node *rn;
7241 
7242 	params = IF_DEF_PARAMS(ifp);
7243 
7244 	if (nbr_str) {
7245 		ret = inet_aton(nbr_str, &addr);
7246 		if (!ret) {
7247 			vty_out(vty,
7248 				"Please specify interface address by A.B.C.D\n");
7249 			return CMD_WARNING_CONFIG_FAILED;
7250 		}
7251 
7252 		params = ospf_get_if_params(ifp, addr);
7253 		ospf_if_update_params(ifp, addr);
7254 	}
7255 
7256 	if (interval_str) {
7257 		seconds = strtoul(interval_str, NULL, 10);
7258 
7259 		/* reset fast_hello too, just to be sure */
7260 		UNSET_IF_PARAM(params, fast_hello);
7261 		params->fast_hello = OSPF_FAST_HELLO_DEFAULT;
7262 	} else if (fast_hello_str) {
7263 		hellomult = strtoul(fast_hello_str, NULL, 10);
7264 		/* 1s dead-interval with sub-second hellos desired */
7265 		seconds = OSPF_ROUTER_DEAD_INTERVAL_MINIMAL;
7266 		SET_IF_PARAM(params, fast_hello);
7267 		params->fast_hello = hellomult;
7268 	} else {
7269 		vty_out(vty,
7270 			"Please specify dead-interval or hello-multiplier\n");
7271 		return CMD_WARNING_CONFIG_FAILED;
7272 	}
7273 
7274 	SET_IF_PARAM(params, v_wait);
7275 	params->v_wait = seconds;
7276 	params->is_v_wait_set = true;
7277 
7278 	/* Update timer values in neighbor structure. */
7279 	if (nbr_str) {
7280 		struct ospf *ospf = NULL;
7281 
7282 		ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
7283 		if (ospf) {
7284 			oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
7285 			if (oi)
7286 				ospf_nbr_timer_update(oi);
7287 		}
7288 	} else {
7289 		for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
7290 			if ((oi = rn->info))
7291 				ospf_nbr_timer_update(oi);
7292 	}
7293 
7294 	return CMD_SUCCESS;
7295 }
7296 
7297 DEFUN (ip_ospf_dead_interval,
7298        ip_ospf_dead_interval_cmd,
7299        "ip ospf dead-interval (1-65535) [A.B.C.D]",
7300        "IP Information\n"
7301        "OSPF interface commands\n"
7302        "Interval time after which a neighbor is declared down\n"
7303        "Seconds\n"
7304        "Address of interface\n")
7305 {
7306 	int idx = 0;
7307 	char *interval = argv_find(argv, argc, "(1-65535)", &idx)
7308 				 ? argv[idx]->arg
7309 				 : NULL;
7310 	char *ifaddr =
7311 		argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
7312 	return ospf_vty_dead_interval_set(vty, interval, ifaddr, NULL);
7313 }
7314 
7315 
7316 DEFUN_HIDDEN (ospf_dead_interval,
7317               ospf_dead_interval_cmd,
7318               "ospf dead-interval (1-65535) [A.B.C.D]",
7319               "OSPF interface commands\n"
7320               "Interval time after which a neighbor is declared down\n"
7321               "Seconds\n"
7322               "Address of interface\n")
7323 {
7324 	return ip_ospf_dead_interval(self, vty, argc, argv);
7325 }
7326 
7327 DEFUN (ip_ospf_dead_interval_minimal,
7328        ip_ospf_dead_interval_minimal_addr_cmd,
7329        "ip ospf dead-interval minimal hello-multiplier (1-10) [A.B.C.D]",
7330        "IP Information\n"
7331        "OSPF interface commands\n"
7332        "Interval time after which a neighbor is declared down\n"
7333        "Minimal 1s dead-interval with fast sub-second hellos\n"
7334        "Hello multiplier factor\n"
7335        "Number of Hellos to send each second\n"
7336        "Address of interface\n")
7337 {
7338 	int idx_number = 5;
7339 	int idx_ipv4 = 6;
7340 	if (argc == 7)
7341 		return ospf_vty_dead_interval_set(
7342 			vty, NULL, argv[idx_ipv4]->arg, argv[idx_number]->arg);
7343 	else
7344 		return ospf_vty_dead_interval_set(vty, NULL, NULL,
7345 						  argv[idx_number]->arg);
7346 }
7347 
7348 DEFUN (no_ip_ospf_dead_interval,
7349        no_ip_ospf_dead_interval_cmd,
7350        "no ip ospf dead-interval [<(1-65535)|minimal hello-multiplier (1-10)> [A.B.C.D]]",
7351        NO_STR
7352        "IP Information\n"
7353        "OSPF interface commands\n"
7354        "Interval time after which a neighbor is declared down\n"
7355        "Seconds\n"
7356        "Minimal 1s dead-interval with fast sub-second hellos\n"
7357        "Hello multiplier factor\n"
7358        "Number of Hellos to send each second\n"
7359        "Address of interface\n")
7360 {
7361 	VTY_DECLVAR_CONTEXT(interface, ifp);
7362 	int idx_ipv4 = argc - 1;
7363 	struct in_addr addr = {.s_addr = 0L};
7364 	int ret;
7365 	struct ospf_if_params *params;
7366 	struct ospf_interface *oi;
7367 	struct route_node *rn;
7368 
7369 	params = IF_DEF_PARAMS(ifp);
7370 
7371 	if (argv[idx_ipv4]->type == IPV4_TKN) {
7372 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
7373 		if (!ret) {
7374 			vty_out(vty,
7375 				"Please specify interface address by A.B.C.D\n");
7376 			return CMD_WARNING_CONFIG_FAILED;
7377 		}
7378 
7379 		params = ospf_lookup_if_params(ifp, addr);
7380 		if (params == NULL)
7381 			return CMD_SUCCESS;
7382 	}
7383 
7384 	UNSET_IF_PARAM(params, v_wait);
7385 	params->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
7386 	params->is_v_wait_set = false;
7387 
7388 	UNSET_IF_PARAM(params, fast_hello);
7389 	params->fast_hello = OSPF_FAST_HELLO_DEFAULT;
7390 
7391 	if (params != IF_DEF_PARAMS(ifp)) {
7392 		ospf_free_if_params(ifp, addr);
7393 		ospf_if_update_params(ifp, addr);
7394 	}
7395 
7396 	/* Update timer values in neighbor structure. */
7397 	if (argc == 1) {
7398 		struct ospf *ospf = NULL;
7399 
7400 		ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
7401 		if (ospf) {
7402 			oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
7403 			if (oi)
7404 				ospf_nbr_timer_update(oi);
7405 		}
7406 	} else {
7407 		for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
7408 			if ((oi = rn->info))
7409 				ospf_nbr_timer_update(oi);
7410 	}
7411 
7412 	return CMD_SUCCESS;
7413 }
7414 
7415 DEFUN_HIDDEN (no_ospf_dead_interval,
7416               no_ospf_dead_interval_cmd,
7417               "no ospf dead-interval [<(1-65535)|minimal hello-multiplier (1-10)> [A.B.C.D]]",
7418               NO_STR
7419               "OSPF interface commands\n"
7420               "Interval time after which a neighbor is declared down\n"
7421               "Seconds\n"
7422               "Minimal 1s dead-interval with fast sub-second hellos\n"
7423               "Hello multiplier factor\n"
7424               "Number of Hellos to send each second\n"
7425               "Address of interface\n")
7426 {
7427 	return no_ip_ospf_dead_interval(self, vty, argc, argv);
7428 }
7429 
7430 DEFUN (ip_ospf_hello_interval,
7431        ip_ospf_hello_interval_cmd,
7432        "ip ospf hello-interval (1-65535) [A.B.C.D]",
7433        "IP Information\n"
7434        "OSPF interface commands\n"
7435        "Time between HELLO packets\n"
7436        "Seconds\n"
7437        "Address of interface\n")
7438 {
7439 	VTY_DECLVAR_CONTEXT(interface, ifp);
7440 	int idx = 0;
7441 	struct in_addr addr;
7442 	struct ospf_if_params *params;
7443 	params = IF_DEF_PARAMS(ifp);
7444 	uint32_t seconds = 0;
7445 
7446 	argv_find(argv, argc, "(1-65535)", &idx);
7447 	seconds = strtol(argv[idx]->arg, NULL, 10);
7448 
7449 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7450 		if (!inet_aton(argv[idx]->arg, &addr)) {
7451 			vty_out(vty,
7452 				"Please specify interface address by A.B.C.D\n");
7453 			return CMD_WARNING_CONFIG_FAILED;
7454 		}
7455 
7456 		params = ospf_get_if_params(ifp, addr);
7457 		ospf_if_update_params(ifp, addr);
7458 	}
7459 
7460 	SET_IF_PARAM(params, v_hello);
7461 	params->v_hello = seconds;
7462 
7463 	if (!params->is_v_wait_set) {
7464 		SET_IF_PARAM(params, v_wait);
7465 		/* As per RFC 4062
7466 		 * The router dead interval should
7467 		 * be some multiple of the HelloInterval (perhaps 4 times the
7468 		 * hello interval) and must be the same for all routers
7469 		 * attached to a common network.
7470 		 */
7471 		params->v_wait	= 4 * seconds;
7472 	}
7473 
7474 	return CMD_SUCCESS;
7475 }
7476 
7477 DEFUN_HIDDEN (ospf_hello_interval,
7478               ospf_hello_interval_cmd,
7479               "ospf hello-interval (1-65535) [A.B.C.D]",
7480               "OSPF interface commands\n"
7481               "Time between HELLO packets\n"
7482               "Seconds\n"
7483               "Address of interface\n")
7484 {
7485 	return ip_ospf_hello_interval(self, vty, argc, argv);
7486 }
7487 
7488 DEFUN (no_ip_ospf_hello_interval,
7489        no_ip_ospf_hello_interval_cmd,
7490        "no ip ospf hello-interval [(1-65535) [A.B.C.D]]",
7491        NO_STR
7492        "IP Information\n"
7493        "OSPF interface commands\n"
7494        "Time between HELLO packets\n" // ignored
7495        "Seconds\n"
7496        "Address of interface\n")
7497 {
7498 	VTY_DECLVAR_CONTEXT(interface, ifp);
7499 	int idx = 0;
7500 	struct in_addr addr;
7501 	struct ospf_if_params *params;
7502 	struct route_node *rn;
7503 
7504 	params = IF_DEF_PARAMS(ifp);
7505 
7506 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7507 		if (!inet_aton(argv[idx]->arg, &addr)) {
7508 			vty_out(vty,
7509 				"Please specify interface address by A.B.C.D\n");
7510 			return CMD_WARNING_CONFIG_FAILED;
7511 		}
7512 
7513 		params = ospf_lookup_if_params(ifp, addr);
7514 		if (params == NULL)
7515 			return CMD_SUCCESS;
7516 	}
7517 
7518 	UNSET_IF_PARAM(params, v_hello);
7519 	params->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
7520 
7521 	if (!params->is_v_wait_set) {
7522 		UNSET_IF_PARAM(params, v_wait);
7523 		params->v_wait  = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
7524 	}
7525 
7526 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
7527 		struct ospf_interface *oi = rn->info;
7528 
7529 		if (!oi)
7530 			continue;
7531 
7532 		oi->type = IF_DEF_PARAMS(ifp)->type;
7533 
7534 		if (oi->state > ISM_Down) {
7535 			OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
7536 			OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
7537 		}
7538 	}
7539 
7540 	if (params != IF_DEF_PARAMS(ifp)) {
7541 		ospf_free_if_params(ifp, addr);
7542 		ospf_if_update_params(ifp, addr);
7543 	}
7544 
7545 	return CMD_SUCCESS;
7546 }
7547 
7548 DEFUN_HIDDEN (no_ospf_hello_interval,
7549               no_ospf_hello_interval_cmd,
7550               "no ospf hello-interval [(1-65535) [A.B.C.D]]",
7551               NO_STR
7552               "OSPF interface commands\n"
7553               "Time between HELLO packets\n" // ignored
7554               "Seconds\n"
7555               "Address of interface\n")
7556 {
7557 	return no_ip_ospf_hello_interval(self, vty, argc, argv);
7558 }
7559 
7560 DEFUN (ip_ospf_network,
7561        ip_ospf_network_cmd,
7562        "ip ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point>",
7563        "IP Information\n"
7564        "OSPF interface commands\n"
7565        "Network type\n"
7566        "Specify OSPF broadcast multi-access network\n"
7567        "Specify OSPF NBMA network\n"
7568        "Specify OSPF point-to-multipoint network\n"
7569        "Specify OSPF point-to-point network\n")
7570 {
7571 	VTY_DECLVAR_CONTEXT(interface, ifp);
7572 	int idx = 0;
7573 	int old_type = IF_DEF_PARAMS(ifp)->type;
7574 	struct route_node *rn;
7575 
7576 	if (old_type == OSPF_IFTYPE_LOOPBACK) {
7577 		vty_out(vty,
7578 			"This is a loopback interface. Can't set network type.\n");
7579 		return CMD_WARNING_CONFIG_FAILED;
7580 	}
7581 
7582 	if (argv_find(argv, argc, "broadcast", &idx))
7583 		IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_BROADCAST;
7584 	else if (argv_find(argv, argc, "non-broadcast", &idx))
7585 		IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA;
7586 	else if (argv_find(argv, argc, "point-to-multipoint", &idx))
7587 		IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT;
7588 	else if (argv_find(argv, argc, "point-to-point", &idx))
7589 		IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOPOINT;
7590 
7591 	if (IF_DEF_PARAMS(ifp)->type == old_type)
7592 		return CMD_SUCCESS;
7593 
7594 	SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
7595 
7596 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
7597 		struct ospf_interface *oi = rn->info;
7598 
7599 		if (!oi)
7600 			continue;
7601 
7602 		oi->type = IF_DEF_PARAMS(ifp)->type;
7603 
7604 		if (oi->state > ISM_Down) {
7605 			OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
7606 			OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
7607 		}
7608 	}
7609 
7610 	return CMD_SUCCESS;
7611 }
7612 
7613 DEFUN_HIDDEN (ospf_network,
7614               ospf_network_cmd,
7615               "ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point>",
7616               "OSPF interface commands\n"
7617               "Network type\n"
7618               "Specify OSPF broadcast multi-access network\n"
7619               "Specify OSPF NBMA network\n"
7620               "Specify OSPF point-to-multipoint network\n"
7621               "Specify OSPF point-to-point network\n")
7622 {
7623 	return ip_ospf_network(self, vty, argc, argv);
7624 }
7625 
7626 DEFUN (no_ip_ospf_network,
7627        no_ip_ospf_network_cmd,
7628        "no ip ospf network [<broadcast|non-broadcast|point-to-multipoint|point-to-point>]",
7629        NO_STR
7630        "IP Information\n"
7631        "OSPF interface commands\n"
7632        "Network type\n"
7633        "Specify OSPF broadcast multi-access network\n"
7634        "Specify OSPF NBMA network\n"
7635        "Specify OSPF point-to-multipoint network\n"
7636        "Specify OSPF point-to-point network\n")
7637 {
7638 	VTY_DECLVAR_CONTEXT(interface, ifp);
7639 	int old_type = IF_DEF_PARAMS(ifp)->type;
7640 	struct route_node *rn;
7641 
7642 	IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
7643 
7644 	if (IF_DEF_PARAMS(ifp)->type == old_type)
7645 		return CMD_SUCCESS;
7646 
7647 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
7648 		struct ospf_interface *oi = rn->info;
7649 
7650 		if (!oi)
7651 			continue;
7652 
7653 		oi->type = IF_DEF_PARAMS(ifp)->type;
7654 
7655 		if (oi->state > ISM_Down) {
7656 			OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
7657 			OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
7658 		}
7659 	}
7660 
7661 	return CMD_SUCCESS;
7662 }
7663 
7664 DEFUN_HIDDEN (no_ospf_network,
7665               no_ospf_network_cmd,
7666               "no ospf network [<broadcast|non-broadcast|point-to-multipoint|point-to-point>]",
7667               NO_STR
7668               "OSPF interface commands\n"
7669               "Network type\n"
7670               "Specify OSPF broadcast multi-access network\n"
7671               "Specify OSPF NBMA network\n"
7672               "Specify OSPF point-to-multipoint network\n"
7673               "Specify OSPF point-to-point network\n")
7674 {
7675 	return no_ip_ospf_network(self, vty, argc, argv);
7676 }
7677 
7678 DEFUN (ip_ospf_priority,
7679        ip_ospf_priority_cmd,
7680        "ip ospf priority (0-255) [A.B.C.D]",
7681        "IP Information\n"
7682        "OSPF interface commands\n"
7683        "Router priority\n"
7684        "Priority\n"
7685        "Address of interface\n")
7686 {
7687 	VTY_DECLVAR_CONTEXT(interface, ifp);
7688 	int idx = 0;
7689 	long priority;
7690 	struct route_node *rn;
7691 	struct in_addr addr;
7692 	struct ospf_if_params *params;
7693 	params = IF_DEF_PARAMS(ifp);
7694 
7695 	argv_find(argv, argc, "(0-255)", &idx);
7696 	priority = strtol(argv[idx]->arg, NULL, 10);
7697 
7698 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7699 		if (!inet_aton(argv[idx]->arg, &addr)) {
7700 			vty_out(vty,
7701 				"Please specify interface address by A.B.C.D\n");
7702 			return CMD_WARNING_CONFIG_FAILED;
7703 		}
7704 
7705 		params = ospf_get_if_params(ifp, addr);
7706 		ospf_if_update_params(ifp, addr);
7707 	}
7708 
7709 	SET_IF_PARAM(params, priority);
7710 	params->priority = priority;
7711 
7712 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
7713 		struct ospf_interface *oi = rn->info;
7714 
7715 		if (!oi)
7716 			continue;
7717 
7718 		if (PRIORITY(oi) != OSPF_IF_PARAM(oi, priority)) {
7719 			PRIORITY(oi) = OSPF_IF_PARAM(oi, priority);
7720 			OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
7721 		}
7722 	}
7723 
7724 	return CMD_SUCCESS;
7725 }
7726 
7727 DEFUN_HIDDEN (ospf_priority,
7728               ospf_priority_cmd,
7729               "ospf priority (0-255) [A.B.C.D]",
7730               "OSPF interface commands\n"
7731               "Router priority\n"
7732               "Priority\n"
7733               "Address of interface\n")
7734 {
7735 	return ip_ospf_priority(self, vty, argc, argv);
7736 }
7737 
7738 DEFUN (no_ip_ospf_priority,
7739        no_ip_ospf_priority_cmd,
7740        "no ip ospf priority [(0-255) [A.B.C.D]]",
7741        NO_STR
7742        "IP Information\n"
7743        "OSPF interface commands\n"
7744        "Router priority\n" // ignored
7745        "Priority\n"
7746        "Address of interface\n")
7747 {
7748 	VTY_DECLVAR_CONTEXT(interface, ifp);
7749 	int idx = 0;
7750 	struct route_node *rn;
7751 	struct in_addr addr;
7752 	struct ospf_if_params *params;
7753 
7754 	params = IF_DEF_PARAMS(ifp);
7755 
7756 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7757 		if (!inet_aton(argv[idx]->arg, &addr)) {
7758 			vty_out(vty,
7759 				"Please specify interface address by A.B.C.D\n");
7760 			return CMD_WARNING_CONFIG_FAILED;
7761 		}
7762 
7763 		params = ospf_lookup_if_params(ifp, addr);
7764 		if (params == NULL)
7765 			return CMD_SUCCESS;
7766 	}
7767 
7768 	UNSET_IF_PARAM(params, priority);
7769 	params->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
7770 
7771 	if (params != IF_DEF_PARAMS(ifp)) {
7772 		ospf_free_if_params(ifp, addr);
7773 		ospf_if_update_params(ifp, addr);
7774 	}
7775 
7776 	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
7777 		struct ospf_interface *oi = rn->info;
7778 
7779 		if (!oi)
7780 			continue;
7781 
7782 		if (PRIORITY(oi) != OSPF_IF_PARAM(oi, priority)) {
7783 			PRIORITY(oi) = OSPF_IF_PARAM(oi, priority);
7784 			OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
7785 		}
7786 	}
7787 
7788 	return CMD_SUCCESS;
7789 }
7790 
7791 DEFUN_HIDDEN (no_ospf_priority,
7792               no_ospf_priority_cmd,
7793               "no ospf priority [(0-255) [A.B.C.D]]",
7794               NO_STR
7795               "OSPF interface commands\n"
7796               "Router priority\n"
7797               "Priority\n"
7798               "Address of interface\n")
7799 {
7800 	return no_ip_ospf_priority(self, vty, argc, argv);
7801 }
7802 
7803 DEFUN (ip_ospf_retransmit_interval,
7804        ip_ospf_retransmit_interval_addr_cmd,
7805        "ip ospf retransmit-interval (1-65535) [A.B.C.D]",
7806        "IP Information\n"
7807        "OSPF interface commands\n"
7808        "Time between retransmitting lost link state advertisements\n"
7809        "Seconds\n"
7810        "Address of interface\n")
7811 {
7812 	VTY_DECLVAR_CONTEXT(interface, ifp);
7813 	int idx = 0;
7814 	uint32_t seconds;
7815 	struct in_addr addr;
7816 	struct ospf_if_params *params;
7817 	params = IF_DEF_PARAMS(ifp);
7818 
7819 	argv_find(argv, argc, "(1-65535)", &idx);
7820 	seconds = strtol(argv[idx]->arg, NULL, 10);
7821 
7822 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7823 		if (!inet_aton(argv[idx]->arg, &addr)) {
7824 			vty_out(vty,
7825 				"Please specify interface address by A.B.C.D\n");
7826 			return CMD_WARNING_CONFIG_FAILED;
7827 		}
7828 
7829 		params = ospf_get_if_params(ifp, addr);
7830 		ospf_if_update_params(ifp, addr);
7831 	}
7832 
7833 	SET_IF_PARAM(params, retransmit_interval);
7834 	params->retransmit_interval = seconds;
7835 
7836 	return CMD_SUCCESS;
7837 }
7838 
7839 DEFUN_HIDDEN (ospf_retransmit_interval,
7840               ospf_retransmit_interval_cmd,
7841               "ospf retransmit-interval (1-65535) [A.B.C.D]",
7842               "OSPF interface commands\n"
7843               "Time between retransmitting lost link state advertisements\n"
7844               "Seconds\n"
7845               "Address of interface\n")
7846 {
7847 	return ip_ospf_retransmit_interval(self, vty, argc, argv);
7848 }
7849 
7850 DEFUN (no_ip_ospf_retransmit_interval,
7851        no_ip_ospf_retransmit_interval_addr_cmd,
7852        "no ip ospf retransmit-interval [(1-65535)] [A.B.C.D]",
7853        NO_STR
7854        "IP Information\n"
7855        "OSPF interface commands\n"
7856        "Time between retransmitting lost link state advertisements\n"
7857        "Seconds\n"
7858        "Address of interface\n")
7859 {
7860 	VTY_DECLVAR_CONTEXT(interface, ifp);
7861 	int idx = 0;
7862 	struct in_addr addr;
7863 	struct ospf_if_params *params;
7864 
7865 	params = IF_DEF_PARAMS(ifp);
7866 
7867 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7868 		if (!inet_aton(argv[idx]->arg, &addr)) {
7869 			vty_out(vty,
7870 				"Please specify interface address by A.B.C.D\n");
7871 			return CMD_WARNING_CONFIG_FAILED;
7872 		}
7873 
7874 		params = ospf_lookup_if_params(ifp, addr);
7875 		if (params == NULL)
7876 			return CMD_SUCCESS;
7877 	}
7878 
7879 	UNSET_IF_PARAM(params, retransmit_interval);
7880 	params->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
7881 
7882 	if (params != IF_DEF_PARAMS(ifp)) {
7883 		ospf_free_if_params(ifp, addr);
7884 		ospf_if_update_params(ifp, addr);
7885 	}
7886 
7887 	return CMD_SUCCESS;
7888 }
7889 
7890 DEFUN_HIDDEN (no_ospf_retransmit_interval,
7891        no_ospf_retransmit_interval_cmd,
7892        "no ospf retransmit-interval [(1-65535)] [A.B.C.D]",
7893        NO_STR
7894        "OSPF interface commands\n"
7895        "Time between retransmitting lost link state advertisements\n"
7896        "Seconds\n"
7897        "Address of interface\n")
7898 {
7899 	return no_ip_ospf_retransmit_interval(self, vty, argc, argv);
7900 }
7901 
7902 DEFUN (ip_ospf_transmit_delay,
7903        ip_ospf_transmit_delay_addr_cmd,
7904        "ip ospf transmit-delay (1-65535) [A.B.C.D]",
7905        "IP Information\n"
7906        "OSPF interface commands\n"
7907        "Link state transmit delay\n"
7908        "Seconds\n"
7909        "Address of interface\n")
7910 {
7911 	VTY_DECLVAR_CONTEXT(interface, ifp);
7912 	int idx = 0;
7913 	uint32_t seconds;
7914 	struct in_addr addr;
7915 	struct ospf_if_params *params;
7916 
7917 	params = IF_DEF_PARAMS(ifp);
7918 	argv_find(argv, argc, "(1-65535)", &idx);
7919 	seconds = strtol(argv[idx]->arg, NULL, 10);
7920 
7921 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7922 		if (!inet_aton(argv[idx]->arg, &addr)) {
7923 			vty_out(vty,
7924 				"Please specify interface address by A.B.C.D\n");
7925 			return CMD_WARNING_CONFIG_FAILED;
7926 		}
7927 
7928 		params = ospf_get_if_params(ifp, addr);
7929 		ospf_if_update_params(ifp, addr);
7930 	}
7931 
7932 	SET_IF_PARAM(params, transmit_delay);
7933 	params->transmit_delay = seconds;
7934 
7935 	return CMD_SUCCESS;
7936 }
7937 
7938 DEFUN_HIDDEN (ospf_transmit_delay,
7939               ospf_transmit_delay_cmd,
7940               "ospf transmit-delay (1-65535) [A.B.C.D]",
7941               "OSPF interface commands\n"
7942               "Link state transmit delay\n"
7943               "Seconds\n"
7944               "Address of interface\n")
7945 {
7946 	return ip_ospf_transmit_delay(self, vty, argc, argv);
7947 }
7948 
7949 DEFUN (no_ip_ospf_transmit_delay,
7950        no_ip_ospf_transmit_delay_addr_cmd,
7951        "no ip ospf transmit-delay [(1-65535)] [A.B.C.D]",
7952        NO_STR
7953        "IP Information\n"
7954        "OSPF interface commands\n"
7955        "Link state transmit delay\n"
7956        "Seconds\n"
7957        "Address of interface\n")
7958 {
7959 	VTY_DECLVAR_CONTEXT(interface, ifp);
7960 	int idx = 0;
7961 	struct in_addr addr;
7962 	struct ospf_if_params *params;
7963 
7964 	params = IF_DEF_PARAMS(ifp);
7965 
7966 	if (argv_find(argv, argc, "A.B.C.D", &idx)) {
7967 		if (!inet_aton(argv[idx]->arg, &addr)) {
7968 			vty_out(vty,
7969 				"Please specify interface address by A.B.C.D\n");
7970 			return CMD_WARNING_CONFIG_FAILED;
7971 		}
7972 
7973 		params = ospf_lookup_if_params(ifp, addr);
7974 		if (params == NULL)
7975 			return CMD_SUCCESS;
7976 	}
7977 
7978 	UNSET_IF_PARAM(params, transmit_delay);
7979 	params->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
7980 
7981 	if (params != IF_DEF_PARAMS(ifp)) {
7982 		ospf_free_if_params(ifp, addr);
7983 		ospf_if_update_params(ifp, addr);
7984 	}
7985 
7986 	return CMD_SUCCESS;
7987 }
7988 
7989 
7990 DEFUN_HIDDEN (no_ospf_transmit_delay,
7991               no_ospf_transmit_delay_cmd,
7992               "no ospf transmit-delay [(1-65535) [A.B.C.D]]",
7993               NO_STR
7994               "OSPF interface commands\n"
7995               "Link state transmit delay\n"
7996               "Seconds\n"
7997               "Address of interface\n")
7998 {
7999 	return no_ip_ospf_transmit_delay(self, vty, argc, argv);
8000 }
8001 
8002 DEFUN (ip_ospf_area,
8003        ip_ospf_area_cmd,
8004        "ip ospf [(1-65535)] area <A.B.C.D|(0-4294967295)> [A.B.C.D]",
8005        "IP Information\n"
8006        "OSPF interface commands\n"
8007        "Instance ID\n"
8008        "Enable OSPF on this interface\n"
8009        "OSPF area ID in IP address format\n"
8010        "OSPF area ID as a decimal value\n"
8011        "Address of interface\n")
8012 {
8013 	VTY_DECLVAR_CONTEXT(interface, ifp);
8014 	int idx = 0;
8015 	int format, ret;
8016 	struct in_addr area_id;
8017 	struct in_addr addr;
8018 	struct ospf_if_params *params = NULL;
8019 	struct route_node *rn;
8020 	struct ospf *ospf = NULL;
8021 	unsigned short instance = 0;
8022 	char *areaid;
8023 	uint32_t count = 0;
8024 
8025 	if (argv_find(argv, argc, "(1-65535)", &idx))
8026 		instance = strtol(argv[idx]->arg, NULL, 10);
8027 
8028 	argv_find(argv, argc, "area", &idx);
8029 	areaid = argv[idx + 1]->arg;
8030 
8031 	if (ifp->vrf_id && !instance)
8032 		ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
8033 	else
8034 		ospf = ospf_lookup_instance(instance);
8035 
8036 	if (instance && ospf == NULL) {
8037 		/*
8038 		 * At this point we know we have received
8039 		 * an instance and there is no ospf instance
8040 		 * associated with it.  This means we are
8041 		 * in a situation where we have an
8042 		 * ospf command that is setup for a different
8043 		 * process(instance).  We need to safely
8044 		 * remove the command from ourselves and
8045 		 * allow the other instance(process) handle
8046 		 * the configuration command.
8047 		 */
8048 		count = 0;
8049 
8050 		params = IF_DEF_PARAMS(ifp);
8051 		if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
8052 			UNSET_IF_PARAM(params, if_area);
8053 			count++;
8054 		}
8055 
8056 		for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
8057 			if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
8058 				UNSET_IF_PARAM(params, if_area);
8059 				count++;
8060 			}
8061 
8062 		if (count > 0) {
8063 			ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
8064 			if (ospf) {
8065 				ospf_interface_area_unset(ospf, ifp);
8066 				ospf->if_ospf_cli_count -= count;
8067 			}
8068 		}
8069 
8070 		return CMD_NOT_MY_INSTANCE;
8071 	}
8072 
8073 	ret = str2area_id(areaid, &area_id, &format);
8074 	if (ret < 0) {
8075 		vty_out(vty, "Please specify area by A.B.C.D|<0-4294967295>\n");
8076 		return CMD_WARNING_CONFIG_FAILED;
8077 	}
8078 	if (memcmp(ifp->name, "VLINK", 5) == 0) {
8079 		vty_out(vty, "Cannot enable OSPF on a virtual link.\n");
8080 		return CMD_WARNING_CONFIG_FAILED;
8081 	}
8082 
8083 	if (ospf) {
8084 		for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
8085 			if (rn->info != NULL) {
8086 				vty_out(vty,
8087 					"Please remove all network commands first.\n");
8088 				return CMD_WARNING_CONFIG_FAILED;
8089 			}
8090 		}
8091 	}
8092 
8093 	params = IF_DEF_PARAMS(ifp);
8094 	if (OSPF_IF_PARAM_CONFIGURED(params, if_area)
8095 	    && !IPV4_ADDR_SAME(&params->if_area, &area_id)) {
8096 		vty_out(vty,
8097 			"Must remove previous area config before changing ospf area \n");
8098 		return CMD_WARNING_CONFIG_FAILED;
8099 	}
8100 
8101 	// Check if we have an address arg and proccess it
8102 	if (argc == idx + 3) {
8103 		if (!inet_aton(argv[idx + 2]->arg, &addr)) {
8104 			vty_out(vty,
8105 				"Please specify Intf Address by A.B.C.D\n");
8106 			return CMD_WARNING_CONFIG_FAILED;
8107 		}
8108 		// update/create address-level params
8109 		params = ospf_get_if_params((ifp), (addr));
8110 		if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
8111 			vty_out(vty,
8112 				"Must remove previous area/address config before changing ospf area\n");
8113 			return CMD_WARNING_CONFIG_FAILED;
8114 		}
8115 		ospf_if_update_params((ifp), (addr));
8116 	}
8117 
8118 	/* enable ospf on this interface with area_id */
8119 	if (params) {
8120 		SET_IF_PARAM(params, if_area);
8121 		params->if_area = area_id;
8122 		params->if_area_id_fmt = format;
8123 	}
8124 
8125 	if (ospf) {
8126 		ospf_interface_area_set(ospf, ifp);
8127 		ospf->if_ospf_cli_count++;
8128 	}
8129 
8130 	return CMD_SUCCESS;
8131 }
8132 
8133 DEFUN (no_ip_ospf_area,
8134        no_ip_ospf_area_cmd,
8135        "no ip ospf [(1-65535)] area [<A.B.C.D|(0-4294967295)> [A.B.C.D]]",
8136        NO_STR
8137        "IP Information\n"
8138        "OSPF interface commands\n"
8139        "Instance ID\n"
8140        "Disable OSPF on this interface\n"
8141        "OSPF area ID in IP address format\n"
8142        "OSPF area ID as a decimal value\n"
8143        "Address of interface\n")
8144 {
8145 	VTY_DECLVAR_CONTEXT(interface, ifp);
8146 	int idx = 0;
8147 	struct ospf *ospf;
8148 	struct ospf_if_params *params;
8149 	unsigned short instance = 0;
8150 	struct in_addr addr;
8151 	struct in_addr area_id;
8152 
8153 	if (argv_find(argv, argc, "(1-65535)", &idx))
8154 		instance = strtol(argv[idx]->arg, NULL, 10);
8155 
8156 	if (ifp->vrf_id && !instance)
8157 		ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
8158 	else
8159 		ospf = ospf_lookup_instance(instance);
8160 
8161 	if (instance && ospf == NULL)
8162 		return CMD_NOT_MY_INSTANCE;
8163 
8164 	argv_find(argv, argc, "area", &idx);
8165 
8166 	// Check if we have an address arg and proccess it
8167 	if (argc == idx + 3) {
8168 		if (!inet_aton(argv[idx + 2]->arg, &addr)) {
8169 			vty_out(vty,
8170 				"Please specify Intf Address by A.B.C.D\n");
8171 			return CMD_WARNING_CONFIG_FAILED;
8172 		}
8173 		params = ospf_lookup_if_params(ifp, addr);
8174 		if ((params) == NULL)
8175 			return CMD_SUCCESS;
8176 	} else
8177 		params = IF_DEF_PARAMS(ifp);
8178 
8179 	area_id = params->if_area;
8180 	if (!OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
8181 		vty_out(vty,
8182 			"Can't find specified interface area configuration.\n");
8183 		return CMD_WARNING_CONFIG_FAILED;
8184 	}
8185 
8186 	UNSET_IF_PARAM(params, if_area);
8187 	if (params != IF_DEF_PARAMS((ifp))) {
8188 		ospf_free_if_params((ifp), (addr));
8189 		ospf_if_update_params((ifp), (addr));
8190 	}
8191 
8192 	if (ospf) {
8193 		ospf_interface_area_unset(ospf, ifp);
8194 		ospf->if_ospf_cli_count--;
8195 		ospf_area_check_free(ospf, area_id);
8196 	}
8197 
8198 	return CMD_SUCCESS;
8199 }
8200 
8201 DEFUN (ospf_redistribute_source,
8202        ospf_redistribute_source_cmd,
8203        "redistribute " FRR_REDIST_STR_OSPFD " [{metric (0-16777214)|metric-type (1-2)|route-map WORD}]",
8204        REDIST_STR
8205        FRR_REDIST_HELP_STR_OSPFD
8206        "Metric for redistributed routes\n"
8207        "OSPF default metric\n"
8208        "OSPF exterior metric type for redistributed routes\n"
8209        "Set OSPF External Type 1/2 metrics\n"
8210        "Route map reference\n"
8211        "Pointer to route-map entries\n")
8212 {
8213 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8214 	int idx_protocol = 1;
8215 	int source;
8216 	int type = -1;
8217 	int metric = -1;
8218 	struct ospf_redist *red;
8219 	int idx = 0;
8220 
8221 	/* Get distribute source. */
8222 	source = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
8223 	if (source < 0)
8224 		return CMD_WARNING_CONFIG_FAILED;
8225 
8226 	red = ospf_redist_add(ospf, source, 0);
8227 
8228 	/* Get metric value. */
8229 	if (argv_find(argv, argc, "(0-16777214)", &idx)) {
8230 		if (!str2metric(argv[idx]->arg, &metric))
8231 			return CMD_WARNING_CONFIG_FAILED;
8232 	}
8233 	idx = 1;
8234 	/* Get metric type. */
8235 	if (argv_find(argv, argc, "(1-2)", &idx)) {
8236 		if (!str2metric_type(argv[idx]->arg, &type))
8237 			return CMD_WARNING_CONFIG_FAILED;
8238 	}
8239 	idx = 1;
8240 	/* Get route-map */
8241 	if (argv_find(argv, argc, "WORD", &idx)) {
8242 		ospf_routemap_set(red, argv[idx]->arg);
8243 	} else
8244 		ospf_routemap_unset(red);
8245 
8246 	return ospf_redistribute_set(ospf, source, 0, type, metric);
8247 }
8248 
8249 DEFUN (no_ospf_redistribute_source,
8250        no_ospf_redistribute_source_cmd,
8251        "no redistribute " FRR_REDIST_STR_OSPFD " [{metric (0-16777214)|metric-type (1-2)|route-map WORD}]",
8252        NO_STR
8253        REDIST_STR
8254        FRR_REDIST_HELP_STR_OSPFD
8255        "Metric for redistributed routes\n"
8256        "OSPF default metric\n"
8257        "OSPF exterior metric type for redistributed routes\n"
8258        "Set OSPF External Type 1/2 metrics\n"
8259        "Route map reference\n"
8260        "Pointer to route-map entries\n")
8261 {
8262 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8263 	int idx_protocol = 2;
8264 	int source;
8265 	struct ospf_redist *red;
8266 
8267 	source = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
8268 	if (source < 0)
8269 		return CMD_WARNING_CONFIG_FAILED;
8270 
8271 	red = ospf_redist_lookup(ospf, source, 0);
8272 	if (!red)
8273 		return CMD_SUCCESS;
8274 
8275 	ospf_routemap_unset(red);
8276 	ospf_redist_del(ospf, source, 0);
8277 
8278 	return ospf_redistribute_unset(ospf, source, 0);
8279 }
8280 
8281 DEFUN (ospf_redistribute_instance_source,
8282        ospf_redistribute_instance_source_cmd,
8283        "redistribute <ospf|table> (1-65535) [{metric (0-16777214)|metric-type (1-2)|route-map WORD}]",
8284        REDIST_STR
8285        "Open Shortest Path First\n"
8286        "Non-main Kernel Routing Table\n"
8287        "Instance ID/Table ID\n"
8288        "Metric for redistributed routes\n"
8289        "OSPF default metric\n"
8290        "OSPF exterior metric type for redistributed routes\n"
8291        "Set OSPF External Type 1/2 metrics\n"
8292        "Route map reference\n"
8293        "Pointer to route-map entries\n")
8294 {
8295 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8296 	int idx_ospf_table = 1;
8297 	int idx_number = 2;
8298 	int idx = 3;
8299 	int source;
8300 	int type = -1;
8301 	int metric = -1;
8302 	unsigned short instance;
8303 	struct ospf_redist *red;
8304 
8305 	source = proto_redistnum(AFI_IP, argv[idx_ospf_table]->text);
8306 
8307 	if (source < 0) {
8308 		vty_out(vty, "Unknown instance redistribution\n");
8309 		return CMD_WARNING_CONFIG_FAILED;
8310 	}
8311 
8312 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
8313 
8314 	if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) {
8315 		vty_out(vty,
8316 			"Instance redistribution in non-instanced OSPF not allowed\n");
8317 		return CMD_WARNING_CONFIG_FAILED;
8318 	}
8319 
8320 	if ((source == ZEBRA_ROUTE_OSPF) && (ospf->instance == instance)) {
8321 		vty_out(vty, "Same instance OSPF redistribution not allowed\n");
8322 		return CMD_WARNING_CONFIG_FAILED;
8323 	}
8324 
8325 	/* Get metric value. */
8326 	if (argv_find(argv, argc, "metric", &idx))
8327 		if (!str2metric(argv[idx + 1]->arg, &metric))
8328 			return CMD_WARNING_CONFIG_FAILED;
8329 
8330 	idx = 3;
8331 	/* Get metric type. */
8332 	if (argv_find(argv, argc, "metric-type", &idx))
8333 		if (!str2metric_type(argv[idx + 1]->arg, &type))
8334 			return CMD_WARNING_CONFIG_FAILED;
8335 
8336 	red = ospf_redist_add(ospf, source, instance);
8337 
8338 	idx = 3;
8339 	if (argv_find(argv, argc, "route-map", &idx))
8340 		ospf_routemap_set(red, argv[idx + 1]->arg);
8341 	else
8342 		ospf_routemap_unset(red);
8343 
8344 	return ospf_redistribute_set(ospf, source, instance, type, metric);
8345 }
8346 
8347 DEFUN (no_ospf_redistribute_instance_source,
8348        no_ospf_redistribute_instance_source_cmd,
8349        "no redistribute <ospf|table> (1-65535) [{metric (0-16777214)|metric-type (1-2)|route-map WORD}]",
8350        NO_STR
8351        REDIST_STR
8352        "Open Shortest Path First\n"
8353        "Non-main Kernel Routing Table\n"
8354        "Instance ID/Table Id\n"
8355        "Metric for redistributed routes\n"
8356        "OSPF default metric\n"
8357        "OSPF exterior metric type for redistributed routes\n"
8358        "Set OSPF External Type 1/2 metrics\n"
8359        "Route map reference\n"
8360        "Pointer to route-map entries\n")
8361 {
8362 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8363 	int idx_ospf_table = 2;
8364 	int idx_number = 3;
8365 	unsigned int instance;
8366 	struct ospf_redist *red;
8367 	int source;
8368 
8369 	if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
8370 		source = ZEBRA_ROUTE_OSPF;
8371 	else
8372 		source = ZEBRA_ROUTE_TABLE;
8373 
8374 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
8375 
8376 	if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) {
8377 		vty_out(vty,
8378 			"Instance redistribution in non-instanced OSPF not allowed\n");
8379 		return CMD_WARNING_CONFIG_FAILED;
8380 	}
8381 
8382 	if ((source == ZEBRA_ROUTE_OSPF) && (ospf->instance == instance)) {
8383 		vty_out(vty, "Same instance OSPF redistribution not allowed\n");
8384 		return CMD_WARNING_CONFIG_FAILED;
8385 	}
8386 
8387 	red = ospf_redist_lookup(ospf, source, instance);
8388 	if (!red)
8389 		return CMD_SUCCESS;
8390 
8391 	ospf_routemap_unset(red);
8392 	ospf_redist_del(ospf, source, instance);
8393 
8394 	return ospf_redistribute_unset(ospf, source, instance);
8395 }
8396 
8397 DEFUN (ospf_distribute_list_out,
8398        ospf_distribute_list_out_cmd,
8399        "distribute-list WORD out " FRR_REDIST_STR_OSPFD,
8400        "Filter networks in routing updates\n"
8401        "Access-list name\n"
8402        OUT_STR
8403        FRR_REDIST_HELP_STR_OSPFD)
8404 {
8405 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8406 	int idx_word = 1;
8407 	int source;
8408 
8409 	char *proto = argv[argc - 1]->text;
8410 
8411 	/* Get distribute source. */
8412 	source = proto_redistnum(AFI_IP, proto);
8413 	if (source < 0)
8414 		return CMD_WARNING_CONFIG_FAILED;
8415 
8416 	return ospf_distribute_list_out_set(ospf, source, argv[idx_word]->arg);
8417 }
8418 
8419 DEFUN (no_ospf_distribute_list_out,
8420        no_ospf_distribute_list_out_cmd,
8421        "no distribute-list WORD out " FRR_REDIST_STR_OSPFD,
8422        NO_STR
8423        "Filter networks in routing updates\n"
8424        "Access-list name\n"
8425        OUT_STR
8426        FRR_REDIST_HELP_STR_OSPFD)
8427 {
8428 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8429 	int idx_word = 2;
8430 	int source;
8431 
8432 	char *proto = argv[argc - 1]->text;
8433 	source = proto_redistnum(AFI_IP, proto);
8434 	if (source < 0)
8435 		return CMD_WARNING_CONFIG_FAILED;
8436 
8437 	return ospf_distribute_list_out_unset(ospf, source,
8438 					      argv[idx_word]->arg);
8439 }
8440 
8441 /* Default information originate. */
8442 DEFUN (ospf_default_information_originate,
8443        ospf_default_information_originate_cmd,
8444        "default-information originate [{always|metric (0-16777214)|metric-type (1-2)|route-map WORD}]",
8445        "Control distribution of default information\n"
8446        "Distribute a default route\n"
8447        "Always advertise default route\n"
8448        "OSPF default metric\n"
8449        "OSPF metric\n"
8450        "OSPF metric type for default routes\n"
8451        "Set OSPF External Type 1/2 metrics\n"
8452        "Route map reference\n"
8453        "Pointer to route-map entries\n")
8454 {
8455 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8456 	int default_originate = DEFAULT_ORIGINATE_ZEBRA;
8457 	int type = -1;
8458 	int metric = -1;
8459 	struct ospf_redist *red;
8460 	int idx = 0;
8461 	int cur_originate = ospf->default_originate;
8462 	int sameRtmap = 0;
8463 	char *rtmap = NULL;
8464 
8465 	red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
8466 
8467 	/* Check whether "always" was specified */
8468 	if (argv_find(argv, argc, "always", &idx))
8469 		default_originate = DEFAULT_ORIGINATE_ALWAYS;
8470 	idx = 1;
8471 	/* Get metric value */
8472 	if (argv_find(argv, argc, "(0-16777214)", &idx)) {
8473 		if (!str2metric(argv[idx]->arg, &metric))
8474 			return CMD_WARNING_CONFIG_FAILED;
8475 	}
8476 	idx = 1;
8477 	/* Get metric type. */
8478 	if (argv_find(argv, argc, "(1-2)", &idx)) {
8479 		if (!str2metric_type(argv[idx]->arg, &type))
8480 			return CMD_WARNING_CONFIG_FAILED;
8481 	}
8482 	idx = 1;
8483 	/* Get route-map */
8484 	if (argv_find(argv, argc, "WORD", &idx))
8485 		rtmap = argv[idx]->arg;
8486 
8487 	/* To check ,if user is providing same route map */
8488 	if ((rtmap == ROUTEMAP_NAME(red)) ||
8489 	    (rtmap && ROUTEMAP_NAME(red)
8490 	    && (strcmp(rtmap, ROUTEMAP_NAME(red)) == 0)))
8491 		sameRtmap = 1;
8492 
8493 	/* Don't allow if the same lsa is aleardy originated. */
8494 	if ((sameRtmap)
8495 	    && (red->dmetric.type == type)
8496 	    && (red->dmetric.value == metric)
8497 	    && (cur_originate == default_originate))
8498 		return CMD_SUCCESS;
8499 
8500 	/* Updating Metric details */
8501 	red->dmetric.type = type;
8502 	red->dmetric.value = metric;
8503 
8504 	/* updating route map details */
8505 	if (rtmap)
8506 		ospf_routemap_set(red, rtmap);
8507 	else
8508 		ospf_routemap_unset(red);
8509 
8510 	return ospf_redistribute_default_set(ospf, default_originate, type,
8511 					     metric);
8512 }
8513 
8514 DEFUN (no_ospf_default_information_originate,
8515        no_ospf_default_information_originate_cmd,
8516        "no default-information originate [{always|metric (0-16777214)|metric-type (1-2)|route-map WORD}]",
8517        NO_STR
8518        "Control distribution of default information\n"
8519        "Distribute a default route\n"
8520        "Always advertise default route\n"
8521        "OSPF default metric\n"
8522        "OSPF metric\n"
8523        "OSPF metric type for default routes\n"
8524        "Set OSPF External Type 1/2 metrics\n"
8525        "Route map reference\n"
8526        "Pointer to route-map entries\n")
8527 {
8528 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8529 	struct ospf_redist *red;
8530 
8531 	red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
8532 	if (!red)
8533 		return CMD_SUCCESS;
8534 
8535 	ospf_routemap_unset(red);
8536 	ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
8537 
8538 	return ospf_redistribute_default_set(ospf, DEFAULT_ORIGINATE_NONE,
8539 					     0, 0);
8540 }
8541 
8542 DEFUN (ospf_default_metric,
8543        ospf_default_metric_cmd,
8544        "default-metric (0-16777214)",
8545        "Set metric of redistributed routes\n"
8546        "Default metric\n")
8547 {
8548 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8549 	int idx_number = 1;
8550 	int metric = -1;
8551 
8552 	if (!str2metric(argv[idx_number]->arg, &metric))
8553 		return CMD_WARNING_CONFIG_FAILED;
8554 
8555 	ospf->default_metric = metric;
8556 
8557 	return CMD_SUCCESS;
8558 }
8559 
8560 DEFUN (no_ospf_default_metric,
8561        no_ospf_default_metric_cmd,
8562        "no default-metric [(0-16777214)]",
8563        NO_STR
8564        "Set metric of redistributed routes\n"
8565        "Default metric\n")
8566 {
8567 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8568 
8569 	ospf->default_metric = -1;
8570 
8571 	return CMD_SUCCESS;
8572 }
8573 
8574 
8575 DEFUN (ospf_distance,
8576        ospf_distance_cmd,
8577        "distance (1-255)",
8578        "Administrative distance\n"
8579        "OSPF Administrative distance\n")
8580 {
8581 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8582 	int idx_number = 1;
8583 
8584 	ospf->distance_all = atoi(argv[idx_number]->arg);
8585 
8586 	return CMD_SUCCESS;
8587 }
8588 
8589 DEFUN (no_ospf_distance,
8590        no_ospf_distance_cmd,
8591        "no distance (1-255)",
8592        NO_STR
8593        "Administrative distance\n"
8594        "OSPF Administrative distance\n")
8595 {
8596 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8597 
8598 	ospf->distance_all = 0;
8599 
8600 	return CMD_SUCCESS;
8601 }
8602 
8603 DEFUN (no_ospf_distance_ospf,
8604        no_ospf_distance_ospf_cmd,
8605        "no distance ospf [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
8606        NO_STR
8607        "Administrative distance\n"
8608        "OSPF administrative distance\n"
8609        "Intra-area routes\n"
8610        "Distance for intra-area routes\n"
8611        "Inter-area routes\n"
8612        "Distance for inter-area routes\n"
8613        "External routes\n"
8614        "Distance for external routes\n")
8615 {
8616 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8617 	int idx = 0;
8618 
8619 	if (argv_find(argv, argc, "intra-area", &idx) || argc == 3)
8620 		idx = ospf->distance_intra = 0;
8621 	if (argv_find(argv, argc, "inter-area", &idx) || argc == 3)
8622 		idx = ospf->distance_inter = 0;
8623 	if (argv_find(argv, argc, "external", &idx) || argc == 3)
8624 		ospf->distance_external = 0;
8625 
8626 	return CMD_SUCCESS;
8627 }
8628 
8629 DEFUN (ospf_distance_ospf,
8630        ospf_distance_ospf_cmd,
8631        "distance ospf {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
8632        "Administrative distance\n"
8633        "OSPF administrative distance\n"
8634        "Intra-area routes\n"
8635        "Distance for intra-area routes\n"
8636        "Inter-area routes\n"
8637        "Distance for inter-area routes\n"
8638        "External routes\n"
8639        "Distance for external routes\n")
8640 {
8641 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8642 	int idx = 0;
8643 
8644 	ospf->distance_intra = 0;
8645 	ospf->distance_inter = 0;
8646 	ospf->distance_external = 0;
8647 
8648 	if (argv_find(argv, argc, "intra-area", &idx))
8649 		ospf->distance_intra = atoi(argv[idx + 1]->arg);
8650 	idx = 0;
8651 	if (argv_find(argv, argc, "inter-area", &idx))
8652 		ospf->distance_inter = atoi(argv[idx + 1]->arg);
8653 	idx = 0;
8654 	if (argv_find(argv, argc, "external", &idx))
8655 		ospf->distance_external = atoi(argv[idx + 1]->arg);
8656 
8657 	return CMD_SUCCESS;
8658 }
8659 
8660 #if 0
8661 DEFUN (ospf_distance_source,
8662        ospf_distance_source_cmd,
8663        "distance (1-255) A.B.C.D/M",
8664        "Administrative distance\n"
8665        "Distance value\n"
8666        "IP source prefix\n")
8667 {
8668   VTY_DECLVAR_CONTEXT(ospf, ospf);
8669   int idx_number = 1;
8670   int idx_ipv4_prefixlen = 2;
8671 
8672   ospf_distance_set (vty, ospf, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
8673 
8674   return CMD_SUCCESS;
8675 }
8676 
8677 DEFUN (no_ospf_distance_source,
8678        no_ospf_distance_source_cmd,
8679        "no distance (1-255) A.B.C.D/M",
8680        NO_STR
8681        "Administrative distance\n"
8682        "Distance value\n"
8683        "IP source prefix\n")
8684 {
8685   VTY_DECLVAR_CONTEXT(ospf, ospf);
8686   int idx_number = 2;
8687   int idx_ipv4_prefixlen = 3;
8688 
8689   ospf_distance_unset (vty, ospf, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
8690 
8691   return CMD_SUCCESS;
8692 }
8693 
8694 DEFUN (ospf_distance_source_access_list,
8695        ospf_distance_source_access_list_cmd,
8696        "distance (1-255) A.B.C.D/M WORD",
8697        "Administrative distance\n"
8698        "Distance value\n"
8699        "IP source prefix\n"
8700        "Access list name\n")
8701 {
8702   VTY_DECLVAR_CONTEXT(ospf, ospf);
8703   int idx_number = 1;
8704   int idx_ipv4_prefixlen = 2;
8705   int idx_word = 3;
8706 
8707   ospf_distance_set (vty, ospf, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
8708 
8709   return CMD_SUCCESS;
8710 }
8711 
8712 DEFUN (no_ospf_distance_source_access_list,
8713        no_ospf_distance_source_access_list_cmd,
8714        "no distance (1-255) A.B.C.D/M WORD",
8715        NO_STR
8716        "Administrative distance\n"
8717        "Distance value\n"
8718        "IP source prefix\n"
8719        "Access list name\n")
8720 {
8721   VTY_DECLVAR_CONTEXT(ospf, ospf);
8722   int idx_number = 2;
8723   int idx_ipv4_prefixlen = 3;
8724   int idx_word = 4;
8725 
8726   ospf_distance_unset (vty, ospf, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
8727 
8728   return CMD_SUCCESS;
8729 }
8730 #endif
8731 
8732 DEFUN (ip_ospf_mtu_ignore,
8733        ip_ospf_mtu_ignore_addr_cmd,
8734        "ip ospf mtu-ignore [A.B.C.D]",
8735        "IP Information\n"
8736        "OSPF interface commands\n"
8737        "Disable MTU mismatch detection on this interface\n"
8738        "Address of interface\n")
8739 {
8740 	VTY_DECLVAR_CONTEXT(interface, ifp);
8741 	int idx_ipv4 = 3;
8742 	struct in_addr addr;
8743 	int ret;
8744 
8745 	struct ospf_if_params *params;
8746 	params = IF_DEF_PARAMS(ifp);
8747 
8748 	if (argc == 4) {
8749 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
8750 		if (!ret) {
8751 			vty_out(vty,
8752 				"Please specify interface address by A.B.C.D\n");
8753 			return CMD_WARNING_CONFIG_FAILED;
8754 		}
8755 		params = ospf_get_if_params(ifp, addr);
8756 		ospf_if_update_params(ifp, addr);
8757 	}
8758 	params->mtu_ignore = 1;
8759 	if (params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT)
8760 		SET_IF_PARAM(params, mtu_ignore);
8761 	else {
8762 		UNSET_IF_PARAM(params, mtu_ignore);
8763 		if (params != IF_DEF_PARAMS(ifp)) {
8764 			ospf_free_if_params(ifp, addr);
8765 			ospf_if_update_params(ifp, addr);
8766 		}
8767 	}
8768 	return CMD_SUCCESS;
8769 }
8770 
8771 DEFUN (no_ip_ospf_mtu_ignore,
8772        no_ip_ospf_mtu_ignore_addr_cmd,
8773        "no ip ospf mtu-ignore [A.B.C.D]",
8774        NO_STR
8775        "IP Information\n"
8776        "OSPF interface commands\n"
8777        "Disable MTU mismatch detection on this interface\n"
8778        "Address of interface\n")
8779 {
8780 	VTY_DECLVAR_CONTEXT(interface, ifp);
8781 	int idx_ipv4 = 4;
8782 	struct in_addr addr;
8783 	int ret;
8784 
8785 	struct ospf_if_params *params;
8786 	params = IF_DEF_PARAMS(ifp);
8787 
8788 	if (argc == 5) {
8789 		ret = inet_aton(argv[idx_ipv4]->arg, &addr);
8790 		if (!ret) {
8791 			vty_out(vty,
8792 				"Please specify interface address by A.B.C.D\n");
8793 			return CMD_WARNING_CONFIG_FAILED;
8794 		}
8795 		params = ospf_get_if_params(ifp, addr);
8796 		ospf_if_update_params(ifp, addr);
8797 	}
8798 	params->mtu_ignore = 0;
8799 	if (params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT)
8800 		SET_IF_PARAM(params, mtu_ignore);
8801 	else {
8802 		UNSET_IF_PARAM(params, mtu_ignore);
8803 		if (params != IF_DEF_PARAMS(ifp)) {
8804 			ospf_free_if_params(ifp, addr);
8805 			ospf_if_update_params(ifp, addr);
8806 		}
8807 	}
8808 	return CMD_SUCCESS;
8809 }
8810 
8811 
8812 DEFUN (ospf_max_metric_router_lsa_admin,
8813        ospf_max_metric_router_lsa_admin_cmd,
8814        "max-metric router-lsa administrative",
8815        "OSPF maximum / infinite-distance metric\n"
8816        "Advertise own Router-LSA with infinite distance (stub router)\n"
8817        "Administratively applied, for an indefinite period\n")
8818 {
8819 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8820 	struct listnode *ln;
8821 	struct ospf_area *area;
8822 
8823 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
8824 		SET_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
8825 
8826 		if (!CHECK_FLAG(area->stub_router_state,
8827 				OSPF_AREA_IS_STUB_ROUTED))
8828 			ospf_router_lsa_update_area(area);
8829 	}
8830 
8831 	/* Allows for areas configured later to get the property */
8832 	ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_SET;
8833 
8834 	return CMD_SUCCESS;
8835 }
8836 
8837 DEFUN (no_ospf_max_metric_router_lsa_admin,
8838        no_ospf_max_metric_router_lsa_admin_cmd,
8839        "no max-metric router-lsa administrative",
8840        NO_STR
8841        "OSPF maximum / infinite-distance metric\n"
8842        "Advertise own Router-LSA with infinite distance (stub router)\n"
8843        "Administratively applied, for an indefinite period\n")
8844 {
8845 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8846 	struct listnode *ln;
8847 	struct ospf_area *area;
8848 
8849 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
8850 		UNSET_FLAG(area->stub_router_state,
8851 			   OSPF_AREA_ADMIN_STUB_ROUTED);
8852 
8853 		/* Don't trample on the start-up stub timer */
8854 		if (CHECK_FLAG(area->stub_router_state,
8855 			       OSPF_AREA_IS_STUB_ROUTED)
8856 		    && !area->t_stub_router) {
8857 			UNSET_FLAG(area->stub_router_state,
8858 				   OSPF_AREA_IS_STUB_ROUTED);
8859 			ospf_router_lsa_update_area(area);
8860 		}
8861 	}
8862 	ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
8863 	return CMD_SUCCESS;
8864 }
8865 
8866 DEFUN (ospf_max_metric_router_lsa_startup,
8867        ospf_max_metric_router_lsa_startup_cmd,
8868        "max-metric router-lsa on-startup (5-86400)",
8869        "OSPF maximum / infinite-distance metric\n"
8870        "Advertise own Router-LSA with infinite distance (stub router)\n"
8871        "Automatically advertise stub Router-LSA on startup of OSPF\n"
8872        "Time (seconds) to advertise self as stub-router\n")
8873 {
8874 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8875 	int idx_number = 3;
8876 	unsigned int seconds;
8877 
8878 	if (argc < 4) {
8879 		vty_out(vty, "%% Must supply stub-router period");
8880 		return CMD_WARNING_CONFIG_FAILED;
8881 	}
8882 
8883 	seconds = strtoul(argv[idx_number]->arg, NULL, 10);
8884 
8885 	ospf->stub_router_startup_time = seconds;
8886 
8887 	return CMD_SUCCESS;
8888 }
8889 
8890 DEFUN (no_ospf_max_metric_router_lsa_startup,
8891        no_ospf_max_metric_router_lsa_startup_cmd,
8892        "no max-metric router-lsa on-startup [(5-86400)]",
8893        NO_STR
8894        "OSPF maximum / infinite-distance metric\n"
8895        "Advertise own Router-LSA with infinite distance (stub router)\n"
8896        "Automatically advertise stub Router-LSA on startup of OSPF\n"
8897        "Time (seconds) to advertise self as stub-router\n")
8898 {
8899 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8900 	struct listnode *ln;
8901 	struct ospf_area *area;
8902 
8903 	ospf->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
8904 
8905 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
8906 		SET_FLAG(area->stub_router_state,
8907 			 OSPF_AREA_WAS_START_STUB_ROUTED);
8908 		OSPF_TIMER_OFF(area->t_stub_router);
8909 
8910 		/* Don't trample on admin stub routed */
8911 		if (!CHECK_FLAG(area->stub_router_state,
8912 				OSPF_AREA_ADMIN_STUB_ROUTED)) {
8913 			UNSET_FLAG(area->stub_router_state,
8914 				   OSPF_AREA_IS_STUB_ROUTED);
8915 			ospf_router_lsa_update_area(area);
8916 		}
8917 	}
8918 	return CMD_SUCCESS;
8919 }
8920 
8921 
8922 DEFUN (ospf_max_metric_router_lsa_shutdown,
8923        ospf_max_metric_router_lsa_shutdown_cmd,
8924        "max-metric router-lsa on-shutdown (5-100)",
8925        "OSPF maximum / infinite-distance metric\n"
8926        "Advertise own Router-LSA with infinite distance (stub router)\n"
8927        "Advertise stub-router prior to full shutdown of OSPF\n"
8928        "Time (seconds) to wait till full shutdown\n")
8929 {
8930 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8931 	int idx_number = 3;
8932 	unsigned int seconds;
8933 
8934 	if (argc < 4) {
8935 		vty_out(vty, "%% Must supply stub-router shutdown period");
8936 		return CMD_WARNING_CONFIG_FAILED;
8937 	}
8938 
8939 	seconds = strtoul(argv[idx_number]->arg, NULL, 10);
8940 
8941 	ospf->stub_router_shutdown_time = seconds;
8942 
8943 	return CMD_SUCCESS;
8944 }
8945 
8946 DEFUN (no_ospf_max_metric_router_lsa_shutdown,
8947        no_ospf_max_metric_router_lsa_shutdown_cmd,
8948        "no max-metric router-lsa on-shutdown [(5-100)]",
8949        NO_STR
8950        "OSPF maximum / infinite-distance metric\n"
8951        "Advertise own Router-LSA with infinite distance (stub router)\n"
8952        "Advertise stub-router prior to full shutdown of OSPF\n"
8953        "Time (seconds) to wait till full shutdown\n")
8954 {
8955 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8956 
8957 	ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
8958 
8959 	return CMD_SUCCESS;
8960 }
8961 
8962 DEFUN (ospf_proactive_arp,
8963        ospf_proactive_arp_cmd,
8964        "proactive-arp",
8965        "Allow sending ARP requests proactively\n")
8966 {
8967 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8968 
8969 	ospf->proactive_arp = true;
8970 
8971 	return CMD_SUCCESS;
8972 }
8973 
8974 DEFUN (no_ospf_proactive_arp,
8975        no_ospf_proactive_arp_cmd,
8976        "no proactive-arp",
8977 	   NO_STR
8978        "Disallow sending ARP requests proactively\n")
8979 {
8980 	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
8981 
8982 	ospf->proactive_arp = false;
8983 
8984 	return CMD_SUCCESS;
8985 }
8986 
config_write_stub_router(struct vty * vty,struct ospf * ospf)8987 static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
8988 {
8989 	struct listnode *ln;
8990 	struct ospf_area *area;
8991 
8992 	if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED)
8993 		vty_out(vty, " max-metric router-lsa on-startup %u\n",
8994 			ospf->stub_router_startup_time);
8995 	if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
8996 		vty_out(vty, " max-metric router-lsa on-shutdown %u\n",
8997 			ospf->stub_router_shutdown_time);
8998 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
8999 		if (CHECK_FLAG(area->stub_router_state,
9000 			       OSPF_AREA_ADMIN_STUB_ROUTED)) {
9001 			vty_out(vty, " max-metric router-lsa administrative\n");
9002 			break;
9003 		}
9004 	}
9005 	return;
9006 }
9007 
show_ip_ospf_route_network(struct vty * vty,struct ospf * ospf,struct route_table * rt,json_object * json)9008 static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
9009 				       struct route_table *rt,
9010 				       json_object *json)
9011 {
9012 	struct route_node *rn;
9013 	struct ospf_route * or ;
9014 	struct listnode *pnode, *pnnode;
9015 	struct ospf_path *path;
9016 	json_object *json_route = NULL, *json_nexthop_array = NULL,
9017 		    *json_nexthop = NULL;
9018 
9019 	if (!json)
9020 		vty_out(vty,
9021 			"============ OSPF network routing table ============\n");
9022 
9023 	for (rn = route_top(rt); rn; rn = route_next(rn)) {
9024 		if ((or = rn->info) == NULL)
9025 			continue;
9026 		char buf1[PREFIX2STR_BUFFER];
9027 
9028 		memset(buf1, 0, sizeof(buf1));
9029 		prefix2str(&rn->p, buf1, sizeof(buf1));
9030 
9031 		json_route = json_object_new_object();
9032 		if (json) {
9033 			json_object_object_add(json, buf1, json_route);
9034 			json_object_to_json_string_ext(
9035 				json, JSON_C_TO_STRING_NOSLASHESCAPE);
9036 		}
9037 
9038 		switch (or->path_type) {
9039 		case OSPF_PATH_INTER_AREA:
9040 			if (or->type == OSPF_DESTINATION_NETWORK) {
9041 				if (json) {
9042 					json_object_string_add(json_route,
9043 							       "routeType",
9044 							       "N IA");
9045 					json_object_int_add(json_route, "cost",
9046 							    or->cost);
9047 					json_object_string_add(
9048 						json_route, "area",
9049 						inet_ntoa(or->u.std.area_id));
9050 				} else {
9051 					vty_out(vty,
9052 						"N IA %-18s    [%d] area: %s\n",
9053 						buf1, or->cost,
9054 						inet_ntoa(or->u.std.area_id));
9055 				}
9056 			} else if (or->type == OSPF_DESTINATION_DISCARD) {
9057 				if (json) {
9058 					json_object_string_add(json_route,
9059 							       "routeType",
9060 							       "D IA");
9061 				} else {
9062 					vty_out(vty,
9063 						"D IA %-18s    Discard entry\n",
9064 						buf1);
9065 				}
9066 			}
9067 			break;
9068 		case OSPF_PATH_INTRA_AREA:
9069 			if (json) {
9070 				json_object_string_add(json_route, "routeType",
9071 						       "N");
9072 				json_object_int_add(json_route, "cost",
9073 						    or->cost);
9074 				json_object_string_add(
9075 					json_route, "area",
9076 					inet_ntoa(or->u.std.area_id));
9077 			} else {
9078 				vty_out(vty, "N    %-18s    [%d] area: %s\n",
9079 					buf1, or->cost,
9080 					inet_ntoa(or->u.std.area_id));
9081 			}
9082 			break;
9083 		default:
9084 			break;
9085 		}
9086 
9087 		if (or->type == OSPF_DESTINATION_NETWORK) {
9088 			if (json) {
9089 				json_nexthop_array = json_object_new_array();
9090 				json_object_object_add(json_route, "nexthops",
9091 						       json_nexthop_array);
9092 			}
9093 
9094 			for (ALL_LIST_ELEMENTS(or->paths, pnode, pnnode,
9095 					       path)) {
9096 				if (json) {
9097 					json_nexthop = json_object_new_object();
9098 					json_object_array_add(
9099 						json_nexthop_array,
9100 						json_nexthop);
9101 				}
9102 				if (if_lookup_by_index(path->ifindex,
9103 						       ospf->vrf_id)) {
9104 
9105 					if (path->nexthop.s_addr == 0) {
9106 						if (json) {
9107 							json_object_string_add(
9108 								json_nexthop,
9109 								"ip", " ");
9110 							json_object_string_add(
9111 								json_nexthop,
9112 								"directly attached to",
9113 								ifindex2ifname(
9114 									path->ifindex,
9115 									ospf->vrf_id));
9116 						} else {
9117 							vty_out(vty,
9118 								"%24s   directly attached to %s\n",
9119 								"",
9120 								ifindex2ifname(
9121 									path->ifindex,
9122 									ospf->vrf_id));
9123 						}
9124 					} else {
9125 						if (json) {
9126 							json_object_string_add(
9127 								json_nexthop,
9128 								"ip",
9129 								inet_ntoa(
9130 									path->nexthop));
9131 							json_object_string_add(
9132 								json_nexthop,
9133 								"via",
9134 								ifindex2ifname(
9135 									path->ifindex,
9136 									ospf->vrf_id));
9137 						} else {
9138 							vty_out(vty,
9139 								"%24s   via %s, %s\n",
9140 								"",
9141 								inet_ntoa(
9142 									path->nexthop),
9143 								ifindex2ifname(
9144 									path->ifindex,
9145 									ospf->vrf_id));
9146 						}
9147 					}
9148 				}
9149 			}
9150 		}
9151 		if (!json)
9152 			json_object_free(json_route);
9153 	}
9154 	if (!json)
9155 		vty_out(vty, "\n");
9156 }
9157 
show_ip_ospf_route_router(struct vty * vty,struct ospf * ospf,struct route_table * rtrs,json_object * json)9158 static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
9159 				      struct route_table *rtrs,
9160 				      json_object *json)
9161 {
9162 	struct route_node *rn;
9163 	struct ospf_route * or ;
9164 	struct listnode *pnode;
9165 	struct listnode *node;
9166 	struct ospf_path *path;
9167 	json_object *json_route = NULL, *json_nexthop_array = NULL,
9168 		    *json_nexthop = NULL;
9169 
9170 	if (!json)
9171 		vty_out(vty,
9172 			"============ OSPF router routing table =============\n");
9173 
9174 	for (rn = route_top(rtrs); rn; rn = route_next(rn)) {
9175 		if (rn->info == NULL)
9176 			continue;
9177 		int flag = 0;
9178 
9179 		json_route = json_object_new_object();
9180 		if (json) {
9181 			json_object_object_add(json, inet_ntoa(rn->p.u.prefix4),
9182 					       json_route);
9183 			json_object_string_add(json_route, "routeType", "R ");
9184 		} else {
9185 			vty_out(vty, "R    %-15s    ",
9186 				inet_ntoa(rn->p.u.prefix4));
9187 		}
9188 
9189 		for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) {
9190 			if (flag++) {
9191 				if (!json)
9192 					vty_out(vty, "%24s", "");
9193 			}
9194 
9195 			/* Show path. */
9196 			if (json) {
9197 				json_object_int_add(json_route, "cost",
9198 						    or->cost);
9199 				json_object_string_add(
9200 					json_route, "area",
9201 					inet_ntoa(or->u.std.area_id));
9202 				if (or->path_type == OSPF_PATH_INTER_AREA)
9203 					json_object_boolean_true_add(json_route,
9204 								     "IA");
9205 				if (or->u.std.flags & ROUTER_LSA_BORDER)
9206 					json_object_string_add(json_route,
9207 							       "routerType",
9208 							       "abr");
9209 				else if (or->u.std.flags & ROUTER_LSA_EXTERNAL)
9210 					json_object_string_add(json_route,
9211 							       "routerType",
9212 							       "asbr");
9213 			} else {
9214 				vty_out(vty, "%s [%d] area: %s",
9215 					(or->path_type == OSPF_PATH_INTER_AREA
9216 						 ? "IA"
9217 						 : "  "),
9218 					or->cost, inet_ntoa(or->u.std.area_id));
9219 				/* Show flags. */
9220 				vty_out(vty, "%s%s\n",
9221 					(or->u.std.flags & ROUTER_LSA_BORDER
9222 						 ? ", ABR"
9223 						 : ""),
9224 					(or->u.std.flags & ROUTER_LSA_EXTERNAL
9225 						 ? ", ASBR"
9226 						 : ""));
9227 			}
9228 
9229 			if (json) {
9230 				json_nexthop_array = json_object_new_array();
9231 				json_object_object_add(json_route, "nexthops",
9232 						       json_nexthop_array);
9233 			}
9234 
9235 			for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, path)) {
9236 				if (json) {
9237 					json_nexthop = json_object_new_object();
9238 					json_object_array_add(
9239 						json_nexthop_array,
9240 						json_nexthop);
9241 				}
9242 				if (if_lookup_by_index(path->ifindex,
9243 						       ospf->vrf_id)) {
9244 					if (path->nexthop.s_addr == 0) {
9245 						if (json) {
9246 							json_object_string_add(
9247 								json_nexthop,
9248 								"ip", " ");
9249 							json_object_string_add(
9250 								json_nexthop,
9251 								"directly attached to",
9252 								ifindex2ifname(
9253 									path->ifindex,
9254 									ospf->vrf_id));
9255 						} else {
9256 							vty_out(vty,
9257 								"%24s   directly attached to %s\n",
9258 								"",
9259 								ifindex2ifname(
9260 									path->ifindex,
9261 									ospf->vrf_id));
9262 						}
9263 					} else {
9264 						if (json) {
9265 							json_object_string_add(
9266 								json_nexthop,
9267 								"ip",
9268 								inet_ntoa(
9269 									path->nexthop));
9270 							json_object_string_add(
9271 								json_nexthop,
9272 								"via",
9273 								ifindex2ifname(
9274 									path->ifindex,
9275 									ospf->vrf_id));
9276 						} else {
9277 							vty_out(vty,
9278 								"%24s   via %s, %s\n",
9279 								"",
9280 								inet_ntoa(
9281 									path->nexthop),
9282 								ifindex2ifname(
9283 									path->ifindex,
9284 									ospf->vrf_id));
9285 						}
9286 					}
9287 				}
9288 			}
9289 		}
9290 		if (!json)
9291 			json_object_free(json_route);
9292 	}
9293 	if (!json)
9294 		vty_out(vty, "\n");
9295 }
9296 
show_ip_ospf_route_external(struct vty * vty,struct ospf * ospf,struct route_table * rt,json_object * json)9297 static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
9298 					struct route_table *rt,
9299 					json_object *json)
9300 {
9301 	struct route_node *rn;
9302 	struct ospf_route *er;
9303 	struct listnode *pnode, *pnnode;
9304 	struct ospf_path *path;
9305 	json_object *json_route = NULL, *json_nexthop_array = NULL,
9306 		    *json_nexthop = NULL;
9307 
9308 	if (!json)
9309 		vty_out(vty,
9310 			"============ OSPF external routing table ===========\n");
9311 
9312 	for (rn = route_top(rt); rn; rn = route_next(rn)) {
9313 		if ((er = rn->info) == NULL)
9314 			continue;
9315 
9316 		char buf1[19];
9317 
9318 		snprintf(buf1, sizeof(buf1), "%s/%d",
9319 			 inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen);
9320 		json_route = json_object_new_object();
9321 		if (json) {
9322 			json_object_object_add(json, buf1, json_route);
9323 			json_object_to_json_string_ext(
9324 				json, JSON_C_TO_STRING_NOSLASHESCAPE);
9325 		}
9326 
9327 		switch (er->path_type) {
9328 		case OSPF_PATH_TYPE1_EXTERNAL:
9329 			if (json) {
9330 				json_object_string_add(json_route, "routeType",
9331 						       "N E1");
9332 				json_object_int_add(json_route, "cost",
9333 						    er->cost);
9334 			} else {
9335 				vty_out(vty,
9336 					"N E1 %-18s    [%d] tag: %" ROUTE_TAG_PRI
9337 					"\n",
9338 					buf1, er->cost, er->u.ext.tag);
9339 			}
9340 			break;
9341 		case OSPF_PATH_TYPE2_EXTERNAL:
9342 			if (json) {
9343 				json_object_string_add(json_route, "routeType",
9344 						       "N E2");
9345 				json_object_int_add(json_route, "cost",
9346 						    er->cost);
9347 			} else {
9348 				vty_out(vty,
9349 					"N E2 %-18s    [%d/%d] tag: %" ROUTE_TAG_PRI
9350 					"\n",
9351 					buf1, er->cost, er->u.ext.type2_cost,
9352 					er->u.ext.tag);
9353 			}
9354 			break;
9355 		}
9356 
9357 		if (json) {
9358 			json_nexthop_array = json_object_new_array();
9359 			json_object_object_add(json_route, "nexthops",
9360 					       json_nexthop_array);
9361 		}
9362 
9363 		for (ALL_LIST_ELEMENTS(er->paths, pnode, pnnode, path)) {
9364 			if (json) {
9365 				json_nexthop = json_object_new_object();
9366 				json_object_array_add(json_nexthop_array,
9367 						      json_nexthop);
9368 			}
9369 
9370 			if (if_lookup_by_index(path->ifindex, ospf->vrf_id)) {
9371 				if (path->nexthop.s_addr == 0) {
9372 					if (json) {
9373 						json_object_string_add(
9374 							json_nexthop, "ip",
9375 							" ");
9376 						json_object_string_add(
9377 							json_nexthop,
9378 							"directly attached to",
9379 							ifindex2ifname(
9380 								path->ifindex,
9381 								ospf->vrf_id));
9382 					} else {
9383 						vty_out(vty,
9384 							"%24s   directly attached to %s\n",
9385 							"",
9386 							ifindex2ifname(
9387 								path->ifindex,
9388 								ospf->vrf_id));
9389 					}
9390 				} else {
9391 					if (json) {
9392 						json_object_string_add(
9393 							json_nexthop, "ip",
9394 							inet_ntoa(
9395 								path->nexthop));
9396 						json_object_string_add(
9397 							json_nexthop, "via",
9398 							ifindex2ifname(
9399 								path->ifindex,
9400 								ospf->vrf_id));
9401 					} else {
9402 						vty_out(vty,
9403 							"%24s   via %s, %s\n",
9404 							"",
9405 							inet_ntoa(
9406 								path->nexthop),
9407 							ifindex2ifname(
9408 								path->ifindex,
9409 								ospf->vrf_id));
9410 					}
9411 				}
9412 			}
9413 		}
9414 		if (!json)
9415 			json_object_free(json_route);
9416 	}
9417 	if (!json)
9418 		vty_out(vty, "\n");
9419 }
9420 
show_ip_ospf_border_routers_common(struct vty * vty,struct ospf * ospf,uint8_t use_vrf)9421 static int show_ip_ospf_border_routers_common(struct vty *vty,
9422 					      struct ospf *ospf,
9423 					      uint8_t use_vrf)
9424 {
9425 	if (ospf->instance)
9426 		vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
9427 
9428 	ospf_show_vrf_name(ospf, vty, NULL, use_vrf);
9429 
9430 	if (ospf->new_table == NULL) {
9431 		vty_out(vty, "No OSPF routing information exist\n");
9432 		return CMD_SUCCESS;
9433 	}
9434 
9435 	/* Show Network routes.
9436 	show_ip_ospf_route_network (vty, ospf->new_table);   */
9437 
9438 	/* Show Router routes. */
9439 	show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs, NULL);
9440 
9441 	vty_out(vty, "\n");
9442 
9443 	return CMD_SUCCESS;
9444 }
9445 
9446 DEFUN (show_ip_ospf_border_routers,
9447        show_ip_ospf_border_routers_cmd,
9448        "show ip ospf [vrf <NAME|all>] border-routers",
9449        SHOW_STR
9450        IP_STR
9451        "OSPF information\n"
9452        VRF_CMD_HELP_STR
9453        "All VRFs\n"
9454        "Show all the ABR's and ASBR's\n")
9455 {
9456 	struct ospf *ospf = NULL;
9457 	struct listnode *node = NULL;
9458 	char *vrf_name = NULL;
9459 	bool all_vrf = false;
9460 	int ret = CMD_SUCCESS;
9461 	int inst = 0;
9462 	int idx_vrf = 0;
9463 	uint8_t use_vrf = 0;
9464 
9465 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
9466 
9467 	if (vrf_name) {
9468 		bool ospf_output = false;
9469 
9470 		use_vrf = 1;
9471 
9472 		if (all_vrf) {
9473 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
9474 				if (!ospf->oi_running)
9475 					continue;
9476 
9477 				ospf_output = true;
9478 				ret = show_ip_ospf_border_routers_common(
9479 					vty, ospf, use_vrf);
9480 			}
9481 
9482 			if (!ospf_output)
9483 				vty_out(vty, "%% OSPF instance not found\n");
9484 		} else {
9485 			ospf = ospf_lookup_by_inst_name(inst, vrf_name);
9486 			if (ospf == NULL || !ospf->oi_running) {
9487 				vty_out(vty, "%% OSPF instance not found\n");
9488 				return CMD_SUCCESS;
9489 			}
9490 
9491 			ret = show_ip_ospf_border_routers_common(vty, ospf,
9492 								 use_vrf);
9493 		}
9494 	} else {
9495 		/* Display default ospf (instance 0) info */
9496 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
9497 		if (ospf == NULL || !ospf->oi_running) {
9498 			vty_out(vty, "%% OSPF instance not found\n");
9499 			return CMD_SUCCESS;
9500 		}
9501 
9502 		ret = show_ip_ospf_border_routers_common(vty, ospf, use_vrf);
9503 	}
9504 
9505 	return ret;
9506 }
9507 
9508 DEFUN (show_ip_ospf_instance_border_routers,
9509        show_ip_ospf_instance_border_routers_cmd,
9510        "show ip ospf (1-65535) border-routers",
9511        SHOW_STR
9512        IP_STR
9513        "OSPF information\n"
9514        "Instance ID\n"
9515        "Show all the ABR's and ASBR's\n")
9516 {
9517 	int idx_number = 3;
9518 	struct ospf *ospf;
9519 	unsigned short instance = 0;
9520 
9521 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
9522 	ospf = ospf_lookup_instance(instance);
9523 	if (ospf == NULL)
9524 		return CMD_NOT_MY_INSTANCE;
9525 
9526 	if (!ospf->oi_running)
9527 		return CMD_SUCCESS;
9528 
9529 	return show_ip_ospf_border_routers_common(vty, ospf, 0);
9530 }
9531 
show_ip_ospf_route_common(struct vty * vty,struct ospf * ospf,json_object * json,uint8_t use_vrf)9532 static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf,
9533 				     json_object *json, uint8_t use_vrf)
9534 {
9535 	json_object *json_vrf = NULL;
9536 
9537 	if (ospf->instance)
9538 		vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
9539 
9540 
9541 	if (json) {
9542 		if (use_vrf)
9543 			json_vrf = json_object_new_object();
9544 		else
9545 			json_vrf = json;
9546 	}
9547 
9548 	ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
9549 
9550 	if (ospf->new_table == NULL) {
9551 		vty_out(vty, "No OSPF routing information exist\n");
9552 		return CMD_SUCCESS;
9553 	}
9554 
9555 	/* Show Network routes. */
9556 	show_ip_ospf_route_network(vty, ospf, ospf->new_table, json_vrf);
9557 
9558 	/* Show Router routes. */
9559 	show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs, json_vrf);
9560 
9561 	/* Show AS External routes. */
9562 	show_ip_ospf_route_external(vty, ospf, ospf->old_external_route,
9563 				    json_vrf);
9564 
9565 	if (json) {
9566 		if (use_vrf) {
9567 			// json_object_object_add(json_vrf, "areas",
9568 			// json_areas);
9569 			if (ospf->vrf_id == VRF_DEFAULT)
9570 				json_object_object_add(json, "default",
9571 						       json_vrf);
9572 			else
9573 				json_object_object_add(json, ospf->name,
9574 						       json_vrf);
9575 		}
9576 	} else {
9577 		vty_out(vty, "\n");
9578 	}
9579 
9580 	return CMD_SUCCESS;
9581 }
9582 
9583 DEFUN (show_ip_ospf_route,
9584        show_ip_ospf_route_cmd,
9585 	"show ip ospf [vrf <NAME|all>] route [json]",
9586 	SHOW_STR
9587 	IP_STR
9588 	"OSPF information\n"
9589 	VRF_CMD_HELP_STR
9590 	"All VRFs\n"
9591 	"OSPF routing table\n"
9592 	JSON_STR)
9593 {
9594 	struct ospf *ospf = NULL;
9595 	struct listnode *node = NULL;
9596 	char *vrf_name = NULL;
9597 	bool all_vrf = false;
9598 	int ret = CMD_SUCCESS;
9599 	int inst = 0;
9600 	int idx_vrf = 0;
9601 	uint8_t use_vrf = 0;
9602 	bool uj = use_json(argc, argv);
9603 	json_object *json = NULL;
9604 
9605 	if (uj)
9606 		json = json_object_new_object();
9607 
9608 	OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
9609 
9610 	/* vrf input is provided could be all or specific vrf*/
9611 	if (vrf_name) {
9612 		bool ospf_output = false;
9613 
9614 		use_vrf = 1;
9615 
9616 		if (all_vrf) {
9617 			for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
9618 				if (!ospf->oi_running)
9619 					continue;
9620 				ospf_output = true;
9621 				ret = show_ip_ospf_route_common(vty, ospf, json,
9622 								use_vrf);
9623 			}
9624 
9625 			if (uj) {
9626 				/* Keep Non-pretty format */
9627 				vty_out(vty, "%s\n",
9628 					json_object_to_json_string(json));
9629 				json_object_free(json);
9630 			} else if (!ospf_output)
9631 				vty_out(vty, "%% OSPF instance not found\n");
9632 
9633 			return ret;
9634 		}
9635 		ospf = ospf_lookup_by_inst_name(inst, vrf_name);
9636 		if (ospf == NULL || !ospf->oi_running) {
9637 			if (uj) {
9638 				vty_out(vty, "%s\n",
9639 					json_object_to_json_string_ext(
9640 						json, JSON_C_TO_STRING_PRETTY));
9641 				json_object_free(json);
9642 			} else
9643 				vty_out(vty, "%% OSPF instance not found\n");
9644 
9645 			return CMD_SUCCESS;
9646 		}
9647 	} else {
9648 		/* Display default ospf (instance 0) info */
9649 		ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
9650 		if (ospf == NULL || !ospf->oi_running) {
9651 			if (uj) {
9652 				vty_out(vty, "%s\n",
9653 					json_object_to_json_string_ext(
9654 						json, JSON_C_TO_STRING_PRETTY));
9655 				json_object_free(json);
9656 			} else
9657 				vty_out(vty, "%% OSPF instance not found\n");
9658 
9659 			return CMD_SUCCESS;
9660 		}
9661 	}
9662 
9663 	if (ospf) {
9664 		ret = show_ip_ospf_route_common(vty, ospf, json, use_vrf);
9665 		/* Keep Non-pretty format */
9666 		if (uj)
9667 			vty_out(vty, "%s\n", json_object_to_json_string(json));
9668 	}
9669 
9670 	if (uj)
9671 		json_object_free(json);
9672 
9673 	return ret;
9674 }
9675 
9676 DEFUN (show_ip_ospf_instance_route,
9677        show_ip_ospf_instance_route_cmd,
9678        "show ip ospf (1-65535) route",
9679        SHOW_STR
9680        IP_STR
9681        "OSPF information\n"
9682        "Instance ID\n"
9683        "OSPF routing table\n")
9684 {
9685 	int idx_number = 3;
9686 	struct ospf *ospf;
9687 	unsigned short instance = 0;
9688 
9689 	instance = strtoul(argv[idx_number]->arg, NULL, 10);
9690 	ospf = ospf_lookup_instance(instance);
9691 	if (ospf == NULL)
9692 		return CMD_NOT_MY_INSTANCE;
9693 
9694 	if (!ospf->oi_running)
9695 		return CMD_SUCCESS;
9696 
9697 	return show_ip_ospf_route_common(vty, ospf, NULL, 0);
9698 }
9699 
9700 
9701 DEFUN (show_ip_ospf_vrfs,
9702 	show_ip_ospf_vrfs_cmd,
9703 	"show ip ospf vrfs [json]",
9704 	SHOW_STR
9705 	IP_STR
9706 	"OSPF information\n"
9707 	"Show OSPF VRFs \n"
9708 	JSON_STR)
9709 {
9710 	bool uj = use_json(argc, argv);
9711 	json_object *json = NULL;
9712 	json_object *json_vrfs = NULL;
9713 	struct ospf *ospf = NULL;
9714 	struct listnode *node = NULL;
9715 	int count = 0;
9716 	static const char header[] = "Name                       Id     RouterId  ";
9717 
9718 	if (uj) {
9719 		json = json_object_new_object();
9720 		json_vrfs = json_object_new_object();
9721 	}
9722 
9723 	for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
9724 		json_object *json_vrf = NULL;
9725 		const char *name = NULL;
9726 		int64_t vrf_id_ui = 0;
9727 
9728 		count++;
9729 
9730 		if (!uj && count == 1)
9731 			vty_out(vty, "%s\n", header);
9732 		if (uj)
9733 			json_vrf = json_object_new_object();
9734 
9735 		if (ospf->vrf_id == VRF_DEFAULT)
9736 			name = VRF_DEFAULT_NAME;
9737 		else
9738 			name = ospf->name;
9739 
9740 		vrf_id_ui = (ospf->vrf_id == VRF_UNKNOWN)
9741 				    ? -1
9742 				    : (int64_t)ospf->vrf_id;
9743 
9744 		if (uj) {
9745 			json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
9746 			json_object_string_add(json_vrf, "routerId",
9747 					       inet_ntoa(ospf->router_id));
9748 
9749 			json_object_object_add(json_vrfs, name, json_vrf);
9750 
9751 		} else {
9752 			vty_out(vty, "%-25s  %-5d  %-16s  \n", name,
9753 				ospf->vrf_id, inet_ntoa(ospf->router_id));
9754 		}
9755 	}
9756 
9757 	if (uj) {
9758 		json_object_object_add(json, "vrfs", json_vrfs);
9759 		json_object_int_add(json, "totalVrfs", count);
9760 
9761 		vty_out(vty, "%s\n", json_object_to_json_string_ext(
9762 					     json, JSON_C_TO_STRING_PRETTY));
9763 		json_object_free(json);
9764 	} else {
9765 		if (count)
9766 			vty_out(vty, "\nTotal number of OSPF VRFs: %d\n",
9767 				count);
9768 	}
9769 
9770 	return CMD_SUCCESS;
9771 }
9772 
9773 static const char *const ospf_abr_type_str[] = {
9774 	"unknown", "standard", "ibm", "cisco", "shortcut"
9775 };
9776 
9777 static const char *const ospf_shortcut_mode_str[] = {
9778 	"default", "enable", "disable"
9779 };
9780 
9781 static const char *const ospf_int_type_str[] = {
9782 	"unknown", /* should never be used. */
9783 	"point-to-point",
9784 	"broadcast",
9785 	"non-broadcast",
9786 	"point-to-multipoint",
9787 	"virtual-link", /* should never be used. */
9788 	"loopback"
9789 };
9790 
config_write_interface_one(struct vty * vty,struct vrf * vrf)9791 static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
9792 {
9793 	struct listnode *node;
9794 	struct interface *ifp;
9795 	struct crypt_key *ck;
9796 	struct route_node *rn = NULL;
9797 	struct ospf_if_params *params;
9798 	int write = 0;
9799 	struct ospf *ospf = vrf->info;
9800 
9801 	FOR_ALL_INTERFACES (vrf, ifp) {
9802 
9803 		if (memcmp(ifp->name, "VLINK", 5) == 0)
9804 			continue;
9805 
9806 		vty_frame(vty, "!\n");
9807 		if (ifp->vrf_id == VRF_DEFAULT)
9808 			vty_frame(vty, "interface %s\n", ifp->name);
9809 		else
9810 			vty_frame(vty, "interface %s vrf %s\n", ifp->name,
9811 				  vrf->name);
9812 		if (ifp->desc)
9813 			vty_out(vty, " description %s\n", ifp->desc);
9814 
9815 		write++;
9816 
9817 		params = IF_DEF_PARAMS(ifp);
9818 
9819 		do {
9820 			/* Interface Network print. */
9821 			if (OSPF_IF_PARAM_CONFIGURED(params, type)
9822 			    && params->type != OSPF_IFTYPE_LOOPBACK) {
9823 				if (params->type != ospf_default_iftype(ifp)) {
9824 					vty_out(vty, " ip ospf network %s",
9825 						ospf_int_type_str
9826 							[params->type]);
9827 					if (params != IF_DEF_PARAMS(ifp) && rn)
9828 						vty_out(vty, " %s",
9829 							inet_ntoa(
9830 								rn->p.u.prefix4));
9831 					vty_out(vty, "\n");
9832 				}
9833 			}
9834 
9835 			/* OSPF interface authentication print */
9836 			if (OSPF_IF_PARAM_CONFIGURED(params, auth_type)
9837 			    && params->auth_type != OSPF_AUTH_NOTSET) {
9838 				const char *auth_str;
9839 
9840 				/* Translation tables are not that much help
9841 				* here due to syntax
9842 				* of the simple option */
9843 				switch (params->auth_type) {
9844 
9845 				case OSPF_AUTH_NULL:
9846 					auth_str = " null";
9847 					break;
9848 
9849 				case OSPF_AUTH_SIMPLE:
9850 					auth_str = "";
9851 					break;
9852 
9853 				case OSPF_AUTH_CRYPTOGRAPHIC:
9854 					auth_str = " message-digest";
9855 					break;
9856 
9857 				default:
9858 					auth_str = "";
9859 					break;
9860 				}
9861 
9862 				vty_out(vty, " ip ospf authentication%s",
9863 					auth_str);
9864 				if (params != IF_DEF_PARAMS(ifp) && rn)
9865 					vty_out(vty, " %s",
9866 						inet_ntoa(rn->p.u.prefix4));
9867 				vty_out(vty, "\n");
9868 			}
9869 
9870 			/* Simple Authentication Password print. */
9871 			if (OSPF_IF_PARAM_CONFIGURED(params, auth_simple)
9872 			    && params->auth_simple[0] != '\0') {
9873 				vty_out(vty, " ip ospf authentication-key %s",
9874 					params->auth_simple);
9875 				if (params != IF_DEF_PARAMS(ifp) && rn)
9876 					vty_out(vty, " %s",
9877 						inet_ntoa(rn->p.u.prefix4));
9878 				vty_out(vty, "\n");
9879 			}
9880 
9881 			/* Cryptographic Authentication Key print. */
9882 			if (params && params->auth_crypt) {
9883 				for (ALL_LIST_ELEMENTS_RO(params->auth_crypt,
9884 							  node, ck)) {
9885 					vty_out(vty,
9886 						" ip ospf message-digest-key %d md5 %s",
9887 						ck->key_id, ck->auth_key);
9888 					if (params != IF_DEF_PARAMS(ifp) && rn)
9889 						vty_out(vty, " %s",
9890 							inet_ntoa(
9891 								rn->p.u.prefix4));
9892 					vty_out(vty, "\n");
9893 				}
9894 			}
9895 
9896 			/* Interface Output Cost print. */
9897 			if (OSPF_IF_PARAM_CONFIGURED(params, output_cost_cmd)) {
9898 				vty_out(vty, " ip ospf cost %u",
9899 					params->output_cost_cmd);
9900 				if (params != IF_DEF_PARAMS(ifp) && rn)
9901 					vty_out(vty, " %s",
9902 						inet_ntoa(rn->p.u.prefix4));
9903 				vty_out(vty, "\n");
9904 			}
9905 
9906 			/* Hello Interval print. */
9907 			if (OSPF_IF_PARAM_CONFIGURED(params, v_hello)
9908 			    && params->v_hello != OSPF_HELLO_INTERVAL_DEFAULT) {
9909 				vty_out(vty, " ip ospf hello-interval %u",
9910 					params->v_hello);
9911 				if (params != IF_DEF_PARAMS(ifp) && rn)
9912 					vty_out(vty, " %s",
9913 						inet_ntoa(rn->p.u.prefix4));
9914 				vty_out(vty, "\n");
9915 			}
9916 
9917 
9918 			/* Router Dead Interval print. */
9919 			if (OSPF_IF_PARAM_CONFIGURED(params, v_wait)
9920 			    && params->v_wait
9921 				       != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
9922 				vty_out(vty, " ip ospf dead-interval ");
9923 
9924 				/* fast hello ? */
9925 				if (OSPF_IF_PARAM_CONFIGURED(params,
9926 							     fast_hello))
9927 					vty_out(vty,
9928 						"minimal hello-multiplier %d",
9929 						params->fast_hello);
9930 				else
9931 					vty_out(vty, "%u", params->v_wait);
9932 
9933 				if (params != IF_DEF_PARAMS(ifp) && rn)
9934 					vty_out(vty, " %s",
9935 						inet_ntoa(rn->p.u.prefix4));
9936 				vty_out(vty, "\n");
9937 			}
9938 
9939 			/* Router Priority print. */
9940 			if (OSPF_IF_PARAM_CONFIGURED(params, priority)
9941 			    && params->priority
9942 				       != OSPF_ROUTER_PRIORITY_DEFAULT) {
9943 				vty_out(vty, " ip ospf priority %u",
9944 					params->priority);
9945 				if (params != IF_DEF_PARAMS(ifp) && rn)
9946 					vty_out(vty, " %s",
9947 						inet_ntoa(rn->p.u.prefix4));
9948 				vty_out(vty, "\n");
9949 			}
9950 
9951 			/* Retransmit Interval print. */
9952 			if (OSPF_IF_PARAM_CONFIGURED(params,
9953 						     retransmit_interval)
9954 			    && params->retransmit_interval
9955 				       != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
9956 				vty_out(vty, " ip ospf retransmit-interval %u",
9957 					params->retransmit_interval);
9958 				if (params != IF_DEF_PARAMS(ifp) && rn)
9959 					vty_out(vty, " %s",
9960 						inet_ntoa(rn->p.u.prefix4));
9961 				vty_out(vty, "\n");
9962 			}
9963 
9964 			/* Transmit Delay print. */
9965 			if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay)
9966 			    && params->transmit_delay
9967 				       != OSPF_TRANSMIT_DELAY_DEFAULT) {
9968 				vty_out(vty, " ip ospf transmit-delay %u",
9969 					params->transmit_delay);
9970 				if (params != IF_DEF_PARAMS(ifp) && rn)
9971 					vty_out(vty, " %s",
9972 						inet_ntoa(rn->p.u.prefix4));
9973 				vty_out(vty, "\n");
9974 			}
9975 
9976 			/* Area  print. */
9977 			if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
9978 				if (ospf && ospf->instance)
9979 					vty_out(vty, " ip ospf %d",
9980 						ospf->instance);
9981 				else
9982 					vty_out(vty, " ip ospf");
9983 
9984 				char buf[INET_ADDRSTRLEN];
9985 
9986 				area_id2str(buf, sizeof(buf), &params->if_area,
9987 					    params->if_area_id_fmt);
9988 				vty_out(vty, " area %s", buf);
9989 				if (params != IF_DEF_PARAMS(ifp) && rn)
9990 					vty_out(vty, " %s",
9991 						inet_ntoa(rn->p.u.prefix4));
9992 				vty_out(vty, "\n");
9993 			}
9994 
9995 			/* bfd  print. */
9996 			if (params && params->bfd_info)
9997 				ospf_bfd_write_config(vty, params);
9998 
9999 			/* MTU ignore print. */
10000 			if (OSPF_IF_PARAM_CONFIGURED(params, mtu_ignore)
10001 			    && params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) {
10002 				if (params->mtu_ignore == 0)
10003 					vty_out(vty, " no ip ospf mtu-ignore");
10004 				else
10005 					vty_out(vty, " ip ospf mtu-ignore");
10006 				if (params != IF_DEF_PARAMS(ifp) && rn)
10007 					vty_out(vty, " %s",
10008 						inet_ntoa(rn->p.u.prefix4));
10009 				vty_out(vty, "\n");
10010 			}
10011 
10012 
10013 			while (1) {
10014 				if (rn == NULL)
10015 					rn = route_top(IF_OIFS_PARAMS(ifp));
10016 				else
10017 					rn = route_next(rn);
10018 
10019 				if (rn == NULL)
10020 					break;
10021 				params = rn->info;
10022 				if (params != NULL)
10023 					break;
10024 			}
10025 		} while (rn);
10026 
10027 		ospf_opaque_config_write_if(vty, ifp);
10028 
10029 		vty_endframe(vty, NULL);
10030 	}
10031 
10032 	return write;
10033 }
10034 
10035 /* Configuration write function for ospfd. */
config_write_interface(struct vty * vty)10036 static int config_write_interface(struct vty *vty)
10037 {
10038 	int write = 0;
10039 	struct vrf *vrf = NULL;
10040 
10041 	/* Display all VRF aware OSPF interface configuration */
10042 	RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
10043 		write += config_write_interface_one(vty, vrf);
10044 	}
10045 
10046 	return write;
10047 }
10048 
config_write_network_area(struct vty * vty,struct ospf * ospf)10049 static int config_write_network_area(struct vty *vty, struct ospf *ospf)
10050 {
10051 	struct route_node *rn;
10052 	char buf[INET_ADDRSTRLEN];
10053 
10054 	/* `network area' print. */
10055 	for (rn = route_top(ospf->networks); rn; rn = route_next(rn))
10056 		if (rn->info) {
10057 			struct ospf_network *n = rn->info;
10058 
10059 			/* Create Area ID string by specified Area ID format. */
10060 			if (n->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD)
10061 				inet_ntop(AF_INET, &n->area_id, buf,
10062 					  sizeof(buf));
10063 			else
10064 				snprintf(buf, sizeof(buf), "%lu",
10065 					 (unsigned long int)ntohl(
10066 						 n->area_id.s_addr));
10067 
10068 			/* Network print. */
10069 			vty_out(vty, " network %s/%d area %s\n",
10070 				inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen,
10071 				buf);
10072 		}
10073 
10074 	return 0;
10075 }
10076 
config_write_ospf_area(struct vty * vty,struct ospf * ospf)10077 static int config_write_ospf_area(struct vty *vty, struct ospf *ospf)
10078 {
10079 	struct listnode *node;
10080 	struct ospf_area *area;
10081 	char buf[INET_ADDRSTRLEN];
10082 
10083 	/* Area configuration print. */
10084 	for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
10085 		struct route_node *rn1;
10086 
10087 		area_id2str(buf, sizeof(buf), &area->area_id,
10088 			    area->area_id_fmt);
10089 
10090 		if (area->auth_type != OSPF_AUTH_NULL) {
10091 			if (area->auth_type == OSPF_AUTH_SIMPLE)
10092 				vty_out(vty, " area %s authentication\n", buf);
10093 			else
10094 				vty_out(vty,
10095 					" area %s authentication message-digest\n",
10096 					buf);
10097 		}
10098 
10099 		if (area->shortcut_configured != OSPF_SHORTCUT_DEFAULT)
10100 			vty_out(vty, " area %s shortcut %s\n", buf,
10101 				ospf_shortcut_mode_str
10102 					[area->shortcut_configured]);
10103 
10104 		if ((area->external_routing == OSPF_AREA_STUB)
10105 		    || (area->external_routing == OSPF_AREA_NSSA)) {
10106 			if (area->external_routing == OSPF_AREA_STUB) {
10107 				vty_out(vty, " area %s stub", buf);
10108 				if (area->no_summary)
10109 					vty_out(vty, " no-summary\n");
10110 				vty_out(vty, "\n");
10111 			} else if (area->external_routing == OSPF_AREA_NSSA) {
10112 				switch (area->NSSATranslatorRole) {
10113 				case OSPF_NSSA_ROLE_NEVER:
10114 					vty_out(vty,
10115 						" area %s nssa translate-never\n",
10116 						buf);
10117 					break;
10118 				case OSPF_NSSA_ROLE_ALWAYS:
10119 					vty_out(vty,
10120 						" area %s nssa translate-always\n",
10121 						buf);
10122 					break;
10123 				case OSPF_NSSA_ROLE_CANDIDATE:
10124 					vty_out(vty, " area %s nssa \n", buf);
10125 					break;
10126 				}
10127 				if (area->no_summary)
10128 					vty_out(vty,
10129 						" area %s nssa no-summary\n",
10130 						buf);
10131 			}
10132 
10133 			if (area->default_cost != 1)
10134 				vty_out(vty, " area %s default-cost %d\n", buf,
10135 					area->default_cost);
10136 		}
10137 
10138 		for (rn1 = route_top(area->ranges); rn1; rn1 = route_next(rn1))
10139 			if (rn1->info) {
10140 				struct ospf_area_range *range = rn1->info;
10141 
10142 				vty_out(vty, " area %s range %s/%d", buf,
10143 					inet_ntoa(rn1->p.u.prefix4),
10144 					rn1->p.prefixlen);
10145 
10146 				if (range->cost_config
10147 				    != OSPF_AREA_RANGE_COST_UNSPEC)
10148 					vty_out(vty, " cost %d",
10149 						range->cost_config);
10150 
10151 				if (!CHECK_FLAG(range->flags,
10152 						OSPF_AREA_RANGE_ADVERTISE))
10153 					vty_out(vty, " not-advertise");
10154 
10155 				if (CHECK_FLAG(range->flags,
10156 					       OSPF_AREA_RANGE_SUBSTITUTE))
10157 					vty_out(vty, " substitute %s/%d",
10158 						inet_ntoa(range->subst_addr),
10159 						range->subst_masklen);
10160 
10161 				vty_out(vty, "\n");
10162 			}
10163 
10164 		if (EXPORT_NAME(area))
10165 			vty_out(vty, " area %s export-list %s\n", buf,
10166 				EXPORT_NAME(area));
10167 
10168 		if (IMPORT_NAME(area))
10169 			vty_out(vty, " area %s import-list %s\n", buf,
10170 				IMPORT_NAME(area));
10171 
10172 		if (PREFIX_NAME_IN(area))
10173 			vty_out(vty, " area %s filter-list prefix %s in\n", buf,
10174 				PREFIX_NAME_IN(area));
10175 
10176 		if (PREFIX_NAME_OUT(area))
10177 			vty_out(vty, " area %s filter-list prefix %s out\n",
10178 				buf, PREFIX_NAME_OUT(area));
10179 	}
10180 
10181 	return 0;
10182 }
10183 
config_write_ospf_nbr_nbma(struct vty * vty,struct ospf * ospf)10184 static int config_write_ospf_nbr_nbma(struct vty *vty, struct ospf *ospf)
10185 {
10186 	struct ospf_nbr_nbma *nbr_nbma;
10187 	struct route_node *rn;
10188 
10189 	/* Static Neighbor configuration print. */
10190 	for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
10191 		if ((nbr_nbma = rn->info)) {
10192 			vty_out(vty, " neighbor %s", inet_ntoa(nbr_nbma->addr));
10193 
10194 			if (nbr_nbma->priority
10195 			    != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
10196 				vty_out(vty, " priority %d",
10197 					nbr_nbma->priority);
10198 
10199 			if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
10200 				vty_out(vty, " poll-interval %d",
10201 					nbr_nbma->v_poll);
10202 
10203 			vty_out(vty, "\n");
10204 		}
10205 
10206 	return 0;
10207 }
10208 
config_write_virtual_link(struct vty * vty,struct ospf * ospf)10209 static int config_write_virtual_link(struct vty *vty, struct ospf *ospf)
10210 {
10211 	struct listnode *node;
10212 	struct ospf_vl_data *vl_data;
10213 	char buf[INET_ADDRSTRLEN];
10214 
10215 	/* Virtual-Link print */
10216 	for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
10217 		struct listnode *n2;
10218 		struct crypt_key *ck;
10219 		struct ospf_interface *oi;
10220 
10221 		if (vl_data != NULL) {
10222 			area_id2str(buf, sizeof(buf), &vl_data->vl_area_id,
10223 				    vl_data->vl_area_id_fmt);
10224 			oi = vl_data->vl_oi;
10225 
10226 			/* timers */
10227 			if (OSPF_IF_PARAM(oi, v_hello)
10228 				    != OSPF_HELLO_INTERVAL_DEFAULT
10229 			    || OSPF_IF_PARAM(oi, v_wait)
10230 				       != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
10231 			    || OSPF_IF_PARAM(oi, retransmit_interval)
10232 				       != OSPF_RETRANSMIT_INTERVAL_DEFAULT
10233 			    || OSPF_IF_PARAM(oi, transmit_delay)
10234 				       != OSPF_TRANSMIT_DELAY_DEFAULT)
10235 				vty_out(vty,
10236 					" area %s virtual-link %s hello-interval %d retransmit-interval %d transmit-delay %d dead-interval %d\n",
10237 					buf, inet_ntoa(vl_data->vl_peer),
10238 					OSPF_IF_PARAM(oi, v_hello),
10239 					OSPF_IF_PARAM(oi, retransmit_interval),
10240 					OSPF_IF_PARAM(oi, transmit_delay),
10241 					OSPF_IF_PARAM(oi, v_wait));
10242 			else
10243 				vty_out(vty, " area %s virtual-link %s\n", buf,
10244 					inet_ntoa(vl_data->vl_peer));
10245 			/* Auth key */
10246 			if (IF_DEF_PARAMS(vl_data->vl_oi->ifp)->auth_simple[0]
10247 			    != '\0')
10248 				vty_out(vty,
10249 					" area %s virtual-link %s authentication-key %s\n",
10250 					buf, inet_ntoa(vl_data->vl_peer),
10251 					IF_DEF_PARAMS(vl_data->vl_oi->ifp)
10252 						->auth_simple);
10253 			/* md5 keys */
10254 			for (ALL_LIST_ELEMENTS_RO(
10255 				     IF_DEF_PARAMS(vl_data->vl_oi->ifp)
10256 					     ->auth_crypt,
10257 				     n2, ck))
10258 				vty_out(vty,
10259 					" area %s virtual-link %s message-digest-key %d md5 %s\n",
10260 					buf, inet_ntoa(vl_data->vl_peer),
10261 					ck->key_id, ck->auth_key);
10262 		}
10263 	}
10264 
10265 	return 0;
10266 }
10267 
10268 
config_write_ospf_redistribute(struct vty * vty,struct ospf * ospf)10269 static int config_write_ospf_redistribute(struct vty *vty, struct ospf *ospf)
10270 {
10271 	int type;
10272 
10273 	/* redistribute print. */
10274 	for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
10275 		struct list *red_list;
10276 		struct listnode *node;
10277 		struct ospf_redist *red;
10278 
10279 		red_list = ospf->redist[type];
10280 		if (!red_list)
10281 			continue;
10282 
10283 		for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
10284 			vty_out(vty, " redistribute %s",
10285 				zebra_route_string(type));
10286 			if (red->instance)
10287 				vty_out(vty, " %d", red->instance);
10288 
10289 			if (red->dmetric.value >= 0)
10290 				vty_out(vty, " metric %d", red->dmetric.value);
10291 
10292 			if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1)
10293 				vty_out(vty, " metric-type 1");
10294 
10295 			if (ROUTEMAP_NAME(red))
10296 				vty_out(vty, " route-map %s",
10297 					ROUTEMAP_NAME(red));
10298 
10299 			vty_out(vty, "\n");
10300 		}
10301 	}
10302 
10303 	return 0;
10304 }
10305 
config_write_ospf_default_metric(struct vty * vty,struct ospf * ospf)10306 static int config_write_ospf_default_metric(struct vty *vty, struct ospf *ospf)
10307 {
10308 	if (ospf->default_metric != -1)
10309 		vty_out(vty, " default-metric %d\n", ospf->default_metric);
10310 	return 0;
10311 }
10312 
config_write_ospf_distribute(struct vty * vty,struct ospf * ospf)10313 static int config_write_ospf_distribute(struct vty *vty, struct ospf *ospf)
10314 {
10315 	int type;
10316 	struct ospf_redist *red;
10317 
10318 	if (ospf) {
10319 		/* distribute-list print. */
10320 		for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
10321 			if (DISTRIBUTE_NAME(ospf, type))
10322 				vty_out(vty, " distribute-list %s out %s\n",
10323 					DISTRIBUTE_NAME(ospf, type),
10324 					zebra_route_string(type));
10325 
10326 		/* default-information print. */
10327 		if (ospf->default_originate != DEFAULT_ORIGINATE_NONE) {
10328 			vty_out(vty, " default-information originate");
10329 			if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
10330 				vty_out(vty, " always");
10331 
10332 			red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
10333 			if (red) {
10334 				if (red->dmetric.value >= 0)
10335 					vty_out(vty, " metric %d",
10336 						red->dmetric.value);
10337 
10338 				if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1)
10339 					vty_out(vty, " metric-type 1");
10340 
10341 				if (ROUTEMAP_NAME(red))
10342 					vty_out(vty, " route-map %s",
10343 						ROUTEMAP_NAME(red));
10344 			}
10345 
10346 			vty_out(vty, "\n");
10347 		}
10348 	}
10349 
10350 	return 0;
10351 }
10352 
config_write_ospf_distance(struct vty * vty,struct ospf * ospf)10353 static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf)
10354 {
10355 	struct route_node *rn;
10356 	struct ospf_distance *odistance;
10357 
10358 	if (ospf->distance_all)
10359 		vty_out(vty, " distance %d\n", ospf->distance_all);
10360 
10361 	if (ospf->distance_intra || ospf->distance_inter
10362 	    || ospf->distance_external) {
10363 		vty_out(vty, " distance ospf");
10364 
10365 		if (ospf->distance_intra)
10366 			vty_out(vty, " intra-area %d", ospf->distance_intra);
10367 		if (ospf->distance_inter)
10368 			vty_out(vty, " inter-area %d", ospf->distance_inter);
10369 		if (ospf->distance_external)
10370 			vty_out(vty, " external %d", ospf->distance_external);
10371 
10372 		vty_out(vty, "\n");
10373 	}
10374 
10375 	for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn))
10376 		if ((odistance = rn->info) != NULL) {
10377 			vty_out(vty, " distance %d %s/%d %s\n",
10378 				odistance->distance, inet_ntoa(rn->p.u.prefix4),
10379 				rn->p.prefixlen,
10380 				odistance->access_list ? odistance->access_list
10381 						       : "");
10382 		}
10383 	return 0;
10384 }
10385 
ospf_config_write_one(struct vty * vty,struct ospf * ospf)10386 static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
10387 {
10388 	struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
10389 	struct interface *ifp;
10390 	struct ospf_interface *oi;
10391 	struct listnode *node = NULL;
10392 	int write = 0;
10393 
10394 	/* `router ospf' print. */
10395 	if (ospf->instance && ospf->name) {
10396 		vty_out(vty, "router ospf %d vrf %s\n", ospf->instance,
10397 			ospf->name);
10398 	} else if (ospf->instance) {
10399 		vty_out(vty, "router ospf %d\n", ospf->instance);
10400 	} else if (ospf->name) {
10401 		vty_out(vty, "router ospf vrf %s\n", ospf->name);
10402 	} else
10403 		vty_out(vty, "router ospf\n");
10404 
10405 	if (!ospf->networks) {
10406 		write++;
10407 		return write;
10408 	}
10409 
10410 	/* Router ID print. */
10411 	if (ospf->router_id_static.s_addr != 0)
10412 		vty_out(vty, " ospf router-id %s\n",
10413 			inet_ntoa(ospf->router_id_static));
10414 
10415 	/* ABR type print. */
10416 	if (ospf->abr_type != OSPF_ABR_DEFAULT)
10417 		vty_out(vty, " ospf abr-type %s\n",
10418 			ospf_abr_type_str[ospf->abr_type]);
10419 
10420 	/* log-adjacency-changes flag print. */
10421 	if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
10422 		if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
10423 			vty_out(vty, " log-adjacency-changes detail\n");
10424 		else if (!SAVE_OSPF_LOG_ADJACENCY_CHANGES)
10425 			vty_out(vty, " log-adjacency-changes\n");
10426 	} else if (SAVE_OSPF_LOG_ADJACENCY_CHANGES) {
10427 		vty_out(vty, " no log-adjacency-changes\n");
10428 	}
10429 
10430 	/* RFC1583 compatibility flag print -- Compatible with CISCO
10431 	 * 12.1. */
10432 	if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
10433 		vty_out(vty, " compatible rfc1583\n");
10434 
10435 	/* auto-cost reference-bandwidth configuration.  */
10436 	if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) {
10437 		vty_out(vty,
10438 			"! Important: ensure reference bandwidth is consistent across all routers\n");
10439 		vty_out(vty, " auto-cost reference-bandwidth %d\n",
10440 			ospf->ref_bandwidth);
10441 	}
10442 
10443 	/* SPF timers print. */
10444 	if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT
10445 	    || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT
10446 	    || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
10447 		vty_out(vty, " timers throttle spf %d %d %d\n", ospf->spf_delay,
10448 			ospf->spf_holdtime, ospf->spf_max_holdtime);
10449 
10450 	/* LSA timers print. */
10451 	if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL)
10452 		vty_out(vty, " timers throttle lsa all %d\n",
10453 			ospf->min_ls_interval);
10454 	if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL)
10455 		vty_out(vty, " timers lsa min-arrival %d\n",
10456 			ospf->min_ls_arrival);
10457 
10458 	/* Write multiplier print. */
10459 	if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT)
10460 		vty_out(vty, " ospf write-multiplier %d\n",
10461 			ospf->write_oi_count);
10462 
10463 	/* Max-metric router-lsa print */
10464 	config_write_stub_router(vty, ospf);
10465 
10466 	/* SPF refresh parameters print. */
10467 	if (ospf->lsa_refresh_interval != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
10468 		vty_out(vty, " refresh timer %d\n", ospf->lsa_refresh_interval);
10469 
10470 	/* Redistribute information print. */
10471 	config_write_ospf_redistribute(vty, ospf);
10472 
10473 	/* passive-interface print. */
10474 	if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
10475 		vty_out(vty, " passive-interface default\n");
10476 
10477 	/* proactive-arp print. */
10478 	if (ospf->proactive_arp != OSPF_PROACTIVE_ARP_DEFAULT) {
10479 		if (ospf->proactive_arp)
10480 			vty_out(vty, " proactive-arp\n");
10481 		else
10482 			vty_out(vty, " no proactive-arp\n");
10483 	}
10484 
10485 	FOR_ALL_INTERFACES (vrf, ifp)
10486 		if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
10487 					     passive_interface)
10488 		    && IF_DEF_PARAMS(ifp)->passive_interface
10489 			       != ospf->passive_interface_default) {
10490 			vty_out(vty, " %spassive-interface %s\n",
10491 				IF_DEF_PARAMS(ifp)->passive_interface ? ""
10492 								      : "no ",
10493 				ifp->name);
10494 		}
10495 	for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
10496 		if (!OSPF_IF_PARAM_CONFIGURED(oi->params, passive_interface))
10497 			continue;
10498 		if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp),
10499 					     passive_interface)) {
10500 			if (oi->params->passive_interface
10501 			    == IF_DEF_PARAMS(oi->ifp)->passive_interface)
10502 				continue;
10503 		} else if (oi->params->passive_interface
10504 			   == ospf->passive_interface_default)
10505 			continue;
10506 
10507 		vty_out(vty, " %spassive-interface %s %s\n",
10508 			oi->params->passive_interface ? "" : "no ",
10509 			oi->ifp->name, inet_ntoa(oi->address->u.prefix4));
10510 	}
10511 
10512 	/* Network area print. */
10513 	config_write_network_area(vty, ospf);
10514 
10515 	/* Area config print. */
10516 	config_write_ospf_area(vty, ospf);
10517 
10518 	/* static neighbor print. */
10519 	config_write_ospf_nbr_nbma(vty, ospf);
10520 
10521 	/* Virtual-Link print. */
10522 	config_write_virtual_link(vty, ospf);
10523 
10524 	/* Default metric configuration.  */
10525 	config_write_ospf_default_metric(vty, ospf);
10526 
10527 	/* Distribute-list and default-information print. */
10528 	config_write_ospf_distribute(vty, ospf);
10529 
10530 	/* Distance configuration. */
10531 	config_write_ospf_distance(vty, ospf);
10532 
10533 	ospf_opaque_config_write_router(vty, ospf);
10534 
10535 	write++;
10536 	return write;
10537 }
10538 
10539 /* OSPF configuration write function. */
ospf_config_write(struct vty * vty)10540 static int ospf_config_write(struct vty *vty)
10541 {
10542 	struct ospf *ospf;
10543 	struct listnode *ospf_node = NULL;
10544 	int write = 0;
10545 
10546 	if (listcount(om->ospf) == 0)
10547 		return write;
10548 
10549 	for (ALL_LIST_ELEMENTS_RO(om->ospf, ospf_node, ospf)) {
10550 		/* VRF Default check if it is running.
10551 		 * Upon daemon start, there could be default instance
10552 		 * in absence of 'router ospf'/oi_running is disabled. */
10553 		if (ospf->vrf_id == VRF_DEFAULT && ospf->oi_running)
10554 			write += ospf_config_write_one(vty, ospf);
10555 		/* For Non-Default VRF simply display the configuration,
10556 		 * even if it is not oi_running. */
10557 		else if (ospf->vrf_id != VRF_DEFAULT)
10558 			write += ospf_config_write_one(vty, ospf);
10559 	}
10560 	return write;
10561 }
10562 
ospf_vty_show_init(void)10563 void ospf_vty_show_init(void)
10564 {
10565 	/* "show ip ospf" commands. */
10566 	install_element(VIEW_NODE, &show_ip_ospf_cmd);
10567 
10568 	install_element(VIEW_NODE, &show_ip_ospf_instance_cmd);
10569 
10570 	/* "show ip ospf database" commands. */
10571 	install_element(VIEW_NODE, &show_ip_ospf_database_max_cmd);
10572 
10573 	install_element(VIEW_NODE,
10574 			&show_ip_ospf_instance_database_type_adv_router_cmd);
10575 	install_element(VIEW_NODE, &show_ip_ospf_instance_database_cmd);
10576 	install_element(VIEW_NODE, &show_ip_ospf_instance_database_max_cmd);
10577 
10578 	/* "show ip ospf interface" commands. */
10579 	install_element(VIEW_NODE, &show_ip_ospf_interface_cmd);
10580 
10581 	install_element(VIEW_NODE, &show_ip_ospf_instance_interface_cmd);
10582 	/* "show ip ospf interface traffic */
10583 	install_element(VIEW_NODE, &show_ip_ospf_interface_traffic_cmd);
10584 
10585 	/* "show ip ospf neighbor" commands. */
10586 	install_element(VIEW_NODE, &show_ip_ospf_neighbor_int_detail_cmd);
10587 	install_element(VIEW_NODE, &show_ip_ospf_neighbor_int_cmd);
10588 	install_element(VIEW_NODE, &show_ip_ospf_neighbor_id_cmd);
10589 	install_element(VIEW_NODE, &show_ip_ospf_neighbor_detail_all_cmd);
10590 	install_element(VIEW_NODE, &show_ip_ospf_neighbor_detail_cmd);
10591 	install_element(VIEW_NODE, &show_ip_ospf_neighbor_cmd);
10592 	install_element(VIEW_NODE, &show_ip_ospf_neighbor_all_cmd);
10593 
10594 	install_element(VIEW_NODE,
10595 			&show_ip_ospf_instance_neighbor_int_detail_cmd);
10596 	install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_int_cmd);
10597 	install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_id_cmd);
10598 	install_element(VIEW_NODE,
10599 			&show_ip_ospf_instance_neighbor_detail_all_cmd);
10600 	install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_cmd);
10601 	install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_cmd);
10602 	install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_all_cmd);
10603 
10604 	/* "show ip ospf route" commands. */
10605 	install_element(VIEW_NODE, &show_ip_ospf_route_cmd);
10606 	install_element(VIEW_NODE, &show_ip_ospf_border_routers_cmd);
10607 
10608 	install_element(VIEW_NODE, &show_ip_ospf_instance_route_cmd);
10609 	install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd);
10610 
10611 	/* "show ip ospf vrfs" commands. */
10612 	install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd);
10613 }
10614 
10615 
10616 static int config_write_interface(struct vty *vty);
10617 /* ospfd's interface node. */
10618 static struct cmd_node interface_node = {
10619 	.name = "interface",
10620 	.node = INTERFACE_NODE,
10621 	.parent_node = CONFIG_NODE,
10622 	.prompt = "%s(config-if)# ",
10623 	.config_write = config_write_interface,
10624 };
10625 
10626 /* Initialization of OSPF interface. */
ospf_vty_if_init(void)10627 static void ospf_vty_if_init(void)
10628 {
10629 	/* Install interface node. */
10630 	install_node(&interface_node);
10631 	if_cmd_init();
10632 
10633 	/* "ip ospf authentication" commands. */
10634 	install_element(INTERFACE_NODE, &ip_ospf_authentication_args_addr_cmd);
10635 	install_element(INTERFACE_NODE, &ip_ospf_authentication_addr_cmd);
10636 	install_element(INTERFACE_NODE,
10637 			&no_ip_ospf_authentication_args_addr_cmd);
10638 	install_element(INTERFACE_NODE, &no_ip_ospf_authentication_addr_cmd);
10639 	install_element(INTERFACE_NODE, &ip_ospf_authentication_key_addr_cmd);
10640 	install_element(INTERFACE_NODE,
10641 			&no_ip_ospf_authentication_key_authkey_addr_cmd);
10642 	install_element(INTERFACE_NODE,
10643 			&no_ospf_authentication_key_authkey_addr_cmd);
10644 
10645 	/* "ip ospf message-digest-key" commands. */
10646 	install_element(INTERFACE_NODE, &ip_ospf_message_digest_key_cmd);
10647 	install_element(INTERFACE_NODE, &no_ip_ospf_message_digest_key_cmd);
10648 
10649 	/* "ip ospf cost" commands. */
10650 	install_element(INTERFACE_NODE, &ip_ospf_cost_cmd);
10651 	install_element(INTERFACE_NODE, &no_ip_ospf_cost_cmd);
10652 
10653 	/* "ip ospf mtu-ignore" commands. */
10654 	install_element(INTERFACE_NODE, &ip_ospf_mtu_ignore_addr_cmd);
10655 	install_element(INTERFACE_NODE, &no_ip_ospf_mtu_ignore_addr_cmd);
10656 
10657 	/* "ip ospf dead-interval" commands. */
10658 	install_element(INTERFACE_NODE, &ip_ospf_dead_interval_cmd);
10659 	install_element(INTERFACE_NODE,
10660 			&ip_ospf_dead_interval_minimal_addr_cmd);
10661 	install_element(INTERFACE_NODE, &no_ip_ospf_dead_interval_cmd);
10662 
10663 	/* "ip ospf hello-interval" commands. */
10664 	install_element(INTERFACE_NODE, &ip_ospf_hello_interval_cmd);
10665 	install_element(INTERFACE_NODE, &no_ip_ospf_hello_interval_cmd);
10666 
10667 	/* "ip ospf network" commands. */
10668 	install_element(INTERFACE_NODE, &ip_ospf_network_cmd);
10669 	install_element(INTERFACE_NODE, &no_ip_ospf_network_cmd);
10670 
10671 	/* "ip ospf priority" commands. */
10672 	install_element(INTERFACE_NODE, &ip_ospf_priority_cmd);
10673 	install_element(INTERFACE_NODE, &no_ip_ospf_priority_cmd);
10674 
10675 	/* "ip ospf retransmit-interval" commands. */
10676 	install_element(INTERFACE_NODE, &ip_ospf_retransmit_interval_addr_cmd);
10677 	install_element(INTERFACE_NODE,
10678 			&no_ip_ospf_retransmit_interval_addr_cmd);
10679 
10680 	/* "ip ospf transmit-delay" commands. */
10681 	install_element(INTERFACE_NODE, &ip_ospf_transmit_delay_addr_cmd);
10682 	install_element(INTERFACE_NODE, &no_ip_ospf_transmit_delay_addr_cmd);
10683 
10684 	/* "ip ospf area" commands. */
10685 	install_element(INTERFACE_NODE, &ip_ospf_area_cmd);
10686 	install_element(INTERFACE_NODE, &no_ip_ospf_area_cmd);
10687 
10688 	/* These commands are compatibitliy for previous version. */
10689 	install_element(INTERFACE_NODE, &ospf_authentication_key_cmd);
10690 	install_element(INTERFACE_NODE, &ospf_message_digest_key_cmd);
10691 	install_element(INTERFACE_NODE, &no_ospf_message_digest_key_cmd);
10692 	install_element(INTERFACE_NODE, &ospf_dead_interval_cmd);
10693 	install_element(INTERFACE_NODE, &no_ospf_dead_interval_cmd);
10694 	install_element(INTERFACE_NODE, &ospf_hello_interval_cmd);
10695 	install_element(INTERFACE_NODE, &no_ospf_hello_interval_cmd);
10696 	install_element(INTERFACE_NODE, &ospf_cost_cmd);
10697 	install_element(INTERFACE_NODE, &no_ospf_cost_cmd);
10698 	install_element(INTERFACE_NODE, &ospf_network_cmd);
10699 	install_element(INTERFACE_NODE, &no_ospf_network_cmd);
10700 	install_element(INTERFACE_NODE, &ospf_priority_cmd);
10701 	install_element(INTERFACE_NODE, &no_ospf_priority_cmd);
10702 	install_element(INTERFACE_NODE, &ospf_retransmit_interval_cmd);
10703 	install_element(INTERFACE_NODE, &no_ospf_retransmit_interval_cmd);
10704 	install_element(INTERFACE_NODE, &ospf_transmit_delay_cmd);
10705 	install_element(INTERFACE_NODE, &no_ospf_transmit_delay_cmd);
10706 }
10707 
ospf_vty_zebra_init(void)10708 static void ospf_vty_zebra_init(void)
10709 {
10710 	install_element(OSPF_NODE, &ospf_redistribute_source_cmd);
10711 	install_element(OSPF_NODE, &no_ospf_redistribute_source_cmd);
10712 	install_element(OSPF_NODE, &ospf_redistribute_instance_source_cmd);
10713 	install_element(OSPF_NODE, &no_ospf_redistribute_instance_source_cmd);
10714 
10715 	install_element(OSPF_NODE, &ospf_distribute_list_out_cmd);
10716 	install_element(OSPF_NODE, &no_ospf_distribute_list_out_cmd);
10717 
10718 	install_element(OSPF_NODE, &ospf_default_information_originate_cmd);
10719 	install_element(OSPF_NODE, &no_ospf_default_information_originate_cmd);
10720 
10721 	install_element(OSPF_NODE, &ospf_default_metric_cmd);
10722 	install_element(OSPF_NODE, &no_ospf_default_metric_cmd);
10723 
10724 	install_element(OSPF_NODE, &ospf_distance_cmd);
10725 	install_element(OSPF_NODE, &no_ospf_distance_cmd);
10726 	install_element(OSPF_NODE, &no_ospf_distance_ospf_cmd);
10727 	install_element(OSPF_NODE, &ospf_distance_ospf_cmd);
10728 #if 0
10729   install_element (OSPF_NODE, &ospf_distance_source_cmd);
10730   install_element (OSPF_NODE, &no_ospf_distance_source_cmd);
10731   install_element (OSPF_NODE, &ospf_distance_source_access_list_cmd);
10732   install_element (OSPF_NODE, &no_ospf_distance_source_access_list_cmd);
10733 #endif /* 0 */
10734 }
10735 
10736 static int ospf_config_write(struct vty *vty);
10737 static struct cmd_node ospf_node = {
10738 	.name = "ospf",
10739 	.node = OSPF_NODE,
10740 	.parent_node = CONFIG_NODE,
10741 	.prompt = "%s(config-router)# ",
10742 	.config_write = ospf_config_write,
10743 };
10744 
ospf_interface_clear(struct interface * ifp)10745 static void ospf_interface_clear(struct interface *ifp)
10746 {
10747 	if (!if_is_operative(ifp))
10748 		return;
10749 
10750 	if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
10751 		zlog_debug("ISM[%s]: clear by reset", ifp->name);
10752 
10753 	ospf_if_reset(ifp);
10754 }
10755 
10756 DEFUN (clear_ip_ospf_interface,
10757        clear_ip_ospf_interface_cmd,
10758        "clear ip ospf [vrf NAME] interface [IFNAME]",
10759        CLEAR_STR
10760        IP_STR
10761        "OSPF information\n"
10762        VRF_CMD_HELP_STR
10763        "Interface information\n"
10764        "Interface name\n")
10765 {
10766 	int idx_ifname = 0;
10767 	int idx_vrf = 0;
10768 	struct interface *ifp;
10769 	struct listnode *node;
10770 	struct ospf *ospf = NULL;
10771 	char *vrf_name = NULL;
10772 	vrf_id_t vrf_id = VRF_DEFAULT;
10773 	struct vrf *vrf = NULL;
10774 
10775 	if (argv_find(argv, argc, "vrf", &idx_vrf))
10776 		vrf_name = argv[idx_vrf + 1]->arg;
10777 	if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
10778 		vrf_name = NULL;
10779 	if (vrf_name) {
10780 		vrf = vrf_lookup_by_name(vrf_name);
10781 		if (vrf)
10782 			vrf_id = vrf->vrf_id;
10783 	}
10784 	if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) {
10785 		/* Clear all the ospfv2 interfaces. */
10786 		for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
10787 			if (vrf_id != ospf->vrf_id)
10788 				continue;
10789 			if (!vrf)
10790 				vrf = vrf_lookup_by_id(ospf->vrf_id);
10791 			FOR_ALL_INTERFACES (vrf, ifp)
10792 				ospf_interface_clear(ifp);
10793 		}
10794 	} else {
10795 		/* Interface name is specified. */
10796 		ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
10797 		if (ifp == NULL)
10798 			vty_out(vty, "No such interface name\n");
10799 		else
10800 			ospf_interface_clear(ifp);
10801 	}
10802 
10803 	return CMD_SUCCESS;
10804 }
10805 
ospf_vty_clear_init(void)10806 void ospf_vty_clear_init(void)
10807 {
10808 	install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
10809 }
10810 
10811 
10812 /* Install OSPF related vty commands. */
ospf_vty_init(void)10813 void ospf_vty_init(void)
10814 {
10815 	/* Install ospf top node. */
10816 	install_node(&ospf_node);
10817 
10818 	/* "router ospf" commands. */
10819 	install_element(CONFIG_NODE, &router_ospf_cmd);
10820 	install_element(CONFIG_NODE, &no_router_ospf_cmd);
10821 
10822 
10823 	install_default(OSPF_NODE);
10824 
10825 	/* "ospf router-id" commands. */
10826 	install_element(OSPF_NODE, &ospf_router_id_cmd);
10827 	install_element(OSPF_NODE, &ospf_router_id_old_cmd);
10828 	install_element(OSPF_NODE, &no_ospf_router_id_cmd);
10829 
10830 	/* "passive-interface" commands. */
10831 	install_element(OSPF_NODE, &ospf_passive_interface_addr_cmd);
10832 	install_element(OSPF_NODE, &no_ospf_passive_interface_addr_cmd);
10833 
10834 	/* "ospf abr-type" commands. */
10835 	install_element(OSPF_NODE, &ospf_abr_type_cmd);
10836 	install_element(OSPF_NODE, &no_ospf_abr_type_cmd);
10837 
10838 	/* "ospf log-adjacency-changes" commands. */
10839 	install_element(OSPF_NODE, &ospf_log_adjacency_changes_cmd);
10840 	install_element(OSPF_NODE, &ospf_log_adjacency_changes_detail_cmd);
10841 	install_element(OSPF_NODE, &no_ospf_log_adjacency_changes_cmd);
10842 	install_element(OSPF_NODE, &no_ospf_log_adjacency_changes_detail_cmd);
10843 
10844 	/* "ospf rfc1583-compatible" commands. */
10845 	install_element(OSPF_NODE, &ospf_compatible_rfc1583_cmd);
10846 	install_element(OSPF_NODE, &no_ospf_compatible_rfc1583_cmd);
10847 	install_element(OSPF_NODE, &ospf_rfc1583_flag_cmd);
10848 	install_element(OSPF_NODE, &no_ospf_rfc1583_flag_cmd);
10849 
10850 	/* "network area" commands. */
10851 	install_element(OSPF_NODE, &ospf_network_area_cmd);
10852 	install_element(OSPF_NODE, &no_ospf_network_area_cmd);
10853 
10854 	/* "area authentication" commands. */
10855 	install_element(OSPF_NODE,
10856 			&ospf_area_authentication_message_digest_cmd);
10857 	install_element(OSPF_NODE, &ospf_area_authentication_cmd);
10858 	install_element(OSPF_NODE, &no_ospf_area_authentication_cmd);
10859 
10860 	/* "area range" commands.  */
10861 	install_element(OSPF_NODE, &ospf_area_range_cmd);
10862 	install_element(OSPF_NODE, &ospf_area_range_cost_cmd);
10863 	install_element(OSPF_NODE, &ospf_area_range_not_advertise_cmd);
10864 	install_element(OSPF_NODE, &no_ospf_area_range_cmd);
10865 	install_element(OSPF_NODE, &ospf_area_range_substitute_cmd);
10866 	install_element(OSPF_NODE, &no_ospf_area_range_substitute_cmd);
10867 
10868 	/* "area virtual-link" commands. */
10869 	install_element(OSPF_NODE, &ospf_area_vlink_cmd);
10870 	install_element(OSPF_NODE, &ospf_area_vlink_intervals_cmd);
10871 	install_element(OSPF_NODE, &no_ospf_area_vlink_cmd);
10872 	install_element(OSPF_NODE, &no_ospf_area_vlink_intervals_cmd);
10873 
10874 
10875 	/* "area stub" commands. */
10876 	install_element(OSPF_NODE, &ospf_area_stub_no_summary_cmd);
10877 	install_element(OSPF_NODE, &ospf_area_stub_cmd);
10878 	install_element(OSPF_NODE, &no_ospf_area_stub_no_summary_cmd);
10879 	install_element(OSPF_NODE, &no_ospf_area_stub_cmd);
10880 
10881 	/* "area nssa" commands. */
10882 	install_element(OSPF_NODE, &ospf_area_nssa_cmd);
10883 	install_element(OSPF_NODE, &ospf_area_nssa_translate_cmd);
10884 	install_element(OSPF_NODE, &ospf_area_nssa_no_summary_cmd);
10885 	install_element(OSPF_NODE, &no_ospf_area_nssa_no_summary_cmd);
10886 	install_element(OSPF_NODE, &no_ospf_area_nssa_cmd);
10887 
10888 	install_element(OSPF_NODE, &ospf_area_default_cost_cmd);
10889 	install_element(OSPF_NODE, &no_ospf_area_default_cost_cmd);
10890 
10891 	install_element(OSPF_NODE, &ospf_area_shortcut_cmd);
10892 	install_element(OSPF_NODE, &no_ospf_area_shortcut_cmd);
10893 
10894 	install_element(OSPF_NODE, &ospf_area_export_list_cmd);
10895 	install_element(OSPF_NODE, &no_ospf_area_export_list_cmd);
10896 
10897 	install_element(OSPF_NODE, &ospf_area_filter_list_cmd);
10898 	install_element(OSPF_NODE, &no_ospf_area_filter_list_cmd);
10899 
10900 	install_element(OSPF_NODE, &ospf_area_import_list_cmd);
10901 	install_element(OSPF_NODE, &no_ospf_area_import_list_cmd);
10902 
10903 	/* SPF timer commands */
10904 	install_element(OSPF_NODE, &ospf_timers_throttle_spf_cmd);
10905 	install_element(OSPF_NODE, &no_ospf_timers_throttle_spf_cmd);
10906 
10907 	/* LSA timers commands */
10908 	install_element(OSPF_NODE, &ospf_timers_min_ls_interval_cmd);
10909 	install_element(OSPF_NODE, &no_ospf_timers_min_ls_interval_cmd);
10910 	install_element(OSPF_NODE, &ospf_timers_lsa_min_arrival_cmd);
10911 	install_element(OSPF_NODE, &no_ospf_timers_lsa_min_arrival_cmd);
10912 
10913 	/* refresh timer commands */
10914 	install_element(OSPF_NODE, &ospf_refresh_timer_cmd);
10915 	install_element(OSPF_NODE, &no_ospf_refresh_timer_val_cmd);
10916 
10917 	/* max-metric commands */
10918 	install_element(OSPF_NODE, &ospf_max_metric_router_lsa_admin_cmd);
10919 	install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_admin_cmd);
10920 	install_element(OSPF_NODE, &ospf_max_metric_router_lsa_startup_cmd);
10921 	install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_startup_cmd);
10922 	install_element(OSPF_NODE, &ospf_max_metric_router_lsa_shutdown_cmd);
10923 	install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_shutdown_cmd);
10924 
10925 	/* reference bandwidth commands */
10926 	install_element(OSPF_NODE, &ospf_auto_cost_reference_bandwidth_cmd);
10927 	install_element(OSPF_NODE, &no_ospf_auto_cost_reference_bandwidth_cmd);
10928 
10929 	/* "neighbor" commands. */
10930 	install_element(OSPF_NODE, &ospf_neighbor_cmd);
10931 	install_element(OSPF_NODE, &ospf_neighbor_poll_interval_cmd);
10932 	install_element(OSPF_NODE, &no_ospf_neighbor_cmd);
10933 	install_element(OSPF_NODE, &no_ospf_neighbor_poll_cmd);
10934 
10935 	/* write multiplier commands */
10936 	install_element(OSPF_NODE, &ospf_write_multiplier_cmd);
10937 	install_element(OSPF_NODE, &write_multiplier_cmd);
10938 	install_element(OSPF_NODE, &no_ospf_write_multiplier_cmd);
10939 	install_element(OSPF_NODE, &no_write_multiplier_cmd);
10940 
10941 	/* "proactive-arp" commands. */
10942 	install_element(OSPF_NODE, &ospf_proactive_arp_cmd);
10943 	install_element(OSPF_NODE, &no_ospf_proactive_arp_cmd);
10944 
10945 	/* Init interface related vty commands. */
10946 	ospf_vty_if_init();
10947 
10948 	/* Init zebra related vty commands. */
10949 	ospf_vty_zebra_init();
10950 }
10951