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