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