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