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