]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_interface.c
ospf6d: fix mistaken if_is_* instead of oi->type
[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
9f5dc319 180 oi = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
d62a17ae 181
d62a17ae 182 oi->area = (struct ospf6_area *)NULL;
183 oi->neighbor_list = list_new();
184 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
185 oi->linklocal_addr = (struct in6_addr *)NULL;
186 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
187 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
188 oi->priority = OSPF6_INTERFACE_PRIORITY;
189
190 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
191 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
192 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
193 oi->type = ospf6_default_iftype(ifp);
194 oi->state = OSPF6_INTERFACE_DOWN;
195 oi->flag = 0;
196 oi->mtu_ignore = 0;
197 oi->c_ifmtu = 0;
198
199 /* Try to adjust I/O buffer size with IfMtu */
200 oi->ifmtu = ifp->mtu6;
201 iobuflen = ospf6_iobuf_size(ifp->mtu6);
202 if (oi->ifmtu > iobuflen) {
203 if (IS_OSPF6_DEBUG_INTERFACE)
204 zlog_debug(
205 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
206 ifp->name, iobuflen);
207 oi->ifmtu = iobuflen;
208 }
209
210 QOBJ_REG(oi, ospf6_interface);
211
212 oi->lsupdate_list = ospf6_lsdb_create(oi);
213 oi->lsack_list = ospf6_lsdb_create(oi);
214 oi->lsdb = ospf6_lsdb_create(oi);
215 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
216 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
217 oi->lsdb_self = ospf6_lsdb_create(oi);
218
219 oi->route_connected =
220 OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
221 oi->route_connected->scope = oi;
222
223 /* link both */
224 oi->interface = ifp;
225 ifp->info = oi;
226
227 /* Compute cost. */
228 oi->cost = ospf6_interface_get_cost(oi);
229
230 return oi;
718e3744 231}
232
d62a17ae 233void ospf6_interface_delete(struct ospf6_interface *oi)
718e3744 234{
d62a17ae 235 struct listnode *node, *nnode;
236 struct ospf6_neighbor *on;
237
238 QOBJ_UNREG(oi);
718e3744 239
d62a17ae 240 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
241 ospf6_neighbor_delete(on);
ae19c240 242
6a154c88 243 list_delete(&oi->neighbor_list);
718e3744 244
d62a17ae 245 THREAD_OFF(oi->thread_send_hello);
246 THREAD_OFF(oi->thread_send_lsupdate);
247 THREAD_OFF(oi->thread_send_lsack);
f80003b0 248 THREAD_OFF(oi->thread_sso);
508e53e2 249
d62a17ae 250 ospf6_lsdb_remove_all(oi->lsdb);
251 ospf6_lsdb_remove_all(oi->lsupdate_list);
252 ospf6_lsdb_remove_all(oi->lsack_list);
508e53e2 253
d62a17ae 254 ospf6_lsdb_delete(oi->lsdb);
255 ospf6_lsdb_delete(oi->lsdb_self);
6452df09 256
d62a17ae 257 ospf6_lsdb_delete(oi->lsupdate_list);
258 ospf6_lsdb_delete(oi->lsack_list);
718e3744 259
d62a17ae 260 ospf6_route_table_delete(oi->route_connected);
718e3744 261
d62a17ae 262 /* cut link */
263 oi->interface->info = NULL;
718e3744 264
d62a17ae 265 /* plist_name */
266 if (oi->plist_name)
267 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
508e53e2 268
d62a17ae 269 ospf6_bfd_info_free(&(oi->bfd_info));
7f342629 270
22b982df
PG
271 /* disable from area list if possible */
272 ospf6_area_interface_delete(oi);
273
d62a17ae 274 XFREE(MTYPE_OSPF6_IF, oi);
508e53e2 275}
276
d62a17ae 277void ospf6_interface_enable(struct ospf6_interface *oi)
508e53e2 278{
d62a17ae 279 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
280 ospf6_interface_state_update(oi->interface);
508e53e2 281}
282
d62a17ae 283void ospf6_interface_disable(struct ospf6_interface *oi)
508e53e2 284{
d62a17ae 285 SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
508e53e2 286
d62a17ae 287 thread_execute(master, interface_down, oi, 0);
508e53e2 288
d62a17ae 289 ospf6_lsdb_remove_all(oi->lsdb);
290 ospf6_lsdb_remove_all(oi->lsdb_self);
291 ospf6_lsdb_remove_all(oi->lsupdate_list);
292 ospf6_lsdb_remove_all(oi->lsack_list);
508e53e2 293
d62a17ae 294 THREAD_OFF(oi->thread_send_hello);
295 THREAD_OFF(oi->thread_send_lsupdate);
296 THREAD_OFF(oi->thread_send_lsack);
f80003b0 297 THREAD_OFF(oi->thread_sso);
d9628728 298
d62a17ae 299 THREAD_OFF(oi->thread_network_lsa);
300 THREAD_OFF(oi->thread_link_lsa);
301 THREAD_OFF(oi->thread_intra_prefix_lsa);
76249532 302 THREAD_OFF(oi->thread_as_extern_lsa);
718e3744 303}
304
305static struct in6_addr *
d62a17ae 306ospf6_interface_get_linklocal_address(struct interface *ifp)
718e3744 307{
d62a17ae 308 struct listnode *n;
309 struct connected *c;
310 struct in6_addr *l = (struct in6_addr *)NULL;
311
312 /* for each connected address */
313 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
314 /* if family not AF_INET6, ignore */
315 if (c->address->family != AF_INET6)
316 continue;
317
318 /* linklocal scope check */
319 if (IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
320 l = &c->address->u.prefix6;
321 }
322 return l;
718e3744 323}
324
d62a17ae 325void ospf6_interface_if_add(struct interface *ifp)
718e3744 326{
d62a17ae 327 struct ospf6_interface *oi;
328 unsigned int iobuflen;
329
330 oi = (struct ospf6_interface *)ifp->info;
331 if (oi == NULL)
332 return;
333
334 /* Try to adjust I/O buffer size with IfMtu */
335 if (oi->ifmtu == 0)
336 oi->ifmtu = ifp->mtu6;
337 iobuflen = ospf6_iobuf_size(ifp->mtu6);
338 if (oi->ifmtu > iobuflen) {
339 if (IS_OSPF6_DEBUG_INTERFACE)
340 zlog_debug(
341 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
342 ifp->name, iobuflen);
343 oi->ifmtu = iobuflen;
344 }
345
346 /* interface start */
347 ospf6_interface_state_update(oi->interface);
718e3744 348}
349
d62a17ae 350void ospf6_interface_state_update(struct interface *ifp)
718e3744 351{
d62a17ae 352 struct ospf6_interface *oi;
353 unsigned int iobuflen;
354
355 oi = (struct ospf6_interface *)ifp->info;
356 if (oi == NULL)
357 return;
d62a17ae 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 */
e5973353 775 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
d62a17ae 776 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
777 } else if (oi->priority == 0)
778 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
779 else {
780 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
781 thread_add_timer(master, wait_timer, oi, oi->dead_interval,
782 NULL);
783 }
784
785 return 0;
718e3744 786}
787
d62a17ae 788int wait_timer(struct thread *thread)
718e3744 789{
d62a17ae 790 struct ospf6_interface *oi;
718e3744 791
d62a17ae 792 oi = (struct ospf6_interface *)THREAD_ARG(thread);
793 assert(oi && oi->interface);
718e3744 794
d62a17ae 795 if (IS_OSPF6_DEBUG_INTERFACE)
796 zlog_debug("Interface Event %s: [WaitTimer]",
797 oi->interface->name);
718e3744 798
d62a17ae 799 if (oi->state == OSPF6_INTERFACE_WAITING)
800 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 801
d62a17ae 802 return 0;
718e3744 803}
804
d62a17ae 805int backup_seen(struct thread *thread)
508e53e2 806{
d62a17ae 807 struct ospf6_interface *oi;
508e53e2 808
d62a17ae 809 oi = (struct ospf6_interface *)THREAD_ARG(thread);
810 assert(oi && oi->interface);
508e53e2 811
d62a17ae 812 if (IS_OSPF6_DEBUG_INTERFACE)
813 zlog_debug("Interface Event %s: [BackupSeen]",
814 oi->interface->name);
508e53e2 815
d62a17ae 816 if (oi->state == OSPF6_INTERFACE_WAITING)
817 ospf6_interface_state_change(dr_election(oi), oi);
508e53e2 818
d62a17ae 819 return 0;
508e53e2 820}
821
d62a17ae 822int neighbor_change(struct thread *thread)
718e3744 823{
d62a17ae 824 struct ospf6_interface *oi;
508e53e2 825
d62a17ae 826 oi = (struct ospf6_interface *)THREAD_ARG(thread);
827 assert(oi && oi->interface);
508e53e2 828
d62a17ae 829 if (IS_OSPF6_DEBUG_INTERFACE)
830 zlog_debug("Interface Event %s: [NeighborChange]",
831 oi->interface->name);
508e53e2 832
d62a17ae 833 if (oi->state == OSPF6_INTERFACE_DROTHER
834 || oi->state == OSPF6_INTERFACE_BDR
835 || oi->state == OSPF6_INTERFACE_DR)
836 ospf6_interface_state_change(dr_election(oi), oi);
508e53e2 837
d62a17ae 838 return 0;
718e3744 839}
840
d62a17ae 841int interface_down(struct thread *thread)
718e3744 842{
d62a17ae 843 struct ospf6_interface *oi;
844 struct listnode *node, *nnode;
845 struct ospf6_neighbor *on;
508e53e2 846
d62a17ae 847 oi = (struct ospf6_interface *)THREAD_ARG(thread);
848 assert(oi && oi->interface);
508e53e2 849
d62a17ae 850 if (IS_OSPF6_DEBUG_INTERFACE)
851 zlog_debug("Interface Event %s: [InterfaceDown]",
852 oi->interface->name);
508e53e2 853
d62a17ae 854 /* Stop Hellos */
855 THREAD_OFF(oi->thread_send_hello);
424cc3bd 856
f80003b0
RZ
857 /* Stop trying to set socket options. */
858 THREAD_OFF(oi->thread_sso);
859
d62a17ae 860 /* Leave AllSPFRouters */
861 if (oi->state > OSPF6_INTERFACE_DOWN)
862 ospf6_sso(oi->interface->ifindex, &allspfrouters6,
863 IPV6_LEAVE_GROUP);
508e53e2 864
d62a17ae 865 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
508e53e2 866
d62a17ae 867 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
868 ospf6_neighbor_delete(on);
508e53e2 869
d62a17ae 870 list_delete_all_node(oi->neighbor_list);
871
872 /* When interface state is reset, also reset information about
873 * DR election, as it is no longer valid. */
874 oi->drouter = oi->prev_drouter = htonl(0);
875 oi->bdrouter = oi->prev_bdrouter = htonl(0);
876 return 0;
718e3744 877}
878
6b0655a2 879
718e3744 880/* show specified interface structure */
d62a17ae 881static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
718e3744 882{
d62a17ae 883 struct ospf6_interface *oi;
884 struct connected *c;
885 struct prefix *p;
886 struct listnode *i;
887 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
d62a17ae 888 const char *type;
889 struct timeval res, now;
890 char duration[32];
891 struct ospf6_lsa *lsa;
892
893 /* check physical interface type */
894 if (if_is_loopback(ifp))
895 type = "LOOPBACK";
896 else if (if_is_broadcast(ifp))
897 type = "BROADCAST";
898 else if (if_is_pointopoint(ifp))
899 type = "POINTOPOINT";
900 else
901 type = "UNKNOWN";
902
903 vty_out(vty, "%s is %s, type %s\n", ifp->name,
246879c3 904 (if_is_operative(ifp) ? "up" : "down"), type);
d62a17ae 905 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
906
907 if (ifp->info == NULL) {
908 vty_out(vty, " OSPF not enabled on this interface\n");
909 return 0;
910 } else
911 oi = (struct ospf6_interface *)ifp->info;
912
913 vty_out(vty, " Internet Address:\n");
914
915 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
916 p = c->address;
917 prefix2str(p, strbuf, sizeof(strbuf));
918 switch (p->family) {
919 case AF_INET:
920 vty_out(vty, " inet : %s\n", strbuf);
921 break;
922 case AF_INET6:
923 vty_out(vty, " inet6: %s\n", strbuf);
924 break;
925 default:
926 vty_out(vty, " ??? : %s\n", strbuf);
927 break;
928 }
929 }
930
931 if (oi->area) {
932 vty_out(vty,
933 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
934 oi->instance_id, oi->ifmtu, ifp->mtu6);
935 vty_out(vty, " MTU mismatch detection: %s\n",
936 oi->mtu_ignore ? "disabled" : "enabled");
937 inet_ntop(AF_INET, &oi->area->area_id, strbuf, sizeof(strbuf));
938 vty_out(vty, " Area ID %s, Cost %u\n", strbuf, oi->cost);
939 } else
940 vty_out(vty, " Not Attached to Area\n");
941
942 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
943 ospf6_interface_state_str[oi->state], oi->transdelay,
944 oi->priority);
945 vty_out(vty, " Timer intervals configured:\n");
946 vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
947 oi->hello_interval, oi->dead_interval, oi->rxmt_interval);
948
949 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
950 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
951 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
952
953 vty_out(vty, " Number of I/F scoped LSAs is %u\n", oi->lsdb->count);
954
955 monotime(&now);
956
957 timerclear(&res);
958 if (oi->thread_send_lsupdate)
959 timersub(&oi->thread_send_lsupdate->u.sands, &now, &res);
960 timerstring(&res, duration, sizeof(duration));
961 vty_out(vty,
962 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
963 oi->lsupdate_list->count, duration,
964 (oi->thread_send_lsupdate ? "on" : "off"));
965 for (ALL_LSDB(oi->lsupdate_list, lsa))
966 vty_out(vty, " %s\n", lsa->name);
967
968 timerclear(&res);
969 if (oi->thread_send_lsack)
970 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
971 timerstring(&res, duration, sizeof(duration));
972 vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
973 oi->lsack_list->count, duration,
974 (oi->thread_send_lsack ? "on" : "off"));
975 for (ALL_LSDB(oi->lsack_list, lsa))
976 vty_out(vty, " %s\n", lsa->name);
977 ospf6_bfd_show_info(vty, oi->bfd_info, 1);
978 return 0;
718e3744 979}
980
981/* show interface */
982DEFUN (show_ipv6_ospf6_interface,
983 show_ipv6_ospf6_interface_ifname_cmd,
1d68dbfe 984 "show ipv6 ospf6 interface [IFNAME]",
718e3744 985 SHOW_STR
986 IP6_STR
987 OSPF6_STR
988 INTERFACE_STR
1d68dbfe 989 IFNAME_STR)
718e3744 990{
f4e14fdb 991 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 992 int idx_ifname = 4;
993 struct interface *ifp;
d62a17ae 994
995 if (argc == 5) {
a36898e7 996 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 997 if (ifp == NULL) {
998 vty_out(vty, "No such Interface: %s\n",
999 argv[idx_ifname]->arg);
1000 return CMD_WARNING;
1001 }
1002 ospf6_interface_show(vty, ifp);
1003 } else {
451fda4f 1004 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1005 ospf6_interface_show(vty, ifp);
1006 }
1007
1008 return CMD_SUCCESS;
718e3744 1009}
1010
996c9314 1011static int ospf6_interface_show_traffic(struct vty *vty, uint32_t vrf_id,
43855e3d
CS
1012 struct interface *intf_ifp,
1013 int display_once)
1014{
1015 struct interface *ifp;
1016 struct vrf *vrf = NULL;
1017 struct ospf6_interface *oi = NULL;
1018
1019 vrf = vrf_lookup_by_id(vrf_id);
1020
1021 if (!display_once) {
1022 vty_out(vty, "\n");
996c9314
LB
1023 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1024 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1025 " LS-Ack");
43855e3d 1026 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
996c9314
LB
1027 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1028 " Rx/Tx");
43855e3d 1029 vty_out(vty,
996c9314 1030 "--------------------------------------------------------------------------------------------\n");
43855e3d
CS
1031 }
1032
1033 if (intf_ifp == NULL) {
1034 FOR_ALL_INTERFACES (vrf, ifp) {
1035 if (ifp->info)
1036 oi = (struct ospf6_interface *)ifp->info;
1037 else
1038 continue;
1039
1040 vty_out(vty,
996c9314 1041 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
43855e3d 1042 oi->interface->name, oi->hello_in,
996c9314
LB
1043 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1044 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1045 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
43855e3d
CS
1046 }
1047 } else {
1048 oi = intf_ifp->info;
1049 if (oi == NULL)
1050 return CMD_WARNING;
1051
1052 vty_out(vty,
1053 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
996c9314
LB
1054 oi->interface->name, oi->hello_in, oi->hello_out,
1055 oi->db_desc_in, oi->db_desc_out, oi->ls_req_in,
1056 oi->ls_req_out, oi->ls_upd_in, oi->ls_upd_out,
43855e3d
CS
1057 oi->ls_ack_in, oi->ls_ack_out);
1058 }
1059
1060 return CMD_SUCCESS;
1061}
1062
1063/* show interface */
1064DEFUN (show_ipv6_ospf6_interface_traffic,
1065 show_ipv6_ospf6_interface_traffic_cmd,
1066 "show ipv6 ospf6 interface traffic [IFNAME]",
1067 SHOW_STR
1068 IP6_STR
1069 OSPF6_STR
1070 INTERFACE_STR
1071 "Protocol Packet counters\n"
1072 IFNAME_STR)
1073{
1074 int idx_ifname = 0;
1075 int display_once = 0;
1076 char *intf_name = NULL;
1077 struct interface *ifp = NULL;
1078
1079 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1080 intf_name = argv[idx_ifname]->arg;
a36898e7 1081 ifp = if_lookup_by_name(intf_name, VRF_DEFAULT);
43855e3d 1082 if (ifp == NULL) {
996c9314 1083 vty_out(vty, "No such Interface: %s\n", intf_name);
43855e3d
CS
1084 return CMD_WARNING;
1085 }
1086 if (ifp->info == NULL) {
1087 vty_out(vty,
1088 " OSPF not enabled on this interface %s\n",
1089 intf_name);
1090 return 0;
1091 }
1092 }
1093
996c9314 1094 ospf6_interface_show_traffic(vty, VRF_DEFAULT, ifp, display_once);
43855e3d
CS
1095
1096
1097 return CMD_SUCCESS;
1098}
1099
1100
508e53e2 1101DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
1102 show_ipv6_ospf6_interface_ifname_prefix_cmd,
25ee05c9
RW
1103 "show ipv6 ospf6 interface IFNAME prefix\
1104 [<\
1105 detail\
1106 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1107 >]",
508e53e2 1108 SHOW_STR
1109 IP6_STR
1110 OSPF6_STR
1111 INTERFACE_STR
1112 IFNAME_STR
093d7a3a 1113 "Display connected prefixes to advertise\n"
25ee05c9 1114 "Display details of the prefixes\n"
093d7a3a
DW
1115 OSPF6_ROUTE_ADDRESS_STR
1116 OSPF6_ROUTE_PREFIX_STR
1117 OSPF6_ROUTE_MATCH_STR
1118 "Display details of the prefixes\n")
508e53e2 1119{
d62a17ae 1120 int idx_ifname = 4;
1121 int idx_prefix = 6;
1122 struct interface *ifp;
1123 struct ospf6_interface *oi;
1124
a36898e7 1125 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 1126 if (ifp == NULL) {
1127 vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
1128 return CMD_WARNING;
1129 }
1130
1131 oi = ifp->info;
1132 if (oi == NULL) {
1133 vty_out(vty, "OSPFv3 is not enabled on %s\n",
1134 argv[idx_ifname]->arg);
1135 return CMD_WARNING;
1136 }
1137
1138 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1139 oi->route_connected);
1140
1141 return CMD_SUCCESS;
508e53e2 1142}
1143
508e53e2 1144DEFUN (show_ipv6_ospf6_interface_prefix,
1145 show_ipv6_ospf6_interface_prefix_cmd,
25ee05c9
RW
1146 "show ipv6 ospf6 interface prefix\
1147 [<\
1148 detail\
1149 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1150 >]",
508e53e2 1151 SHOW_STR
1152 IP6_STR
1153 OSPF6_STR
1154 INTERFACE_STR
1155 "Display connected prefixes to advertise\n"
25ee05c9 1156 "Display details of the prefixes\n"
093d7a3a
DW
1157 OSPF6_ROUTE_ADDRESS_STR
1158 OSPF6_ROUTE_PREFIX_STR
1159 OSPF6_ROUTE_MATCH_STR
1160 "Display details of the prefixes\n")
508e53e2 1161{
f4e14fdb 1162 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1163 int idx_prefix = 5;
d62a17ae 1164 struct ospf6_interface *oi;
1165 struct interface *ifp;
1166
451fda4f 1167 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1168 oi = (struct ospf6_interface *)ifp->info;
1169 if (oi == NULL)
1170 continue;
1171
1172 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1173 oi->route_connected);
1174 }
508e53e2 1175
d62a17ae 1176 return CMD_SUCCESS;
508e53e2 1177}
1178
718e3744 1179/* interface variable set command */
b596c71e 1180DEFUN (ipv6_ospf6_ifmtu,
1181 ipv6_ospf6_ifmtu_cmd,
6147e2c6 1182 "ipv6 ospf6 ifmtu (1-65535)",
b596c71e 1183 IP6_STR
1184 OSPF6_STR
1185 "Interface MTU\n"
1186 "OSPFv3 Interface MTU\n"
1187 )
1188{
d62a17ae 1189 VTY_DECLVAR_CONTEXT(interface, ifp);
1190 int idx_number = 3;
1191 struct ospf6_interface *oi;
1192 unsigned int ifmtu, iobuflen;
1193 struct listnode *node, *nnode;
1194 struct ospf6_neighbor *on;
1195
1196 assert(ifp);
1197
1198 oi = (struct ospf6_interface *)ifp->info;
1199 if (oi == NULL)
1200 oi = ospf6_interface_create(ifp);
1201 assert(oi);
1202
1203 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1204
1205 if (oi->c_ifmtu == ifmtu)
1206 return CMD_SUCCESS;
1207
1208 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1209 vty_out(vty,
1210 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1211 ifp->name, ifp->mtu6);
1212 return CMD_WARNING_CONFIG_FAILED;
1213 }
1214
1215 if (oi->ifmtu < ifmtu) {
1216 iobuflen = ospf6_iobuf_size(ifmtu);
1217 if (iobuflen < ifmtu) {
1218 vty_out(vty,
1219 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1220 ifp->name, iobuflen);
1221 oi->ifmtu = oi->c_ifmtu = iobuflen;
1222 } else
1223 oi->ifmtu = oi->c_ifmtu = ifmtu;
1224 } else
1225 oi->ifmtu = oi->c_ifmtu = ifmtu;
1226
1227 /* re-establish adjacencies */
1228 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1229 THREAD_OFF(on->inactivity_timer);
1230 thread_add_event(master, inactivity_timer, on, 0, NULL);
1231 }
1232
1233 return CMD_SUCCESS;
b596c71e 1234}
1235
049207c3 1236DEFUN (no_ipv6_ospf6_ifmtu,
1237 no_ipv6_ospf6_ifmtu_cmd,
0c7ef48a 1238 "no ipv6 ospf6 ifmtu [(1-65535)]",
049207c3 1239 NO_STR
1240 IP6_STR
1241 OSPF6_STR
1242 "Interface MTU\n"
0c7ef48a 1243 "OSPFv3 Interface MTU\n"
049207c3 1244 )
1245{
d62a17ae 1246 VTY_DECLVAR_CONTEXT(interface, ifp);
1247 struct ospf6_interface *oi;
1248 unsigned int iobuflen;
1249 struct listnode *node, *nnode;
1250 struct ospf6_neighbor *on;
1251
1252 assert(ifp);
1253
1254 oi = (struct ospf6_interface *)ifp->info;
1255 if (oi == NULL)
1256 oi = ospf6_interface_create(ifp);
1257 assert(oi);
1258
1259 if (oi->ifmtu < ifp->mtu) {
1260 iobuflen = ospf6_iobuf_size(ifp->mtu);
1261 if (iobuflen < ifp->mtu) {
1262 vty_out(vty,
1263 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1264 ifp->name, iobuflen);
1265 oi->ifmtu = iobuflen;
1266 } else
1267 oi->ifmtu = ifp->mtu;
1268 } else
1269 oi->ifmtu = ifp->mtu;
1270
1271 oi->c_ifmtu = 0;
1272
1273 /* re-establish adjacencies */
1274 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1275 THREAD_OFF(on->inactivity_timer);
1276 thread_add_event(master, inactivity_timer, on, 0, NULL);
1277 }
1278
1279 return CMD_SUCCESS;
049207c3 1280}
1281
718e3744 1282DEFUN (ipv6_ospf6_cost,
1283 ipv6_ospf6_cost_cmd,
6147e2c6 1284 "ipv6 ospf6 cost (1-65535)",
718e3744 1285 IP6_STR
1286 OSPF6_STR
1287 "Interface cost\n"
32573073 1288 "Outgoing metric of this interface\n")
718e3744 1289{
d62a17ae 1290 VTY_DECLVAR_CONTEXT(interface, ifp);
1291 int idx_number = 3;
1292 struct ospf6_interface *oi;
1293 unsigned long int lcost;
1294
1295 assert(ifp);
1296
1297 oi = (struct ospf6_interface *)ifp->info;
1298 if (oi == NULL)
1299 oi = ospf6_interface_create(ifp);
1300 assert(oi);
1301
1302 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1303
1304 if (lcost > UINT32_MAX) {
1305 vty_out(vty, "Cost %ld is out of range\n", lcost);
1306 return CMD_WARNING_CONFIG_FAILED;
1307 }
1308
1309 if (oi->cost == lcost)
1310 return CMD_SUCCESS;
1311
1312 oi->cost = lcost;
1313 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1314
0db8196a 1315 ospf6_interface_force_recalculate_cost(oi);
d62a17ae 1316
1317 return CMD_SUCCESS;
c19543b2
VB
1318}
1319
1320DEFUN (no_ipv6_ospf6_cost,
1321 no_ipv6_ospf6_cost_cmd,
32573073 1322 "no ipv6 ospf6 cost [(1-65535)]",
c19543b2
VB
1323 NO_STR
1324 IP6_STR
1325 OSPF6_STR
1326 "Calculate interface cost from bandwidth\n"
32573073 1327 "Outgoing metric of this interface\n")
c19543b2 1328{
d62a17ae 1329 VTY_DECLVAR_CONTEXT(interface, ifp);
1330 struct ospf6_interface *oi;
1331 assert(ifp);
c19543b2 1332
d62a17ae 1333 oi = (struct ospf6_interface *)ifp->info;
1334 if (oi == NULL)
1335 oi = ospf6_interface_create(ifp);
1336 assert(oi);
c19543b2 1337
d62a17ae 1338 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
c19543b2 1339
d62a17ae 1340 ospf6_interface_recalculate_cost(oi);
718e3744 1341
d62a17ae 1342 return CMD_SUCCESS;
718e3744 1343}
1344
fd500689
VB
1345DEFUN (auto_cost_reference_bandwidth,
1346 auto_cost_reference_bandwidth_cmd,
6147e2c6 1347 "auto-cost reference-bandwidth (1-4294967)",
fd500689
VB
1348 "Calculate OSPF interface cost according to bandwidth\n"
1349 "Use reference bandwidth method to assign OSPF cost\n"
1350 "The reference bandwidth in terms of Mbits per second\n")
1351{
d62a17ae 1352 VTY_DECLVAR_CONTEXT(ospf6, o);
1353 int idx_number = 2;
1354 struct ospf6_area *oa;
1355 struct ospf6_interface *oi;
1356 struct listnode *i, *j;
d7c0a89a 1357 uint32_t refbw;
d62a17ae 1358
1359 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1360 if (refbw < 1 || refbw > 4294967) {
1361 vty_out(vty, "reference-bandwidth value is invalid\n");
1362 return CMD_WARNING_CONFIG_FAILED;
1363 }
1364
1365 /* If reference bandwidth is changed. */
1366 if ((refbw) == o->ref_bandwidth)
1367 return CMD_SUCCESS;
1368
1369 o->ref_bandwidth = refbw;
1370 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1371 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1372 ospf6_interface_recalculate_cost(oi);
1373
1374 return CMD_SUCCESS;
fd500689
VB
1375}
1376
1377DEFUN (no_auto_cost_reference_bandwidth,
1378 no_auto_cost_reference_bandwidth_cmd,
ccb8e0c7 1379 "no auto-cost reference-bandwidth [(1-4294967)]",
fd500689
VB
1380 NO_STR
1381 "Calculate OSPF interface cost according to bandwidth\n"
1d68dbfe
DW
1382 "Use reference bandwidth method to assign OSPF cost\n"
1383 "The reference bandwidth in terms of Mbits per second\n")
fd500689 1384{
d62a17ae 1385 VTY_DECLVAR_CONTEXT(ospf6, o);
1386 struct ospf6_area *oa;
1387 struct ospf6_interface *oi;
1388 struct listnode *i, *j;
fd500689 1389
d62a17ae 1390 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1391 return CMD_SUCCESS;
fd500689 1392
d62a17ae 1393 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1394 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1395 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1396 ospf6_interface_recalculate_cost(oi);
fd500689 1397
d62a17ae 1398 return CMD_SUCCESS;
fd500689
VB
1399}
1400
813d4307 1401
718e3744 1402DEFUN (ipv6_ospf6_hellointerval,
1403 ipv6_ospf6_hellointerval_cmd,
6147e2c6 1404 "ipv6 ospf6 hello-interval (1-65535)",
718e3744 1405 IP6_STR
1406 OSPF6_STR
99a522c7 1407 "Time between HELLO packets\n"
d23d6de8 1408 SECONDS_STR)
718e3744 1409{
d62a17ae 1410 VTY_DECLVAR_CONTEXT(interface, ifp);
1411 int idx_number = 3;
1412 struct ospf6_interface *oi;
1413 assert(ifp);
1414
1415 oi = (struct ospf6_interface *)ifp->info;
1416 if (oi == NULL)
1417 oi = ospf6_interface_create(ifp);
1418 assert(oi);
1419
d23d6de8
QY
1420 oi->hello_interval = strmatch(argv[0]->text, "no")
1421 ? OSPF_HELLO_INTERVAL_DEFAULT
1422 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1423 return CMD_SUCCESS;
718e3744 1424}
1425
d23d6de8
QY
1426ALIAS (ipv6_ospf6_hellointerval,
1427 no_ipv6_ospf6_hellointerval_cmd,
1428 "no ipv6 ospf6 hello-interval [(1-65535)]",
1429 NO_STR
1430 IP6_STR
1431 OSPF6_STR
1432 "Time between HELLO packets\n"
1433 SECONDS_STR)
1434
718e3744 1435/* interface variable set command */
1436DEFUN (ipv6_ospf6_deadinterval,
1437 ipv6_ospf6_deadinterval_cmd,
6147e2c6 1438 "ipv6 ospf6 dead-interval (1-65535)",
718e3744 1439 IP6_STR
1440 OSPF6_STR
508e53e2 1441 "Interval time after which a neighbor is declared down\n"
d23d6de8 1442 SECONDS_STR)
718e3744 1443{
d62a17ae 1444 VTY_DECLVAR_CONTEXT(interface, ifp);
1445 int idx_number = 3;
1446 struct ospf6_interface *oi;
1447 assert(ifp);
1448
1449 oi = (struct ospf6_interface *)ifp->info;
1450 if (oi == NULL)
1451 oi = ospf6_interface_create(ifp);
1452 assert(oi);
1453
d23d6de8
QY
1454 oi->dead_interval = strmatch(argv[0]->arg, "no")
1455 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1456 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1457 return CMD_SUCCESS;
718e3744 1458}
1459
d23d6de8
QY
1460ALIAS (ipv6_ospf6_deadinterval,
1461 no_ipv6_ospf6_deadinterval_cmd,
1462 "no ipv6 ospf6 dead-interval [(1-65535)]",
1463 NO_STR
1464 IP6_STR
1465 OSPF6_STR
1466 "Interval time after which a neighbor is declared down\n"
1467 SECONDS_STR)
1468
718e3744 1469/* interface variable set command */
1470DEFUN (ipv6_ospf6_transmitdelay,
1471 ipv6_ospf6_transmitdelay_cmd,
6147e2c6 1472 "ipv6 ospf6 transmit-delay (1-3600)",
718e3744 1473 IP6_STR
1474 OSPF6_STR
99a522c7 1475 "Link state transmit delay\n"
98cfd06b 1476 SECONDS_STR)
718e3744 1477{
d62a17ae 1478 VTY_DECLVAR_CONTEXT(interface, ifp);
1479 int idx_number = 3;
1480 struct ospf6_interface *oi;
1481 assert(ifp);
1482
1483 oi = (struct ospf6_interface *)ifp->info;
1484 if (oi == NULL)
1485 oi = ospf6_interface_create(ifp);
1486 assert(oi);
1487
d23d6de8
QY
1488 oi->transdelay = strmatch(argv[0]->text, "no")
1489 ? OSPF6_INTERFACE_TRANSDELAY
1490 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1491 return CMD_SUCCESS;
718e3744 1492}
1493
d23d6de8
QY
1494ALIAS (ipv6_ospf6_transmitdelay,
1495 no_ipv6_ospf6_transmitdelay_cmd,
1496 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1497 NO_STR
1498 IP6_STR
1499 OSPF6_STR
1500 "Link state transmit delay\n"
1501 SECONDS_STR)
1502
718e3744 1503/* interface variable set command */
1504DEFUN (ipv6_ospf6_retransmitinterval,
1505 ipv6_ospf6_retransmitinterval_cmd,
6147e2c6 1506 "ipv6 ospf6 retransmit-interval (1-65535)",
718e3744 1507 IP6_STR
1508 OSPF6_STR
1509 "Time between retransmitting lost link state advertisements\n"
d23d6de8 1510 SECONDS_STR)
718e3744 1511{
d62a17ae 1512 VTY_DECLVAR_CONTEXT(interface, ifp);
1513 int idx_number = 3;
1514 struct ospf6_interface *oi;
1515 assert(ifp);
1516
1517 oi = (struct ospf6_interface *)ifp->info;
1518 if (oi == NULL)
1519 oi = ospf6_interface_create(ifp);
1520 assert(oi);
1521
d23d6de8
QY
1522 oi->rxmt_interval = strmatch(argv[0]->text, "no")
1523 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1524 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1525 return CMD_SUCCESS;
718e3744 1526}
1527
d23d6de8
QY
1528ALIAS (ipv6_ospf6_retransmitinterval,
1529 no_ipv6_ospf6_retransmitinterval_cmd,
1530 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1531 NO_STR
1532 IP6_STR
1533 OSPF6_STR
1534 "Time between retransmitting lost link state advertisements\n"
1535 SECONDS_STR)
1536
718e3744 1537/* interface variable set command */
1538DEFUN (ipv6_ospf6_priority,
1539 ipv6_ospf6_priority_cmd,
6147e2c6 1540 "ipv6 ospf6 priority (0-255)",
718e3744 1541 IP6_STR
1542 OSPF6_STR
1543 "Router priority\n"
d23d6de8 1544 "Priority value\n")
718e3744 1545{
d62a17ae 1546 VTY_DECLVAR_CONTEXT(interface, ifp);
1547 int idx_number = 3;
1548 struct ospf6_interface *oi;
1549 assert(ifp);
718e3744 1550
d62a17ae 1551 oi = (struct ospf6_interface *)ifp->info;
1552 if (oi == NULL)
1553 oi = ospf6_interface_create(ifp);
1554 assert(oi);
508e53e2 1555
d23d6de8
QY
1556 oi->priority = strmatch(argv[0]->text, "no")
1557 ? OSPF6_INTERFACE_PRIORITY
1558 : strtoul(argv[idx_number]->arg, NULL, 10);
718e3744 1559
9d303b37
DL
1560 if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
1561 || oi->state == OSPF6_INTERFACE_BDR
1562 || oi->state == OSPF6_INTERFACE_DR))
d62a17ae 1563 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 1564
d62a17ae 1565 return CMD_SUCCESS;
718e3744 1566}
1567
d23d6de8
QY
1568ALIAS (ipv6_ospf6_priority,
1569 no_ipv6_ospf6_priority_cmd,
1570 "no ipv6 ospf6 priority [(0-255)]",
1571 NO_STR
1572 IP6_STR
1573 OSPF6_STR
1574 "Router priority\n"
1575 "Priority value\n")
1576
718e3744 1577DEFUN (ipv6_ospf6_instance,
1578 ipv6_ospf6_instance_cmd,
6147e2c6 1579 "ipv6 ospf6 instance-id (0-255)",
718e3744 1580 IP6_STR
1581 OSPF6_STR
508e53e2 1582 "Instance ID for this interface\n"
d23d6de8 1583 "Instance ID value\n")
718e3744 1584{
d62a17ae 1585 VTY_DECLVAR_CONTEXT(interface, ifp);
1586 int idx_number = 3;
1587 struct ospf6_interface *oi;
1588 assert(ifp);
1589
1590 oi = (struct ospf6_interface *)ifp->info;
1591 if (oi == NULL)
1592 oi = ospf6_interface_create(ifp);
1593 assert(oi);
1594
d23d6de8
QY
1595 oi->instance_id = strmatch(argv[0]->text, "no")
1596 ? OSPF6_INTERFACE_INSTANCE_ID
1597 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1598 return CMD_SUCCESS;
718e3744 1599}
1600
d23d6de8
QY
1601ALIAS (ipv6_ospf6_instance,
1602 no_ipv6_ospf6_instance_cmd,
1603 "no ipv6 ospf6 instance-id [(0-255)]",
1604 NO_STR
1605 IP6_STR
1606 OSPF6_STR
1607 "Instance ID for this interface\n"
1608 "Instance ID value\n")
1609
718e3744 1610DEFUN (ipv6_ospf6_passive,
1611 ipv6_ospf6_passive_cmd,
1612 "ipv6 ospf6 passive",
1613 IP6_STR
1614 OSPF6_STR
99a522c7 1615 "Passive interface; no adjacency will be formed on this interface\n"
718e3744 1616 )
1617{
d62a17ae 1618 VTY_DECLVAR_CONTEXT(interface, ifp);
1619 struct ospf6_interface *oi;
1620 struct listnode *node, *nnode;
1621 struct ospf6_neighbor *on;
718e3744 1622
d62a17ae 1623 assert(ifp);
718e3744 1624
d62a17ae 1625 oi = (struct ospf6_interface *)ifp->info;
1626 if (oi == NULL)
1627 oi = ospf6_interface_create(ifp);
1628 assert(oi);
718e3744 1629
d62a17ae 1630 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1631 THREAD_OFF(oi->thread_send_hello);
f80003b0 1632 THREAD_OFF(oi->thread_sso);
508e53e2 1633
d62a17ae 1634 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1635 THREAD_OFF(on->inactivity_timer);
1636 thread_add_event(master, inactivity_timer, on, 0, NULL);
1637 }
718e3744 1638
d62a17ae 1639 return CMD_SUCCESS;
718e3744 1640}
1641
1642DEFUN (no_ipv6_ospf6_passive,
1643 no_ipv6_ospf6_passive_cmd,
1644 "no ipv6 ospf6 passive",
1645 NO_STR
1646 IP6_STR
1647 OSPF6_STR
1648 "passive interface: No Adjacency will be formed on this I/F\n"
1649 )
1650{
d62a17ae 1651 VTY_DECLVAR_CONTEXT(interface, ifp);
1652 struct ospf6_interface *oi;
1653 assert(ifp);
718e3744 1654
d62a17ae 1655 oi = (struct ospf6_interface *)ifp->info;
1656 if (oi == NULL)
1657 oi = ospf6_interface_create(ifp);
1658 assert(oi);
718e3744 1659
d62a17ae 1660 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1661 THREAD_OFF(oi->thread_send_hello);
f80003b0 1662 THREAD_OFF(oi->thread_sso);
d62a17ae 1663 thread_add_event(master, ospf6_hello_send, oi, 0,
1664 &oi->thread_send_hello);
718e3744 1665
d62a17ae 1666 return CMD_SUCCESS;
718e3744 1667}
1668
d42306d9
DT
1669DEFUN (ipv6_ospf6_mtu_ignore,
1670 ipv6_ospf6_mtu_ignore_cmd,
1671 "ipv6 ospf6 mtu-ignore",
1672 IP6_STR
1673 OSPF6_STR
99a522c7 1674 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1675 )
1676{
d62a17ae 1677 VTY_DECLVAR_CONTEXT(interface, ifp);
1678 struct ospf6_interface *oi;
1679 assert(ifp);
d42306d9 1680
d62a17ae 1681 oi = (struct ospf6_interface *)ifp->info;
1682 if (oi == NULL)
1683 oi = ospf6_interface_create(ifp);
1684 assert(oi);
d42306d9 1685
d62a17ae 1686 oi->mtu_ignore = 1;
d42306d9 1687
d62a17ae 1688 return CMD_SUCCESS;
d42306d9
DT
1689}
1690
1691DEFUN (no_ipv6_ospf6_mtu_ignore,
1692 no_ipv6_ospf6_mtu_ignore_cmd,
1693 "no ipv6 ospf6 mtu-ignore",
1694 NO_STR
1695 IP6_STR
1696 OSPF6_STR
99a522c7 1697 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1698 )
1699{
d62a17ae 1700 VTY_DECLVAR_CONTEXT(interface, ifp);
1701 struct ospf6_interface *oi;
1702 assert(ifp);
d42306d9 1703
d62a17ae 1704 oi = (struct ospf6_interface *)ifp->info;
1705 if (oi == NULL)
1706 oi = ospf6_interface_create(ifp);
1707 assert(oi);
d42306d9 1708
d62a17ae 1709 oi->mtu_ignore = 0;
d42306d9 1710
d62a17ae 1711 return CMD_SUCCESS;
d42306d9
DT
1712}
1713
718e3744 1714DEFUN (ipv6_ospf6_advertise_prefix_list,
1715 ipv6_ospf6_advertise_prefix_list_cmd,
1716 "ipv6 ospf6 advertise prefix-list WORD",
1717 IP6_STR
1718 OSPF6_STR
1719 "Advertising options\n"
1720 "Filter prefix using prefix-list\n"
1721 "Prefix list name\n"
1722 )
1723{
d62a17ae 1724 VTY_DECLVAR_CONTEXT(interface, ifp);
1725 int idx_word = 4;
1726 struct ospf6_interface *oi;
1727 assert(ifp);
1728
1729 oi = (struct ospf6_interface *)ifp->info;
1730 if (oi == NULL)
1731 oi = ospf6_interface_create(ifp);
1732 assert(oi);
1733
1734 if (oi->plist_name)
1735 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
1736 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
1737
1738 ospf6_interface_connected_route_update(oi->interface);
1739
1740 if (oi->area) {
1741 OSPF6_LINK_LSA_SCHEDULE(oi);
1742 if (oi->state == OSPF6_INTERFACE_DR) {
1743 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1744 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1745 }
1746 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1747 }
1748
1749 return CMD_SUCCESS;
718e3744 1750}
1751
1752DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1753 no_ipv6_ospf6_advertise_prefix_list_cmd,
d23d6de8 1754 "no ipv6 ospf6 advertise prefix-list [WORD]",
718e3744 1755 NO_STR
1756 IP6_STR
1757 OSPF6_STR
1758 "Advertising options\n"
1759 "Filter prefix using prefix-list\n"
d23d6de8 1760 "Prefix list name\n")
718e3744 1761{
d62a17ae 1762 VTY_DECLVAR_CONTEXT(interface, ifp);
1763 struct ospf6_interface *oi;
1764 assert(ifp);
1765
1766 oi = (struct ospf6_interface *)ifp->info;
1767 if (oi == NULL)
1768 oi = ospf6_interface_create(ifp);
1769 assert(oi);
1770
d23d6de8 1771 if (oi->plist_name)
d62a17ae 1772 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
d62a17ae 1773
1774 ospf6_interface_connected_route_update(oi->interface);
1775
1776 if (oi->area) {
1777 OSPF6_LINK_LSA_SCHEDULE(oi);
1778 if (oi->state == OSPF6_INTERFACE_DR) {
1779 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1780 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1781 }
1782 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1783 }
1784
1785 return CMD_SUCCESS;
718e3744 1786}
1787
c5926a92
DD
1788DEFUN (ipv6_ospf6_network,
1789 ipv6_ospf6_network_cmd,
6147e2c6 1790 "ipv6 ospf6 network <broadcast|point-to-point>",
c5926a92
DD
1791 IP6_STR
1792 OSPF6_STR
99a522c7 1793 "Network type\n"
b2d4d039 1794 "Specify OSPF6 broadcast network\n"
c5926a92
DD
1795 "Specify OSPF6 point-to-point network\n"
1796 )
1797{
d62a17ae 1798 VTY_DECLVAR_CONTEXT(interface, ifp);
1799 int idx_network = 3;
1800 struct ospf6_interface *oi;
1801 assert(ifp);
1802
1803 oi = (struct ospf6_interface *)ifp->info;
1804 if (oi == NULL) {
1805 oi = ospf6_interface_create(ifp);
1806 }
1807 assert(oi);
1808
1809 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
1810 if (oi->type == OSPF_IFTYPE_BROADCAST)
1811 return CMD_SUCCESS;
1812
1813 oi->type = OSPF_IFTYPE_BROADCAST;
1814 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
1815 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
1816 return CMD_SUCCESS;
1817 }
1818 oi->type = OSPF_IFTYPE_POINTOPOINT;
c5926a92 1819 }
c5926a92 1820
d62a17ae 1821 /* Reset the interface */
849576ee
RZ
1822 thread_execute(master, interface_down, oi, 0);
1823 thread_execute(master, interface_up, oi, 0);
c5926a92 1824
d62a17ae 1825 return CMD_SUCCESS;
c5926a92
DD
1826}
1827
1828DEFUN (no_ipv6_ospf6_network,
1829 no_ipv6_ospf6_network_cmd,
32573073 1830 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
c5926a92
DD
1831 NO_STR
1832 IP6_STR
1833 OSPF6_STR
32573073
QY
1834 "Set default network type\n"
1835 "Specify OSPF6 broadcast network\n"
1836 "Specify OSPF6 point-to-point network\n")
c5926a92 1837{
d62a17ae 1838 VTY_DECLVAR_CONTEXT(interface, ifp);
1839 struct ospf6_interface *oi;
1840 int type;
c5926a92 1841
d62a17ae 1842 assert(ifp);
c5926a92 1843
d62a17ae 1844 oi = (struct ospf6_interface *)ifp->info;
1845 if (oi == NULL) {
1846 return CMD_SUCCESS;
1847 }
c5926a92 1848
d62a17ae 1849 type = ospf6_default_iftype(ifp);
1850 if (oi->type == type) {
1851 return CMD_SUCCESS;
1852 }
1853 oi->type = type;
c5926a92 1854
d62a17ae 1855 /* Reset the interface */
849576ee
RZ
1856 thread_execute(master, interface_down, oi, 0);
1857 thread_execute(master, interface_up, oi, 0);
c5926a92 1858
d62a17ae 1859 return CMD_SUCCESS;
c5926a92
DD
1860}
1861
d62a17ae 1862static int config_write_ospf6_interface(struct vty *vty)
718e3744 1863{
f4e14fdb 1864 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1865 struct ospf6_interface *oi;
1866 struct interface *ifp;
1867
451fda4f 1868 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1869 oi = (struct ospf6_interface *)ifp->info;
1870 if (oi == NULL)
1871 continue;
1872
a8b828f3 1873 vty_frame(vty, "interface %s\n", oi->interface->name);
d62a17ae 1874
1875 if (ifp->desc)
1876 vty_out(vty, " description %s\n", ifp->desc);
1877 if (oi->c_ifmtu)
1878 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
1879
1880 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
1881 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
1882
1883 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1884 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
1885 oi->hello_interval);
1886
1887 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1888 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
1889 oi->dead_interval);
1890
1891 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1892 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
1893 oi->rxmt_interval);
1894
1895 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1896 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
1897
1898 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1899 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
1900 oi->transdelay);
1901
1902 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1903 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
1904 oi->instance_id);
1905
1906 if (oi->plist_name)
1907 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
1908 oi->plist_name);
1909
1910 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
1911 vty_out(vty, " ipv6 ospf6 passive\n");
1912
1913 if (oi->mtu_ignore)
1914 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
1915
1916 if (oi->type != ospf6_default_iftype(ifp)) {
1917 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
1918 vty_out(vty,
1919 " ipv6 ospf6 network point-to-point\n");
1920 else if (oi->type == OSPF_IFTYPE_BROADCAST)
1921 vty_out(vty, " ipv6 ospf6 network broadcast\n");
1922 }
1923
1924 ospf6_bfd_write_config(vty, oi);
1925
a8b828f3 1926 vty_endframe(vty, "!\n");
d62a17ae 1927 }
1928 return 0;
718e3744 1929}
1930
d62a17ae 1931static struct cmd_node interface_node = {
1932 INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */
718e3744 1933};
1934
d62a17ae 1935void ospf6_interface_init(void)
718e3744 1936{
d62a17ae 1937 /* Install interface node. */
1938 install_node(&interface_node, config_write_ospf6_interface);
1939 if_cmd_init();
1940
1941 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
1942 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1943 install_element(VIEW_NODE,
1944 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
996c9314 1945 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
d62a17ae 1946
1947 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
1948 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
1949 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
1950 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
d23d6de8 1951
d62a17ae 1952 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1953 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1954 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1955 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1956 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1957 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
d23d6de8
QY
1958 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
1959 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
1960 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
1961 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
1962 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
1963 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
d62a17ae 1964
1965 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1966 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
1967
1968 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
1969 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
1970
1971 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1972 install_element(INTERFACE_NODE,
1973 &no_ipv6_ospf6_advertise_prefix_list_cmd);
1974
1975 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
1976 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
1977
1978 /* reference bandwidth commands */
1979 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
1980 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
508e53e2 1981}
1982
a1b11f9b 1983/* Clear the specified interface structure */
d62a17ae 1984static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
a1b11f9b 1985{
d62a17ae 1986 struct ospf6_interface *oi;
a1b11f9b 1987
d62a17ae 1988 if (!if_is_operative(ifp))
1989 return;
a1b11f9b 1990
d62a17ae 1991 if (ifp->info == NULL)
1992 return;
a1b11f9b 1993
d62a17ae 1994 oi = (struct ospf6_interface *)ifp->info;
a1b11f9b 1995
d62a17ae 1996 if (IS_OSPF6_DEBUG_INTERFACE)
1997 zlog_debug("Interface %s: clear by reset", ifp->name);
a1b11f9b 1998
d62a17ae 1999 /* Reset the interface */
849576ee
RZ
2000 thread_execute(master, interface_down, oi, 0);
2001 thread_execute(master, interface_up, oi, 0);
a1b11f9b
DS
2002}
2003
2004/* Clear interface */
2005DEFUN (clear_ipv6_ospf6_interface,
2006 clear_ipv6_ospf6_interface_cmd,
2007 "clear ipv6 ospf6 interface [IFNAME]",
2008 CLEAR_STR
2009 IP6_STR
2010 OSPF6_STR
2011 INTERFACE_STR
2012 IFNAME_STR
2013 )
2014{
f4e14fdb 2015 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 2016 int idx_ifname = 4;
2017 struct interface *ifp;
d62a17ae 2018
2019 if (argc == 4) /* Clear all the ospfv3 interfaces. */
2020 {
451fda4f 2021 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 2022 ospf6_interface_clear(vty, ifp);
2023 } else /* Interface name is specified. */
2024 {
2025 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
a36898e7 2026 VRF_DEFAULT))
d62a17ae 2027 == NULL) {
2028 vty_out(vty, "No such Interface: %s\n",
2029 argv[idx_ifname]->arg);
2030 return CMD_WARNING;
2031 }
2032 ospf6_interface_clear(vty, ifp);
2033 }
2034
2035 return CMD_SUCCESS;
a1b11f9b
DS
2036}
2037
d62a17ae 2038void install_element_ospf6_clear_interface(void)
a1b11f9b 2039{
d62a17ae 2040 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
a1b11f9b
DS
2041}
2042
508e53e2 2043DEFUN (debug_ospf6_interface,
2044 debug_ospf6_interface_cmd,
2045 "debug ospf6 interface",
2046 DEBUG_STR
2047 OSPF6_STR
2048 "Debug OSPFv3 Interface\n"
2049 )
2050{
d62a17ae 2051 OSPF6_DEBUG_INTERFACE_ON();
2052 return CMD_SUCCESS;
508e53e2 2053}
2054
2055DEFUN (no_debug_ospf6_interface,
2056 no_debug_ospf6_interface_cmd,
2057 "no debug ospf6 interface",
2058 NO_STR
2059 DEBUG_STR
2060 OSPF6_STR
2061 "Debug OSPFv3 Interface\n"
2062 )
2063{
d62a17ae 2064 OSPF6_DEBUG_INTERFACE_OFF();
2065 return CMD_SUCCESS;
508e53e2 2066}
2067
d62a17ae 2068int config_write_ospf6_debug_interface(struct vty *vty)
508e53e2 2069{
d62a17ae 2070 if (IS_OSPF6_DEBUG_INTERFACE)
2071 vty_out(vty, "debug ospf6 interface\n");
2072 return 0;
508e53e2 2073}
2074
d62a17ae 2075void install_element_ospf6_debug_interface(void)
508e53e2 2076{
d62a17ae 2077 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2078 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2079 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2080 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
718e3744 2081}