]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_interface.c
Merge pull request #10398 from patrasar/pim_debug_fix
[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;
608c8870 130 else if (if_is_loopback(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
096f7609 153 ospf6 = oi->interface->vrf->info;
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)
608c8870 390 || if_is_loopback(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. */
81e06dd3
DS
678 thread_add_event(master, adj_ok, on, 0,
679 &on->thread_adj_ok);
d62a17ae 680 }
681 }
682
683 oi->drouter = (drouter ? drouter->router_id : htonl(0));
684 oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
685 return next_state;
718e3744 686}
687
93828a99
IR
688#ifdef __FreeBSD__
689
690#include <ifaddrs.h>
691
692static bool ifmaddr_check(ifindex_t ifindex, struct in6_addr *addr)
693{
694 struct ifmaddrs *ifmap, *ifma;
695 struct sockaddr_dl *sdl;
696 struct sockaddr_in6 *sin6;
697 bool found = false;
698
699 if (getifmaddrs(&ifmap) != 0)
700 return false;
701
702 for (ifma = ifmap; ifma; ifma = ifma->ifma_next) {
703 if (ifma->ifma_name == NULL || ifma->ifma_addr == NULL)
704 continue;
705 if (ifma->ifma_name->sa_family != AF_LINK)
706 continue;
707 if (ifma->ifma_addr->sa_family != AF_INET6)
708 continue;
709 sdl = (struct sockaddr_dl *)ifma->ifma_name;
710 sin6 = (struct sockaddr_in6 *)ifma->ifma_addr;
711 if (sdl->sdl_index == ifindex
712 && memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) {
713 found = true;
714 break;
715 }
716 }
717
718 if (ifmap)
719 freeifmaddrs(ifmap);
720
721 return found;
722}
723
724#endif /* __FreeBSD__ */
6b0655a2 725
508e53e2 726/* Interface State Machine */
d62a17ae 727int interface_up(struct thread *thread)
718e3744 728{
d62a17ae 729 struct ospf6_interface *oi;
beadc736 730 struct ospf6 *ospf6;
d62a17ae 731
732 oi = (struct ospf6_interface *)THREAD_ARG(thread);
733 assert(oi && oi->interface);
734
5aeb4f3c
DL
735 if (!oi->type_cfg)
736 oi->type = ospf6_default_iftype(oi->interface);
737
93828a99 738 thread_cancel(&oi->thread_sso);
f80003b0 739
d62a17ae 740 if (IS_OSPF6_DEBUG_INTERFACE)
741 zlog_debug("Interface Event %s: [InterfaceUp]",
742 oi->interface->name);
743
744 /* check physical interface is up */
745 if (!if_is_operative(oi->interface)) {
1b1f7b4f 746 zlog_warn("Interface %s is down, can't execute [InterfaceUp]",
747 oi->interface->name);
d62a17ae 748 return 0;
749 }
750
751 /* check interface has a link-local address */
752 if (!(ospf6_interface_get_linklocal_address(oi->interface)
608c8870 753 || if_is_loopback(oi->interface))) {
1b1f7b4f 754 zlog_warn(
755 "Interface %s has no link local address, can't execute [InterfaceUp]",
756 oi->interface->name);
d62a17ae 757 return 0;
758 }
759
760 /* Recompute cost */
761 ospf6_interface_recalculate_cost(oi);
762
763 /* if already enabled, do nothing */
764 if (oi->state > OSPF6_INTERFACE_DOWN) {
765 if (IS_OSPF6_DEBUG_INTERFACE)
766 zlog_debug("Interface %s already enabled",
767 oi->interface->name);
768 return 0;
769 }
770
771 /* If no area assigned, return */
772 if (oi->area == NULL) {
1b1f7b4f 773 zlog_warn(
482467dc 774 "%s: Not scheduling Hello for %s as there is no area assigned yet",
d62a17ae 775 __func__, oi->interface->name);
776 return 0;
777 }
778
bc482dc0
RZ
779#ifdef __FreeBSD__
780 /*
93828a99
IR
781 * There's a delay in FreeBSD between issuing a command to leave a
782 * multicast group and an actual leave. If we execute "no router ospf6"
783 * and "router ospf6" fast enough, we can end up in a situation when OS
784 * performs the leave later than it performs the join and the interface
785 * remains without a multicast group. We have to do the join only after
786 * the interface actually left the group.
bc482dc0 787 */
93828a99
IR
788 if (ifmaddr_check(oi->interface->ifindex, &allspfrouters6)) {
789 zlog_info(
790 "Interface %s is still in all routers group, rescheduling for SSO",
791 oi->interface->name);
bc482dc0
RZ
792 thread_add_timer(master, interface_up, oi,
793 OSPF6_INTERFACE_SSO_RETRY_INT,
794 &oi->thread_sso);
795 return 0;
796 }
797#endif /* __FreeBSD__ */
b4b6bd00
IR
798
799 ospf6 = oi->area->ospf6;
bc482dc0 800
d62a17ae 801 /* Join AllSPFRouters */
beadc736 802 if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP,
803 ospf6->fd)
d62a17ae 804 < 0) {
805 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
806 zlog_info(
807 "Scheduling %s for sso retry, trial count: %d",
808 oi->interface->name, oi->sso_try_cnt);
809 thread_add_timer(master, interface_up, oi,
f80003b0
RZ
810 OSPF6_INTERFACE_SSO_RETRY_INT,
811 &oi->thread_sso);
d62a17ae 812 }
813 return 0;
814 }
815 oi->sso_try_cnt = 0; /* Reset on success */
816
817 /* Update interface route */
818 ospf6_interface_connected_route_update(oi->interface);
819
820 /* Schedule Hello */
821 if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
608c8870 822 && !if_is_loopback(oi->interface)) {
d62a17ae 823 thread_add_event(master, ospf6_hello_send, oi, 0,
824 &oi->thread_send_hello);
825 }
826
827 /* decide next interface state */
621ee705
DL
828 if (oi->type == OSPF_IFTYPE_LOOPBACK) {
829 ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK, oi);
830 } else if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
d62a17ae 831 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
832 } else if (oi->priority == 0)
833 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
834 else {
835 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
836 thread_add_timer(master, wait_timer, oi, oi->dead_interval,
9ae41e31 837 &oi->thread_wait_timer);
d62a17ae 838 }
839
840 return 0;
718e3744 841}
842
d62a17ae 843int wait_timer(struct thread *thread)
718e3744 844{
d62a17ae 845 struct ospf6_interface *oi;
718e3744 846
d62a17ae 847 oi = (struct ospf6_interface *)THREAD_ARG(thread);
848 assert(oi && oi->interface);
718e3744 849
d62a17ae 850 if (IS_OSPF6_DEBUG_INTERFACE)
851 zlog_debug("Interface Event %s: [WaitTimer]",
852 oi->interface->name);
718e3744 853
d62a17ae 854 if (oi->state == OSPF6_INTERFACE_WAITING)
855 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 856
d62a17ae 857 return 0;
718e3744 858}
859
d62a17ae 860int backup_seen(struct thread *thread)
508e53e2 861{
d62a17ae 862 struct ospf6_interface *oi;
508e53e2 863
d62a17ae 864 oi = (struct ospf6_interface *)THREAD_ARG(thread);
865 assert(oi && oi->interface);
508e53e2 866
d62a17ae 867 if (IS_OSPF6_DEBUG_INTERFACE)
868 zlog_debug("Interface Event %s: [BackupSeen]",
869 oi->interface->name);
508e53e2 870
d62a17ae 871 if (oi->state == OSPF6_INTERFACE_WAITING)
872 ospf6_interface_state_change(dr_election(oi), oi);
508e53e2 873
d62a17ae 874 return 0;
508e53e2 875}
876
d62a17ae 877int neighbor_change(struct thread *thread)
718e3744 878{
d62a17ae 879 struct ospf6_interface *oi;
508e53e2 880
d62a17ae 881 oi = (struct ospf6_interface *)THREAD_ARG(thread);
882 assert(oi && oi->interface);
508e53e2 883
d62a17ae 884 if (IS_OSPF6_DEBUG_INTERFACE)
885 zlog_debug("Interface Event %s: [NeighborChange]",
886 oi->interface->name);
508e53e2 887
d62a17ae 888 if (oi->state == OSPF6_INTERFACE_DROTHER
889 || oi->state == OSPF6_INTERFACE_BDR
890 || oi->state == OSPF6_INTERFACE_DR)
891 ospf6_interface_state_change(dr_election(oi), oi);
508e53e2 892
d62a17ae 893 return 0;
718e3744 894}
895
d62a17ae 896int interface_down(struct thread *thread)
718e3744 897{
d62a17ae 898 struct ospf6_interface *oi;
899 struct listnode *node, *nnode;
900 struct ospf6_neighbor *on;
beadc736 901 struct ospf6 *ospf6;
508e53e2 902
d62a17ae 903 oi = (struct ospf6_interface *)THREAD_ARG(thread);
904 assert(oi && oi->interface);
508e53e2 905
d62a17ae 906 if (IS_OSPF6_DEBUG_INTERFACE)
907 zlog_debug("Interface Event %s: [InterfaceDown]",
908 oi->interface->name);
508e53e2 909
d62a17ae 910 /* Stop Hellos */
911 THREAD_OFF(oi->thread_send_hello);
424cc3bd 912
f80003b0
RZ
913 /* Stop trying to set socket options. */
914 THREAD_OFF(oi->thread_sso);
508e53e2 915
9a06f23d 916 /* Cease the HELPER role for all the neighbours
917 * of this interface.
918 */
919 if (ospf6_interface_neighbor_count(oi)) {
920 struct listnode *ln;
921 struct ospf6_neighbor *nbr = NULL;
922
923 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, ln, nbr))
924 ospf6_gr_helper_exit(nbr, OSPF6_GR_HELPER_TOPO_CHG);
925 }
926
d62a17ae 927 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
928 ospf6_neighbor_delete(on);
508e53e2 929
d62a17ae 930 list_delete_all_node(oi->neighbor_list);
931
932 /* When interface state is reset, also reset information about
933 * DR election, as it is no longer valid. */
934 oi->drouter = oi->prev_drouter = htonl(0);
935 oi->bdrouter = oi->prev_bdrouter = htonl(0);
b4b6bd00
IR
936
937 if (oi->area == NULL)
938 return 0;
939
940 ospf6 = oi->area->ospf6;
941 /* Leave AllSPFRouters */
942 if (oi->state > OSPF6_INTERFACE_DOWN)
943 ospf6_sso(oi->interface->ifindex, &allspfrouters6,
944 IPV6_LEAVE_GROUP, ospf6->fd);
945
4f7bf1ab
PR
946 /* deal with write fifo */
947 ospf6_fifo_flush(oi->obuf);
948 if (oi->on_write_q) {
949 listnode_delete(ospf6->oi_write_q, oi);
950 if (list_isempty(ospf6->oi_write_q))
951 thread_cancel(&ospf6->t_write);
952 oi->on_write_q = 0;
953 }
954
b4b6bd00
IR
955 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
956
d62a17ae 957 return 0;
718e3744 958}
959
6b0655a2 960
5aeb4f3c
DL
961static const char *ospf6_iftype_str(uint8_t iftype)
962{
963 switch (iftype) {
964 case OSPF_IFTYPE_LOOPBACK:
965 return "LOOPBACK";
966 case OSPF_IFTYPE_BROADCAST:
967 return "BROADCAST";
968 case OSPF_IFTYPE_POINTOPOINT:
969 return "POINTOPOINT";
970 }
971 return "UNKNOWN";
972}
973
40a08809
MR
974#if CONFDATE > 20220709
975CPP_NOTICE("Time to remove ospf6Enabled from JSON output")
976#endif
977
718e3744 978/* show specified interface structure */
f16ae8cf 979static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
980 json_object *json_obj, bool use_json)
718e3744 981{
d62a17ae 982 struct ospf6_interface *oi;
983 struct connected *c;
984 struct prefix *p;
985 struct listnode *i;
986 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
5aeb4f3c 987 uint8_t default_iftype;
d62a17ae 988 struct timeval res, now;
989 char duration[32];
2e37407f 990 struct ospf6_lsa *lsa, *lsanext;
f16ae8cf 991 json_object *json_arr;
992 json_object *json_addr;
d62a17ae 993
5aeb4f3c 994 default_iftype = ospf6_default_iftype(ifp);
d62a17ae 995
f16ae8cf 996 if (use_json) {
997 json_object_string_add(json_obj, "status",
998 (if_is_operative(ifp) ? "up" : "down"));
999 json_object_string_add(json_obj, "type",
1000 ospf6_iftype_str(default_iftype));
1001 json_object_int_add(json_obj, "interfaceId", ifp->ifindex);
1002
1003 if (ifp->info == NULL) {
1004 json_object_boolean_false_add(json_obj, "ospf6Enabled");
1005 return 0;
1006 }
1007 json_object_boolean_true_add(json_obj, "ospf6Enabled");
d62a17ae 1008
d62a17ae 1009 oi = (struct ospf6_interface *)ifp->info;
1010
f16ae8cf 1011 if (if_is_operative(ifp) && oi->type != default_iftype)
1012 json_object_string_add(json_obj, "operatingAsType",
1013 ospf6_iftype_str(oi->type));
1014
1015 } else {
1016 vty_out(vty, "%s is %s, type %s\n", ifp->name,
1017 (if_is_operative(ifp) ? "up" : "down"),
1018 ospf6_iftype_str(default_iftype));
1019 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
1020
1021 if (ifp->info == NULL) {
1022 vty_out(vty, " OSPF not enabled on this interface\n");
1023 return 0;
d62a17ae 1024 }
f16ae8cf 1025 oi = (struct ospf6_interface *)ifp->info;
1026
1027 if (if_is_operative(ifp) && oi->type != default_iftype)
1028 vty_out(vty, " Operating as type %s\n",
1029 ospf6_iftype_str(oi->type));
d62a17ae 1030 }
1031
f16ae8cf 1032 if (use_json) {
1033 json_arr = json_object_new_array();
1034 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1035 json_addr = json_object_new_object();
1036 p = c->address;
1037 prefix2str(p, strbuf, sizeof(strbuf));
1038 switch (p->family) {
1039 case AF_INET:
1040 json_object_string_add(json_addr, "type",
1041 "inet");
1042 json_object_string_add(json_addr, "address",
1043 strbuf);
1044 json_object_array_add(json_arr, json_addr);
1045 break;
1046 case AF_INET6:
1047 json_object_string_add(json_addr, "type",
1048 "inet6");
1049 json_object_string_add(json_addr, "address",
1050 strbuf);
1051 json_object_array_add(json_arr, json_addr);
1052 break;
1053 default:
1054 json_object_string_add(json_addr, "type",
1055 "unknown");
1056 json_object_string_add(json_addr, "address",
1057 strbuf);
1058 json_object_array_add(json_arr, json_addr);
1059 break;
1060 }
1061 }
1062 json_object_object_add(json_obj, "internetAddress", json_arr);
1063 } else {
1064 vty_out(vty, " Internet Address:\n");
1065
1066 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1067 p = c->address;
1068 prefix2str(p, strbuf, sizeof(strbuf));
1069 switch (p->family) {
1070 case AF_INET:
1071 vty_out(vty, " inet : %pFX\n", p);
1072 break;
1073 case AF_INET6:
1074 vty_out(vty, " inet6: %pFX\n", p);
1075 break;
1076 default:
1077 vty_out(vty, " ??? : %pFX\n", p);
1078 break;
1079 }
1080 }
1081 }
1082
1083 if (use_json) {
1084 if (oi->area) {
1085 json_object_boolean_true_add(json_obj,
1086 "attachedToArea");
1087 json_object_int_add(json_obj, "instanceId",
1088 oi->instance_id);
1089 json_object_int_add(json_obj, "interfaceMtu",
1090 oi->ifmtu);
1091 json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
1092 json_object_string_add(json_obj, "mtuMismatchDetection",
1093 oi->mtu_ignore ? "disabled"
1094 : "enabled");
1095 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1096 sizeof(strbuf));
1097 json_object_string_add(json_obj, "areaId", strbuf);
1098 json_object_int_add(json_obj, "cost", oi->cost);
1099 } else
1100 json_object_boolean_false_add(json_obj,
1101 "attachedToArea");
1102
1103 } else {
1104 if (oi->area) {
1105 vty_out(vty,
1106 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1107 oi->instance_id, oi->ifmtu, ifp->mtu6);
1108 vty_out(vty, " MTU mismatch detection: %s\n",
1109 oi->mtu_ignore ? "disabled" : "enabled");
1110 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1111 sizeof(strbuf));
1112 vty_out(vty, " Area ID %s, Cost %u\n", strbuf,
1113 oi->cost);
1114 } else
1115 vty_out(vty, " Not Attached to Area\n");
1116 }
1117
1118 if (use_json) {
1119 json_object_string_add(json_obj, "ospf6InterfaceState",
1120 ospf6_interface_state_str[oi->state]);
1121 json_object_int_add(json_obj, "transmitDelaySec",
1122 oi->transdelay);
1123 json_object_int_add(json_obj, "priority", oi->priority);
1124 json_object_int_add(json_obj, "timerIntervalsConfigHello",
1125 oi->hello_interval);
1126 json_object_int_add(json_obj, "timerIntervalsConfigDead",
1127 oi->dead_interval);
1128 json_object_int_add(json_obj, "timerIntervalsConfigRetransmit",
1129 oi->rxmt_interval);
1130 } else {
1131 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
1132 ospf6_interface_state_str[oi->state], oi->transdelay,
1133 oi->priority);
1134 vty_out(vty, " Timer intervals configured:\n");
1135 vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
1136 oi->hello_interval, oi->dead_interval,
1137 oi->rxmt_interval);
1138 }
d62a17ae 1139
1140 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
1141 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
f16ae8cf 1142 if (use_json) {
1143 json_object_string_add(json_obj, "dr", drouter);
1144 json_object_string_add(json_obj, "bdr", bdrouter);
1145 json_object_int_add(json_obj, "numberOfInterfaceScopedLsa",
1146 oi->lsdb->count);
1147 } else {
1148 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
1149 vty_out(vty, " Number of I/F scoped LSAs is %u\n",
1150 oi->lsdb->count);
1151 }
d62a17ae 1152
1153 monotime(&now);
1154
f16ae8cf 1155 if (use_json) {
1156 timerclear(&res);
1157 if (oi->thread_send_lsupdate)
1158 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1159 &res);
1160 timerstring(&res, duration, sizeof(duration));
1161 json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
1162 oi->lsupdate_list->count);
1163 json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
1164 duration);
1165 json_object_string_add(
1166 json_obj, "lsUpdateSendThread",
1167 (oi->thread_send_lsupdate ? "on" : "off"));
1168
1169 json_arr = json_object_new_array();
1170 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1171 json_object_array_add(
1172 json_arr, json_object_new_string(lsa->name));
1173 json_object_object_add(json_obj, "pendingLsaLsUpdate",
1174 json_arr);
1175
1176 timerclear(&res);
1177 if (oi->thread_send_lsack)
1178 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1179 timerstring(&res, duration, sizeof(duration));
1180
1181 json_object_int_add(json_obj, "pendingLsaLsAckCount",
1182 oi->lsack_list->count);
1183 json_object_string_add(json_obj, "pendingLsaLsAckTime",
1184 duration);
1185 json_object_string_add(json_obj, "lsAckSendThread",
1186 (oi->thread_send_lsack ? "on" : "off"));
1187
1188 json_arr = json_object_new_array();
1189 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1190 json_object_array_add(
1191 json_arr, json_object_new_string(lsa->name));
1192 json_object_object_add(json_obj, "pendingLsaLsAck", json_arr);
1193
1194 } else {
1195 timerclear(&res);
1196 if (oi->thread_send_lsupdate)
1197 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1198 &res);
1199 timerstring(&res, duration, sizeof(duration));
1200 vty_out(vty,
1201 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1202 oi->lsupdate_list->count, duration,
1203 (oi->thread_send_lsupdate ? "on" : "off"));
1204 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1205 vty_out(vty, " %s\n", lsa->name);
1206
1207 timerclear(&res);
1208 if (oi->thread_send_lsack)
1209 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1210 timerstring(&res, duration, sizeof(duration));
1211 vty_out(vty,
1212 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1213 oi->lsack_list->count, duration,
1214 (oi->thread_send_lsack ? "on" : "off"));
1215 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1216 vty_out(vty, " %s\n", lsa->name);
1217 }
d06cc416
RZ
1218
1219 /* BFD specific. */
1220 if (oi->bfd_config.enabled) {
1221 if (use_json) {
1222 struct json_object *json_bfd = json_object_new_object();
1223
1224 json_object_int_add(
1225 json_bfd, "detectMultiplier",
1226 oi->bfd_config.detection_multiplier);
1227 json_object_int_add(json_bfd, "rxMinInterval",
1228 oi->bfd_config.min_rx);
1229 json_object_int_add(json_bfd, "txMinInterval",
1230 oi->bfd_config.min_tx);
1231 json_object_object_add(json_obj, "peerBfdInfo",
1232 json_bfd);
1233 } else {
1234 vty_out(vty,
1235 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1236 oi->bfd_config.detection_multiplier,
1237 oi->bfd_config.min_rx, oi->bfd_config.min_tx);
1238 }
1239 }
1240
d62a17ae 1241 return 0;
718e3744 1242}
1243
ad500b22
K
1244/* Find the global address to be used as a forwarding address in NSSA LSA.*/
1245struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
1246{
1247 struct listnode *n;
1248 struct connected *c;
ad500b22
K
1249
1250 /* for each connected address */
1251 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
1252 /* if family not AF_INET6, ignore */
1253 if (c->address->family != AF_INET6)
1254 continue;
1255
1256 if (!IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
5f2fe4bb 1257 return &c->address->u.prefix6;
ad500b22 1258 }
5f2fe4bb
RW
1259
1260 return NULL;
ad500b22
K
1261}
1262
1263
d48ef099 1264static int show_ospf6_interface_common(struct vty *vty, vrf_id_t vrf_id,
1265 int argc, struct cmd_token **argv,
1266 int idx_ifname, int intf_idx,
d6b901ac 1267 int json_idx, bool uj)
718e3744 1268{
d48ef099 1269
1270 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
d62a17ae 1271 struct interface *ifp;
f16ae8cf 1272 json_object *json;
1273 json_object *json_int;
f16ae8cf 1274
1275 if (uj) {
1276 json = json_object_new_object();
d48ef099 1277 if (argc == json_idx) {
1278 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
f16ae8cf 1279 json_int = json_object_new_object();
1280 if (ifp == NULL) {
1281 json_object_string_add(json, "noSuchInterface",
1282 argv[idx_ifname]->arg);
5a6c232b 1283 vty_json(vty, json);
f16ae8cf 1284 json_object_free(json_int);
1285 return CMD_WARNING;
1286 }
1287 ospf6_interface_show(vty, ifp, json_int, uj);
1288 json_object_object_add(json, ifp->name, json_int);
1289 } else {
1290 FOR_ALL_INTERFACES (vrf, ifp) {
1291 json_int = json_object_new_object();
1292 ospf6_interface_show(vty, ifp, json_int, uj);
1293 json_object_object_add(json, ifp->name,
1294 json_int);
1295 }
d62a17ae 1296 }
5a6c232b 1297 vty_json(vty, json);
d62a17ae 1298 } else {
d48ef099 1299 if (argc == intf_idx) {
1300 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
f16ae8cf 1301 if (ifp == NULL) {
1302 vty_out(vty, "No such Interface: %s\n",
1303 argv[idx_ifname]->arg);
1304 return CMD_WARNING;
1305 }
1306 ospf6_interface_show(vty, ifp, NULL, uj);
1307 } else {
1308 FOR_ALL_INTERFACES (vrf, ifp)
1309 ospf6_interface_show(vty, ifp, NULL, uj);
1310 }
d62a17ae 1311 }
d48ef099 1312 return CMD_SUCCESS;
1313}
1314
1315/* show interface */
1316DEFUN(show_ipv6_ospf6_interface, show_ipv6_ospf6_interface_ifname_cmd,
1317 "show ipv6 ospf6 [vrf <NAME|all>] interface [IFNAME] [json]",
1318 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1319 "All VRFs\n" INTERFACE_STR IFNAME_STR JSON_STR)
1320{
1321 int idx_ifname = 4;
1322 int intf_idx = 5;
1323 int json_idx = 6;
1324 struct listnode *node;
1325 struct ospf6 *ospf6;
1326 const char *vrf_name = NULL;
1327 bool all_vrf = false;
1328 int idx_vrf = 0;
d6b901ac 1329 bool uj = use_json(argc, argv);
d48ef099 1330
d48ef099 1331 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1332 if (idx_vrf > 0) {
1333 idx_ifname += 2;
1334 intf_idx += 2;
1335 json_idx += 2;
1336 }
1337
1338 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1339 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1340 show_ospf6_interface_common(vty, ospf6->vrf_id, argc,
1341 argv, idx_ifname, intf_idx,
d6b901ac 1342 json_idx, uj);
d48ef099 1343
1344 if (!all_vrf)
1345 break;
1346 }
1347 }
d62a17ae 1348
d6b901ac 1349 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1350
d62a17ae 1351 return CMD_SUCCESS;
718e3744 1352}
1353
c5d28568 1354static int ospf6_interface_show_traffic(struct vty *vty,
43855e3d 1355 struct interface *intf_ifp,
ba30b376 1356 int display_once, json_object *json,
d48ef099 1357 bool use_json, vrf_id_t vrf_id)
43855e3d
CS
1358{
1359 struct interface *ifp;
1360 struct vrf *vrf = NULL;
1361 struct ospf6_interface *oi = NULL;
ba30b376 1362 json_object *json_interface;
43855e3d 1363
ba30b376 1364 if (!display_once && !use_json) {
43855e3d 1365 vty_out(vty, "\n");
996c9314
LB
1366 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1367 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1368 " LS-Ack");
43855e3d 1369 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
996c9314
LB
1370 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1371 " Rx/Tx");
43855e3d 1372 vty_out(vty,
996c9314 1373 "--------------------------------------------------------------------------------------------\n");
43855e3d
CS
1374 }
1375
1376 if (intf_ifp == NULL) {
096f7609 1377 vrf = vrf_lookup_by_id(vrf_id);
43855e3d
CS
1378 FOR_ALL_INTERFACES (vrf, ifp) {
1379 if (ifp->info)
1380 oi = (struct ospf6_interface *)ifp->info;
1381 else
1382 continue;
1383
ba30b376 1384 if (use_json) {
1385 json_interface = json_object_new_object();
1386 json_object_int_add(json_interface, "helloRx",
1387 oi->hello_in);
1388 json_object_int_add(json_interface, "helloTx",
1389 oi->hello_out);
1390 json_object_int_add(json_interface, "dbDescRx",
1391 oi->db_desc_in);
1392 json_object_int_add(json_interface, "dbDescTx",
1393 oi->db_desc_out);
1394 json_object_int_add(json_interface, "lsReqRx",
1395 oi->ls_req_in);
1396 json_object_int_add(json_interface, "lsReqTx",
1397 oi->ls_req_out);
1398 json_object_int_add(json_interface,
1399 "lsUpdateRx",
1400 oi->ls_upd_in);
1401 json_object_int_add(json_interface,
1402 "lsUpdateTx",
1403 oi->ls_upd_out);
1404 json_object_int_add(json_interface, "lsAckRx",
1405 oi->ls_ack_in);
1406 json_object_int_add(json_interface, "lsAckTx",
1407 oi->ls_ack_out);
1408
1409 json_object_object_add(json,
1410 oi->interface->name,
1411 json_interface);
1412 } else
1413 vty_out(vty,
1414 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1415 oi->interface->name, oi->hello_in,
1416 oi->hello_out, oi->db_desc_in,
1417 oi->db_desc_out, oi->ls_req_in,
1418 oi->ls_req_out, oi->ls_upd_in,
1419 oi->ls_upd_out, oi->ls_ack_in,
1420 oi->ls_ack_out);
43855e3d
CS
1421 }
1422 } else {
1423 oi = intf_ifp->info;
1424 if (oi == NULL)
1425 return CMD_WARNING;
1426
ba30b376 1427 if (use_json) {
1428 json_interface = json_object_new_object();
1429 json_object_int_add(json_interface, "helloRx",
1430 oi->hello_in);
1431 json_object_int_add(json_interface, "helloTx",
1432 oi->hello_out);
1433 json_object_int_add(json_interface, "dbDescRx",
1434 oi->db_desc_in);
1435 json_object_int_add(json_interface, "dbDescTx",
1436 oi->db_desc_out);
1437 json_object_int_add(json_interface, "lsReqRx",
1438 oi->ls_req_in);
1439 json_object_int_add(json_interface, "lsReqTx",
1440 oi->ls_req_out);
1441 json_object_int_add(json_interface, "lsUpdateRx",
1442 oi->ls_upd_in);
1443 json_object_int_add(json_interface, "lsUpdateTx",
1444 oi->ls_upd_out);
1445 json_object_int_add(json_interface, "lsAckRx",
1446 oi->ls_ack_in);
1447 json_object_int_add(json_interface, "lsAckTx",
1448 oi->ls_ack_out);
1449
1450 json_object_object_add(json, oi->interface->name,
1451 json_interface);
1452 } else
1453 vty_out(vty,
1454 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1455 oi->interface->name, oi->hello_in,
1456 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1457 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1458 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
43855e3d
CS
1459 }
1460
1461 return CMD_SUCCESS;
1462}
1463
d48ef099 1464static int ospf6_interface_show_traffic_common(struct vty *vty, int argc,
1465 struct cmd_token **argv,
d6b901ac 1466 vrf_id_t vrf_id, bool uj)
43855e3d
CS
1467{
1468 int idx_ifname = 0;
1469 int display_once = 0;
1470 char *intf_name = NULL;
1471 struct interface *ifp = NULL;
ba30b376 1472 json_object *json = NULL;
ba30b376 1473
1474 if (uj)
1475 json = json_object_new_object();
43855e3d
CS
1476
1477 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1478 intf_name = argv[idx_ifname]->arg;
d48ef099 1479 ifp = if_lookup_by_name(intf_name, vrf_id);
ba30b376 1480 if (uj) {
1481 if (ifp == NULL) {
1482 json_object_string_add(json, "status",
1483 "No Such Interface");
1484 json_object_string_add(json, "interface",
1485 intf_name);
5a6c232b 1486 vty_json(vty, json);
ba30b376 1487 return CMD_WARNING;
1488 }
1489 if (ifp->info == NULL) {
1490 json_object_string_add(
1491 json, "status",
1492 "OSPF not enabled on this interface");
1493 json_object_string_add(json, "interface",
1494 intf_name);
5a6c232b 1495 vty_json(vty, json);
ba30b376 1496 return 0;
1497 }
1498 } else {
1499 if (ifp == NULL) {
1500 vty_out(vty, "No such Interface: %s\n",
1501 intf_name);
1502 return CMD_WARNING;
1503 }
1504 if (ifp->info == NULL) {
1505 vty_out(vty,
1506 " OSPF not enabled on this interface %s\n",
1507 intf_name);
1508 return 0;
1509 }
43855e3d
CS
1510 }
1511 }
1512
d48ef099 1513 ospf6_interface_show_traffic(vty, ifp, display_once, json, uj, vrf_id);
ba30b376 1514
c48349e3 1515 if (uj)
5a6c232b 1516 vty_json(vty, json);
43855e3d 1517
d48ef099 1518 return CMD_SUCCESS;
1519}
1520
1521/* show interface */
1522DEFUN(show_ipv6_ospf6_interface_traffic, show_ipv6_ospf6_interface_traffic_cmd,
1523 "show ipv6 ospf6 [vrf <NAME|all>] interface traffic [IFNAME] [json]",
1524 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1525 "All VRFs\n" INTERFACE_STR
1526 "Protocol Packet counters\n" IFNAME_STR JSON_STR)
1527{
1528 struct ospf6 *ospf6;
1529 struct listnode *node;
1530 const char *vrf_name = NULL;
1531 bool all_vrf = false;
1532 int idx_vrf = 0;
d6b901ac 1533 bool uj = use_json(argc, argv);
d48ef099 1534
d48ef099 1535 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1536
1537 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1538 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1539 ospf6_interface_show_traffic_common(vty, argc, argv,
d6b901ac 1540 ospf6->vrf_id, uj);
d48ef099 1541
1542 if (!all_vrf)
1543 break;
1544 }
1545 }
43855e3d 1546
d6b901ac 1547 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1548
43855e3d
CS
1549 return CMD_SUCCESS;
1550}
1551
1552
d48ef099 1553DEFUN(show_ipv6_ospf6_interface_ifname_prefix,
1554 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1555 "show ipv6 ospf6 [vrf <NAME|all>] interface IFNAME prefix\
25ee05c9
RW
1556 [<\
1557 detail\
1558 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
35aeb295 1559 >] [json]",
d48ef099 1560 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1561 "All VRFs\n" INTERFACE_STR IFNAME_STR
1562 "Display connected prefixes to advertise\n"
1563 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1564 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1565 "Display details of the prefixes\n" JSON_STR)
508e53e2 1566{
d62a17ae 1567 int idx_ifname = 4;
1568 int idx_prefix = 6;
d62a17ae 1569 struct ospf6_interface *oi;
35aeb295 1570 bool uj = use_json(argc, argv);
d62a17ae 1571
d48ef099 1572 struct ospf6 *ospf6;
1573 struct listnode *node;
1574 struct interface *ifp;
1575 const char *vrf_name = NULL;
1576 bool all_vrf = false;
1577 int idx_vrf = 0;
1578
d48ef099 1579 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1580 if (idx_vrf > 0) {
1581 idx_ifname += 2;
1582 idx_prefix += 2;
d62a17ae 1583 }
1584
d48ef099 1585 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1586 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1587 ifp = if_lookup_by_name(argv[idx_ifname]->arg,
1588 ospf6->vrf_id);
1589 if (ifp == NULL) {
1590 vty_out(vty, "No such Interface: %s\n",
1591 argv[idx_ifname]->arg);
1592 return CMD_WARNING;
1593 }
d62a17ae 1594
d48ef099 1595 oi = ifp->info;
1596 if (oi == NULL
1597 || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
1598 vty_out(vty,
1599 "Interface %s not attached to area\n",
1600 argv[idx_ifname]->arg);
1601 return CMD_WARNING;
1602 }
d100d0b0 1603
d48ef099 1604 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1605 oi->route_connected, uj);
1606
1607 if (!all_vrf)
1608 break;
1609 }
1610 }
d62a17ae 1611
d6b901ac 1612 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1613
d62a17ae 1614 return CMD_SUCCESS;
508e53e2 1615}
1616
d48ef099 1617DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd,
1618 "show ipv6 ospf6 [vrf <NAME|all>] interface prefix\
25ee05c9
RW
1619 [<\
1620 detail\
1621 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
35aeb295 1622 >] [json]",
d48ef099 1623 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1624 "All VRFs\n" INTERFACE_STR
1625 "Display connected prefixes to advertise\n"
1626 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1627 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1628 "Display details of the prefixes\n" JSON_STR)
508e53e2 1629{
d48ef099 1630 struct vrf *vrf = NULL;
d62a17ae 1631 int idx_prefix = 5;
d62a17ae 1632 struct ospf6_interface *oi;
1633 struct interface *ifp;
35aeb295 1634 bool uj = use_json(argc, argv);
d48ef099 1635 struct listnode *node;
1636 struct ospf6 *ospf6;
1637 const char *vrf_name = NULL;
1638 bool all_vrf = false;
1639 int idx_vrf = 0;
1640
d48ef099 1641 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1642 if (idx_vrf > 0)
1643 idx_prefix += 2;
1644
1645 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1646 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1647 vrf = vrf_lookup_by_id(ospf6->vrf_id);
1648 FOR_ALL_INTERFACES (vrf, ifp) {
1649 oi = (struct ospf6_interface *)ifp->info;
1650 if (oi == NULL
1651 || CHECK_FLAG(oi->flag,
1652 OSPF6_INTERFACE_DISABLE))
1653 continue;
1654
1655 ospf6_route_table_show(vty, idx_prefix, argc,
1656 argv,
1657 oi->route_connected, uj);
1658 }
1659 if (!all_vrf)
1660 break;
1661 }
d62a17ae 1662 }
508e53e2 1663
d6b901ac 1664 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1665
d62a17ae 1666 return CMD_SUCCESS;
508e53e2 1667}
1668
42cabc55
IR
1669void ospf6_interface_start(struct ospf6_interface *oi)
1670{
1671 struct ospf6 *ospf6;
1672 struct ospf6_area *oa;
1673
1674 if (oi->area_id_format == OSPF6_AREA_FMT_UNSET)
1675 return;
1676
40699728
AR
1677 if (oi->area)
1678 return;
1679
096f7609 1680 ospf6 = oi->interface->vrf->info;
42cabc55
IR
1681 if (!ospf6)
1682 return;
1683
1684 oa = ospf6_area_lookup(oi->area_id, ospf6);
1685 if (oa == NULL)
1686 oa = ospf6_area_create(oi->area_id, ospf6, oi->area_id_format);
1687
1688 /* attach interface to area */
1689 listnode_add(oa->if_list, oi);
1690 oi->area = oa;
1691
1692 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1693
1694 /* start up */
1695 ospf6_interface_enable(oi);
1696
1697 /* If the router is ABR, originate summary routes */
5c2b86bb 1698 if (ospf6_check_and_set_router_abr(ospf6))
42cabc55
IR
1699 ospf6_abr_enable_area(oa);
1700}
1701
1702void ospf6_interface_stop(struct ospf6_interface *oi)
1703{
1704 struct ospf6_area *oa;
1705
1706 oa = oi->area;
1707 if (!oa)
1708 return;
1709
1710 ospf6_interface_disable(oi);
1711
1712 listnode_delete(oa->if_list, oi);
1713 oi->area = NULL;
1714
1715 if (oa->if_list->count == 0) {
1716 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1717 ospf6_abr_disable_area(oa);
1718 }
1719}
1720
718e3744 1721/* interface variable set command */
42cabc55
IR
1722DEFUN (ipv6_ospf6_area,
1723 ipv6_ospf6_area_cmd,
1724 "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
1725 IP6_STR
1726 OSPF6_STR
1727 "Specify the OSPF6 area ID\n"
1728 "OSPF6 area ID in IPv4 address notation\n"
1729 "OSPF6 area ID in decimal notation\n")
1730{
1731 VTY_DECLVAR_CONTEXT(interface, ifp);
1732 struct ospf6_interface *oi;
1733 int idx_ipv4 = 3;
1734 uint32_t area_id;
1735 int format;
42cabc55
IR
1736
1737 assert(ifp);
1738
1739 oi = (struct ospf6_interface *)ifp->info;
1740 if (oi == NULL)
1741 oi = ospf6_interface_create(ifp);
1742 assert(oi);
1743
1744 if (oi->area) {
1745 vty_out(vty, "%s already attached to Area %s\n",
1746 oi->interface->name, oi->area->name);
1747 return CMD_SUCCESS;
1748 }
1749
42cabc55
IR
1750 if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) {
1751 vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
1752 return CMD_WARNING_CONFIG_FAILED;
1753 }
1754
1755 oi->area_id = area_id;
1756 oi->area_id_format = format;
1757
1758 ospf6_interface_start(oi);
1759
1760 return CMD_SUCCESS;
1761}
1762
1763DEFUN (no_ipv6_ospf6_area,
1764 no_ipv6_ospf6_area_cmd,
1765 "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
1766 NO_STR
1767 IP6_STR
1768 OSPF6_STR
1769 "Specify the OSPF6 area ID\n"
1770 "OSPF6 area ID in IPv4 address notation\n"
1771 "OSPF6 area ID in decimal notation\n")
1772{
1773 VTY_DECLVAR_CONTEXT(interface, ifp);
1774 struct ospf6_interface *oi;
1775
1776 assert(ifp);
1777
1778 oi = (struct ospf6_interface *)ifp->info;
1779 if (oi == NULL)
1780 oi = ospf6_interface_create(ifp);
1781 assert(oi);
1782
1783 ospf6_interface_stop(oi);
1784
1785 oi->area_id = 0;
1786 oi->area_id_format = OSPF6_AREA_FMT_UNSET;
1787
1788 return CMD_SUCCESS;
1789}
1790
b596c71e 1791DEFUN (ipv6_ospf6_ifmtu,
1792 ipv6_ospf6_ifmtu_cmd,
6147e2c6 1793 "ipv6 ospf6 ifmtu (1-65535)",
b596c71e 1794 IP6_STR
1795 OSPF6_STR
1796 "Interface MTU\n"
1797 "OSPFv3 Interface MTU\n"
1798 )
1799{
d62a17ae 1800 VTY_DECLVAR_CONTEXT(interface, ifp);
1801 int idx_number = 3;
1802 struct ospf6_interface *oi;
1803 unsigned int ifmtu, iobuflen;
1804 struct listnode *node, *nnode;
1805 struct ospf6_neighbor *on;
1806
1807 assert(ifp);
1808
1809 oi = (struct ospf6_interface *)ifp->info;
1810 if (oi == NULL)
1811 oi = ospf6_interface_create(ifp);
1812 assert(oi);
1813
1814 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1815
1816 if (oi->c_ifmtu == ifmtu)
1817 return CMD_SUCCESS;
1818
1819 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1820 vty_out(vty,
1821 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1822 ifp->name, ifp->mtu6);
1823 return CMD_WARNING_CONFIG_FAILED;
1824 }
1825
1826 if (oi->ifmtu < ifmtu) {
1827 iobuflen = ospf6_iobuf_size(ifmtu);
1828 if (iobuflen < ifmtu) {
1829 vty_out(vty,
1830 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1831 ifp->name, iobuflen);
1832 oi->ifmtu = oi->c_ifmtu = iobuflen;
1833 } else
1834 oi->ifmtu = oi->c_ifmtu = ifmtu;
1835 } else
1836 oi->ifmtu = oi->c_ifmtu = ifmtu;
1837
1838 /* re-establish adjacencies */
1839 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1840 THREAD_OFF(on->inactivity_timer);
1841 thread_add_event(master, inactivity_timer, on, 0, NULL);
1842 }
1843
1844 return CMD_SUCCESS;
b596c71e 1845}
1846
049207c3 1847DEFUN (no_ipv6_ospf6_ifmtu,
1848 no_ipv6_ospf6_ifmtu_cmd,
0c7ef48a 1849 "no ipv6 ospf6 ifmtu [(1-65535)]",
049207c3 1850 NO_STR
1851 IP6_STR
1852 OSPF6_STR
1853 "Interface MTU\n"
0c7ef48a 1854 "OSPFv3 Interface MTU\n"
049207c3 1855 )
1856{
d62a17ae 1857 VTY_DECLVAR_CONTEXT(interface, ifp);
1858 struct ospf6_interface *oi;
1859 unsigned int iobuflen;
1860 struct listnode *node, *nnode;
1861 struct ospf6_neighbor *on;
1862
1863 assert(ifp);
1864
1865 oi = (struct ospf6_interface *)ifp->info;
1866 if (oi == NULL)
1867 oi = ospf6_interface_create(ifp);
1868 assert(oi);
1869
1870 if (oi->ifmtu < ifp->mtu) {
1871 iobuflen = ospf6_iobuf_size(ifp->mtu);
1872 if (iobuflen < ifp->mtu) {
1873 vty_out(vty,
1874 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1875 ifp->name, iobuflen);
1876 oi->ifmtu = iobuflen;
1877 } else
1878 oi->ifmtu = ifp->mtu;
1879 } else
1880 oi->ifmtu = ifp->mtu;
1881
1882 oi->c_ifmtu = 0;
1883
1884 /* re-establish adjacencies */
1885 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1886 THREAD_OFF(on->inactivity_timer);
1887 thread_add_event(master, inactivity_timer, on, 0, NULL);
1888 }
1889
1890 return CMD_SUCCESS;
049207c3 1891}
1892
718e3744 1893DEFUN (ipv6_ospf6_cost,
1894 ipv6_ospf6_cost_cmd,
6147e2c6 1895 "ipv6 ospf6 cost (1-65535)",
718e3744 1896 IP6_STR
1897 OSPF6_STR
1898 "Interface cost\n"
32573073 1899 "Outgoing metric of this interface\n")
718e3744 1900{
d62a17ae 1901 VTY_DECLVAR_CONTEXT(interface, ifp);
1902 int idx_number = 3;
1903 struct ospf6_interface *oi;
1904 unsigned long int lcost;
1905
1906 assert(ifp);
1907
1908 oi = (struct ospf6_interface *)ifp->info;
1909 if (oi == NULL)
1910 oi = ospf6_interface_create(ifp);
1911 assert(oi);
1912
1913 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1914
1915 if (lcost > UINT32_MAX) {
1916 vty_out(vty, "Cost %ld is out of range\n", lcost);
1917 return CMD_WARNING_CONFIG_FAILED;
1918 }
1919
7bfc5ae8 1920 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
d62a17ae 1921 if (oi->cost == lcost)
1922 return CMD_SUCCESS;
1923
1924 oi->cost = lcost;
0db8196a 1925 ospf6_interface_force_recalculate_cost(oi);
d62a17ae 1926
1927 return CMD_SUCCESS;
c19543b2
VB
1928}
1929
1930DEFUN (no_ipv6_ospf6_cost,
1931 no_ipv6_ospf6_cost_cmd,
32573073 1932 "no ipv6 ospf6 cost [(1-65535)]",
c19543b2
VB
1933 NO_STR
1934 IP6_STR
1935 OSPF6_STR
1936 "Calculate interface cost from bandwidth\n"
32573073 1937 "Outgoing metric of this interface\n")
c19543b2 1938{
d62a17ae 1939 VTY_DECLVAR_CONTEXT(interface, ifp);
1940 struct ospf6_interface *oi;
1941 assert(ifp);
c19543b2 1942
d62a17ae 1943 oi = (struct ospf6_interface *)ifp->info;
1944 if (oi == NULL)
1945 oi = ospf6_interface_create(ifp);
1946 assert(oi);
c19543b2 1947
d62a17ae 1948 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
c19543b2 1949
d62a17ae 1950 ospf6_interface_recalculate_cost(oi);
718e3744 1951
d62a17ae 1952 return CMD_SUCCESS;
718e3744 1953}
1954
fd500689
VB
1955DEFUN (auto_cost_reference_bandwidth,
1956 auto_cost_reference_bandwidth_cmd,
6147e2c6 1957 "auto-cost reference-bandwidth (1-4294967)",
fd500689
VB
1958 "Calculate OSPF interface cost according to bandwidth\n"
1959 "Use reference bandwidth method to assign OSPF cost\n"
1960 "The reference bandwidth in terms of Mbits per second\n")
1961{
d62a17ae 1962 VTY_DECLVAR_CONTEXT(ospf6, o);
1963 int idx_number = 2;
1964 struct ospf6_area *oa;
1965 struct ospf6_interface *oi;
1966 struct listnode *i, *j;
d7c0a89a 1967 uint32_t refbw;
d62a17ae 1968
1969 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1970 if (refbw < 1 || refbw > 4294967) {
1971 vty_out(vty, "reference-bandwidth value is invalid\n");
1972 return CMD_WARNING_CONFIG_FAILED;
1973 }
1974
1975 /* If reference bandwidth is changed. */
1976 if ((refbw) == o->ref_bandwidth)
1977 return CMD_SUCCESS;
1978
1979 o->ref_bandwidth = refbw;
1980 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1981 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1982 ospf6_interface_recalculate_cost(oi);
1983
1984 return CMD_SUCCESS;
fd500689
VB
1985}
1986
1987DEFUN (no_auto_cost_reference_bandwidth,
1988 no_auto_cost_reference_bandwidth_cmd,
ccb8e0c7 1989 "no auto-cost reference-bandwidth [(1-4294967)]",
fd500689
VB
1990 NO_STR
1991 "Calculate OSPF interface cost according to bandwidth\n"
1d68dbfe
DW
1992 "Use reference bandwidth method to assign OSPF cost\n"
1993 "The reference bandwidth in terms of Mbits per second\n")
fd500689 1994{
d62a17ae 1995 VTY_DECLVAR_CONTEXT(ospf6, o);
1996 struct ospf6_area *oa;
1997 struct ospf6_interface *oi;
1998 struct listnode *i, *j;
fd500689 1999
d62a17ae 2000 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
2001 return CMD_SUCCESS;
fd500689 2002
d62a17ae 2003 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
2004 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
2005 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
2006 ospf6_interface_recalculate_cost(oi);
fd500689 2007
d62a17ae 2008 return CMD_SUCCESS;
fd500689
VB
2009}
2010
813d4307 2011
78156066
PR
2012DEFUN (ospf6_write_multiplier,
2013 ospf6_write_multiplier_cmd,
2014 "write-multiplier (1-100)",
2015 "Write multiplier\n"
2016 "Maximum number of interface serviced per write\n")
2017{
2018 VTY_DECLVAR_CONTEXT(ospf6, o);
2019 uint32_t write_oi_count;
2020
2021 write_oi_count = strtol(argv[1]->arg, NULL, 10);
2022 if (write_oi_count < 1 || write_oi_count > 100) {
2023 vty_out(vty, "write-multiplier value is invalid\n");
2024 return CMD_WARNING_CONFIG_FAILED;
2025 }
2026
2027 o->write_oi_count = write_oi_count;
2028 return CMD_SUCCESS;
2029}
2030
2031DEFUN (no_ospf6_write_multiplier,
2032 no_ospf6_write_multiplier_cmd,
2033 "no write-multiplier (1-100)",
2034 NO_STR
2035 "Write multiplier\n"
2036 "Maximum number of interface serviced per write\n")
2037{
2038 VTY_DECLVAR_CONTEXT(ospf6, o);
2039
2040 o->write_oi_count = OSPF6_WRITE_INTERFACE_COUNT_DEFAULT;
2041 return CMD_SUCCESS;
2042}
2043
718e3744 2044DEFUN (ipv6_ospf6_hellointerval,
2045 ipv6_ospf6_hellointerval_cmd,
6147e2c6 2046 "ipv6 ospf6 hello-interval (1-65535)",
718e3744 2047 IP6_STR
2048 OSPF6_STR
99a522c7 2049 "Time between HELLO packets\n"
d23d6de8 2050 SECONDS_STR)
718e3744 2051{
d62a17ae 2052 VTY_DECLVAR_CONTEXT(interface, ifp);
2053 int idx_number = 3;
2054 struct ospf6_interface *oi;
2055 assert(ifp);
2056
2057 oi = (struct ospf6_interface *)ifp->info;
2058 if (oi == NULL)
2059 oi = ospf6_interface_create(ifp);
2060 assert(oi);
2061
d23d6de8
QY
2062 oi->hello_interval = strmatch(argv[0]->text, "no")
2063 ? OSPF_HELLO_INTERVAL_DEFAULT
2064 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2065 return CMD_SUCCESS;
718e3744 2066}
2067
d23d6de8
QY
2068ALIAS (ipv6_ospf6_hellointerval,
2069 no_ipv6_ospf6_hellointerval_cmd,
2070 "no ipv6 ospf6 hello-interval [(1-65535)]",
2071 NO_STR
2072 IP6_STR
2073 OSPF6_STR
2074 "Time between HELLO packets\n"
2075 SECONDS_STR)
2076
718e3744 2077/* interface variable set command */
2078DEFUN (ipv6_ospf6_deadinterval,
2079 ipv6_ospf6_deadinterval_cmd,
6147e2c6 2080 "ipv6 ospf6 dead-interval (1-65535)",
718e3744 2081 IP6_STR
2082 OSPF6_STR
508e53e2 2083 "Interval time after which a neighbor is declared down\n"
d23d6de8 2084 SECONDS_STR)
718e3744 2085{
d62a17ae 2086 VTY_DECLVAR_CONTEXT(interface, ifp);
2087 int idx_number = 3;
2088 struct ospf6_interface *oi;
2089 assert(ifp);
2090
2091 oi = (struct ospf6_interface *)ifp->info;
2092 if (oi == NULL)
2093 oi = ospf6_interface_create(ifp);
2094 assert(oi);
2095
d23d6de8
QY
2096 oi->dead_interval = strmatch(argv[0]->arg, "no")
2097 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
2098 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2099 return CMD_SUCCESS;
718e3744 2100}
2101
d23d6de8
QY
2102ALIAS (ipv6_ospf6_deadinterval,
2103 no_ipv6_ospf6_deadinterval_cmd,
2104 "no ipv6 ospf6 dead-interval [(1-65535)]",
2105 NO_STR
2106 IP6_STR
2107 OSPF6_STR
2108 "Interval time after which a neighbor is declared down\n"
2109 SECONDS_STR)
2110
718e3744 2111/* interface variable set command */
2112DEFUN (ipv6_ospf6_transmitdelay,
2113 ipv6_ospf6_transmitdelay_cmd,
6147e2c6 2114 "ipv6 ospf6 transmit-delay (1-3600)",
718e3744 2115 IP6_STR
2116 OSPF6_STR
99a522c7 2117 "Link state transmit delay\n"
98cfd06b 2118 SECONDS_STR)
718e3744 2119{
d62a17ae 2120 VTY_DECLVAR_CONTEXT(interface, ifp);
2121 int idx_number = 3;
2122 struct ospf6_interface *oi;
2123 assert(ifp);
2124
2125 oi = (struct ospf6_interface *)ifp->info;
2126 if (oi == NULL)
2127 oi = ospf6_interface_create(ifp);
2128 assert(oi);
2129
d23d6de8
QY
2130 oi->transdelay = strmatch(argv[0]->text, "no")
2131 ? OSPF6_INTERFACE_TRANSDELAY
2132 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2133 return CMD_SUCCESS;
718e3744 2134}
2135
d23d6de8
QY
2136ALIAS (ipv6_ospf6_transmitdelay,
2137 no_ipv6_ospf6_transmitdelay_cmd,
2138 "no ipv6 ospf6 transmit-delay [(1-3600)]",
2139 NO_STR
2140 IP6_STR
2141 OSPF6_STR
2142 "Link state transmit delay\n"
2143 SECONDS_STR)
2144
718e3744 2145/* interface variable set command */
2146DEFUN (ipv6_ospf6_retransmitinterval,
2147 ipv6_ospf6_retransmitinterval_cmd,
6147e2c6 2148 "ipv6 ospf6 retransmit-interval (1-65535)",
718e3744 2149 IP6_STR
2150 OSPF6_STR
2151 "Time between retransmitting lost link state advertisements\n"
d23d6de8 2152 SECONDS_STR)
718e3744 2153{
d62a17ae 2154 VTY_DECLVAR_CONTEXT(interface, ifp);
2155 int idx_number = 3;
2156 struct ospf6_interface *oi;
2157 assert(ifp);
2158
2159 oi = (struct ospf6_interface *)ifp->info;
2160 if (oi == NULL)
2161 oi = ospf6_interface_create(ifp);
2162 assert(oi);
2163
d23d6de8
QY
2164 oi->rxmt_interval = strmatch(argv[0]->text, "no")
2165 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
2166 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2167 return CMD_SUCCESS;
718e3744 2168}
2169
d23d6de8
QY
2170ALIAS (ipv6_ospf6_retransmitinterval,
2171 no_ipv6_ospf6_retransmitinterval_cmd,
2172 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
2173 NO_STR
2174 IP6_STR
2175 OSPF6_STR
2176 "Time between retransmitting lost link state advertisements\n"
2177 SECONDS_STR)
2178
718e3744 2179/* interface variable set command */
2180DEFUN (ipv6_ospf6_priority,
2181 ipv6_ospf6_priority_cmd,
6147e2c6 2182 "ipv6 ospf6 priority (0-255)",
718e3744 2183 IP6_STR
2184 OSPF6_STR
2185 "Router priority\n"
d23d6de8 2186 "Priority value\n")
718e3744 2187{
d62a17ae 2188 VTY_DECLVAR_CONTEXT(interface, ifp);
2189 int idx_number = 3;
2190 struct ospf6_interface *oi;
2191 assert(ifp);
718e3744 2192
d62a17ae 2193 oi = (struct ospf6_interface *)ifp->info;
2194 if (oi == NULL)
2195 oi = ospf6_interface_create(ifp);
2196 assert(oi);
508e53e2 2197
d23d6de8
QY
2198 oi->priority = strmatch(argv[0]->text, "no")
2199 ? OSPF6_INTERFACE_PRIORITY
2200 : strtoul(argv[idx_number]->arg, NULL, 10);
718e3744 2201
17ab36c6
YR
2202 if (oi->area
2203 && (oi->state == OSPF6_INTERFACE_DROTHER
2204 || oi->state == OSPF6_INTERFACE_BDR
2205 || oi->state == OSPF6_INTERFACE_DR)) {
2206 if (ospf6_interface_state_change(dr_election(oi), oi) == -1)
2207 OSPF6_LINK_LSA_SCHEDULE(oi);
2208 }
718e3744 2209
d62a17ae 2210 return CMD_SUCCESS;
718e3744 2211}
2212
d23d6de8
QY
2213ALIAS (ipv6_ospf6_priority,
2214 no_ipv6_ospf6_priority_cmd,
2215 "no ipv6 ospf6 priority [(0-255)]",
2216 NO_STR
2217 IP6_STR
2218 OSPF6_STR
2219 "Router priority\n"
2220 "Priority value\n")
2221
718e3744 2222DEFUN (ipv6_ospf6_instance,
2223 ipv6_ospf6_instance_cmd,
6147e2c6 2224 "ipv6 ospf6 instance-id (0-255)",
718e3744 2225 IP6_STR
2226 OSPF6_STR
508e53e2 2227 "Instance ID for this interface\n"
d23d6de8 2228 "Instance ID value\n")
718e3744 2229{
d62a17ae 2230 VTY_DECLVAR_CONTEXT(interface, ifp);
2231 int idx_number = 3;
2232 struct ospf6_interface *oi;
2233 assert(ifp);
2234
2235 oi = (struct ospf6_interface *)ifp->info;
2236 if (oi == NULL)
2237 oi = ospf6_interface_create(ifp);
2238 assert(oi);
2239
d23d6de8
QY
2240 oi->instance_id = strmatch(argv[0]->text, "no")
2241 ? OSPF6_INTERFACE_INSTANCE_ID
2242 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 2243 return CMD_SUCCESS;
718e3744 2244}
2245
d23d6de8
QY
2246ALIAS (ipv6_ospf6_instance,
2247 no_ipv6_ospf6_instance_cmd,
2248 "no ipv6 ospf6 instance-id [(0-255)]",
2249 NO_STR
2250 IP6_STR
2251 OSPF6_STR
2252 "Instance ID for this interface\n"
2253 "Instance ID value\n")
2254
718e3744 2255DEFUN (ipv6_ospf6_passive,
2256 ipv6_ospf6_passive_cmd,
2257 "ipv6 ospf6 passive",
2258 IP6_STR
2259 OSPF6_STR
99a522c7 2260 "Passive interface; no adjacency will be formed on this interface\n"
718e3744 2261 )
2262{
d62a17ae 2263 VTY_DECLVAR_CONTEXT(interface, ifp);
2264 struct ospf6_interface *oi;
2265 struct listnode *node, *nnode;
2266 struct ospf6_neighbor *on;
718e3744 2267
d62a17ae 2268 assert(ifp);
718e3744 2269
d62a17ae 2270 oi = (struct ospf6_interface *)ifp->info;
2271 if (oi == NULL)
2272 oi = ospf6_interface_create(ifp);
2273 assert(oi);
718e3744 2274
d62a17ae 2275 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2276 THREAD_OFF(oi->thread_send_hello);
f80003b0 2277 THREAD_OFF(oi->thread_sso);
508e53e2 2278
d62a17ae 2279 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
2280 THREAD_OFF(on->inactivity_timer);
2281 thread_add_event(master, inactivity_timer, on, 0, NULL);
2282 }
718e3744 2283
d62a17ae 2284 return CMD_SUCCESS;
718e3744 2285}
2286
2287DEFUN (no_ipv6_ospf6_passive,
2288 no_ipv6_ospf6_passive_cmd,
2289 "no ipv6 ospf6 passive",
2290 NO_STR
2291 IP6_STR
2292 OSPF6_STR
2293 "passive interface: No Adjacency will be formed on this I/F\n"
2294 )
2295{
d62a17ae 2296 VTY_DECLVAR_CONTEXT(interface, ifp);
2297 struct ospf6_interface *oi;
2298 assert(ifp);
718e3744 2299
d62a17ae 2300 oi = (struct ospf6_interface *)ifp->info;
2301 if (oi == NULL)
2302 oi = ospf6_interface_create(ifp);
2303 assert(oi);
718e3744 2304
d62a17ae 2305 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2306 THREAD_OFF(oi->thread_send_hello);
f80003b0 2307 THREAD_OFF(oi->thread_sso);
cb978d68 2308
2309 /* don't send hellos over loopback interface */
608c8870 2310 if (!if_is_loopback(oi->interface))
cb978d68 2311 thread_add_event(master, ospf6_hello_send, oi, 0,
2312 &oi->thread_send_hello);
718e3744 2313
d62a17ae 2314 return CMD_SUCCESS;
718e3744 2315}
2316
d42306d9
DT
2317DEFUN (ipv6_ospf6_mtu_ignore,
2318 ipv6_ospf6_mtu_ignore_cmd,
2319 "ipv6 ospf6 mtu-ignore",
2320 IP6_STR
2321 OSPF6_STR
99a522c7 2322 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
2323 )
2324{
d62a17ae 2325 VTY_DECLVAR_CONTEXT(interface, ifp);
2326 struct ospf6_interface *oi;
2327 assert(ifp);
d42306d9 2328
d62a17ae 2329 oi = (struct ospf6_interface *)ifp->info;
2330 if (oi == NULL)
2331 oi = ospf6_interface_create(ifp);
2332 assert(oi);
d42306d9 2333
d62a17ae 2334 oi->mtu_ignore = 1;
d42306d9 2335
d62a17ae 2336 return CMD_SUCCESS;
d42306d9
DT
2337}
2338
2339DEFUN (no_ipv6_ospf6_mtu_ignore,
2340 no_ipv6_ospf6_mtu_ignore_cmd,
2341 "no ipv6 ospf6 mtu-ignore",
2342 NO_STR
2343 IP6_STR
2344 OSPF6_STR
99a522c7 2345 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
2346 )
2347{
d62a17ae 2348 VTY_DECLVAR_CONTEXT(interface, ifp);
2349 struct ospf6_interface *oi;
2350 assert(ifp);
d42306d9 2351
d62a17ae 2352 oi = (struct ospf6_interface *)ifp->info;
2353 if (oi == NULL)
2354 oi = ospf6_interface_create(ifp);
2355 assert(oi);
d42306d9 2356
d62a17ae 2357 oi->mtu_ignore = 0;
d42306d9 2358
d62a17ae 2359 return CMD_SUCCESS;
d42306d9
DT
2360}
2361
718e3744 2362DEFUN (ipv6_ospf6_advertise_prefix_list,
2363 ipv6_ospf6_advertise_prefix_list_cmd,
2364 "ipv6 ospf6 advertise prefix-list WORD",
2365 IP6_STR
2366 OSPF6_STR
2367 "Advertising options\n"
2368 "Filter prefix using prefix-list\n"
2369 "Prefix list name\n"
2370 )
2371{
d62a17ae 2372 VTY_DECLVAR_CONTEXT(interface, ifp);
2373 int idx_word = 4;
2374 struct ospf6_interface *oi;
2375 assert(ifp);
2376
2377 oi = (struct ospf6_interface *)ifp->info;
2378 if (oi == NULL)
2379 oi = ospf6_interface_create(ifp);
2380 assert(oi);
2381
2382 if (oi->plist_name)
2383 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2384 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
2385
2386 ospf6_interface_connected_route_update(oi->interface);
2387
2388 if (oi->area) {
2389 OSPF6_LINK_LSA_SCHEDULE(oi);
2390 if (oi->state == OSPF6_INTERFACE_DR) {
2391 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2392 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2393 }
2394 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2395 }
2396
2397 return CMD_SUCCESS;
718e3744 2398}
2399
2400DEFUN (no_ipv6_ospf6_advertise_prefix_list,
2401 no_ipv6_ospf6_advertise_prefix_list_cmd,
d23d6de8 2402 "no ipv6 ospf6 advertise prefix-list [WORD]",
718e3744 2403 NO_STR
2404 IP6_STR
2405 OSPF6_STR
2406 "Advertising options\n"
2407 "Filter prefix using prefix-list\n"
d23d6de8 2408 "Prefix list name\n")
718e3744 2409{
d62a17ae 2410 VTY_DECLVAR_CONTEXT(interface, ifp);
2411 struct ospf6_interface *oi;
2412 assert(ifp);
2413
2414 oi = (struct ospf6_interface *)ifp->info;
2415 if (oi == NULL)
2416 oi = ospf6_interface_create(ifp);
2417 assert(oi);
2418
d23d6de8 2419 if (oi->plist_name)
d62a17ae 2420 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
d62a17ae 2421
2422 ospf6_interface_connected_route_update(oi->interface);
2423
2424 if (oi->area) {
2425 OSPF6_LINK_LSA_SCHEDULE(oi);
2426 if (oi->state == OSPF6_INTERFACE_DR) {
2427 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2428 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2429 }
2430 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2431 }
2432
2433 return CMD_SUCCESS;
718e3744 2434}
2435
c5926a92
DD
2436DEFUN (ipv6_ospf6_network,
2437 ipv6_ospf6_network_cmd,
6147e2c6 2438 "ipv6 ospf6 network <broadcast|point-to-point>",
c5926a92
DD
2439 IP6_STR
2440 OSPF6_STR
99a522c7 2441 "Network type\n"
b2d4d039 2442 "Specify OSPF6 broadcast network\n"
c5926a92
DD
2443 "Specify OSPF6 point-to-point network\n"
2444 )
2445{
d62a17ae 2446 VTY_DECLVAR_CONTEXT(interface, ifp);
2447 int idx_network = 3;
2448 struct ospf6_interface *oi;
2449 assert(ifp);
2450
2451 oi = (struct ospf6_interface *)ifp->info;
2452 if (oi == NULL) {
2453 oi = ospf6_interface_create(ifp);
2454 }
2455 assert(oi);
2456
5aeb4f3c
DL
2457 oi->type_cfg = true;
2458
d62a17ae 2459 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
2460 if (oi->type == OSPF_IFTYPE_BROADCAST)
2461 return CMD_SUCCESS;
2462
2463 oi->type = OSPF_IFTYPE_BROADCAST;
2464 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
2465 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
2466 return CMD_SUCCESS;
2467 }
2468 oi->type = OSPF_IFTYPE_POINTOPOINT;
c5926a92 2469 }
c5926a92 2470
d62a17ae 2471 /* Reset the interface */
849576ee
RZ
2472 thread_execute(master, interface_down, oi, 0);
2473 thread_execute(master, interface_up, oi, 0);
c5926a92 2474
d62a17ae 2475 return CMD_SUCCESS;
c5926a92
DD
2476}
2477
2478DEFUN (no_ipv6_ospf6_network,
2479 no_ipv6_ospf6_network_cmd,
32573073 2480 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
c5926a92
DD
2481 NO_STR
2482 IP6_STR
2483 OSPF6_STR
32573073
QY
2484 "Set default network type\n"
2485 "Specify OSPF6 broadcast network\n"
2486 "Specify OSPF6 point-to-point network\n")
c5926a92 2487{
d62a17ae 2488 VTY_DECLVAR_CONTEXT(interface, ifp);
2489 struct ospf6_interface *oi;
2490 int type;
c5926a92 2491
d62a17ae 2492 assert(ifp);
c5926a92 2493
d62a17ae 2494 oi = (struct ospf6_interface *)ifp->info;
2495 if (oi == NULL) {
2496 return CMD_SUCCESS;
2497 }
c5926a92 2498
5aeb4f3c
DL
2499 oi->type_cfg = false;
2500
d62a17ae 2501 type = ospf6_default_iftype(ifp);
2502 if (oi->type == type) {
2503 return CMD_SUCCESS;
2504 }
2505 oi->type = type;
c5926a92 2506
d62a17ae 2507 /* Reset the interface */
849576ee
RZ
2508 thread_execute(master, interface_down, oi, 0);
2509 thread_execute(master, interface_up, oi, 0);
c5926a92 2510
d62a17ae 2511 return CMD_SUCCESS;
c5926a92
DD
2512}
2513
d48ef099 2514static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
718e3744 2515{
d62a17ae 2516 struct ospf6_interface *oi;
2517 struct interface *ifp;
42cabc55 2518 char buf[INET_ADDRSTRLEN];
d62a17ae 2519
451fda4f 2520 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 2521 oi = (struct ospf6_interface *)ifp->info;
2522 if (oi == NULL)
2523 continue;
2524
d48ef099 2525 if (vrf->vrf_id == VRF_DEFAULT)
2526 vty_frame(vty, "interface %s\n", oi->interface->name);
2527 else
2528 vty_frame(vty, "interface %s vrf %s\n",
2529 oi->interface->name, vrf->name);
d62a17ae 2530
2531 if (ifp->desc)
2532 vty_out(vty, " description %s\n", ifp->desc);
42cabc55
IR
2533 if (oi->area_id_format != OSPF6_AREA_FMT_UNSET) {
2534 area_id2str(buf, sizeof(buf), oi->area_id,
2535 oi->area_id_format);
2536 vty_out(vty, " ipv6 ospf6 area %s\n", buf);
2537 }
d62a17ae 2538 if (oi->c_ifmtu)
2539 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
2540
2541 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
2542 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
2543
2544 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
2545 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
2546 oi->hello_interval);
2547
2548 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
2549 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
2550 oi->dead_interval);
2551
2552 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
2553 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
2554 oi->rxmt_interval);
2555
2556 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
2557 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
2558
2559 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
2560 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
2561 oi->transdelay);
2562
2563 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
2564 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
2565 oi->instance_id);
2566
2567 if (oi->plist_name)
2568 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
2569 oi->plist_name);
2570
2571 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
2572 vty_out(vty, " ipv6 ospf6 passive\n");
2573
2574 if (oi->mtu_ignore)
2575 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
2576
5aeb4f3c
DL
2577 if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
2578 vty_out(vty, " ipv6 ospf6 network point-to-point\n");
2579 else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
2580 vty_out(vty, " ipv6 ospf6 network broadcast\n");
d62a17ae 2581
2582 ospf6_bfd_write_config(vty, oi);
2583
07679ad9 2584 vty_endframe(vty, "exit\n!\n");
d62a17ae 2585 }
2586 return 0;
718e3744 2587}
2588
d48ef099 2589/* Configuration write function for ospfd. */
2590static int config_write_interface(struct vty *vty)
2591{
2592 int write = 0;
2593 struct vrf *vrf = NULL;
2594
2595 /* Display all VRF aware OSPF interface configuration */
2596 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2597 write += config_write_ospf6_interface(vty, vrf);
2598 }
2599
2600 return write;
2601}
2602
138c5a74
DS
2603static int ospf6_ifp_create(struct interface *ifp)
2604{
ef7bd2a3
DS
2605 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2606 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
2607 ifp->ifindex, ifp->mtu6);
42cabc55
IR
2608
2609 if (ifp->info)
2610 ospf6_interface_start(ifp->info);
ef7bd2a3 2611
138c5a74
DS
2612 return 0;
2613}
2614
2615static int ospf6_ifp_up(struct interface *ifp)
2616{
ddbf3e60
DS
2617 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2618 zlog_debug(
3efd0893 2619 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
ddbf3e60
DS
2620 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2621 ifp->metric, ifp->mtu6, ifp->bandwidth);
2622
2623 ospf6_interface_state_update(ifp);
2624
138c5a74
DS
2625 return 0;
2626}
2627
2628static int ospf6_ifp_down(struct interface *ifp)
2629{
b0b69e59
DS
2630 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2631 zlog_debug(
3efd0893 2632 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
b0b69e59
DS
2633 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2634 ifp->metric, ifp->mtu6, ifp->bandwidth);
2635
2636 ospf6_interface_state_update(ifp);
2637
138c5a74
DS
2638 return 0;
2639}
2640
2641static int ospf6_ifp_destroy(struct interface *ifp)
2642{
3c3c3252
DS
2643 if (if_is_up(ifp))
2644 zlog_warn("Zebra: got delete of %s, but interface is still up",
2645 ifp->name);
2646
2647 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2648 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2649 ifp->name, ifp->ifindex, ifp->mtu6);
2650
42cabc55
IR
2651 if (ifp->info)
2652 ospf6_interface_stop(ifp->info);
2653
138c5a74
DS
2654 return 0;
2655}
2656
d62a17ae 2657void ospf6_interface_init(void)
718e3744 2658{
d62a17ae 2659 /* Install interface node. */
9da01b0b 2660 if_cmd_init(config_write_interface);
138c5a74
DS
2661 if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
2662 ospf6_ifp_down, ospf6_ifp_destroy);
d62a17ae 2663
2664 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
2665 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
2666 install_element(VIEW_NODE,
2667 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
996c9314 2668 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
d62a17ae 2669
42cabc55
IR
2670 install_element(INTERFACE_NODE, &ipv6_ospf6_area_cmd);
2671 install_element(INTERFACE_NODE, &no_ipv6_ospf6_area_cmd);
d62a17ae 2672 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
2673 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
2674 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
2675 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
d23d6de8 2676
d62a17ae 2677 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
2678 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
2679 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
2680 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
2681 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
2682 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
d23d6de8
QY
2683 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
2684 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
2685 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
2686 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
2687 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
2688 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
d62a17ae 2689
2690 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
2691 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
2692
2693 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
2694 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
2695
2696 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
2697 install_element(INTERFACE_NODE,
2698 &no_ipv6_ospf6_advertise_prefix_list_cmd);
2699
2700 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
2701 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
2702
2703 /* reference bandwidth commands */
2704 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
2705 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
78156066
PR
2706 /* write-multiplier commands */
2707 install_element(OSPF6_NODE, &ospf6_write_multiplier_cmd);
2708 install_element(OSPF6_NODE, &no_ospf6_write_multiplier_cmd);
508e53e2 2709}
2710
a1b11f9b 2711/* Clear the specified interface structure */
f71ed6df 2712void ospf6_interface_clear(struct interface *ifp)
a1b11f9b 2713{
d62a17ae 2714 struct ospf6_interface *oi;
a1b11f9b 2715
d62a17ae 2716 if (!if_is_operative(ifp))
2717 return;
a1b11f9b 2718
d62a17ae 2719 if (ifp->info == NULL)
2720 return;
a1b11f9b 2721
d62a17ae 2722 oi = (struct ospf6_interface *)ifp->info;
a1b11f9b 2723
d62a17ae 2724 if (IS_OSPF6_DEBUG_INTERFACE)
2725 zlog_debug("Interface %s: clear by reset", ifp->name);
a1b11f9b 2726
d62a17ae 2727 /* Reset the interface */
849576ee
RZ
2728 thread_execute(master, interface_down, oi, 0);
2729 thread_execute(master, interface_up, oi, 0);
a1b11f9b
DS
2730}
2731
2732/* Clear interface */
2733DEFUN (clear_ipv6_ospf6_interface,
2734 clear_ipv6_ospf6_interface_cmd,
ad7e12b0 2735 "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
a1b11f9b
DS
2736 CLEAR_STR
2737 IP6_STR
2738 OSPF6_STR
ad7e12b0 2739 VRF_CMD_HELP_STR
a1b11f9b
DS
2740 INTERFACE_STR
2741 IFNAME_STR
2742 )
2743{
ad7e12b0
IR
2744 struct vrf *vrf;
2745 int idx_vrf = 3;
d62a17ae 2746 int idx_ifname = 4;
2747 struct interface *ifp;
ad7e12b0 2748 const char *vrf_name;
d62a17ae 2749
ad7e12b0
IR
2750 if (argv_find(argv, argc, "vrf", &idx_vrf))
2751 vrf_name = argv[idx_vrf + 1]->arg;
2752 else
2753 vrf_name = VRF_DEFAULT_NAME;
2754 vrf = vrf_lookup_by_name(vrf_name);
2755 if (!vrf) {
2756 vty_out(vty, "%% VRF %s not found\n", vrf_name);
2757 return CMD_WARNING;
2758 }
2759
2760 if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) {
2761 /* Clear all the ospfv3 interfaces. */
451fda4f 2762 FOR_ALL_INTERFACES (vrf, ifp)
f71ed6df 2763 ospf6_interface_clear(ifp);
ad7e12b0
IR
2764 } else {
2765 /* Interface name is specified. */
2766 ifp = if_lookup_by_name_vrf(argv[idx_ifname]->arg, vrf);
2767 if (!ifp) {
d62a17ae 2768 vty_out(vty, "No such Interface: %s\n",
2769 argv[idx_ifname]->arg);
2770 return CMD_WARNING;
2771 }
f71ed6df 2772 ospf6_interface_clear(ifp);
d62a17ae 2773 }
2774
2775 return CMD_SUCCESS;
a1b11f9b
DS
2776}
2777
d62a17ae 2778void install_element_ospf6_clear_interface(void)
a1b11f9b 2779{
d62a17ae 2780 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
a1b11f9b
DS
2781}
2782
508e53e2 2783DEFUN (debug_ospf6_interface,
2784 debug_ospf6_interface_cmd,
2785 "debug ospf6 interface",
2786 DEBUG_STR
2787 OSPF6_STR
2788 "Debug OSPFv3 Interface\n"
2789 )
2790{
d62a17ae 2791 OSPF6_DEBUG_INTERFACE_ON();
2792 return CMD_SUCCESS;
508e53e2 2793}
2794
2795DEFUN (no_debug_ospf6_interface,
2796 no_debug_ospf6_interface_cmd,
2797 "no debug ospf6 interface",
2798 NO_STR
2799 DEBUG_STR
2800 OSPF6_STR
2801 "Debug OSPFv3 Interface\n"
2802 )
2803{
d62a17ae 2804 OSPF6_DEBUG_INTERFACE_OFF();
2805 return CMD_SUCCESS;
508e53e2 2806}
2807
d62a17ae 2808int config_write_ospf6_debug_interface(struct vty *vty)
508e53e2 2809{
d62a17ae 2810 if (IS_OSPF6_DEBUG_INTERFACE)
2811 vty_out(vty, "debug ospf6 interface\n");
2812 return 0;
508e53e2 2813}
2814
d62a17ae 2815void install_element_ospf6_debug_interface(void)
508e53e2 2816{
d62a17ae 2817 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2818 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2819 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2820 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
718e3744 2821}