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