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