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