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