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