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