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