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