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