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