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