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