]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_interface.c
*: require semicolon after DEFINE_HOOK & co.
[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
bf8d3d6a 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),
8451921b 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>]\
35aeb295 1419 >] [json]",
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
35aeb295
YR
1430 "Display details of the prefixes\n"
1431 JSON_STR)
508e53e2 1432{
d62a17ae 1433 int idx_ifname = 4;
1434 int idx_prefix = 6;
1435 struct interface *ifp;
1436 struct ospf6_interface *oi;
35aeb295 1437 bool uj = use_json(argc, argv);
d62a17ae 1438
a36898e7 1439 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 1440 if (ifp == NULL) {
1441 vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
1442 return CMD_WARNING;
1443 }
1444
1445 oi = ifp->info;
1446 if (oi == NULL) {
1447 vty_out(vty, "OSPFv3 is not enabled on %s\n",
1448 argv[idx_ifname]->arg);
1449 return CMD_WARNING;
1450 }
1451
eacd0828 1452 ospf6_route_table_show(vty, idx_prefix, argc, argv, oi->route_connected,
35aeb295 1453 uj);
d62a17ae 1454
1455 return CMD_SUCCESS;
508e53e2 1456}
1457
508e53e2 1458DEFUN (show_ipv6_ospf6_interface_prefix,
1459 show_ipv6_ospf6_interface_prefix_cmd,
25ee05c9
RW
1460 "show ipv6 ospf6 interface prefix\
1461 [<\
1462 detail\
1463 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
35aeb295 1464 >] [json]",
508e53e2 1465 SHOW_STR
1466 IP6_STR
1467 OSPF6_STR
1468 INTERFACE_STR
1469 "Display connected prefixes to advertise\n"
25ee05c9 1470 "Display details of the prefixes\n"
093d7a3a
DW
1471 OSPF6_ROUTE_ADDRESS_STR
1472 OSPF6_ROUTE_PREFIX_STR
1473 OSPF6_ROUTE_MATCH_STR
35aeb295
YR
1474 "Display details of the prefixes\n"
1475 JSON_STR)
508e53e2 1476{
f4e14fdb 1477 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1478 int idx_prefix = 5;
d62a17ae 1479 struct ospf6_interface *oi;
1480 struct interface *ifp;
35aeb295 1481 bool uj = use_json(argc, argv);
d62a17ae 1482
451fda4f 1483 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1484 oi = (struct ospf6_interface *)ifp->info;
1485 if (oi == NULL)
1486 continue;
1487
1488 ospf6_route_table_show(vty, idx_prefix, argc, argv,
35aeb295 1489 oi->route_connected, uj);
d62a17ae 1490 }
508e53e2 1491
d62a17ae 1492 return CMD_SUCCESS;
508e53e2 1493}
1494
718e3744 1495/* interface variable set command */
b596c71e 1496DEFUN (ipv6_ospf6_ifmtu,
1497 ipv6_ospf6_ifmtu_cmd,
6147e2c6 1498 "ipv6 ospf6 ifmtu (1-65535)",
b596c71e 1499 IP6_STR
1500 OSPF6_STR
1501 "Interface MTU\n"
1502 "OSPFv3 Interface MTU\n"
1503 )
1504{
d62a17ae 1505 VTY_DECLVAR_CONTEXT(interface, ifp);
1506 int idx_number = 3;
1507 struct ospf6_interface *oi;
1508 unsigned int ifmtu, iobuflen;
1509 struct listnode *node, *nnode;
1510 struct ospf6_neighbor *on;
1511
1512 assert(ifp);
1513
1514 oi = (struct ospf6_interface *)ifp->info;
1515 if (oi == NULL)
1516 oi = ospf6_interface_create(ifp);
1517 assert(oi);
1518
1519 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1520
1521 if (oi->c_ifmtu == ifmtu)
1522 return CMD_SUCCESS;
1523
1524 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1525 vty_out(vty,
1526 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1527 ifp->name, ifp->mtu6);
1528 return CMD_WARNING_CONFIG_FAILED;
1529 }
1530
1531 if (oi->ifmtu < ifmtu) {
1532 iobuflen = ospf6_iobuf_size(ifmtu);
1533 if (iobuflen < ifmtu) {
1534 vty_out(vty,
1535 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1536 ifp->name, iobuflen);
1537 oi->ifmtu = oi->c_ifmtu = iobuflen;
1538 } else
1539 oi->ifmtu = oi->c_ifmtu = ifmtu;
1540 } else
1541 oi->ifmtu = oi->c_ifmtu = ifmtu;
1542
1543 /* re-establish adjacencies */
1544 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1545 THREAD_OFF(on->inactivity_timer);
1546 thread_add_event(master, inactivity_timer, on, 0, NULL);
1547 }
1548
1549 return CMD_SUCCESS;
b596c71e 1550}
1551
049207c3 1552DEFUN (no_ipv6_ospf6_ifmtu,
1553 no_ipv6_ospf6_ifmtu_cmd,
0c7ef48a 1554 "no ipv6 ospf6 ifmtu [(1-65535)]",
049207c3 1555 NO_STR
1556 IP6_STR
1557 OSPF6_STR
1558 "Interface MTU\n"
0c7ef48a 1559 "OSPFv3 Interface MTU\n"
049207c3 1560 )
1561{
d62a17ae 1562 VTY_DECLVAR_CONTEXT(interface, ifp);
1563 struct ospf6_interface *oi;
1564 unsigned int iobuflen;
1565 struct listnode *node, *nnode;
1566 struct ospf6_neighbor *on;
1567
1568 assert(ifp);
1569
1570 oi = (struct ospf6_interface *)ifp->info;
1571 if (oi == NULL)
1572 oi = ospf6_interface_create(ifp);
1573 assert(oi);
1574
1575 if (oi->ifmtu < ifp->mtu) {
1576 iobuflen = ospf6_iobuf_size(ifp->mtu);
1577 if (iobuflen < ifp->mtu) {
1578 vty_out(vty,
1579 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1580 ifp->name, iobuflen);
1581 oi->ifmtu = iobuflen;
1582 } else
1583 oi->ifmtu = ifp->mtu;
1584 } else
1585 oi->ifmtu = ifp->mtu;
1586
1587 oi->c_ifmtu = 0;
1588
1589 /* re-establish adjacencies */
1590 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1591 THREAD_OFF(on->inactivity_timer);
1592 thread_add_event(master, inactivity_timer, on, 0, NULL);
1593 }
1594
1595 return CMD_SUCCESS;
049207c3 1596}
1597
718e3744 1598DEFUN (ipv6_ospf6_cost,
1599 ipv6_ospf6_cost_cmd,
6147e2c6 1600 "ipv6 ospf6 cost (1-65535)",
718e3744 1601 IP6_STR
1602 OSPF6_STR
1603 "Interface cost\n"
32573073 1604 "Outgoing metric of this interface\n")
718e3744 1605{
d62a17ae 1606 VTY_DECLVAR_CONTEXT(interface, ifp);
1607 int idx_number = 3;
1608 struct ospf6_interface *oi;
1609 unsigned long int lcost;
1610
1611 assert(ifp);
1612
1613 oi = (struct ospf6_interface *)ifp->info;
1614 if (oi == NULL)
1615 oi = ospf6_interface_create(ifp);
1616 assert(oi);
1617
1618 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1619
1620 if (lcost > UINT32_MAX) {
1621 vty_out(vty, "Cost %ld is out of range\n", lcost);
1622 return CMD_WARNING_CONFIG_FAILED;
1623 }
1624
7bfc5ae8 1625 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
d62a17ae 1626 if (oi->cost == lcost)
1627 return CMD_SUCCESS;
1628
1629 oi->cost = lcost;
0db8196a 1630 ospf6_interface_force_recalculate_cost(oi);
d62a17ae 1631
1632 return CMD_SUCCESS;
c19543b2
VB
1633}
1634
1635DEFUN (no_ipv6_ospf6_cost,
1636 no_ipv6_ospf6_cost_cmd,
32573073 1637 "no ipv6 ospf6 cost [(1-65535)]",
c19543b2
VB
1638 NO_STR
1639 IP6_STR
1640 OSPF6_STR
1641 "Calculate interface cost from bandwidth\n"
32573073 1642 "Outgoing metric of this interface\n")
c19543b2 1643{
d62a17ae 1644 VTY_DECLVAR_CONTEXT(interface, ifp);
1645 struct ospf6_interface *oi;
1646 assert(ifp);
c19543b2 1647
d62a17ae 1648 oi = (struct ospf6_interface *)ifp->info;
1649 if (oi == NULL)
1650 oi = ospf6_interface_create(ifp);
1651 assert(oi);
c19543b2 1652
d62a17ae 1653 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
c19543b2 1654
d62a17ae 1655 ospf6_interface_recalculate_cost(oi);
718e3744 1656
d62a17ae 1657 return CMD_SUCCESS;
718e3744 1658}
1659
fd500689
VB
1660DEFUN (auto_cost_reference_bandwidth,
1661 auto_cost_reference_bandwidth_cmd,
6147e2c6 1662 "auto-cost reference-bandwidth (1-4294967)",
fd500689
VB
1663 "Calculate OSPF interface cost according to bandwidth\n"
1664 "Use reference bandwidth method to assign OSPF cost\n"
1665 "The reference bandwidth in terms of Mbits per second\n")
1666{
d62a17ae 1667 VTY_DECLVAR_CONTEXT(ospf6, o);
1668 int idx_number = 2;
1669 struct ospf6_area *oa;
1670 struct ospf6_interface *oi;
1671 struct listnode *i, *j;
d7c0a89a 1672 uint32_t refbw;
d62a17ae 1673
1674 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1675 if (refbw < 1 || refbw > 4294967) {
1676 vty_out(vty, "reference-bandwidth value is invalid\n");
1677 return CMD_WARNING_CONFIG_FAILED;
1678 }
1679
1680 /* If reference bandwidth is changed. */
1681 if ((refbw) == o->ref_bandwidth)
1682 return CMD_SUCCESS;
1683
1684 o->ref_bandwidth = refbw;
1685 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1686 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1687 ospf6_interface_recalculate_cost(oi);
1688
1689 return CMD_SUCCESS;
fd500689
VB
1690}
1691
1692DEFUN (no_auto_cost_reference_bandwidth,
1693 no_auto_cost_reference_bandwidth_cmd,
ccb8e0c7 1694 "no auto-cost reference-bandwidth [(1-4294967)]",
fd500689
VB
1695 NO_STR
1696 "Calculate OSPF interface cost according to bandwidth\n"
1d68dbfe
DW
1697 "Use reference bandwidth method to assign OSPF cost\n"
1698 "The reference bandwidth in terms of Mbits per second\n")
fd500689 1699{
d62a17ae 1700 VTY_DECLVAR_CONTEXT(ospf6, o);
1701 struct ospf6_area *oa;
1702 struct ospf6_interface *oi;
1703 struct listnode *i, *j;
fd500689 1704
d62a17ae 1705 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1706 return CMD_SUCCESS;
fd500689 1707
d62a17ae 1708 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1709 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1710 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1711 ospf6_interface_recalculate_cost(oi);
fd500689 1712
d62a17ae 1713 return CMD_SUCCESS;
fd500689
VB
1714}
1715
813d4307 1716
718e3744 1717DEFUN (ipv6_ospf6_hellointerval,
1718 ipv6_ospf6_hellointerval_cmd,
6147e2c6 1719 "ipv6 ospf6 hello-interval (1-65535)",
718e3744 1720 IP6_STR
1721 OSPF6_STR
99a522c7 1722 "Time between HELLO packets\n"
d23d6de8 1723 SECONDS_STR)
718e3744 1724{
d62a17ae 1725 VTY_DECLVAR_CONTEXT(interface, ifp);
1726 int idx_number = 3;
1727 struct ospf6_interface *oi;
1728 assert(ifp);
1729
1730 oi = (struct ospf6_interface *)ifp->info;
1731 if (oi == NULL)
1732 oi = ospf6_interface_create(ifp);
1733 assert(oi);
1734
d23d6de8
QY
1735 oi->hello_interval = strmatch(argv[0]->text, "no")
1736 ? OSPF_HELLO_INTERVAL_DEFAULT
1737 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1738 return CMD_SUCCESS;
718e3744 1739}
1740
d23d6de8
QY
1741ALIAS (ipv6_ospf6_hellointerval,
1742 no_ipv6_ospf6_hellointerval_cmd,
1743 "no ipv6 ospf6 hello-interval [(1-65535)]",
1744 NO_STR
1745 IP6_STR
1746 OSPF6_STR
1747 "Time between HELLO packets\n"
1748 SECONDS_STR)
1749
718e3744 1750/* interface variable set command */
1751DEFUN (ipv6_ospf6_deadinterval,
1752 ipv6_ospf6_deadinterval_cmd,
6147e2c6 1753 "ipv6 ospf6 dead-interval (1-65535)",
718e3744 1754 IP6_STR
1755 OSPF6_STR
508e53e2 1756 "Interval time after which a neighbor is declared down\n"
d23d6de8 1757 SECONDS_STR)
718e3744 1758{
d62a17ae 1759 VTY_DECLVAR_CONTEXT(interface, ifp);
1760 int idx_number = 3;
1761 struct ospf6_interface *oi;
1762 assert(ifp);
1763
1764 oi = (struct ospf6_interface *)ifp->info;
1765 if (oi == NULL)
1766 oi = ospf6_interface_create(ifp);
1767 assert(oi);
1768
d23d6de8
QY
1769 oi->dead_interval = strmatch(argv[0]->arg, "no")
1770 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1771 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1772 return CMD_SUCCESS;
718e3744 1773}
1774
d23d6de8
QY
1775ALIAS (ipv6_ospf6_deadinterval,
1776 no_ipv6_ospf6_deadinterval_cmd,
1777 "no ipv6 ospf6 dead-interval [(1-65535)]",
1778 NO_STR
1779 IP6_STR
1780 OSPF6_STR
1781 "Interval time after which a neighbor is declared down\n"
1782 SECONDS_STR)
1783
718e3744 1784/* interface variable set command */
1785DEFUN (ipv6_ospf6_transmitdelay,
1786 ipv6_ospf6_transmitdelay_cmd,
6147e2c6 1787 "ipv6 ospf6 transmit-delay (1-3600)",
718e3744 1788 IP6_STR
1789 OSPF6_STR
99a522c7 1790 "Link state transmit delay\n"
98cfd06b 1791 SECONDS_STR)
718e3744 1792{
d62a17ae 1793 VTY_DECLVAR_CONTEXT(interface, ifp);
1794 int idx_number = 3;
1795 struct ospf6_interface *oi;
1796 assert(ifp);
1797
1798 oi = (struct ospf6_interface *)ifp->info;
1799 if (oi == NULL)
1800 oi = ospf6_interface_create(ifp);
1801 assert(oi);
1802
d23d6de8
QY
1803 oi->transdelay = strmatch(argv[0]->text, "no")
1804 ? OSPF6_INTERFACE_TRANSDELAY
1805 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1806 return CMD_SUCCESS;
718e3744 1807}
1808
d23d6de8
QY
1809ALIAS (ipv6_ospf6_transmitdelay,
1810 no_ipv6_ospf6_transmitdelay_cmd,
1811 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1812 NO_STR
1813 IP6_STR
1814 OSPF6_STR
1815 "Link state transmit delay\n"
1816 SECONDS_STR)
1817
718e3744 1818/* interface variable set command */
1819DEFUN (ipv6_ospf6_retransmitinterval,
1820 ipv6_ospf6_retransmitinterval_cmd,
6147e2c6 1821 "ipv6 ospf6 retransmit-interval (1-65535)",
718e3744 1822 IP6_STR
1823 OSPF6_STR
1824 "Time between retransmitting lost link state advertisements\n"
d23d6de8 1825 SECONDS_STR)
718e3744 1826{
d62a17ae 1827 VTY_DECLVAR_CONTEXT(interface, ifp);
1828 int idx_number = 3;
1829 struct ospf6_interface *oi;
1830 assert(ifp);
1831
1832 oi = (struct ospf6_interface *)ifp->info;
1833 if (oi == NULL)
1834 oi = ospf6_interface_create(ifp);
1835 assert(oi);
1836
d23d6de8
QY
1837 oi->rxmt_interval = strmatch(argv[0]->text, "no")
1838 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1839 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1840 return CMD_SUCCESS;
718e3744 1841}
1842
d23d6de8
QY
1843ALIAS (ipv6_ospf6_retransmitinterval,
1844 no_ipv6_ospf6_retransmitinterval_cmd,
1845 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1846 NO_STR
1847 IP6_STR
1848 OSPF6_STR
1849 "Time between retransmitting lost link state advertisements\n"
1850 SECONDS_STR)
1851
718e3744 1852/* interface variable set command */
1853DEFUN (ipv6_ospf6_priority,
1854 ipv6_ospf6_priority_cmd,
6147e2c6 1855 "ipv6 ospf6 priority (0-255)",
718e3744 1856 IP6_STR
1857 OSPF6_STR
1858 "Router priority\n"
d23d6de8 1859 "Priority value\n")
718e3744 1860{
d62a17ae 1861 VTY_DECLVAR_CONTEXT(interface, ifp);
1862 int idx_number = 3;
1863 struct ospf6_interface *oi;
1864 assert(ifp);
718e3744 1865
d62a17ae 1866 oi = (struct ospf6_interface *)ifp->info;
1867 if (oi == NULL)
1868 oi = ospf6_interface_create(ifp);
1869 assert(oi);
508e53e2 1870
d23d6de8
QY
1871 oi->priority = strmatch(argv[0]->text, "no")
1872 ? OSPF6_INTERFACE_PRIORITY
1873 : strtoul(argv[idx_number]->arg, NULL, 10);
718e3744 1874
9d303b37
DL
1875 if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
1876 || oi->state == OSPF6_INTERFACE_BDR
1877 || oi->state == OSPF6_INTERFACE_DR))
d62a17ae 1878 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 1879
d62a17ae 1880 return CMD_SUCCESS;
718e3744 1881}
1882
d23d6de8
QY
1883ALIAS (ipv6_ospf6_priority,
1884 no_ipv6_ospf6_priority_cmd,
1885 "no ipv6 ospf6 priority [(0-255)]",
1886 NO_STR
1887 IP6_STR
1888 OSPF6_STR
1889 "Router priority\n"
1890 "Priority value\n")
1891
718e3744 1892DEFUN (ipv6_ospf6_instance,
1893 ipv6_ospf6_instance_cmd,
6147e2c6 1894 "ipv6 ospf6 instance-id (0-255)",
718e3744 1895 IP6_STR
1896 OSPF6_STR
508e53e2 1897 "Instance ID for this interface\n"
d23d6de8 1898 "Instance ID value\n")
718e3744 1899{
d62a17ae 1900 VTY_DECLVAR_CONTEXT(interface, ifp);
1901 int idx_number = 3;
1902 struct ospf6_interface *oi;
1903 assert(ifp);
1904
1905 oi = (struct ospf6_interface *)ifp->info;
1906 if (oi == NULL)
1907 oi = ospf6_interface_create(ifp);
1908 assert(oi);
1909
d23d6de8
QY
1910 oi->instance_id = strmatch(argv[0]->text, "no")
1911 ? OSPF6_INTERFACE_INSTANCE_ID
1912 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1913 return CMD_SUCCESS;
718e3744 1914}
1915
d23d6de8
QY
1916ALIAS (ipv6_ospf6_instance,
1917 no_ipv6_ospf6_instance_cmd,
1918 "no ipv6 ospf6 instance-id [(0-255)]",
1919 NO_STR
1920 IP6_STR
1921 OSPF6_STR
1922 "Instance ID for this interface\n"
1923 "Instance ID value\n")
1924
718e3744 1925DEFUN (ipv6_ospf6_passive,
1926 ipv6_ospf6_passive_cmd,
1927 "ipv6 ospf6 passive",
1928 IP6_STR
1929 OSPF6_STR
99a522c7 1930 "Passive interface; no adjacency will be formed on this interface\n"
718e3744 1931 )
1932{
d62a17ae 1933 VTY_DECLVAR_CONTEXT(interface, ifp);
1934 struct ospf6_interface *oi;
1935 struct listnode *node, *nnode;
1936 struct ospf6_neighbor *on;
718e3744 1937
d62a17ae 1938 assert(ifp);
718e3744 1939
d62a17ae 1940 oi = (struct ospf6_interface *)ifp->info;
1941 if (oi == NULL)
1942 oi = ospf6_interface_create(ifp);
1943 assert(oi);
718e3744 1944
d62a17ae 1945 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1946 THREAD_OFF(oi->thread_send_hello);
f80003b0 1947 THREAD_OFF(oi->thread_sso);
508e53e2 1948
d62a17ae 1949 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1950 THREAD_OFF(on->inactivity_timer);
1951 thread_add_event(master, inactivity_timer, on, 0, NULL);
1952 }
718e3744 1953
d62a17ae 1954 return CMD_SUCCESS;
718e3744 1955}
1956
1957DEFUN (no_ipv6_ospf6_passive,
1958 no_ipv6_ospf6_passive_cmd,
1959 "no ipv6 ospf6 passive",
1960 NO_STR
1961 IP6_STR
1962 OSPF6_STR
1963 "passive interface: No Adjacency will be formed on this I/F\n"
1964 )
1965{
d62a17ae 1966 VTY_DECLVAR_CONTEXT(interface, ifp);
1967 struct ospf6_interface *oi;
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 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1976 THREAD_OFF(oi->thread_send_hello);
f80003b0 1977 THREAD_OFF(oi->thread_sso);
cb978d68 1978
1979 /* don't send hellos over loopback interface */
1980 if (!if_is_loopback(oi->interface))
1981 thread_add_event(master, ospf6_hello_send, oi, 0,
1982 &oi->thread_send_hello);
718e3744 1983
d62a17ae 1984 return CMD_SUCCESS;
718e3744 1985}
1986
d42306d9
DT
1987DEFUN (ipv6_ospf6_mtu_ignore,
1988 ipv6_ospf6_mtu_ignore_cmd,
1989 "ipv6 ospf6 mtu-ignore",
1990 IP6_STR
1991 OSPF6_STR
99a522c7 1992 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1993 )
1994{
d62a17ae 1995 VTY_DECLVAR_CONTEXT(interface, ifp);
1996 struct ospf6_interface *oi;
1997 assert(ifp);
d42306d9 1998
d62a17ae 1999 oi = (struct ospf6_interface *)ifp->info;
2000 if (oi == NULL)
2001 oi = ospf6_interface_create(ifp);
2002 assert(oi);
d42306d9 2003
d62a17ae 2004 oi->mtu_ignore = 1;
d42306d9 2005
d62a17ae 2006 return CMD_SUCCESS;
d42306d9
DT
2007}
2008
2009DEFUN (no_ipv6_ospf6_mtu_ignore,
2010 no_ipv6_ospf6_mtu_ignore_cmd,
2011 "no ipv6 ospf6 mtu-ignore",
2012 NO_STR
2013 IP6_STR
2014 OSPF6_STR
99a522c7 2015 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
2016 )
2017{
d62a17ae 2018 VTY_DECLVAR_CONTEXT(interface, ifp);
2019 struct ospf6_interface *oi;
2020 assert(ifp);
d42306d9 2021
d62a17ae 2022 oi = (struct ospf6_interface *)ifp->info;
2023 if (oi == NULL)
2024 oi = ospf6_interface_create(ifp);
2025 assert(oi);
d42306d9 2026
d62a17ae 2027 oi->mtu_ignore = 0;
d42306d9 2028
d62a17ae 2029 return CMD_SUCCESS;
d42306d9
DT
2030}
2031
718e3744 2032DEFUN (ipv6_ospf6_advertise_prefix_list,
2033 ipv6_ospf6_advertise_prefix_list_cmd,
2034 "ipv6 ospf6 advertise prefix-list WORD",
2035 IP6_STR
2036 OSPF6_STR
2037 "Advertising options\n"
2038 "Filter prefix using prefix-list\n"
2039 "Prefix list name\n"
2040 )
2041{
d62a17ae 2042 VTY_DECLVAR_CONTEXT(interface, ifp);
2043 int idx_word = 4;
2044 struct ospf6_interface *oi;
2045 assert(ifp);
2046
2047 oi = (struct ospf6_interface *)ifp->info;
2048 if (oi == NULL)
2049 oi = ospf6_interface_create(ifp);
2050 assert(oi);
2051
2052 if (oi->plist_name)
2053 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2054 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
2055
2056 ospf6_interface_connected_route_update(oi->interface);
2057
2058 if (oi->area) {
2059 OSPF6_LINK_LSA_SCHEDULE(oi);
2060 if (oi->state == OSPF6_INTERFACE_DR) {
2061 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2062 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2063 }
2064 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2065 }
2066
2067 return CMD_SUCCESS;
718e3744 2068}
2069
2070DEFUN (no_ipv6_ospf6_advertise_prefix_list,
2071 no_ipv6_ospf6_advertise_prefix_list_cmd,
d23d6de8 2072 "no ipv6 ospf6 advertise prefix-list [WORD]",
718e3744 2073 NO_STR
2074 IP6_STR
2075 OSPF6_STR
2076 "Advertising options\n"
2077 "Filter prefix using prefix-list\n"
d23d6de8 2078 "Prefix list name\n")
718e3744 2079{
d62a17ae 2080 VTY_DECLVAR_CONTEXT(interface, ifp);
2081 struct ospf6_interface *oi;
2082 assert(ifp);
2083
2084 oi = (struct ospf6_interface *)ifp->info;
2085 if (oi == NULL)
2086 oi = ospf6_interface_create(ifp);
2087 assert(oi);
2088
d23d6de8 2089 if (oi->plist_name)
d62a17ae 2090 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
d62a17ae 2091
2092 ospf6_interface_connected_route_update(oi->interface);
2093
2094 if (oi->area) {
2095 OSPF6_LINK_LSA_SCHEDULE(oi);
2096 if (oi->state == OSPF6_INTERFACE_DR) {
2097 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2098 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2099 }
2100 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2101 }
2102
2103 return CMD_SUCCESS;
718e3744 2104}
2105
c5926a92
DD
2106DEFUN (ipv6_ospf6_network,
2107 ipv6_ospf6_network_cmd,
6147e2c6 2108 "ipv6 ospf6 network <broadcast|point-to-point>",
c5926a92
DD
2109 IP6_STR
2110 OSPF6_STR
99a522c7 2111 "Network type\n"
b2d4d039 2112 "Specify OSPF6 broadcast network\n"
c5926a92
DD
2113 "Specify OSPF6 point-to-point network\n"
2114 )
2115{
d62a17ae 2116 VTY_DECLVAR_CONTEXT(interface, ifp);
2117 int idx_network = 3;
2118 struct ospf6_interface *oi;
2119 assert(ifp);
2120
2121 oi = (struct ospf6_interface *)ifp->info;
2122 if (oi == NULL) {
2123 oi = ospf6_interface_create(ifp);
2124 }
2125 assert(oi);
2126
5aeb4f3c
DL
2127 oi->type_cfg = true;
2128
d62a17ae 2129 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
2130 if (oi->type == OSPF_IFTYPE_BROADCAST)
2131 return CMD_SUCCESS;
2132
2133 oi->type = OSPF_IFTYPE_BROADCAST;
2134 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
2135 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
2136 return CMD_SUCCESS;
2137 }
2138 oi->type = OSPF_IFTYPE_POINTOPOINT;
c5926a92 2139 }
c5926a92 2140
d62a17ae 2141 /* Reset the interface */
849576ee
RZ
2142 thread_execute(master, interface_down, oi, 0);
2143 thread_execute(master, interface_up, oi, 0);
c5926a92 2144
d62a17ae 2145 return CMD_SUCCESS;
c5926a92
DD
2146}
2147
2148DEFUN (no_ipv6_ospf6_network,
2149 no_ipv6_ospf6_network_cmd,
32573073 2150 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
c5926a92
DD
2151 NO_STR
2152 IP6_STR
2153 OSPF6_STR
32573073
QY
2154 "Set default network type\n"
2155 "Specify OSPF6 broadcast network\n"
2156 "Specify OSPF6 point-to-point network\n")
c5926a92 2157{
d62a17ae 2158 VTY_DECLVAR_CONTEXT(interface, ifp);
2159 struct ospf6_interface *oi;
2160 int type;
c5926a92 2161
d62a17ae 2162 assert(ifp);
c5926a92 2163
d62a17ae 2164 oi = (struct ospf6_interface *)ifp->info;
2165 if (oi == NULL) {
2166 return CMD_SUCCESS;
2167 }
c5926a92 2168
5aeb4f3c
DL
2169 oi->type_cfg = false;
2170
d62a17ae 2171 type = ospf6_default_iftype(ifp);
2172 if (oi->type == type) {
2173 return CMD_SUCCESS;
2174 }
2175 oi->type = type;
c5926a92 2176
d62a17ae 2177 /* Reset the interface */
849576ee
RZ
2178 thread_execute(master, interface_down, oi, 0);
2179 thread_execute(master, interface_up, oi, 0);
c5926a92 2180
d62a17ae 2181 return CMD_SUCCESS;
c5926a92
DD
2182}
2183
d62a17ae 2184static int config_write_ospf6_interface(struct vty *vty)
718e3744 2185{
f4e14fdb 2186 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 2187 struct ospf6_interface *oi;
2188 struct interface *ifp;
2189
451fda4f 2190 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 2191 oi = (struct ospf6_interface *)ifp->info;
2192 if (oi == NULL)
2193 continue;
2194
a8b828f3 2195 vty_frame(vty, "interface %s\n", oi->interface->name);
d62a17ae 2196
2197 if (ifp->desc)
2198 vty_out(vty, " description %s\n", ifp->desc);
2199 if (oi->c_ifmtu)
2200 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
2201
2202 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
2203 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
2204
2205 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
2206 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
2207 oi->hello_interval);
2208
2209 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
2210 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
2211 oi->dead_interval);
2212
2213 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
2214 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
2215 oi->rxmt_interval);
2216
2217 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
2218 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
2219
2220 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
2221 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
2222 oi->transdelay);
2223
2224 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
2225 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
2226 oi->instance_id);
2227
2228 if (oi->plist_name)
2229 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
2230 oi->plist_name);
2231
2232 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
2233 vty_out(vty, " ipv6 ospf6 passive\n");
2234
2235 if (oi->mtu_ignore)
2236 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
2237
5aeb4f3c
DL
2238 if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
2239 vty_out(vty, " ipv6 ospf6 network point-to-point\n");
2240 else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
2241 vty_out(vty, " ipv6 ospf6 network broadcast\n");
d62a17ae 2242
2243 ospf6_bfd_write_config(vty, oi);
2244
a8b828f3 2245 vty_endframe(vty, "!\n");
d62a17ae 2246 }
2247 return 0;
718e3744 2248}
2249
612c2c15 2250static int config_write_ospf6_interface(struct vty *vty);
d62a17ae 2251static struct cmd_node interface_node = {
f4b8291f 2252 .name = "interface",
62b346ee 2253 .node = INTERFACE_NODE,
24389580 2254 .parent_node = CONFIG_NODE,
62b346ee 2255 .prompt = "%s(config-if)# ",
612c2c15 2256 .config_write = config_write_ospf6_interface,
718e3744 2257};
2258
138c5a74
DS
2259static int ospf6_ifp_create(struct interface *ifp)
2260{
ef7bd2a3
DS
2261 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2262 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
2263 ifp->ifindex, ifp->mtu6);
2264 ospf6_interface_if_add(ifp);
2265
138c5a74
DS
2266 return 0;
2267}
2268
2269static int ospf6_ifp_up(struct interface *ifp)
2270{
ddbf3e60
DS
2271 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2272 zlog_debug(
3efd0893 2273 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
ddbf3e60
DS
2274 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2275 ifp->metric, ifp->mtu6, ifp->bandwidth);
2276
2277 ospf6_interface_state_update(ifp);
2278
138c5a74
DS
2279 return 0;
2280}
2281
2282static int ospf6_ifp_down(struct interface *ifp)
2283{
b0b69e59
DS
2284 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2285 zlog_debug(
3efd0893 2286 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
b0b69e59
DS
2287 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2288 ifp->metric, ifp->mtu6, ifp->bandwidth);
2289
2290 ospf6_interface_state_update(ifp);
2291
138c5a74
DS
2292 return 0;
2293}
2294
2295static int ospf6_ifp_destroy(struct interface *ifp)
2296{
3c3c3252
DS
2297 if (if_is_up(ifp))
2298 zlog_warn("Zebra: got delete of %s, but interface is still up",
2299 ifp->name);
2300
2301 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2302 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2303 ifp->name, ifp->ifindex, ifp->mtu6);
2304
138c5a74
DS
2305 return 0;
2306}
2307
d62a17ae 2308void ospf6_interface_init(void)
718e3744 2309{
d62a17ae 2310 /* Install interface node. */
612c2c15 2311 install_node(&interface_node);
d62a17ae 2312 if_cmd_init();
138c5a74
DS
2313 if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
2314 ospf6_ifp_down, ospf6_ifp_destroy);
d62a17ae 2315
2316 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
2317 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
2318 install_element(VIEW_NODE,
2319 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
996c9314 2320 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
d62a17ae 2321
2322 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
2323 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
2324 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
2325 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
d23d6de8 2326
d62a17ae 2327 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
2328 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
2329 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
2330 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
2331 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
2332 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
d23d6de8
QY
2333 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
2334 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
2335 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
2336 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
2337 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
2338 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
d62a17ae 2339
2340 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
2341 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
2342
2343 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
2344 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
2345
2346 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
2347 install_element(INTERFACE_NODE,
2348 &no_ipv6_ospf6_advertise_prefix_list_cmd);
2349
2350 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
2351 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
2352
2353 /* reference bandwidth commands */
2354 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
2355 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
508e53e2 2356}
2357
a1b11f9b 2358/* Clear the specified interface structure */
d62a17ae 2359static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
a1b11f9b 2360{
d62a17ae 2361 struct ospf6_interface *oi;
a1b11f9b 2362
d62a17ae 2363 if (!if_is_operative(ifp))
2364 return;
a1b11f9b 2365
d62a17ae 2366 if (ifp->info == NULL)
2367 return;
a1b11f9b 2368
d62a17ae 2369 oi = (struct ospf6_interface *)ifp->info;
a1b11f9b 2370
d62a17ae 2371 if (IS_OSPF6_DEBUG_INTERFACE)
2372 zlog_debug("Interface %s: clear by reset", ifp->name);
a1b11f9b 2373
d62a17ae 2374 /* Reset the interface */
849576ee
RZ
2375 thread_execute(master, interface_down, oi, 0);
2376 thread_execute(master, interface_up, oi, 0);
a1b11f9b
DS
2377}
2378
2379/* Clear interface */
2380DEFUN (clear_ipv6_ospf6_interface,
2381 clear_ipv6_ospf6_interface_cmd,
2382 "clear ipv6 ospf6 interface [IFNAME]",
2383 CLEAR_STR
2384 IP6_STR
2385 OSPF6_STR
2386 INTERFACE_STR
2387 IFNAME_STR
2388 )
2389{
f4e14fdb 2390 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 2391 int idx_ifname = 4;
2392 struct interface *ifp;
d62a17ae 2393
2394 if (argc == 4) /* Clear all the ospfv3 interfaces. */
2395 {
451fda4f 2396 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 2397 ospf6_interface_clear(vty, ifp);
2398 } else /* Interface name is specified. */
2399 {
2400 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
a36898e7 2401 VRF_DEFAULT))
d62a17ae 2402 == NULL) {
2403 vty_out(vty, "No such Interface: %s\n",
2404 argv[idx_ifname]->arg);
2405 return CMD_WARNING;
2406 }
2407 ospf6_interface_clear(vty, ifp);
2408 }
2409
2410 return CMD_SUCCESS;
a1b11f9b
DS
2411}
2412
d62a17ae 2413void install_element_ospf6_clear_interface(void)
a1b11f9b 2414{
d62a17ae 2415 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
a1b11f9b
DS
2416}
2417
508e53e2 2418DEFUN (debug_ospf6_interface,
2419 debug_ospf6_interface_cmd,
2420 "debug ospf6 interface",
2421 DEBUG_STR
2422 OSPF6_STR
2423 "Debug OSPFv3 Interface\n"
2424 )
2425{
d62a17ae 2426 OSPF6_DEBUG_INTERFACE_ON();
2427 return CMD_SUCCESS;
508e53e2 2428}
2429
2430DEFUN (no_debug_ospf6_interface,
2431 no_debug_ospf6_interface_cmd,
2432 "no debug ospf6 interface",
2433 NO_STR
2434 DEBUG_STR
2435 OSPF6_STR
2436 "Debug OSPFv3 Interface\n"
2437 )
2438{
d62a17ae 2439 OSPF6_DEBUG_INTERFACE_OFF();
2440 return CMD_SUCCESS;
508e53e2 2441}
2442
d62a17ae 2443int config_write_ospf6_debug_interface(struct vty *vty)
508e53e2 2444{
d62a17ae 2445 if (IS_OSPF6_DEBUG_INTERFACE)
2446 vty_out(vty, "debug ospf6 interface\n");
2447 return 0;
508e53e2 2448}
2449
d62a17ae 2450void install_element_ospf6_debug_interface(void)
508e53e2 2451{
d62a17ae 2452 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2453 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2454 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2455 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
718e3744 2456}