]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_interface.c
ospf6d: add "nssa" option to the "debug ospf6 lsa" command
[mirror_frr.git] / ospf6d / ospf6_interface.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 19 */
20
508e53e2 21#include <zebra.h>
718e3744 22
508e53e2 23#include "memory.h"
718e3744 24#include "if.h"
25#include "log.h"
26#include "command.h"
508e53e2 27#include "thread.h"
28#include "prefix.h"
29#include "plist.h"
88177fe3 30#include "zclient.h"
718e3744 31
508e53e2 32#include "ospf6_lsa.h"
718e3744 33#include "ospf6_lsdb.h"
c527acf1 34#include "ospf6_top.h"
508e53e2 35#include "ospf6_network.h"
36#include "ospf6_message.h"
37#include "ospf6_route.h"
718e3744 38#include "ospf6_area.h"
42cabc55 39#include "ospf6_abr.h"
718e3744 40#include "ospf6_interface.h"
508e53e2 41#include "ospf6_neighbor.h"
42#include "ospf6_intra.h"
43#include "ospf6_spf.h"
049207c3 44#include "ospf6d.h"
7f342629 45#include "ospf6_bfd.h"
ef7bd2a3 46#include "ospf6_zebra.h"
9a06f23d 47#include "ospf6_gr.h"
f16ae8cf 48#include "lib/json.h"
718e3744 49
9a06f23d 50DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_IF, "OSPF6 interface");
bf8d3d6a 51DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names");
96244aca 52DEFINE_QOBJ_TYPE(ospf6_interface);
3012671f 53DEFINE_HOOK(ospf6_interface_change,
d62a17ae 54 (struct ospf6_interface * oi, int state, int old_state),
8451921b 55 (oi, state, old_state));
4a1ab8e4 56
508e53e2 57unsigned char conf_debug_ospf6_interface = 0;
58
2b64873d 59const char *const ospf6_interface_state_str[] = {
d62a17ae 60 "None", "Down", "Loopback", "Waiting", "PointToPoint",
61 "DROther", "BDR", "DR", NULL};
718e3744 62
9a06f23d 63int ospf6_interface_neighbor_count(struct ospf6_interface *oi)
64{
65 int count = 0;
66 struct ospf6_neighbor *nbr = NULL;
67 struct listnode *node;
68
69 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, nbr)) {
70 /* Down state is not shown. */
71 if (nbr->state == OSPF6_NEIGHBOR_DOWN)
72 continue;
73 count++;
74 }
75
76 return count;
77}
78
c5d28568
K
79struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex,
80 vrf_id_t vrf_id)
718e3744 81{
d62a17ae 82 struct ospf6_interface *oi;
83 struct interface *ifp;
718e3744 84
c5d28568 85 ifp = if_lookup_by_index(ifindex, vrf_id);
d62a17ae 86 if (ifp == NULL)
87 return (struct ospf6_interface *)NULL;
508e53e2 88
d62a17ae 89 oi = (struct ospf6_interface *)ifp->info;
90 return oi;
718e3744 91}
92
508e53e2 93/* schedule routing table recalculation */
d62a17ae 94static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa,
95 unsigned int reason)
718e3744 96{
d62a17ae 97 struct ospf6_interface *oi;
98
99 if (lsa == NULL)
100 return;
101
102 oi = lsa->lsdb->data;
103 switch (ntohs(lsa->header->type)) {
104 case OSPF6_LSTYPE_LINK:
105 if (oi->state == OSPF6_INTERFACE_DR)
106 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
107 if (oi->area)
108 ospf6_spf_schedule(oi->area->ospf6, reason);
109 break;
110
111 default:
112 break;
113 }
718e3744 114}
115
d62a17ae 116static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa *lsa)
a0edf674 117{
d62a17ae 118 ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa));
a0edf674
DD
119}
120
d62a17ae 121static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa *lsa)
a0edf674 122{
d62a17ae 123 ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa));
a0edf674
DD
124}
125
d7c0a89a 126static uint8_t ospf6_default_iftype(struct interface *ifp)
c5926a92 127{
d62a17ae 128 if (if_is_pointopoint(ifp))
129 return OSPF_IFTYPE_POINTOPOINT;
d16cff32 130 else if (if_is_loopback_or_vrf(ifp))
d62a17ae 131 return OSPF_IFTYPE_LOOPBACK;
132 else
133 return OSPF_IFTYPE_BROADCAST;
c5926a92
DD
134}
135
d7c0a89a 136static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
c19543b2 137{
d62a17ae 138 /* If all else fails, use default OSPF cost */
d7c0a89a
QY
139 uint32_t cost;
140 uint32_t bw, refbw;
beadc736 141 struct ospf6 *ospf6;
27ae9bcd
CS
142 /* interface speed and bw can be 0 in some platforms,
143 * use ospf default bw. If bw is configured then it would
144 * be used.
145 */
146 if (!oi->interface->bandwidth && oi->interface->speed) {
147 bw = oi->interface->speed;
148 } else {
149 bw = oi->interface->bandwidth ? oi->interface->bandwidth
996c9314 150 : OSPF6_INTERFACE_BANDWIDTH;
27ae9bcd
CS
151 }
152
beadc736 153 ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
d62a17ae 154 refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
155
156 /* A specifed ip ospf cost overrides a calculated one. */
157 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
158 cost = oi->cost;
159 else {
d7c0a89a 160 cost = (uint32_t)((double)refbw / (double)bw + (double)0.5);
d62a17ae 161 if (cost < 1)
162 cost = 1;
163 else if (cost > UINT32_MAX)
164 cost = UINT32_MAX;
165 }
166
167 return cost;
c19543b2
VB
168}
169
0db8196a 170static void ospf6_interface_force_recalculate_cost(struct ospf6_interface *oi)
c19543b2 171{
d62a17ae 172 /* update cost held in route_connected list in ospf6_interface */
173 ospf6_interface_connected_route_update(oi->interface);
174
175 /* execute LSA hooks */
176 if (oi->area) {
177 OSPF6_LINK_LSA_SCHEDULE(oi);
178 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
179 OSPF6_NETWORK_LSA_SCHEDULE(oi);
180 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
181 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
182 }
c19543b2
VB
183}
184
0db8196a
JK
185static void ospf6_interface_recalculate_cost(struct ospf6_interface *oi)
186{
d7c0a89a 187 uint32_t newcost;
0db8196a
JK
188
189 newcost = ospf6_interface_get_cost(oi);
190 if (newcost == oi->cost)
191 return;
192 oi->cost = newcost;
193
194 ospf6_interface_force_recalculate_cost(oi);
195}
196
718e3744 197/* Create new ospf6 interface structure */
d62a17ae 198struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
718e3744 199{
d62a17ae 200 struct ospf6_interface *oi;
201 unsigned int iobuflen;
202
9f5dc319 203 oi = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
d62a17ae 204
4f7bf1ab
PR
205 oi->obuf = ospf6_fifo_new();
206
d62a17ae 207 oi->area = (struct ospf6_area *)NULL;
208 oi->neighbor_list = list_new();
209 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
210 oi->linklocal_addr = (struct in6_addr *)NULL;
211 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
212 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
213 oi->priority = OSPF6_INTERFACE_PRIORITY;
214
215 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
216 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
217 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
218 oi->type = ospf6_default_iftype(ifp);
219 oi->state = OSPF6_INTERFACE_DOWN;
220 oi->flag = 0;
221 oi->mtu_ignore = 0;
222 oi->c_ifmtu = 0;
223
224 /* Try to adjust I/O buffer size with IfMtu */
225 oi->ifmtu = ifp->mtu6;
226 iobuflen = ospf6_iobuf_size(ifp->mtu6);
227 if (oi->ifmtu > iobuflen) {
228 if (IS_OSPF6_DEBUG_INTERFACE)
229 zlog_debug(
230 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
231 ifp->name, iobuflen);
232 oi->ifmtu = iobuflen;
233 }
234
235 QOBJ_REG(oi, ospf6_interface);
236
237 oi->lsupdate_list = ospf6_lsdb_create(oi);
238 oi->lsack_list = ospf6_lsdb_create(oi);
239 oi->lsdb = ospf6_lsdb_create(oi);
240 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
241 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
242 oi->lsdb_self = ospf6_lsdb_create(oi);
243
244 oi->route_connected =
245 OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
246 oi->route_connected->scope = oi;
247
248 /* link both */
249 oi->interface = ifp;
250 ifp->info = oi;
251
252 /* Compute cost. */
253 oi->cost = ospf6_interface_get_cost(oi);
254
255 return oi;
718e3744 256}
257
d62a17ae 258void ospf6_interface_delete(struct ospf6_interface *oi)
718e3744 259{
d62a17ae 260 struct listnode *node, *nnode;
261 struct ospf6_neighbor *on;
262
263 QOBJ_UNREG(oi);
718e3744 264
4f7bf1ab
PR
265 ospf6_fifo_free(oi->obuf);
266
d62a17ae 267 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
268 ospf6_neighbor_delete(on);
ae19c240 269
6a154c88 270 list_delete(&oi->neighbor_list);
718e3744 271
d62a17ae 272 THREAD_OFF(oi->thread_send_hello);
273 THREAD_OFF(oi->thread_send_lsupdate);
274 THREAD_OFF(oi->thread_send_lsack);
f80003b0 275 THREAD_OFF(oi->thread_sso);
9ae41e31 276 THREAD_OFF(oi->thread_wait_timer);
508e53e2 277
d62a17ae 278 ospf6_lsdb_remove_all(oi->lsdb);
279 ospf6_lsdb_remove_all(oi->lsupdate_list);
280 ospf6_lsdb_remove_all(oi->lsack_list);
508e53e2 281
d62a17ae 282 ospf6_lsdb_delete(oi->lsdb);
283 ospf6_lsdb_delete(oi->lsdb_self);
6452df09 284
d62a17ae 285 ospf6_lsdb_delete(oi->lsupdate_list);
286 ospf6_lsdb_delete(oi->lsack_list);
718e3744 287
e285b70d 288 ospf6_route_table_delete(oi->route_connected);
718e3744 289
d62a17ae 290 /* cut link */
291 oi->interface->info = NULL;
718e3744 292
d62a17ae 293 /* plist_name */
294 if (oi->plist_name)
295 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
508e53e2 296
22b982df
PG
297 /* disable from area list if possible */
298 ospf6_area_interface_delete(oi);
299
1f7be0d2
RZ
300 /* Free BFD allocated data. */
301 XFREE(MTYPE_TMP, oi->bfd_config.profile);
302
d62a17ae 303 XFREE(MTYPE_OSPF6_IF, oi);
508e53e2 304}
305
d62a17ae 306void ospf6_interface_enable(struct ospf6_interface *oi)
508e53e2 307{
d62a17ae 308 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
309 ospf6_interface_state_update(oi->interface);
508e53e2 310}
311
d62a17ae 312void ospf6_interface_disable(struct ospf6_interface *oi)
508e53e2 313{
d62a17ae 314 SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
508e53e2 315
d62a17ae 316 thread_execute(master, interface_down, oi, 0);
508e53e2 317
d62a17ae 318 ospf6_lsdb_remove_all(oi->lsdb);
319 ospf6_lsdb_remove_all(oi->lsdb_self);
320 ospf6_lsdb_remove_all(oi->lsupdate_list);
321 ospf6_lsdb_remove_all(oi->lsack_list);
508e53e2 322
d62a17ae 323 THREAD_OFF(oi->thread_send_hello);
324 THREAD_OFF(oi->thread_send_lsupdate);
325 THREAD_OFF(oi->thread_send_lsack);
f80003b0 326 THREAD_OFF(oi->thread_sso);
d9628728 327
d62a17ae 328 THREAD_OFF(oi->thread_network_lsa);
329 THREAD_OFF(oi->thread_link_lsa);
330 THREAD_OFF(oi->thread_intra_prefix_lsa);
76249532 331 THREAD_OFF(oi->thread_as_extern_lsa);
9ae41e31 332 THREAD_OFF(oi->thread_wait_timer);
718e3744 333}
334
335static struct in6_addr *
d62a17ae 336ospf6_interface_get_linklocal_address(struct interface *ifp)
718e3744 337{
d62a17ae 338 struct listnode *n;
339 struct connected *c;
340 struct in6_addr *l = (struct in6_addr *)NULL;
341
342 /* for each connected address */
343 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
344 /* if family not AF_INET6, ignore */
345 if (c->address->family != AF_INET6)
346 continue;
347
348 /* linklocal scope check */
349 if (IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
350 l = &c->address->u.prefix6;
351 }
352 return l;
718e3744 353}
354
d62a17ae 355void ospf6_interface_state_update(struct interface *ifp)
718e3744 356{
d62a17ae 357 struct ospf6_interface *oi;
358 unsigned int iobuflen;
359
360 oi = (struct ospf6_interface *)ifp->info;
361 if (oi == NULL)
362 return;
d62a17ae 363 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
364 return;
365
366 /* Adjust the mtu values if the kernel told us something new */
367 if (ifp->mtu6 != oi->ifmtu) {
368 /* If nothing configured, accept it and check for buffer size */
369 if (!oi->c_ifmtu) {
370 oi->ifmtu = ifp->mtu6;
371 iobuflen = ospf6_iobuf_size(ifp->mtu6);
372 if (oi->ifmtu > iobuflen) {
373 if (IS_OSPF6_DEBUG_INTERFACE)
374 zlog_debug(
375 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
376 ifp->name, iobuflen);
377 oi->ifmtu = iobuflen;
378 }
379 } else if (oi->c_ifmtu > ifp->mtu6) {
380 oi->ifmtu = ifp->mtu6;
381 zlog_warn(
382 "Configured mtu %u on %s overridden by kernel %u",
383 oi->c_ifmtu, ifp->name, ifp->mtu6);
384 } else
385 oi->ifmtu = oi->c_ifmtu;
386 }
387
388 if (if_is_operative(ifp)
389 && (ospf6_interface_get_linklocal_address(oi->interface)
d16cff32 390 || if_is_loopback_or_vrf(oi->interface)))
849576ee 391 thread_execute(master, interface_up, oi, 0);
d62a17ae 392 else
849576ee 393 thread_execute(master, interface_down, oi, 0);
d62a17ae 394
395 return;
718e3744 396}
397
d62a17ae 398void ospf6_interface_connected_route_update(struct interface *ifp)
718e3744 399{
d62a17ae 400 struct ospf6_interface *oi;
401 struct ospf6_route *route;
402 struct connected *c;
403 struct listnode *node, *nnode;
404 struct in6_addr nh_addr;
405
406 oi = (struct ospf6_interface *)ifp->info;
407 if (oi == NULL)
408 return;
409
410 /* reset linklocal pointer */
411 oi->linklocal_addr = ospf6_interface_get_linklocal_address(ifp);
412
413 /* if area is null, do not make connected-route list */
414 if (oi->area == NULL)
415 return;
416
417 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
418 return;
419
420 /* update "route to advertise" interface route table */
e285b70d 421 ospf6_route_remove_all(oi->route_connected);
d62a17ae 422
423 for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
424 if (c->address->family != AF_INET6)
425 continue;
426
427 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE,
428 c->address);
429 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE,
430 c->address);
431 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE,
432 c->address);
433 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE,
434 c->address);
435 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE,
436 c->address);
437
438 /* apply filter */
439 if (oi->plist_name) {
440 struct prefix_list *plist;
441 enum prefix_list_type ret;
d62a17ae 442
d62a17ae 443 plist = prefix_list_lookup(AFI_IP6, oi->plist_name);
444 ret = prefix_list_apply(plist, (void *)c->address);
445 if (ret == PREFIX_DENY) {
446 if (IS_OSPF6_DEBUG_INTERFACE)
447 zlog_debug(
2dbe669b
DA
448 "%pFX on %s filtered by prefix-list %s ",
449 c->address, oi->interface->name,
d62a17ae 450 oi->plist_name);
451 continue;
452 }
453 }
454
22813fdb 455 route = ospf6_route_create(oi->area->ospf6);
d62a17ae 456 memcpy(&route->prefix, c->address, sizeof(struct prefix));
457 apply_mask(&route->prefix);
458 route->type = OSPF6_DEST_TYPE_NETWORK;
459 route->path.area_id = oi->area->area_id;
460 route->path.type = OSPF6_PATH_TYPE_INTRA;
461 route->path.cost = oi->cost;
462 inet_pton(AF_INET6, "::1", &nh_addr);
463 ospf6_route_add_nexthop(route, oi->interface->ifindex,
464 &nh_addr);
e285b70d 465 ospf6_route_add(route, oi->route_connected);
d62a17ae 466 }
467
468 /* create new Link-LSA */
469 OSPF6_LINK_LSA_SCHEDULE(oi);
470 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
471 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
718e3744 472}
473
17ab36c6
YR
474static int ospf6_interface_state_change(uint8_t next_state,
475 struct ospf6_interface *oi)
718e3744 476{
d7c0a89a 477 uint8_t prev_state;
beadc736 478 struct ospf6 *ospf6;
d62a17ae 479
480 prev_state = oi->state;
481 oi->state = next_state;
482
483 if (prev_state == next_state)
17ab36c6 484 return -1;
d62a17ae 485
b4b6bd00
IR
486 if (!oi->area)
487 return -1;
488
d62a17ae 489 /* log */
490 if (IS_OSPF6_DEBUG_INTERFACE) {
491 zlog_debug("Interface state change %s: %s -> %s",
492 oi->interface->name,
493 ospf6_interface_state_str[prev_state],
494 ospf6_interface_state_str[next_state]);
495 }
496 oi->state_change++;
b4b6bd00
IR
497
498 ospf6 = oi->area->ospf6;
d62a17ae 499
500 if ((prev_state == OSPF6_INTERFACE_DR
501 || prev_state == OSPF6_INTERFACE_BDR)
502 && (next_state != OSPF6_INTERFACE_DR
503 && next_state != OSPF6_INTERFACE_BDR))
504 ospf6_sso(oi->interface->ifindex, &alldrouters6,
beadc736 505 IPV6_LEAVE_GROUP, ospf6->fd);
d62a17ae 506
507 if ((prev_state != OSPF6_INTERFACE_DR
508 && prev_state != OSPF6_INTERFACE_BDR)
509 && (next_state == OSPF6_INTERFACE_DR
510 || next_state == OSPF6_INTERFACE_BDR))
511 ospf6_sso(oi->interface->ifindex, &alldrouters6,
beadc736 512 IPV6_JOIN_GROUP, ospf6->fd);
d62a17ae 513
514 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
bb4c5661 515 OSPF6_LINK_LSA_SCHEDULE(oi);
d62a17ae 516 if (next_state == OSPF6_INTERFACE_DOWN) {
517 OSPF6_NETWORK_LSA_EXECUTE(oi);
518 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
519 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
76249532 520 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
d62a17ae 521 } else if (prev_state == OSPF6_INTERFACE_DR
522 || next_state == OSPF6_INTERFACE_DR) {
523 OSPF6_NETWORK_LSA_SCHEDULE(oi);
524 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
525 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
526 }
527
528 hook_call(ospf6_interface_change, oi, next_state, prev_state);
17ab36c6
YR
529
530 return 0;
718e3744 531}
532
6b0655a2 533
508e53e2 534/* DR Election, RFC2328 section 9.4 */
718e3744 535
d62a17ae 536#define IS_ELIGIBLE(n) \
537 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
718e3744 538
d62a17ae 539static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a,
540 struct ospf6_neighbor *b)
508e53e2 541{
d62a17ae 542 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
543 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id))
544 return NULL;
545 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
546 return b;
547 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)
548 return a;
549
550 if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
551 return a;
552 if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
553 return b;
554
555 if (a->priority > b->priority)
556 return a;
557 if (a->priority < b->priority)
558 return b;
559
560 if (ntohl(a->router_id) > ntohl(b->router_id))
561 return a;
562 if (ntohl(a->router_id) < ntohl(b->router_id))
563 return b;
564
565 zlog_warn("Router-ID duplicate ?");
566 return a;
508e53e2 567}
718e3744 568
d62a17ae 569static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
570 struct ospf6_neighbor *b)
508e53e2 571{
d62a17ae 572 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
573 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id))
574 return NULL;
575 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
576 return b;
577 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)
578 return a;
579
580 if (a->drouter == a->router_id && b->drouter != b->router_id)
581 return a;
582 if (a->drouter != a->router_id && b->drouter == b->router_id)
583 return b;
584
585 if (a->priority > b->priority)
586 return a;
587 if (a->priority < b->priority)
588 return b;
589
590 if (ntohl(a->router_id) > ntohl(b->router_id))
591 return a;
592 if (ntohl(a->router_id) < ntohl(b->router_id))
593 return b;
594
595 zlog_warn("Router-ID duplicate ?");
596 return a;
718e3744 597}
598
9a06f23d 599uint8_t dr_election(struct ospf6_interface *oi)
718e3744 600{
d62a17ae 601 struct listnode *node, *nnode;
602 struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
603 struct ospf6_neighbor *best_drouter, *best_bdrouter;
d7c0a89a 604 uint8_t next_state = 0;
d62a17ae 605
606 drouter = bdrouter = NULL;
607 best_drouter = best_bdrouter = NULL;
608
609 /* pseudo neighbor myself, including noting current DR/BDR (1) */
610 memset(&myself, 0, sizeof(myself));
611 inet_ntop(AF_INET, &oi->area->ospf6->router_id, myself.name,
612 sizeof(myself.name));
613 myself.state = OSPF6_NEIGHBOR_TWOWAY;
614 myself.drouter = oi->drouter;
615 myself.bdrouter = oi->bdrouter;
616 myself.priority = oi->priority;
617 myself.router_id = oi->area->ospf6->router_id;
618
619 /* Electing BDR (2) */
620 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
621 bdrouter = better_bdrouter(bdrouter, on);
622
623 best_bdrouter = bdrouter;
624 bdrouter = better_bdrouter(best_bdrouter, &myself);
625
626 /* Electing DR (3) */
627 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
628 drouter = better_drouter(drouter, on);
629
630 best_drouter = drouter;
631 drouter = better_drouter(best_drouter, &myself);
632 if (drouter == NULL)
633 drouter = bdrouter;
634
635 /* the router itself is newly/no longer DR/BDR (4) */
636 if ((drouter == &myself && myself.drouter != myself.router_id)
637 || (drouter != &myself && myself.drouter == myself.router_id)
638 || (bdrouter == &myself && myself.bdrouter != myself.router_id)
639 || (bdrouter != &myself && myself.bdrouter == myself.router_id)) {
640 myself.drouter = (drouter ? drouter->router_id : htonl(0));
641 myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
642
643 /* compatible to Electing BDR (2) */
644 bdrouter = better_bdrouter(best_bdrouter, &myself);
645
646 /* compatible to Electing DR (3) */
647 drouter = better_drouter(best_drouter, &myself);
648 if (drouter == NULL)
649 drouter = bdrouter;
650 }
651
652 /* Set interface state accordingly (5) */
653 if (drouter && drouter == &myself)
654 next_state = OSPF6_INTERFACE_DR;
655 else if (bdrouter && bdrouter == &myself)
656 next_state = OSPF6_INTERFACE_BDR;
657 else
658 next_state = OSPF6_INTERFACE_DROTHER;
659
660 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
661 /* XXX */
662
663 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
664 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
665 accordingly after AdjOK */
666 if (oi->drouter != (drouter ? drouter->router_id : htonl(0))
667 || oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0))) {
668 if (IS_OSPF6_DEBUG_INTERFACE)
669 zlog_debug("DR Election on %s: DR: %s BDR: %s",
670 oi->interface->name,
671 (drouter ? drouter->name : "0.0.0.0"),
672 (bdrouter ? bdrouter->name : "0.0.0.0"));
673
674 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) {
675 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
676 continue;
677 /* Schedule AdjOK. */
678 thread_add_event(master, adj_ok, on, 0, NULL);
679 }
680 }
681
682 oi->drouter = (drouter ? drouter->router_id : htonl(0));
683 oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
684 return next_state;
718e3744 685}
686
93828a99
IR
687#ifdef __FreeBSD__
688
689#include <ifaddrs.h>
690
691static bool ifmaddr_check(ifindex_t ifindex, struct in6_addr *addr)
692{
693 struct ifmaddrs *ifmap, *ifma;
694 struct sockaddr_dl *sdl;
695 struct sockaddr_in6 *sin6;
696 bool found = false;
697
698 if (getifmaddrs(&ifmap) != 0)
699 return false;
700
701 for (ifma = ifmap; ifma; ifma = ifma->ifma_next) {
702 if (ifma->ifma_name == NULL || ifma->ifma_addr == NULL)
703 continue;
704 if (ifma->ifma_name->sa_family != AF_LINK)
705 continue;
706 if (ifma->ifma_addr->sa_family != AF_INET6)
707 continue;
708 sdl = (struct sockaddr_dl *)ifma->ifma_name;
709 sin6 = (struct sockaddr_in6 *)ifma->ifma_addr;
710 if (sdl->sdl_index == ifindex
711 && memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) {
712 found = true;
713 break;
714 }
715 }
716
717 if (ifmap)
718 freeifmaddrs(ifmap);
719
720 return found;
721}
722
723#endif /* __FreeBSD__ */
6b0655a2 724
508e53e2 725/* Interface State Machine */
d62a17ae 726int interface_up(struct thread *thread)
718e3744 727{
d62a17ae 728 struct ospf6_interface *oi;
beadc736 729 struct ospf6 *ospf6;
d62a17ae 730
731 oi = (struct ospf6_interface *)THREAD_ARG(thread);
732 assert(oi && oi->interface);
733
5aeb4f3c
DL
734 if (!oi->type_cfg)
735 oi->type = ospf6_default_iftype(oi->interface);
736
93828a99 737 thread_cancel(&oi->thread_sso);
f80003b0 738
d62a17ae 739 if (IS_OSPF6_DEBUG_INTERFACE)
740 zlog_debug("Interface Event %s: [InterfaceUp]",
741 oi->interface->name);
742
743 /* check physical interface is up */
744 if (!if_is_operative(oi->interface)) {
1b1f7b4f 745 zlog_warn("Interface %s is down, can't execute [InterfaceUp]",
746 oi->interface->name);
d62a17ae 747 return 0;
748 }
749
750 /* check interface has a link-local address */
751 if (!(ospf6_interface_get_linklocal_address(oi->interface)
d16cff32 752 || if_is_loopback_or_vrf(oi->interface))) {
1b1f7b4f 753 zlog_warn(
754 "Interface %s has no link local address, can't execute [InterfaceUp]",
755 oi->interface->name);
d62a17ae 756 return 0;
757 }
758
759 /* Recompute cost */
760 ospf6_interface_recalculate_cost(oi);
761
762 /* if already enabled, do nothing */
763 if (oi->state > OSPF6_INTERFACE_DOWN) {
764 if (IS_OSPF6_DEBUG_INTERFACE)
765 zlog_debug("Interface %s already enabled",
766 oi->interface->name);
767 return 0;
768 }
769
770 /* If no area assigned, return */
771 if (oi->area == NULL) {
1b1f7b4f 772 zlog_warn(
482467dc 773 "%s: Not scheduling Hello for %s as there is no area assigned yet",
d62a17ae 774 __func__, oi->interface->name);
775 return 0;
776 }
777
bc482dc0
RZ
778#ifdef __FreeBSD__
779 /*
93828a99
IR
780 * There's a delay in FreeBSD between issuing a command to leave a
781 * multicast group and an actual leave. If we execute "no router ospf6"
782 * and "router ospf6" fast enough, we can end up in a situation when OS
783 * performs the leave later than it performs the join and the interface
784 * remains without a multicast group. We have to do the join only after
785 * the interface actually left the group.
bc482dc0 786 */
93828a99
IR
787 if (ifmaddr_check(oi->interface->ifindex, &allspfrouters6)) {
788 zlog_info(
789 "Interface %s is still in all routers group, rescheduling for SSO",
790 oi->interface->name);
bc482dc0
RZ
791 thread_add_timer(master, interface_up, oi,
792 OSPF6_INTERFACE_SSO_RETRY_INT,
793 &oi->thread_sso);
794 return 0;
795 }
796#endif /* __FreeBSD__ */
b4b6bd00
IR
797
798 ospf6 = oi->area->ospf6;
bc482dc0 799
d62a17ae 800 /* Join AllSPFRouters */
beadc736 801 if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP,
802 ospf6->fd)
d62a17ae 803 < 0) {
804 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
805 zlog_info(
806 "Scheduling %s for sso retry, trial count: %d",
807 oi->interface->name, oi->sso_try_cnt);
808 thread_add_timer(master, interface_up, oi,
f80003b0
RZ
809 OSPF6_INTERFACE_SSO_RETRY_INT,
810 &oi->thread_sso);
d62a17ae 811 }
812 return 0;
813 }
814 oi->sso_try_cnt = 0; /* Reset on success */
815
816 /* Update interface route */
817 ospf6_interface_connected_route_update(oi->interface);
818
819 /* Schedule Hello */
820 if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
d16cff32 821 && !if_is_loopback_or_vrf(oi->interface)) {
d62a17ae 822 thread_add_event(master, ospf6_hello_send, oi, 0,
823 &oi->thread_send_hello);
824 }
825
826 /* decide next interface state */
621ee705
DL
827 if (oi->type == OSPF_IFTYPE_LOOPBACK) {
828 ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK, oi);
829 } else if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
d62a17ae 830 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
831 } else if (oi->priority == 0)
832 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
833 else {
834 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
835 thread_add_timer(master, wait_timer, oi, oi->dead_interval,
9ae41e31 836 &oi->thread_wait_timer);
d62a17ae 837 }
838
839 return 0;
718e3744 840}
841
d62a17ae 842int wait_timer(struct thread *thread)
718e3744 843{
d62a17ae 844 struct ospf6_interface *oi;
718e3744 845
d62a17ae 846 oi = (struct ospf6_interface *)THREAD_ARG(thread);
847 assert(oi && oi->interface);
718e3744 848
d62a17ae 849 if (IS_OSPF6_DEBUG_INTERFACE)
850 zlog_debug("Interface Event %s: [WaitTimer]",
851 oi->interface->name);
718e3744 852
d62a17ae 853 if (oi->state == OSPF6_INTERFACE_WAITING)
854 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 855
d62a17ae 856 return 0;
718e3744 857}
858
d62a17ae 859int backup_seen(struct thread *thread)
508e53e2 860{
d62a17ae 861 struct ospf6_interface *oi;
508e53e2 862
d62a17ae 863 oi = (struct ospf6_interface *)THREAD_ARG(thread);
864 assert(oi && oi->interface);
508e53e2 865
d62a17ae 866 if (IS_OSPF6_DEBUG_INTERFACE)
867 zlog_debug("Interface Event %s: [BackupSeen]",
868 oi->interface->name);
508e53e2 869
d62a17ae 870 if (oi->state == OSPF6_INTERFACE_WAITING)
871 ospf6_interface_state_change(dr_election(oi), oi);
508e53e2 872
d62a17ae 873 return 0;
508e53e2 874}
875
d62a17ae 876int neighbor_change(struct thread *thread)
718e3744 877{
d62a17ae 878 struct ospf6_interface *oi;
508e53e2 879
d62a17ae 880 oi = (struct ospf6_interface *)THREAD_ARG(thread);
881 assert(oi && oi->interface);
508e53e2 882
d62a17ae 883 if (IS_OSPF6_DEBUG_INTERFACE)
884 zlog_debug("Interface Event %s: [NeighborChange]",
885 oi->interface->name);
508e53e2 886
d62a17ae 887 if (oi->state == OSPF6_INTERFACE_DROTHER
888 || oi->state == OSPF6_INTERFACE_BDR
889 || oi->state == OSPF6_INTERFACE_DR)
890 ospf6_interface_state_change(dr_election(oi), oi);
508e53e2 891
d62a17ae 892 return 0;
718e3744 893}
894
d62a17ae 895int interface_down(struct thread *thread)
718e3744 896{
d62a17ae 897 struct ospf6_interface *oi;
898 struct listnode *node, *nnode;
899 struct ospf6_neighbor *on;
beadc736 900 struct ospf6 *ospf6;
508e53e2 901
d62a17ae 902 oi = (struct ospf6_interface *)THREAD_ARG(thread);
903 assert(oi && oi->interface);
508e53e2 904
d62a17ae 905 if (IS_OSPF6_DEBUG_INTERFACE)
906 zlog_debug("Interface Event %s: [InterfaceDown]",
907 oi->interface->name);
508e53e2 908
d62a17ae 909 /* Stop Hellos */
910 THREAD_OFF(oi->thread_send_hello);
424cc3bd 911
f80003b0
RZ
912 /* Stop trying to set socket options. */
913 THREAD_OFF(oi->thread_sso);
508e53e2 914
9a06f23d 915 /* Cease the HELPER role for all the neighbours
916 * of this interface.
917 */
918 if (ospf6_interface_neighbor_count(oi)) {
919 struct listnode *ln;
920 struct ospf6_neighbor *nbr = NULL;
921
922 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, ln, nbr))
923 ospf6_gr_helper_exit(nbr, OSPF6_GR_HELPER_TOPO_CHG);
924 }
925
d62a17ae 926 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
927 ospf6_neighbor_delete(on);
508e53e2 928
d62a17ae 929 list_delete_all_node(oi->neighbor_list);
930
931 /* When interface state is reset, also reset information about
932 * DR election, as it is no longer valid. */
933 oi->drouter = oi->prev_drouter = htonl(0);
934 oi->bdrouter = oi->prev_bdrouter = htonl(0);
b4b6bd00
IR
935
936 if (oi->area == NULL)
937 return 0;
938
939 ospf6 = oi->area->ospf6;
940 /* Leave AllSPFRouters */
941 if (oi->state > OSPF6_INTERFACE_DOWN)
942 ospf6_sso(oi->interface->ifindex, &allspfrouters6,
943 IPV6_LEAVE_GROUP, ospf6->fd);
944
4f7bf1ab
PR
945 /* deal with write fifo */
946 ospf6_fifo_flush(oi->obuf);
947 if (oi->on_write_q) {
948 listnode_delete(ospf6->oi_write_q, oi);
949 if (list_isempty(ospf6->oi_write_q))
950 thread_cancel(&ospf6->t_write);
951 oi->on_write_q = 0;
952 }
953
b4b6bd00
IR
954 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
955
d62a17ae 956 return 0;
718e3744 957}
958
6b0655a2 959
5aeb4f3c
DL
960static const char *ospf6_iftype_str(uint8_t iftype)
961{
962 switch (iftype) {
963 case OSPF_IFTYPE_LOOPBACK:
964 return "LOOPBACK";
965 case OSPF_IFTYPE_BROADCAST:
966 return "BROADCAST";
967 case OSPF_IFTYPE_POINTOPOINT:
968 return "POINTOPOINT";
969 }
970 return "UNKNOWN";
971}
972
718e3744 973/* show specified interface structure */
f16ae8cf 974static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
975 json_object *json_obj, bool use_json)
718e3744 976{
d62a17ae 977 struct ospf6_interface *oi;
978 struct connected *c;
979 struct prefix *p;
980 struct listnode *i;
981 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
5aeb4f3c 982 uint8_t default_iftype;
d62a17ae 983 struct timeval res, now;
984 char duration[32];
2e37407f 985 struct ospf6_lsa *lsa, *lsanext;
f16ae8cf 986 json_object *json_arr;
987 json_object *json_addr;
d62a17ae 988
5aeb4f3c 989 default_iftype = ospf6_default_iftype(ifp);
d62a17ae 990
f16ae8cf 991 if (use_json) {
992 json_object_string_add(json_obj, "status",
993 (if_is_operative(ifp) ? "up" : "down"));
994 json_object_string_add(json_obj, "type",
995 ospf6_iftype_str(default_iftype));
996 json_object_int_add(json_obj, "interfaceId", ifp->ifindex);
997
998 if (ifp->info == NULL) {
999 json_object_boolean_false_add(json_obj, "ospf6Enabled");
1000 return 0;
1001 }
1002 json_object_boolean_true_add(json_obj, "ospf6Enabled");
d62a17ae 1003
d62a17ae 1004 oi = (struct ospf6_interface *)ifp->info;
1005
f16ae8cf 1006 if (if_is_operative(ifp) && oi->type != default_iftype)
1007 json_object_string_add(json_obj, "operatingAsType",
1008 ospf6_iftype_str(oi->type));
1009
1010 } else {
1011 vty_out(vty, "%s is %s, type %s\n", ifp->name,
1012 (if_is_operative(ifp) ? "up" : "down"),
1013 ospf6_iftype_str(default_iftype));
1014 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
1015
1016 if (ifp->info == NULL) {
1017 vty_out(vty, " OSPF not enabled on this interface\n");
1018 return 0;
d62a17ae 1019 }
f16ae8cf 1020 oi = (struct ospf6_interface *)ifp->info;
1021
1022 if (if_is_operative(ifp) && oi->type != default_iftype)
1023 vty_out(vty, " Operating as type %s\n",
1024 ospf6_iftype_str(oi->type));
d62a17ae 1025 }
1026
f16ae8cf 1027 if (use_json) {
1028 json_arr = json_object_new_array();
1029 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1030 json_addr = json_object_new_object();
1031 p = c->address;
1032 prefix2str(p, strbuf, sizeof(strbuf));
1033 switch (p->family) {
1034 case AF_INET:
1035 json_object_string_add(json_addr, "type",
1036 "inet");
1037 json_object_string_add(json_addr, "address",
1038 strbuf);
1039 json_object_array_add(json_arr, json_addr);
1040 break;
1041 case AF_INET6:
1042 json_object_string_add(json_addr, "type",
1043 "inet6");
1044 json_object_string_add(json_addr, "address",
1045 strbuf);
1046 json_object_array_add(json_arr, json_addr);
1047 break;
1048 default:
1049 json_object_string_add(json_addr, "type",
1050 "unknown");
1051 json_object_string_add(json_addr, "address",
1052 strbuf);
1053 json_object_array_add(json_arr, json_addr);
1054 break;
1055 }
1056 }
1057 json_object_object_add(json_obj, "internetAddress", json_arr);
1058 } else {
1059 vty_out(vty, " Internet Address:\n");
1060
1061 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1062 p = c->address;
1063 prefix2str(p, strbuf, sizeof(strbuf));
1064 switch (p->family) {
1065 case AF_INET:
1066 vty_out(vty, " inet : %pFX\n", p);
1067 break;
1068 case AF_INET6:
1069 vty_out(vty, " inet6: %pFX\n", p);
1070 break;
1071 default:
1072 vty_out(vty, " ??? : %pFX\n", p);
1073 break;
1074 }
1075 }
1076 }
1077
1078 if (use_json) {
1079 if (oi->area) {
1080 json_object_boolean_true_add(json_obj,
1081 "attachedToArea");
1082 json_object_int_add(json_obj, "instanceId",
1083 oi->instance_id);
1084 json_object_int_add(json_obj, "interfaceMtu",
1085 oi->ifmtu);
1086 json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
1087 json_object_string_add(json_obj, "mtuMismatchDetection",
1088 oi->mtu_ignore ? "disabled"
1089 : "enabled");
1090 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1091 sizeof(strbuf));
1092 json_object_string_add(json_obj, "areaId", strbuf);
1093 json_object_int_add(json_obj, "cost", oi->cost);
1094 } else
1095 json_object_boolean_false_add(json_obj,
1096 "attachedToArea");
1097
1098 } else {
1099 if (oi->area) {
1100 vty_out(vty,
1101 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1102 oi->instance_id, oi->ifmtu, ifp->mtu6);
1103 vty_out(vty, " MTU mismatch detection: %s\n",
1104 oi->mtu_ignore ? "disabled" : "enabled");
1105 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1106 sizeof(strbuf));
1107 vty_out(vty, " Area ID %s, Cost %u\n", strbuf,
1108 oi->cost);
1109 } else
1110 vty_out(vty, " Not Attached to Area\n");
1111 }
1112
1113 if (use_json) {
1114 json_object_string_add(json_obj, "ospf6InterfaceState",
1115 ospf6_interface_state_str[oi->state]);
1116 json_object_int_add(json_obj, "transmitDelaySec",
1117 oi->transdelay);
1118 json_object_int_add(json_obj, "priority", oi->priority);
1119 json_object_int_add(json_obj, "timerIntervalsConfigHello",
1120 oi->hello_interval);
1121 json_object_int_add(json_obj, "timerIntervalsConfigDead",
1122 oi->dead_interval);
1123 json_object_int_add(json_obj, "timerIntervalsConfigRetransmit",
1124 oi->rxmt_interval);
1125 } else {
1126 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
1127 ospf6_interface_state_str[oi->state], oi->transdelay,
1128 oi->priority);
1129 vty_out(vty, " Timer intervals configured:\n");
1130 vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
1131 oi->hello_interval, oi->dead_interval,
1132 oi->rxmt_interval);
1133 }
d62a17ae 1134
1135 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
1136 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
f16ae8cf 1137 if (use_json) {
1138 json_object_string_add(json_obj, "dr", drouter);
1139 json_object_string_add(json_obj, "bdr", bdrouter);
1140 json_object_int_add(json_obj, "numberOfInterfaceScopedLsa",
1141 oi->lsdb->count);
1142 } else {
1143 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
1144 vty_out(vty, " Number of I/F scoped LSAs is %u\n",
1145 oi->lsdb->count);
1146 }
d62a17ae 1147
1148 monotime(&now);
1149
f16ae8cf 1150 if (use_json) {
1151 timerclear(&res);
1152 if (oi->thread_send_lsupdate)
1153 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1154 &res);
1155 timerstring(&res, duration, sizeof(duration));
1156 json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
1157 oi->lsupdate_list->count);
1158 json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
1159 duration);
1160 json_object_string_add(
1161 json_obj, "lsUpdateSendThread",
1162 (oi->thread_send_lsupdate ? "on" : "off"));
1163
1164 json_arr = json_object_new_array();
1165 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1166 json_object_array_add(
1167 json_arr, json_object_new_string(lsa->name));
1168 json_object_object_add(json_obj, "pendingLsaLsUpdate",
1169 json_arr);
1170
1171 timerclear(&res);
1172 if (oi->thread_send_lsack)
1173 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1174 timerstring(&res, duration, sizeof(duration));
1175
1176 json_object_int_add(json_obj, "pendingLsaLsAckCount",
1177 oi->lsack_list->count);
1178 json_object_string_add(json_obj, "pendingLsaLsAckTime",
1179 duration);
1180 json_object_string_add(json_obj, "lsAckSendThread",
1181 (oi->thread_send_lsack ? "on" : "off"));
1182
1183 json_arr = json_object_new_array();
1184 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1185 json_object_array_add(
1186 json_arr, json_object_new_string(lsa->name));
1187 json_object_object_add(json_obj, "pendingLsaLsAck", json_arr);
1188
1189 } else {
1190 timerclear(&res);
1191 if (oi->thread_send_lsupdate)
1192 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1193 &res);
1194 timerstring(&res, duration, sizeof(duration));
1195 vty_out(vty,
1196 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1197 oi->lsupdate_list->count, duration,
1198 (oi->thread_send_lsupdate ? "on" : "off"));
1199 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1200 vty_out(vty, " %s\n", lsa->name);
1201
1202 timerclear(&res);
1203 if (oi->thread_send_lsack)
1204 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1205 timerstring(&res, duration, sizeof(duration));
1206 vty_out(vty,
1207 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1208 oi->lsack_list->count, duration,
1209 (oi->thread_send_lsack ? "on" : "off"));
1210 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1211 vty_out(vty, " %s\n", lsa->name);
1212 }
d06cc416
RZ
1213
1214 /* BFD specific. */
1215 if (oi->bfd_config.enabled) {
1216 if (use_json) {
1217 struct json_object *json_bfd = json_object_new_object();
1218
1219 json_object_int_add(
1220 json_bfd, "detectMultiplier",
1221 oi->bfd_config.detection_multiplier);
1222 json_object_int_add(json_bfd, "rxMinInterval",
1223 oi->bfd_config.min_rx);
1224 json_object_int_add(json_bfd, "txMinInterval",
1225 oi->bfd_config.min_tx);
1226 json_object_object_add(json_obj, "peerBfdInfo",
1227 json_bfd);
1228 } else {
1229 vty_out(vty,
1230 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1231 oi->bfd_config.detection_multiplier,
1232 oi->bfd_config.min_rx, oi->bfd_config.min_tx);
1233 }
1234 }
1235
d62a17ae 1236 return 0;
718e3744 1237}
1238
ad500b22
K
1239/* Find the global address to be used as a forwarding address in NSSA LSA.*/
1240struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
1241{
1242 struct listnode *n;
1243 struct connected *c;
1244 struct in6_addr *l = (struct in6_addr *)NULL;
1245
1246 /* for each connected address */
1247 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
1248 /* if family not AF_INET6, ignore */
1249 if (c->address->family != AF_INET6)
1250 continue;
1251
1252 if (!IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
1253 l = &c->address->u.prefix6;
1254 }
1255 return l;
1256}
1257
1258
d48ef099 1259static int show_ospf6_interface_common(struct vty *vty, vrf_id_t vrf_id,
1260 int argc, struct cmd_token **argv,
1261 int idx_ifname, int intf_idx,
1262 int json_idx)
718e3744 1263{
d48ef099 1264
1265 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
d62a17ae 1266 struct interface *ifp;
f16ae8cf 1267 json_object *json;
1268 json_object *json_int;
1269 bool uj = use_json(argc, argv);
1270
1271 if (uj) {
1272 json = json_object_new_object();
d48ef099 1273 if (argc == json_idx) {
1274 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
f16ae8cf 1275 json_int = json_object_new_object();
1276 if (ifp == NULL) {
1277 json_object_string_add(json, "noSuchInterface",
1278 argv[idx_ifname]->arg);
1279 vty_out(vty, "%s\n",
1280 json_object_to_json_string_ext(
1281 json, JSON_C_TO_STRING_PRETTY));
1282 json_object_free(json);
1283 json_object_free(json_int);
1284 return CMD_WARNING;
1285 }
1286 ospf6_interface_show(vty, ifp, json_int, uj);
1287 json_object_object_add(json, ifp->name, json_int);
1288 } else {
1289 FOR_ALL_INTERFACES (vrf, ifp) {
1290 json_int = json_object_new_object();
1291 ospf6_interface_show(vty, ifp, json_int, uj);
1292 json_object_object_add(json, ifp->name,
1293 json_int);
1294 }
d62a17ae 1295 }
f16ae8cf 1296 vty_out(vty, "%s\n",
1297 json_object_to_json_string_ext(
1298 json, JSON_C_TO_STRING_PRETTY));
1299 json_object_free(json);
d62a17ae 1300 } else {
d48ef099 1301 if (argc == intf_idx) {
1302 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
f16ae8cf 1303 if (ifp == NULL) {
1304 vty_out(vty, "No such Interface: %s\n",
1305 argv[idx_ifname]->arg);
1306 return CMD_WARNING;
1307 }
1308 ospf6_interface_show(vty, ifp, NULL, uj);
1309 } else {
1310 FOR_ALL_INTERFACES (vrf, ifp)
1311 ospf6_interface_show(vty, ifp, NULL, uj);
1312 }
d62a17ae 1313 }
d48ef099 1314 return CMD_SUCCESS;
1315}
1316
1317/* show interface */
1318DEFUN(show_ipv6_ospf6_interface, show_ipv6_ospf6_interface_ifname_cmd,
1319 "show ipv6 ospf6 [vrf <NAME|all>] interface [IFNAME] [json]",
1320 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1321 "All VRFs\n" INTERFACE_STR IFNAME_STR JSON_STR)
1322{
1323 int idx_ifname = 4;
1324 int intf_idx = 5;
1325 int json_idx = 6;
1326 struct listnode *node;
1327 struct ospf6 *ospf6;
1328 const char *vrf_name = NULL;
1329 bool all_vrf = false;
1330 int idx_vrf = 0;
1331
d48ef099 1332 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1333 if (idx_vrf > 0) {
1334 idx_ifname += 2;
1335 intf_idx += 2;
1336 json_idx += 2;
1337 }
1338
1339 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1340 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1341 show_ospf6_interface_common(vty, ospf6->vrf_id, argc,
1342 argv, idx_ifname, intf_idx,
1343 json_idx);
1344
1345 if (!all_vrf)
1346 break;
1347 }
1348 }
d62a17ae 1349
1350 return CMD_SUCCESS;
718e3744 1351}
1352
c5d28568 1353static int ospf6_interface_show_traffic(struct vty *vty,
43855e3d 1354 struct interface *intf_ifp,
ba30b376 1355 int display_once, json_object *json,
d48ef099 1356 bool use_json, vrf_id_t vrf_id)
43855e3d
CS
1357{
1358 struct interface *ifp;
1359 struct vrf *vrf = NULL;
1360 struct ospf6_interface *oi = NULL;
ba30b376 1361 json_object *json_interface;
43855e3d 1362
f6d11a9b
MS
1363 if (intf_ifp)
1364 vrf = vrf_lookup_by_id(intf_ifp->vrf_id);
1365 else
d48ef099 1366 vrf = vrf_lookup_by_id(vrf_id);
43855e3d 1367
ba30b376 1368 if (!display_once && !use_json) {
43855e3d 1369 vty_out(vty, "\n");
996c9314
LB
1370 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1371 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1372 " LS-Ack");
43855e3d 1373 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
996c9314
LB
1374 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1375 " Rx/Tx");
43855e3d 1376 vty_out(vty,
996c9314 1377 "--------------------------------------------------------------------------------------------\n");
43855e3d
CS
1378 }
1379
1380 if (intf_ifp == NULL) {
1381 FOR_ALL_INTERFACES (vrf, ifp) {
1382 if (ifp->info)
1383 oi = (struct ospf6_interface *)ifp->info;
1384 else
1385 continue;
1386
ba30b376 1387 if (use_json) {
1388 json_interface = json_object_new_object();
1389 json_object_int_add(json_interface, "helloRx",
1390 oi->hello_in);
1391 json_object_int_add(json_interface, "helloTx",
1392 oi->hello_out);
1393 json_object_int_add(json_interface, "dbDescRx",
1394 oi->db_desc_in);
1395 json_object_int_add(json_interface, "dbDescTx",
1396 oi->db_desc_out);
1397 json_object_int_add(json_interface, "lsReqRx",
1398 oi->ls_req_in);
1399 json_object_int_add(json_interface, "lsReqTx",
1400 oi->ls_req_out);
1401 json_object_int_add(json_interface,
1402 "lsUpdateRx",
1403 oi->ls_upd_in);
1404 json_object_int_add(json_interface,
1405 "lsUpdateTx",
1406 oi->ls_upd_out);
1407 json_object_int_add(json_interface, "lsAckRx",
1408 oi->ls_ack_in);
1409 json_object_int_add(json_interface, "lsAckTx",
1410 oi->ls_ack_out);
1411
1412 json_object_object_add(json,
1413 oi->interface->name,
1414 json_interface);
1415 } else
1416 vty_out(vty,
1417 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1418 oi->interface->name, oi->hello_in,
1419 oi->hello_out, oi->db_desc_in,
1420 oi->db_desc_out, oi->ls_req_in,
1421 oi->ls_req_out, oi->ls_upd_in,
1422 oi->ls_upd_out, oi->ls_ack_in,
1423 oi->ls_ack_out);
43855e3d
CS
1424 }
1425 } else {
1426 oi = intf_ifp->info;
1427 if (oi == NULL)
1428 return CMD_WARNING;
1429
ba30b376 1430 if (use_json) {
1431 json_interface = json_object_new_object();
1432 json_object_int_add(json_interface, "helloRx",
1433 oi->hello_in);
1434 json_object_int_add(json_interface, "helloTx",
1435 oi->hello_out);
1436 json_object_int_add(json_interface, "dbDescRx",
1437 oi->db_desc_in);
1438 json_object_int_add(json_interface, "dbDescTx",
1439 oi->db_desc_out);
1440 json_object_int_add(json_interface, "lsReqRx",
1441 oi->ls_req_in);
1442 json_object_int_add(json_interface, "lsReqTx",
1443 oi->ls_req_out);
1444 json_object_int_add(json_interface, "lsUpdateRx",
1445 oi->ls_upd_in);
1446 json_object_int_add(json_interface, "lsUpdateTx",
1447 oi->ls_upd_out);
1448 json_object_int_add(json_interface, "lsAckRx",
1449 oi->ls_ack_in);
1450 json_object_int_add(json_interface, "lsAckTx",
1451 oi->ls_ack_out);
1452
1453 json_object_object_add(json, oi->interface->name,
1454 json_interface);
1455 } else
1456 vty_out(vty,
1457 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1458 oi->interface->name, oi->hello_in,
1459 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1460 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1461 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
43855e3d
CS
1462 }
1463
1464 return CMD_SUCCESS;
1465}
1466
d48ef099 1467static int ospf6_interface_show_traffic_common(struct vty *vty, int argc,
1468 struct cmd_token **argv,
1469 vrf_id_t vrf_id)
43855e3d
CS
1470{
1471 int idx_ifname = 0;
1472 int display_once = 0;
1473 char *intf_name = NULL;
1474 struct interface *ifp = NULL;
ba30b376 1475 json_object *json = NULL;
1476 bool uj = use_json(argc, argv);
1477
1478 if (uj)
1479 json = json_object_new_object();
43855e3d
CS
1480
1481 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1482 intf_name = argv[idx_ifname]->arg;
d48ef099 1483 ifp = if_lookup_by_name(intf_name, vrf_id);
ba30b376 1484 if (uj) {
1485 if (ifp == NULL) {
1486 json_object_string_add(json, "status",
1487 "No Such Interface");
1488 json_object_string_add(json, "interface",
1489 intf_name);
1490 vty_out(vty, "%s\n",
1491 json_object_to_json_string_ext(
1492 json, JSON_C_TO_STRING_PRETTY));
1493 json_object_free(json);
1494 return CMD_WARNING;
1495 }
1496 if (ifp->info == NULL) {
1497 json_object_string_add(
1498 json, "status",
1499 "OSPF not enabled on this interface");
1500 json_object_string_add(json, "interface",
1501 intf_name);
1502 vty_out(vty, "%s\n",
1503 json_object_to_json_string_ext(
1504 json, JSON_C_TO_STRING_PRETTY));
1505 json_object_free(json);
1506 return 0;
1507 }
1508 } else {
1509 if (ifp == NULL) {
1510 vty_out(vty, "No such Interface: %s\n",
1511 intf_name);
1512 return CMD_WARNING;
1513 }
1514 if (ifp->info == NULL) {
1515 vty_out(vty,
1516 " OSPF not enabled on this interface %s\n",
1517 intf_name);
1518 return 0;
1519 }
43855e3d
CS
1520 }
1521 }
1522
d48ef099 1523 ospf6_interface_show_traffic(vty, ifp, display_once, json, uj, vrf_id);
ba30b376 1524
1525 if (uj) {
1526 vty_out(vty, "%s\n",
1527 json_object_to_json_string_ext(
1528 json, JSON_C_TO_STRING_PRETTY));
1529 json_object_free(json);
1530 }
43855e3d 1531
d48ef099 1532 return CMD_SUCCESS;
1533}
1534
1535/* show interface */
1536DEFUN(show_ipv6_ospf6_interface_traffic, show_ipv6_ospf6_interface_traffic_cmd,
1537 "show ipv6 ospf6 [vrf <NAME|all>] interface traffic [IFNAME] [json]",
1538 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1539 "All VRFs\n" INTERFACE_STR
1540 "Protocol Packet counters\n" IFNAME_STR JSON_STR)
1541{
1542 struct ospf6 *ospf6;
1543 struct listnode *node;
1544 const char *vrf_name = NULL;
1545 bool all_vrf = false;
1546 int idx_vrf = 0;
1547
d48ef099 1548 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1549
1550 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1551 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1552 ospf6_interface_show_traffic_common(vty, argc, argv,
1553 ospf6->vrf_id);
1554
1555 if (!all_vrf)
1556 break;
1557 }
1558 }
43855e3d
CS
1559
1560 return CMD_SUCCESS;
1561}
1562
1563
d48ef099 1564DEFUN(show_ipv6_ospf6_interface_ifname_prefix,
1565 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1566 "show ipv6 ospf6 [vrf <NAME|all>] interface IFNAME prefix\
25ee05c9
RW
1567 [<\
1568 detail\
1569 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
35aeb295 1570 >] [json]",
d48ef099 1571 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1572 "All VRFs\n" INTERFACE_STR IFNAME_STR
1573 "Display connected prefixes to advertise\n"
1574 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1575 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1576 "Display details of the prefixes\n" JSON_STR)
508e53e2 1577{
d62a17ae 1578 int idx_ifname = 4;
1579 int idx_prefix = 6;
d62a17ae 1580 struct ospf6_interface *oi;
35aeb295 1581 bool uj = use_json(argc, argv);
d62a17ae 1582
d48ef099 1583 struct ospf6 *ospf6;
1584 struct listnode *node;
1585 struct interface *ifp;
1586 const char *vrf_name = NULL;
1587 bool all_vrf = false;
1588 int idx_vrf = 0;
1589
d48ef099 1590 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1591 if (idx_vrf > 0) {
1592 idx_ifname += 2;
1593 idx_prefix += 2;
d62a17ae 1594 }
1595
d48ef099 1596 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1597 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1598 ifp = if_lookup_by_name(argv[idx_ifname]->arg,
1599 ospf6->vrf_id);
1600 if (ifp == NULL) {
1601 vty_out(vty, "No such Interface: %s\n",
1602 argv[idx_ifname]->arg);
1603 return CMD_WARNING;
1604 }
d62a17ae 1605
d48ef099 1606 oi = ifp->info;
1607 if (oi == NULL
1608 || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
1609 vty_out(vty,
1610 "Interface %s not attached to area\n",
1611 argv[idx_ifname]->arg);
1612 return CMD_WARNING;
1613 }
d100d0b0 1614
d48ef099 1615 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1616 oi->route_connected, uj);
1617
1618 if (!all_vrf)
1619 break;
1620 }
1621 }
d62a17ae 1622
1623 return CMD_SUCCESS;
508e53e2 1624}
1625
d48ef099 1626DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd,
1627 "show ipv6 ospf6 [vrf <NAME|all>] interface prefix\
25ee05c9
RW
1628 [<\
1629 detail\
1630 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
35aeb295 1631 >] [json]",
d48ef099 1632 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1633 "All VRFs\n" INTERFACE_STR
1634 "Display connected prefixes to advertise\n"
1635 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1636 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1637 "Display details of the prefixes\n" JSON_STR)
508e53e2 1638{
d48ef099 1639 struct vrf *vrf = NULL;
d62a17ae 1640 int idx_prefix = 5;
d62a17ae 1641 struct ospf6_interface *oi;
1642 struct interface *ifp;
35aeb295 1643 bool uj = use_json(argc, argv);
d48ef099 1644 struct listnode *node;
1645 struct ospf6 *ospf6;
1646 const char *vrf_name = NULL;
1647 bool all_vrf = false;
1648 int idx_vrf = 0;
1649
d48ef099 1650 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1651 if (idx_vrf > 0)
1652 idx_prefix += 2;
1653
1654 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1655 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1656 vrf = vrf_lookup_by_id(ospf6->vrf_id);
1657 FOR_ALL_INTERFACES (vrf, ifp) {
1658 oi = (struct ospf6_interface *)ifp->info;
1659 if (oi == NULL
1660 || CHECK_FLAG(oi->flag,
1661 OSPF6_INTERFACE_DISABLE))
1662 continue;
1663
1664 ospf6_route_table_show(vty, idx_prefix, argc,
1665 argv,
1666 oi->route_connected, uj);
1667 }
1668 if (!all_vrf)
1669 break;
1670 }
d62a17ae 1671 }
508e53e2 1672
d62a17ae 1673 return CMD_SUCCESS;
508e53e2 1674}
1675
42cabc55
IR
1676void ospf6_interface_start(struct ospf6_interface *oi)
1677{
1678 struct ospf6 *ospf6;
1679 struct ospf6_area *oa;
1680
1681 if (oi->area_id_format == OSPF6_AREA_FMT_UNSET)
1682 return;
1683
40699728
AR
1684 if (oi->area)
1685 return;
1686
42cabc55
IR
1687 ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
1688 if (!ospf6)
1689 return;
1690
1691 oa = ospf6_area_lookup(oi->area_id, ospf6);
1692 if (oa == NULL)
1693 oa = ospf6_area_create(oi->area_id, ospf6, oi->area_id_format);
1694
1695 /* attach interface to area */
1696 listnode_add(oa->if_list, oi);
1697 oi->area = oa;
1698
1699 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1700
1701 /* start up */
1702 ospf6_interface_enable(oi);
1703
1704 /* If the router is ABR, originate summary routes */
5c2b86bb 1705 if (ospf6_check_and_set_router_abr(ospf6))
42cabc55
IR
1706 ospf6_abr_enable_area(oa);
1707}
1708
1709void ospf6_interface_stop(struct ospf6_interface *oi)
1710{
1711 struct ospf6_area *oa;
1712
1713 oa = oi->area;
1714 if (!oa)
1715 return;
1716
1717 ospf6_interface_disable(oi);
1718
1719 listnode_delete(oa->if_list, oi);
1720 oi->area = NULL;
1721
1722 if (oa->if_list->count == 0) {
1723 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1724 ospf6_abr_disable_area(oa);
1725 }
1726}
1727
718e3744 1728/* interface variable set command */
42cabc55
IR
1729DEFUN (ipv6_ospf6_area,
1730 ipv6_ospf6_area_cmd,
1731 "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
1732 IP6_STR
1733 OSPF6_STR
1734 "Specify the OSPF6 area ID\n"
1735 "OSPF6 area ID in IPv4 address notation\n"
1736 "OSPF6 area ID in decimal notation\n")
1737{
1738 VTY_DECLVAR_CONTEXT(interface, ifp);
1739 struct ospf6_interface *oi;
1740 int idx_ipv4 = 3;
1741 uint32_t area_id;
1742 int format;
42cabc55
IR
1743
1744 assert(ifp);
1745
1746 oi = (struct ospf6_interface *)ifp->info;
1747 if (oi == NULL)
1748 oi = ospf6_interface_create(ifp);
1749 assert(oi);
1750
1751 if (oi->area) {
1752 vty_out(vty, "%s already attached to Area %s\n",
1753 oi->interface->name, oi->area->name);
1754 return CMD_SUCCESS;
1755 }
1756
42cabc55
IR
1757 if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) {
1758 vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
1759 return CMD_WARNING_CONFIG_FAILED;
1760 }
1761
1762 oi->area_id = area_id;
1763 oi->area_id_format = format;
1764
1765 ospf6_interface_start(oi);
1766
1767 return CMD_SUCCESS;
1768}
1769
1770DEFUN (no_ipv6_ospf6_area,
1771 no_ipv6_ospf6_area_cmd,
1772 "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
1773 NO_STR
1774 IP6_STR
1775 OSPF6_STR
1776 "Specify the OSPF6 area ID\n"
1777 "OSPF6 area ID in IPv4 address notation\n"
1778 "OSPF6 area ID in decimal notation\n")
1779{
1780 VTY_DECLVAR_CONTEXT(interface, ifp);
1781 struct ospf6_interface *oi;
1782
1783 assert(ifp);
1784
1785 oi = (struct ospf6_interface *)ifp->info;
1786 if (oi == NULL)
1787 oi = ospf6_interface_create(ifp);
1788 assert(oi);
1789
1790 ospf6_interface_stop(oi);
1791
1792 oi->area_id = 0;
1793 oi->area_id_format = OSPF6_AREA_FMT_UNSET;
1794
1795 return CMD_SUCCESS;
1796}
1797
b596c71e 1798DEFUN (ipv6_ospf6_ifmtu,
1799 ipv6_ospf6_ifmtu_cmd,
6147e2c6 1800 "ipv6 ospf6 ifmtu (1-65535)",
b596c71e 1801 IP6_STR
1802 OSPF6_STR
1803 "Interface MTU\n"
1804 "OSPFv3 Interface MTU\n"
1805 )
1806{
d62a17ae 1807 VTY_DECLVAR_CONTEXT(interface, ifp);
1808 int idx_number = 3;
1809 struct ospf6_interface *oi;
1810 unsigned int ifmtu, iobuflen;
1811 struct listnode *node, *nnode;
1812 struct ospf6_neighbor *on;
1813
1814 assert(ifp);
1815
1816 oi = (struct ospf6_interface *)ifp->info;
1817 if (oi == NULL)
1818 oi = ospf6_interface_create(ifp);
1819 assert(oi);
1820
1821 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1822
1823 if (oi->c_ifmtu == ifmtu)
1824 return CMD_SUCCESS;
1825
1826 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1827 vty_out(vty,
1828 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1829 ifp->name, ifp->mtu6);
1830 return CMD_WARNING_CONFIG_FAILED;
1831 }
1832
1833 if (oi->ifmtu < ifmtu) {
1834 iobuflen = ospf6_iobuf_size(ifmtu);
1835 if (iobuflen < ifmtu) {
1836 vty_out(vty,
1837 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1838 ifp->name, iobuflen);
1839 oi->ifmtu = oi->c_ifmtu = iobuflen;
1840 } else
1841 oi->ifmtu = oi->c_ifmtu = ifmtu;
1842 } else
1843 oi->ifmtu = oi->c_ifmtu = ifmtu;
1844
1845 /* re-establish adjacencies */
1846 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1847 THREAD_OFF(on->inactivity_timer);
1848 thread_add_event(master, inactivity_timer, on, 0, NULL);
1849 }
1850
1851 return CMD_SUCCESS;
b596c71e 1852}
1853
049207c3 1854DEFUN (no_ipv6_ospf6_ifmtu,
1855 no_ipv6_ospf6_ifmtu_cmd,
0c7ef48a 1856 "no ipv6 ospf6 ifmtu [(1-65535)]",
049207c3 1857 NO_STR
1858 IP6_STR
1859 OSPF6_STR
1860 "Interface MTU\n"
0c7ef48a 1861 "OSPFv3 Interface MTU\n"
049207c3 1862 )
1863{
d62a17ae 1864 VTY_DECLVAR_CONTEXT(interface, ifp);
1865 struct ospf6_interface *oi;
1866 unsigned int iobuflen;
1867 struct listnode *node, *nnode;
1868 struct ospf6_neighbor *on;
1869
1870 assert(ifp);
1871
1872 oi = (struct ospf6_interface *)ifp->info;
1873 if (oi == NULL)
1874 oi = ospf6_interface_create(ifp);
1875 assert(oi);
1876
1877 if (oi->ifmtu < ifp->mtu) {
1878 iobuflen = ospf6_iobuf_size(ifp->mtu);
1879 if (iobuflen < ifp->mtu) {
1880 vty_out(vty,
1881 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1882 ifp->name, iobuflen);
1883 oi->ifmtu = iobuflen;
1884 } else
1885 oi->ifmtu = ifp->mtu;
1886 } else
1887 oi->ifmtu = ifp->mtu;
1888
1889 oi->c_ifmtu = 0;
1890
1891 /* re-establish adjacencies */
1892 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1893 THREAD_OFF(on->inactivity_timer);
1894 thread_add_event(master, inactivity_timer, on, 0, NULL);
1895 }
1896
1897 return CMD_SUCCESS;
049207c3 1898}
1899
718e3744 1900DEFUN (ipv6_ospf6_cost,
1901 ipv6_ospf6_cost_cmd,
6147e2c6 1902 "ipv6 ospf6 cost (1-65535)",
718e3744 1903 IP6_STR
1904 OSPF6_STR
1905 "Interface cost\n"
32573073 1906 "Outgoing metric of this interface\n")
718e3744 1907{
d62a17ae 1908 VTY_DECLVAR_CONTEXT(interface, ifp);
1909 int idx_number = 3;
1910 struct ospf6_interface *oi;
1911 unsigned long int lcost;
1912
1913 assert(ifp);
1914
1915 oi = (struct ospf6_interface *)ifp->info;
1916 if (oi == NULL)
1917 oi = ospf6_interface_create(ifp);
1918 assert(oi);
1919
1920 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1921
1922 if (lcost > UINT32_MAX) {
1923 vty_out(vty, "Cost %ld is out of range\n", lcost);
1924 return CMD_WARNING_CONFIG_FAILED;
1925 }
1926
7bfc5ae8 1927 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
d62a17ae 1928 if (oi->cost == lcost)
1929 return CMD_SUCCESS;
1930
1931 oi->cost = lcost;
0db8196a 1932 ospf6_interface_force_recalculate_cost(oi);
d62a17ae 1933
1934 return CMD_SUCCESS;
c19543b2
VB
1935}
1936
1937DEFUN (no_ipv6_ospf6_cost,
1938 no_ipv6_ospf6_cost_cmd,
32573073 1939 "no ipv6 ospf6 cost [(1-65535)]",
c19543b2
VB
1940 NO_STR
1941 IP6_STR
1942 OSPF6_STR
1943 "Calculate interface cost from bandwidth\n"
32573073 1944 "Outgoing metric of this interface\n")
c19543b2 1945{
d62a17ae 1946 VTY_DECLVAR_CONTEXT(interface, ifp);
1947 struct ospf6_interface *oi;
1948 assert(ifp);
c19543b2 1949
d62a17ae 1950 oi = (struct ospf6_interface *)ifp->info;
1951 if (oi == NULL)
1952 oi = ospf6_interface_create(ifp);
1953 assert(oi);
c19543b2 1954
d62a17ae 1955 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
c19543b2 1956
d62a17ae 1957 ospf6_interface_recalculate_cost(oi);
718e3744 1958
d62a17ae 1959 return CMD_SUCCESS;
718e3744 1960}
1961
fd500689
VB
1962DEFUN (auto_cost_reference_bandwidth,
1963 auto_cost_reference_bandwidth_cmd,
6147e2c6 1964 "auto-cost reference-bandwidth (1-4294967)",
fd500689
VB
1965 "Calculate OSPF interface cost according to bandwidth\n"
1966 "Use reference bandwidth method to assign OSPF cost\n"
1967 "The reference bandwidth in terms of Mbits per second\n")
1968{
d62a17ae 1969 VTY_DECLVAR_CONTEXT(ospf6, o);
1970 int idx_number = 2;
1971 struct ospf6_area *oa;
1972 struct ospf6_interface *oi;
1973 struct listnode *i, *j;
d7c0a89a 1974 uint32_t refbw;
d62a17ae 1975
1976 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1977 if (refbw < 1 || refbw > 4294967) {
1978 vty_out(vty, "reference-bandwidth value is invalid\n");
1979 return CMD_WARNING_CONFIG_FAILED;
1980 }
1981
1982 /* If reference bandwidth is changed. */
1983 if ((refbw) == o->ref_bandwidth)
1984 return CMD_SUCCESS;
1985
1986 o->ref_bandwidth = refbw;
1987 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1988 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1989 ospf6_interface_recalculate_cost(oi);
1990
1991 return CMD_SUCCESS;
fd500689
VB
1992}
1993
1994DEFUN (no_auto_cost_reference_bandwidth,
1995 no_auto_cost_reference_bandwidth_cmd,
ccb8e0c7 1996 "no auto-cost reference-bandwidth [(1-4294967)]",
fd500689
VB
1997 NO_STR
1998 "Calculate OSPF interface cost according to bandwidth\n"
1d68dbfe
DW
1999 "Use reference bandwidth method to assign OSPF cost\n"
2000 "The reference bandwidth in terms of Mbits per second\n")
fd500689 2001{
d62a17ae 2002 VTY_DECLVAR_CONTEXT(ospf6, o);
2003 struct ospf6_area *oa;
2004 struct ospf6_interface *oi;
2005 struct listnode *i, *j;
fd500689 2006
d62a17ae 2007 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
2008 return CMD_SUCCESS;
fd500689 2009
d62a17ae 2010 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
2011 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
2012 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
2013 ospf6_interface_recalculate_cost(oi);
fd500689 2014
d62a17ae 2015 return CMD_SUCCESS;
fd500689
VB
2016}
2017
813d4307 2018
78156066
PR
2019DEFUN (ospf6_write_multiplier,
2020 ospf6_write_multiplier_cmd,
2021 "write-multiplier (1-100)",
2022 "Write multiplier\n"
2023 "Maximum number of interface serviced per write\n")
2024{
2025 VTY_DECLVAR_CONTEXT(ospf6, o);
2026 uint32_t write_oi_count;
2027
2028 write_oi_count = strtol(argv[1]->arg, NULL, 10);
2029 if (write_oi_count < 1 || write_oi_count > 100) {
2030 vty_out(vty, "write-multiplier value is invalid\n");
2031 return CMD_WARNING_CONFIG_FAILED;
2032 }
2033
2034 o->write_oi_count = write_oi_count;
2035 return CMD_SUCCESS;
2036}
2037
2038DEFUN (no_ospf6_write_multiplier,
2039 no_ospf6_write_multiplier_cmd,
2040 "no write-multiplier (1-100)",
2041 NO_STR
2042 "Write multiplier\n"
2043 "Maximum number of interface serviced per write\n")
2044{
2045 VTY_DECLVAR_CONTEXT(ospf6, o);
2046
2047 o->write_oi_count = OSPF6_WRITE_INTERFACE_COUNT_DEFAULT;
2048 return CMD_SUCCESS;
2049}
2050
718e3744 2051DEFUN (ipv6_ospf6_hellointerval,
2052 ipv6_ospf6_hellointerval_cmd,
6147e2c6 2053 "ipv6 ospf6 hello-interval (1-65535)",
718e3744 2054 IP6_STR
2055 OSPF6_STR
99a522c7 2056 "Time between HELLO packets\n"
d23d6de8 2057 SECONDS_STR)
718e3744 2058{
d62a17ae 2059 VTY_DECLVAR_CONTEXT(interface, ifp);
2060 int idx_number = 3;
2061 struct ospf6_interface *oi;
2062 assert(ifp);
2063
2064 oi = (struct ospf6_interface *)ifp->info;
2065 if (oi == NULL)
2066 oi = ospf6_interface_create(ifp);
2067 assert(oi);
2068
d23d6de8
QY
2069 oi->hello_interval = strmatch(argv[0]->text, "no")
2070 ? OSPF_HELLO_INTERVAL_DEFAULT
2071 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2072 return CMD_SUCCESS;
718e3744 2073}
2074
d23d6de8
QY
2075ALIAS (ipv6_ospf6_hellointerval,
2076 no_ipv6_ospf6_hellointerval_cmd,
2077 "no ipv6 ospf6 hello-interval [(1-65535)]",
2078 NO_STR
2079 IP6_STR
2080 OSPF6_STR
2081 "Time between HELLO packets\n"
2082 SECONDS_STR)
2083
718e3744 2084/* interface variable set command */
2085DEFUN (ipv6_ospf6_deadinterval,
2086 ipv6_ospf6_deadinterval_cmd,
6147e2c6 2087 "ipv6 ospf6 dead-interval (1-65535)",
718e3744 2088 IP6_STR
2089 OSPF6_STR
508e53e2 2090 "Interval time after which a neighbor is declared down\n"
d23d6de8 2091 SECONDS_STR)
718e3744 2092{
d62a17ae 2093 VTY_DECLVAR_CONTEXT(interface, ifp);
2094 int idx_number = 3;
2095 struct ospf6_interface *oi;
2096 assert(ifp);
2097
2098 oi = (struct ospf6_interface *)ifp->info;
2099 if (oi == NULL)
2100 oi = ospf6_interface_create(ifp);
2101 assert(oi);
2102
d23d6de8
QY
2103 oi->dead_interval = strmatch(argv[0]->arg, "no")
2104 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
2105 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2106 return CMD_SUCCESS;
718e3744 2107}
2108
d23d6de8
QY
2109ALIAS (ipv6_ospf6_deadinterval,
2110 no_ipv6_ospf6_deadinterval_cmd,
2111 "no ipv6 ospf6 dead-interval [(1-65535)]",
2112 NO_STR
2113 IP6_STR
2114 OSPF6_STR
2115 "Interval time after which a neighbor is declared down\n"
2116 SECONDS_STR)
2117
718e3744 2118/* interface variable set command */
2119DEFUN (ipv6_ospf6_transmitdelay,
2120 ipv6_ospf6_transmitdelay_cmd,
6147e2c6 2121 "ipv6 ospf6 transmit-delay (1-3600)",
718e3744 2122 IP6_STR
2123 OSPF6_STR
99a522c7 2124 "Link state transmit delay\n"
98cfd06b 2125 SECONDS_STR)
718e3744 2126{
d62a17ae 2127 VTY_DECLVAR_CONTEXT(interface, ifp);
2128 int idx_number = 3;
2129 struct ospf6_interface *oi;
2130 assert(ifp);
2131
2132 oi = (struct ospf6_interface *)ifp->info;
2133 if (oi == NULL)
2134 oi = ospf6_interface_create(ifp);
2135 assert(oi);
2136
d23d6de8
QY
2137 oi->transdelay = strmatch(argv[0]->text, "no")
2138 ? OSPF6_INTERFACE_TRANSDELAY
2139 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2140 return CMD_SUCCESS;
718e3744 2141}
2142
d23d6de8
QY
2143ALIAS (ipv6_ospf6_transmitdelay,
2144 no_ipv6_ospf6_transmitdelay_cmd,
2145 "no ipv6 ospf6 transmit-delay [(1-3600)]",
2146 NO_STR
2147 IP6_STR
2148 OSPF6_STR
2149 "Link state transmit delay\n"
2150 SECONDS_STR)
2151
718e3744 2152/* interface variable set command */
2153DEFUN (ipv6_ospf6_retransmitinterval,
2154 ipv6_ospf6_retransmitinterval_cmd,
6147e2c6 2155 "ipv6 ospf6 retransmit-interval (1-65535)",
718e3744 2156 IP6_STR
2157 OSPF6_STR
2158 "Time between retransmitting lost link state advertisements\n"
d23d6de8 2159 SECONDS_STR)
718e3744 2160{
d62a17ae 2161 VTY_DECLVAR_CONTEXT(interface, ifp);
2162 int idx_number = 3;
2163 struct ospf6_interface *oi;
2164 assert(ifp);
2165
2166 oi = (struct ospf6_interface *)ifp->info;
2167 if (oi == NULL)
2168 oi = ospf6_interface_create(ifp);
2169 assert(oi);
2170
d23d6de8
QY
2171 oi->rxmt_interval = strmatch(argv[0]->text, "no")
2172 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
2173 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2174 return CMD_SUCCESS;
718e3744 2175}
2176
d23d6de8
QY
2177ALIAS (ipv6_ospf6_retransmitinterval,
2178 no_ipv6_ospf6_retransmitinterval_cmd,
2179 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
2180 NO_STR
2181 IP6_STR
2182 OSPF6_STR
2183 "Time between retransmitting lost link state advertisements\n"
2184 SECONDS_STR)
2185
718e3744 2186/* interface variable set command */
2187DEFUN (ipv6_ospf6_priority,
2188 ipv6_ospf6_priority_cmd,
6147e2c6 2189 "ipv6 ospf6 priority (0-255)",
718e3744 2190 IP6_STR
2191 OSPF6_STR
2192 "Router priority\n"
d23d6de8 2193 "Priority value\n")
718e3744 2194{
d62a17ae 2195 VTY_DECLVAR_CONTEXT(interface, ifp);
2196 int idx_number = 3;
2197 struct ospf6_interface *oi;
2198 assert(ifp);
718e3744 2199
d62a17ae 2200 oi = (struct ospf6_interface *)ifp->info;
2201 if (oi == NULL)
2202 oi = ospf6_interface_create(ifp);
2203 assert(oi);
508e53e2 2204
d23d6de8
QY
2205 oi->priority = strmatch(argv[0]->text, "no")
2206 ? OSPF6_INTERFACE_PRIORITY
2207 : strtoul(argv[idx_number]->arg, NULL, 10);
718e3744 2208
17ab36c6
YR
2209 if (oi->area
2210 && (oi->state == OSPF6_INTERFACE_DROTHER
2211 || oi->state == OSPF6_INTERFACE_BDR
2212 || oi->state == OSPF6_INTERFACE_DR)) {
2213 if (ospf6_interface_state_change(dr_election(oi), oi) == -1)
2214 OSPF6_LINK_LSA_SCHEDULE(oi);
2215 }
718e3744 2216
d62a17ae 2217 return CMD_SUCCESS;
718e3744 2218}
2219
d23d6de8
QY
2220ALIAS (ipv6_ospf6_priority,
2221 no_ipv6_ospf6_priority_cmd,
2222 "no ipv6 ospf6 priority [(0-255)]",
2223 NO_STR
2224 IP6_STR
2225 OSPF6_STR
2226 "Router priority\n"
2227 "Priority value\n")
2228
718e3744 2229DEFUN (ipv6_ospf6_instance,
2230 ipv6_ospf6_instance_cmd,
6147e2c6 2231 "ipv6 ospf6 instance-id (0-255)",
718e3744 2232 IP6_STR
2233 OSPF6_STR
508e53e2 2234 "Instance ID for this interface\n"
d23d6de8 2235 "Instance ID value\n")
718e3744 2236{
d62a17ae 2237 VTY_DECLVAR_CONTEXT(interface, ifp);
2238 int idx_number = 3;
2239 struct ospf6_interface *oi;
2240 assert(ifp);
2241
2242 oi = (struct ospf6_interface *)ifp->info;
2243 if (oi == NULL)
2244 oi = ospf6_interface_create(ifp);
2245 assert(oi);
2246
d23d6de8
QY
2247 oi->instance_id = strmatch(argv[0]->text, "no")
2248 ? OSPF6_INTERFACE_INSTANCE_ID
2249 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2250 return CMD_SUCCESS;
718e3744 2251}
2252
d23d6de8
QY
2253ALIAS (ipv6_ospf6_instance,
2254 no_ipv6_ospf6_instance_cmd,
2255 "no ipv6 ospf6 instance-id [(0-255)]",
2256 NO_STR
2257 IP6_STR
2258 OSPF6_STR
2259 "Instance ID for this interface\n"
2260 "Instance ID value\n")
2261
718e3744 2262DEFUN (ipv6_ospf6_passive,
2263 ipv6_ospf6_passive_cmd,
2264 "ipv6 ospf6 passive",
2265 IP6_STR
2266 OSPF6_STR
99a522c7 2267 "Passive interface; no adjacency will be formed on this interface\n"
718e3744 2268 )
2269{
d62a17ae 2270 VTY_DECLVAR_CONTEXT(interface, ifp);
2271 struct ospf6_interface *oi;
2272 struct listnode *node, *nnode;
2273 struct ospf6_neighbor *on;
718e3744 2274
d62a17ae 2275 assert(ifp);
718e3744 2276
d62a17ae 2277 oi = (struct ospf6_interface *)ifp->info;
2278 if (oi == NULL)
2279 oi = ospf6_interface_create(ifp);
2280 assert(oi);
718e3744 2281
d62a17ae 2282 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2283 THREAD_OFF(oi->thread_send_hello);
f80003b0 2284 THREAD_OFF(oi->thread_sso);
508e53e2 2285
d62a17ae 2286 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
2287 THREAD_OFF(on->inactivity_timer);
2288 thread_add_event(master, inactivity_timer, on, 0, NULL);
2289 }
718e3744 2290
d62a17ae 2291 return CMD_SUCCESS;
718e3744 2292}
2293
2294DEFUN (no_ipv6_ospf6_passive,
2295 no_ipv6_ospf6_passive_cmd,
2296 "no ipv6 ospf6 passive",
2297 NO_STR
2298 IP6_STR
2299 OSPF6_STR
2300 "passive interface: No Adjacency will be formed on this I/F\n"
2301 )
2302{
d62a17ae 2303 VTY_DECLVAR_CONTEXT(interface, ifp);
2304 struct ospf6_interface *oi;
2305 assert(ifp);
718e3744 2306
d62a17ae 2307 oi = (struct ospf6_interface *)ifp->info;
2308 if (oi == NULL)
2309 oi = ospf6_interface_create(ifp);
2310 assert(oi);
718e3744 2311
d62a17ae 2312 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2313 THREAD_OFF(oi->thread_send_hello);
f80003b0 2314 THREAD_OFF(oi->thread_sso);
cb978d68 2315
2316 /* don't send hellos over loopback interface */
d16cff32 2317 if (!if_is_loopback_or_vrf(oi->interface))
cb978d68 2318 thread_add_event(master, ospf6_hello_send, oi, 0,
2319 &oi->thread_send_hello);
718e3744 2320
d62a17ae 2321 return CMD_SUCCESS;
718e3744 2322}
2323
d42306d9
DT
2324DEFUN (ipv6_ospf6_mtu_ignore,
2325 ipv6_ospf6_mtu_ignore_cmd,
2326 "ipv6 ospf6 mtu-ignore",
2327 IP6_STR
2328 OSPF6_STR
99a522c7 2329 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
2330 )
2331{
d62a17ae 2332 VTY_DECLVAR_CONTEXT(interface, ifp);
2333 struct ospf6_interface *oi;
2334 assert(ifp);
d42306d9 2335
d62a17ae 2336 oi = (struct ospf6_interface *)ifp->info;
2337 if (oi == NULL)
2338 oi = ospf6_interface_create(ifp);
2339 assert(oi);
d42306d9 2340
d62a17ae 2341 oi->mtu_ignore = 1;
d42306d9 2342
d62a17ae 2343 return CMD_SUCCESS;
d42306d9
DT
2344}
2345
2346DEFUN (no_ipv6_ospf6_mtu_ignore,
2347 no_ipv6_ospf6_mtu_ignore_cmd,
2348 "no ipv6 ospf6 mtu-ignore",
2349 NO_STR
2350 IP6_STR
2351 OSPF6_STR
99a522c7 2352 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
2353 )
2354{
d62a17ae 2355 VTY_DECLVAR_CONTEXT(interface, ifp);
2356 struct ospf6_interface *oi;
2357 assert(ifp);
d42306d9 2358
d62a17ae 2359 oi = (struct ospf6_interface *)ifp->info;
2360 if (oi == NULL)
2361 oi = ospf6_interface_create(ifp);
2362 assert(oi);
d42306d9 2363
d62a17ae 2364 oi->mtu_ignore = 0;
d42306d9 2365
d62a17ae 2366 return CMD_SUCCESS;
d42306d9
DT
2367}
2368
718e3744 2369DEFUN (ipv6_ospf6_advertise_prefix_list,
2370 ipv6_ospf6_advertise_prefix_list_cmd,
2371 "ipv6 ospf6 advertise prefix-list WORD",
2372 IP6_STR
2373 OSPF6_STR
2374 "Advertising options\n"
2375 "Filter prefix using prefix-list\n"
2376 "Prefix list name\n"
2377 )
2378{
d62a17ae 2379 VTY_DECLVAR_CONTEXT(interface, ifp);
2380 int idx_word = 4;
2381 struct ospf6_interface *oi;
2382 assert(ifp);
2383
2384 oi = (struct ospf6_interface *)ifp->info;
2385 if (oi == NULL)
2386 oi = ospf6_interface_create(ifp);
2387 assert(oi);
2388
2389 if (oi->plist_name)
2390 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2391 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
2392
2393 ospf6_interface_connected_route_update(oi->interface);
2394
2395 if (oi->area) {
2396 OSPF6_LINK_LSA_SCHEDULE(oi);
2397 if (oi->state == OSPF6_INTERFACE_DR) {
2398 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2399 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2400 }
2401 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2402 }
2403
2404 return CMD_SUCCESS;
718e3744 2405}
2406
2407DEFUN (no_ipv6_ospf6_advertise_prefix_list,
2408 no_ipv6_ospf6_advertise_prefix_list_cmd,
d23d6de8 2409 "no ipv6 ospf6 advertise prefix-list [WORD]",
718e3744 2410 NO_STR
2411 IP6_STR
2412 OSPF6_STR
2413 "Advertising options\n"
2414 "Filter prefix using prefix-list\n"
d23d6de8 2415 "Prefix list name\n")
718e3744 2416{
d62a17ae 2417 VTY_DECLVAR_CONTEXT(interface, ifp);
2418 struct ospf6_interface *oi;
2419 assert(ifp);
2420
2421 oi = (struct ospf6_interface *)ifp->info;
2422 if (oi == NULL)
2423 oi = ospf6_interface_create(ifp);
2424 assert(oi);
2425
d23d6de8 2426 if (oi->plist_name)
d62a17ae 2427 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
d62a17ae 2428
2429 ospf6_interface_connected_route_update(oi->interface);
2430
2431 if (oi->area) {
2432 OSPF6_LINK_LSA_SCHEDULE(oi);
2433 if (oi->state == OSPF6_INTERFACE_DR) {
2434 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2435 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2436 }
2437 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2438 }
2439
2440 return CMD_SUCCESS;
718e3744 2441}
2442
c5926a92
DD
2443DEFUN (ipv6_ospf6_network,
2444 ipv6_ospf6_network_cmd,
6147e2c6 2445 "ipv6 ospf6 network <broadcast|point-to-point>",
c5926a92
DD
2446 IP6_STR
2447 OSPF6_STR
99a522c7 2448 "Network type\n"
b2d4d039 2449 "Specify OSPF6 broadcast network\n"
c5926a92
DD
2450 "Specify OSPF6 point-to-point network\n"
2451 )
2452{
d62a17ae 2453 VTY_DECLVAR_CONTEXT(interface, ifp);
2454 int idx_network = 3;
2455 struct ospf6_interface *oi;
2456 assert(ifp);
2457
2458 oi = (struct ospf6_interface *)ifp->info;
2459 if (oi == NULL) {
2460 oi = ospf6_interface_create(ifp);
2461 }
2462 assert(oi);
2463
5aeb4f3c
DL
2464 oi->type_cfg = true;
2465
d62a17ae 2466 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
2467 if (oi->type == OSPF_IFTYPE_BROADCAST)
2468 return CMD_SUCCESS;
2469
2470 oi->type = OSPF_IFTYPE_BROADCAST;
2471 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
2472 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
2473 return CMD_SUCCESS;
2474 }
2475 oi->type = OSPF_IFTYPE_POINTOPOINT;
c5926a92 2476 }
c5926a92 2477
d62a17ae 2478 /* Reset the interface */
849576ee
RZ
2479 thread_execute(master, interface_down, oi, 0);
2480 thread_execute(master, interface_up, oi, 0);
c5926a92 2481
d62a17ae 2482 return CMD_SUCCESS;
c5926a92
DD
2483}
2484
2485DEFUN (no_ipv6_ospf6_network,
2486 no_ipv6_ospf6_network_cmd,
32573073 2487 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
c5926a92
DD
2488 NO_STR
2489 IP6_STR
2490 OSPF6_STR
32573073
QY
2491 "Set default network type\n"
2492 "Specify OSPF6 broadcast network\n"
2493 "Specify OSPF6 point-to-point network\n")
c5926a92 2494{
d62a17ae 2495 VTY_DECLVAR_CONTEXT(interface, ifp);
2496 struct ospf6_interface *oi;
2497 int type;
c5926a92 2498
d62a17ae 2499 assert(ifp);
c5926a92 2500
d62a17ae 2501 oi = (struct ospf6_interface *)ifp->info;
2502 if (oi == NULL) {
2503 return CMD_SUCCESS;
2504 }
c5926a92 2505
5aeb4f3c
DL
2506 oi->type_cfg = false;
2507
d62a17ae 2508 type = ospf6_default_iftype(ifp);
2509 if (oi->type == type) {
2510 return CMD_SUCCESS;
2511 }
2512 oi->type = type;
c5926a92 2513
d62a17ae 2514 /* Reset the interface */
849576ee
RZ
2515 thread_execute(master, interface_down, oi, 0);
2516 thread_execute(master, interface_up, oi, 0);
c5926a92 2517
d62a17ae 2518 return CMD_SUCCESS;
c5926a92
DD
2519}
2520
d48ef099 2521static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
718e3744 2522{
d62a17ae 2523 struct ospf6_interface *oi;
2524 struct interface *ifp;
42cabc55 2525 char buf[INET_ADDRSTRLEN];
d62a17ae 2526
451fda4f 2527 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 2528 oi = (struct ospf6_interface *)ifp->info;
2529 if (oi == NULL)
2530 continue;
2531
d48ef099 2532 if (vrf->vrf_id == VRF_DEFAULT)
2533 vty_frame(vty, "interface %s\n", oi->interface->name);
2534 else
2535 vty_frame(vty, "interface %s vrf %s\n",
2536 oi->interface->name, vrf->name);
d62a17ae 2537
2538 if (ifp->desc)
2539 vty_out(vty, " description %s\n", ifp->desc);
42cabc55
IR
2540 if (oi->area_id_format != OSPF6_AREA_FMT_UNSET) {
2541 area_id2str(buf, sizeof(buf), oi->area_id,
2542 oi->area_id_format);
2543 vty_out(vty, " ipv6 ospf6 area %s\n", buf);
2544 }
d62a17ae 2545 if (oi->c_ifmtu)
2546 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
2547
2548 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
2549 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
2550
2551 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
2552 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
2553 oi->hello_interval);
2554
2555 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
2556 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
2557 oi->dead_interval);
2558
2559 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
2560 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
2561 oi->rxmt_interval);
2562
2563 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
2564 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
2565
2566 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
2567 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
2568 oi->transdelay);
2569
2570 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
2571 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
2572 oi->instance_id);
2573
2574 if (oi->plist_name)
2575 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
2576 oi->plist_name);
2577
2578 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
2579 vty_out(vty, " ipv6 ospf6 passive\n");
2580
2581 if (oi->mtu_ignore)
2582 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
2583
5aeb4f3c
DL
2584 if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
2585 vty_out(vty, " ipv6 ospf6 network point-to-point\n");
2586 else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
2587 vty_out(vty, " ipv6 ospf6 network broadcast\n");
d62a17ae 2588
2589 ospf6_bfd_write_config(vty, oi);
2590
07679ad9 2591 vty_endframe(vty, "exit\n!\n");
d62a17ae 2592 }
2593 return 0;
718e3744 2594}
2595
d48ef099 2596/* Configuration write function for ospfd. */
2597static int config_write_interface(struct vty *vty)
2598{
2599 int write = 0;
2600 struct vrf *vrf = NULL;
2601
2602 /* Display all VRF aware OSPF interface configuration */
2603 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2604 write += config_write_ospf6_interface(vty, vrf);
2605 }
2606
2607 return write;
2608}
2609
138c5a74
DS
2610static int ospf6_ifp_create(struct interface *ifp)
2611{
ef7bd2a3
DS
2612 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2613 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
2614 ifp->ifindex, ifp->mtu6);
42cabc55
IR
2615
2616 if (ifp->info)
2617 ospf6_interface_start(ifp->info);
ef7bd2a3 2618
138c5a74
DS
2619 return 0;
2620}
2621
2622static int ospf6_ifp_up(struct interface *ifp)
2623{
ddbf3e60
DS
2624 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2625 zlog_debug(
3efd0893 2626 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
ddbf3e60
DS
2627 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2628 ifp->metric, ifp->mtu6, ifp->bandwidth);
2629
2630 ospf6_interface_state_update(ifp);
2631
138c5a74
DS
2632 return 0;
2633}
2634
2635static int ospf6_ifp_down(struct interface *ifp)
2636{
b0b69e59
DS
2637 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2638 zlog_debug(
3efd0893 2639 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
b0b69e59
DS
2640 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2641 ifp->metric, ifp->mtu6, ifp->bandwidth);
2642
2643 ospf6_interface_state_update(ifp);
2644
138c5a74
DS
2645 return 0;
2646}
2647
2648static int ospf6_ifp_destroy(struct interface *ifp)
2649{
3c3c3252
DS
2650 if (if_is_up(ifp))
2651 zlog_warn("Zebra: got delete of %s, but interface is still up",
2652 ifp->name);
2653
2654 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2655 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2656 ifp->name, ifp->ifindex, ifp->mtu6);
2657
42cabc55
IR
2658 if (ifp->info)
2659 ospf6_interface_stop(ifp->info);
2660
138c5a74
DS
2661 return 0;
2662}
2663
d62a17ae 2664void ospf6_interface_init(void)
718e3744 2665{
d62a17ae 2666 /* Install interface node. */
9da01b0b 2667 if_cmd_init(config_write_interface);
138c5a74
DS
2668 if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
2669 ospf6_ifp_down, ospf6_ifp_destroy);
d62a17ae 2670
2671 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
2672 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
2673 install_element(VIEW_NODE,
2674 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
996c9314 2675 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
d62a17ae 2676
42cabc55
IR
2677 install_element(INTERFACE_NODE, &ipv6_ospf6_area_cmd);
2678 install_element(INTERFACE_NODE, &no_ipv6_ospf6_area_cmd);
d62a17ae 2679 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
2680 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
2681 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
2682 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
d23d6de8 2683
d62a17ae 2684 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
2685 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
2686 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
2687 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
2688 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
2689 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
d23d6de8
QY
2690 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
2691 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
2692 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
2693 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
2694 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
2695 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
d62a17ae 2696
2697 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
2698 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
2699
2700 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
2701 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
2702
2703 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
2704 install_element(INTERFACE_NODE,
2705 &no_ipv6_ospf6_advertise_prefix_list_cmd);
2706
2707 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
2708 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
2709
2710 /* reference bandwidth commands */
2711 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
2712 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
78156066
PR
2713 /* write-multiplier commands */
2714 install_element(OSPF6_NODE, &ospf6_write_multiplier_cmd);
2715 install_element(OSPF6_NODE, &no_ospf6_write_multiplier_cmd);
508e53e2 2716}
2717
a1b11f9b 2718/* Clear the specified interface structure */
f71ed6df 2719void ospf6_interface_clear(struct interface *ifp)
a1b11f9b 2720{
d62a17ae 2721 struct ospf6_interface *oi;
a1b11f9b 2722
d62a17ae 2723 if (!if_is_operative(ifp))
2724 return;
a1b11f9b 2725
d62a17ae 2726 if (ifp->info == NULL)
2727 return;
a1b11f9b 2728
d62a17ae 2729 oi = (struct ospf6_interface *)ifp->info;
a1b11f9b 2730
d62a17ae 2731 if (IS_OSPF6_DEBUG_INTERFACE)
2732 zlog_debug("Interface %s: clear by reset", ifp->name);
a1b11f9b 2733
d62a17ae 2734 /* Reset the interface */
849576ee
RZ
2735 thread_execute(master, interface_down, oi, 0);
2736 thread_execute(master, interface_up, oi, 0);
a1b11f9b
DS
2737}
2738
2739/* Clear interface */
2740DEFUN (clear_ipv6_ospf6_interface,
2741 clear_ipv6_ospf6_interface_cmd,
2742 "clear ipv6 ospf6 interface [IFNAME]",
2743 CLEAR_STR
2744 IP6_STR
2745 OSPF6_STR
2746 INTERFACE_STR
2747 IFNAME_STR
2748 )
2749{
f4e14fdb 2750 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 2751 int idx_ifname = 4;
2752 struct interface *ifp;
d62a17ae 2753
2754 if (argc == 4) /* Clear all the ospfv3 interfaces. */
2755 {
451fda4f 2756 FOR_ALL_INTERFACES (vrf, ifp)
f71ed6df 2757 ospf6_interface_clear(ifp);
d62a17ae 2758 } else /* Interface name is specified. */
2759 {
2760 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
a36898e7 2761 VRF_DEFAULT))
d62a17ae 2762 == NULL) {
2763 vty_out(vty, "No such Interface: %s\n",
2764 argv[idx_ifname]->arg);
2765 return CMD_WARNING;
2766 }
f71ed6df 2767 ospf6_interface_clear(ifp);
d62a17ae 2768 }
2769
2770 return CMD_SUCCESS;
a1b11f9b
DS
2771}
2772
d62a17ae 2773void install_element_ospf6_clear_interface(void)
a1b11f9b 2774{
d62a17ae 2775 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
a1b11f9b
DS
2776}
2777
508e53e2 2778DEFUN (debug_ospf6_interface,
2779 debug_ospf6_interface_cmd,
2780 "debug ospf6 interface",
2781 DEBUG_STR
2782 OSPF6_STR
2783 "Debug OSPFv3 Interface\n"
2784 )
2785{
d62a17ae 2786 OSPF6_DEBUG_INTERFACE_ON();
2787 return CMD_SUCCESS;
508e53e2 2788}
2789
2790DEFUN (no_debug_ospf6_interface,
2791 no_debug_ospf6_interface_cmd,
2792 "no debug ospf6 interface",
2793 NO_STR
2794 DEBUG_STR
2795 OSPF6_STR
2796 "Debug OSPFv3 Interface\n"
2797 )
2798{
d62a17ae 2799 OSPF6_DEBUG_INTERFACE_OFF();
2800 return CMD_SUCCESS;
508e53e2 2801}
2802
d62a17ae 2803int config_write_ospf6_debug_interface(struct vty *vty)
508e53e2 2804{
d62a17ae 2805 if (IS_OSPF6_DEBUG_INTERFACE)
2806 vty_out(vty, "debug ospf6 interface\n");
2807 return 0;
508e53e2 2808}
2809
d62a17ae 2810void install_element_ospf6_debug_interface(void)
508e53e2 2811{
d62a17ae 2812 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2813 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2814 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2815 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
718e3744 2816}