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