]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_interface.c
Merge pull request #5044 from chiragshah6/evpn_dev2
[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
5aeb4f3c
DL
684 if (!oi->type_cfg)
685 oi->type = ospf6_default_iftype(oi->interface);
686
f80003b0
RZ
687 /*
688 * Remove old pointer. If this thread wasn't a timer this
689 * operation won't make a difference, because it is already NULL.
690 */
691 oi->thread_sso = NULL;
692
d62a17ae 693 if (IS_OSPF6_DEBUG_INTERFACE)
694 zlog_debug("Interface Event %s: [InterfaceUp]",
695 oi->interface->name);
696
697 /* check physical interface is up */
698 if (!if_is_operative(oi->interface)) {
699 if (IS_OSPF6_DEBUG_INTERFACE)
700 zlog_debug(
701 "Interface %s is down, can't execute [InterfaceUp]",
702 oi->interface->name);
703 return 0;
704 }
705
706 /* check interface has a link-local address */
707 if (!(ospf6_interface_get_linklocal_address(oi->interface)
708 || if_is_loopback(oi->interface))) {
709 if (IS_OSPF6_DEBUG_INTERFACE)
710 zlog_debug(
711 "Interface %s has no link local address, can't execute [InterfaceUp]",
712 oi->interface->name);
713 return 0;
714 }
715
716 /* Recompute cost */
717 ospf6_interface_recalculate_cost(oi);
718
719 /* if already enabled, do nothing */
720 if (oi->state > OSPF6_INTERFACE_DOWN) {
721 if (IS_OSPF6_DEBUG_INTERFACE)
722 zlog_debug("Interface %s already enabled",
723 oi->interface->name);
724 return 0;
725 }
726
727 /* If no area assigned, return */
728 if (oi->area == NULL) {
729 zlog_debug(
730 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
731 __func__, oi->interface->name);
732 return 0;
733 }
734
bc482dc0
RZ
735#ifdef __FreeBSD__
736 /*
737 * XXX: Schedule IPv6 group join for later, otherwise we might
738 * lose the multicast group registration caused by IPv6 group
739 * leave race.
740 */
741 if (oi->sso_try_cnt == 0) {
742 oi->sso_try_cnt++;
743 zlog_info("Scheduling %s for sso", oi->interface->name);
744 thread_add_timer(master, interface_up, oi,
745 OSPF6_INTERFACE_SSO_RETRY_INT,
746 &oi->thread_sso);
747 return 0;
748 }
749#endif /* __FreeBSD__ */
750
d62a17ae 751 /* Join AllSPFRouters */
752 if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP)
753 < 0) {
754 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
755 zlog_info(
756 "Scheduling %s for sso retry, trial count: %d",
757 oi->interface->name, oi->sso_try_cnt);
758 thread_add_timer(master, interface_up, oi,
f80003b0
RZ
759 OSPF6_INTERFACE_SSO_RETRY_INT,
760 &oi->thread_sso);
d62a17ae 761 }
762 return 0;
763 }
764 oi->sso_try_cnt = 0; /* Reset on success */
765
766 /* Update interface route */
767 ospf6_interface_connected_route_update(oi->interface);
768
769 /* Schedule Hello */
770 if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
771 && !if_is_loopback(oi->interface)) {
772 oi->thread_send_hello = NULL;
773 thread_add_event(master, ospf6_hello_send, oi, 0,
774 &oi->thread_send_hello);
775 }
776
777 /* decide next interface state */
e5973353 778 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
d62a17ae 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
5aeb4f3c
DL
883static const char *ospf6_iftype_str(uint8_t iftype)
884{
885 switch (iftype) {
886 case OSPF_IFTYPE_LOOPBACK:
887 return "LOOPBACK";
888 case OSPF_IFTYPE_BROADCAST:
889 return "BROADCAST";
890 case OSPF_IFTYPE_POINTOPOINT:
891 return "POINTOPOINT";
892 }
893 return "UNKNOWN";
894}
895
718e3744 896/* show specified interface structure */
d62a17ae 897static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
718e3744 898{
d62a17ae 899 struct ospf6_interface *oi;
900 struct connected *c;
901 struct prefix *p;
902 struct listnode *i;
903 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
5aeb4f3c 904 uint8_t default_iftype;
d62a17ae 905 struct timeval res, now;
906 char duration[32];
907 struct ospf6_lsa *lsa;
908
5aeb4f3c 909 default_iftype = ospf6_default_iftype(ifp);
d62a17ae 910
911 vty_out(vty, "%s is %s, type %s\n", ifp->name,
5aeb4f3c
DL
912 (if_is_operative(ifp) ? "up" : "down"),
913 ospf6_iftype_str(default_iftype));
d62a17ae 914 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
915
916 if (ifp->info == NULL) {
917 vty_out(vty, " OSPF not enabled on this interface\n");
918 return 0;
919 } else
920 oi = (struct ospf6_interface *)ifp->info;
921
5aeb4f3c
DL
922 if (if_is_operative(ifp) && oi->type != default_iftype)
923 vty_out(vty, " Operating as type %s\n",
924 ospf6_iftype_str(oi->type));
925
d62a17ae 926 vty_out(vty, " Internet Address:\n");
927
928 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
929 p = c->address;
930 prefix2str(p, strbuf, sizeof(strbuf));
931 switch (p->family) {
932 case AF_INET:
933 vty_out(vty, " inet : %s\n", strbuf);
934 break;
935 case AF_INET6:
936 vty_out(vty, " inet6: %s\n", strbuf);
937 break;
938 default:
939 vty_out(vty, " ??? : %s\n", strbuf);
940 break;
941 }
942 }
943
944 if (oi->area) {
945 vty_out(vty,
946 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
947 oi->instance_id, oi->ifmtu, ifp->mtu6);
948 vty_out(vty, " MTU mismatch detection: %s\n",
949 oi->mtu_ignore ? "disabled" : "enabled");
950 inet_ntop(AF_INET, &oi->area->area_id, strbuf, sizeof(strbuf));
951 vty_out(vty, " Area ID %s, Cost %u\n", strbuf, oi->cost);
952 } else
953 vty_out(vty, " Not Attached to Area\n");
954
955 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
956 ospf6_interface_state_str[oi->state], oi->transdelay,
957 oi->priority);
958 vty_out(vty, " Timer intervals configured:\n");
959 vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
960 oi->hello_interval, oi->dead_interval, oi->rxmt_interval);
961
962 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
963 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
964 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
965
966 vty_out(vty, " Number of I/F scoped LSAs is %u\n", oi->lsdb->count);
967
968 monotime(&now);
969
970 timerclear(&res);
971 if (oi->thread_send_lsupdate)
972 timersub(&oi->thread_send_lsupdate->u.sands, &now, &res);
973 timerstring(&res, duration, sizeof(duration));
974 vty_out(vty,
975 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
976 oi->lsupdate_list->count, duration,
977 (oi->thread_send_lsupdate ? "on" : "off"));
978 for (ALL_LSDB(oi->lsupdate_list, lsa))
979 vty_out(vty, " %s\n", lsa->name);
980
981 timerclear(&res);
982 if (oi->thread_send_lsack)
983 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
984 timerstring(&res, duration, sizeof(duration));
985 vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
986 oi->lsack_list->count, duration,
987 (oi->thread_send_lsack ? "on" : "off"));
988 for (ALL_LSDB(oi->lsack_list, lsa))
989 vty_out(vty, " %s\n", lsa->name);
990 ospf6_bfd_show_info(vty, oi->bfd_info, 1);
991 return 0;
718e3744 992}
993
994/* show interface */
995DEFUN (show_ipv6_ospf6_interface,
996 show_ipv6_ospf6_interface_ifname_cmd,
1d68dbfe 997 "show ipv6 ospf6 interface [IFNAME]",
718e3744 998 SHOW_STR
999 IP6_STR
1000 OSPF6_STR
1001 INTERFACE_STR
1d68dbfe 1002 IFNAME_STR)
718e3744 1003{
f4e14fdb 1004 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1005 int idx_ifname = 4;
1006 struct interface *ifp;
d62a17ae 1007
1008 if (argc == 5) {
a36898e7 1009 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 1010 if (ifp == NULL) {
1011 vty_out(vty, "No such Interface: %s\n",
1012 argv[idx_ifname]->arg);
1013 return CMD_WARNING;
1014 }
1015 ospf6_interface_show(vty, ifp);
1016 } else {
451fda4f 1017 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1018 ospf6_interface_show(vty, ifp);
1019 }
1020
1021 return CMD_SUCCESS;
718e3744 1022}
1023
996c9314 1024static int ospf6_interface_show_traffic(struct vty *vty, uint32_t vrf_id,
43855e3d
CS
1025 struct interface *intf_ifp,
1026 int display_once)
1027{
1028 struct interface *ifp;
1029 struct vrf *vrf = NULL;
1030 struct ospf6_interface *oi = NULL;
1031
1032 vrf = vrf_lookup_by_id(vrf_id);
1033
1034 if (!display_once) {
1035 vty_out(vty, "\n");
996c9314
LB
1036 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1037 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1038 " LS-Ack");
43855e3d 1039 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
996c9314
LB
1040 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1041 " Rx/Tx");
43855e3d 1042 vty_out(vty,
996c9314 1043 "--------------------------------------------------------------------------------------------\n");
43855e3d
CS
1044 }
1045
1046 if (intf_ifp == NULL) {
1047 FOR_ALL_INTERFACES (vrf, ifp) {
1048 if (ifp->info)
1049 oi = (struct ospf6_interface *)ifp->info;
1050 else
1051 continue;
1052
1053 vty_out(vty,
996c9314 1054 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
43855e3d 1055 oi->interface->name, oi->hello_in,
996c9314
LB
1056 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1057 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1058 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
43855e3d
CS
1059 }
1060 } else {
1061 oi = intf_ifp->info;
1062 if (oi == NULL)
1063 return CMD_WARNING;
1064
1065 vty_out(vty,
1066 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
996c9314
LB
1067 oi->interface->name, oi->hello_in, oi->hello_out,
1068 oi->db_desc_in, oi->db_desc_out, oi->ls_req_in,
1069 oi->ls_req_out, oi->ls_upd_in, oi->ls_upd_out,
43855e3d
CS
1070 oi->ls_ack_in, oi->ls_ack_out);
1071 }
1072
1073 return CMD_SUCCESS;
1074}
1075
1076/* show interface */
1077DEFUN (show_ipv6_ospf6_interface_traffic,
1078 show_ipv6_ospf6_interface_traffic_cmd,
1079 "show ipv6 ospf6 interface traffic [IFNAME]",
1080 SHOW_STR
1081 IP6_STR
1082 OSPF6_STR
1083 INTERFACE_STR
1084 "Protocol Packet counters\n"
1085 IFNAME_STR)
1086{
1087 int idx_ifname = 0;
1088 int display_once = 0;
1089 char *intf_name = NULL;
1090 struct interface *ifp = NULL;
1091
1092 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1093 intf_name = argv[idx_ifname]->arg;
a36898e7 1094 ifp = if_lookup_by_name(intf_name, VRF_DEFAULT);
43855e3d 1095 if (ifp == NULL) {
996c9314 1096 vty_out(vty, "No such Interface: %s\n", intf_name);
43855e3d
CS
1097 return CMD_WARNING;
1098 }
1099 if (ifp->info == NULL) {
1100 vty_out(vty,
1101 " OSPF not enabled on this interface %s\n",
1102 intf_name);
1103 return 0;
1104 }
1105 }
1106
996c9314 1107 ospf6_interface_show_traffic(vty, VRF_DEFAULT, ifp, display_once);
43855e3d
CS
1108
1109
1110 return CMD_SUCCESS;
1111}
1112
1113
508e53e2 1114DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
1115 show_ipv6_ospf6_interface_ifname_prefix_cmd,
25ee05c9
RW
1116 "show ipv6 ospf6 interface IFNAME prefix\
1117 [<\
1118 detail\
1119 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1120 >]",
508e53e2 1121 SHOW_STR
1122 IP6_STR
1123 OSPF6_STR
1124 INTERFACE_STR
1125 IFNAME_STR
093d7a3a 1126 "Display connected prefixes to advertise\n"
25ee05c9 1127 "Display details of the prefixes\n"
093d7a3a
DW
1128 OSPF6_ROUTE_ADDRESS_STR
1129 OSPF6_ROUTE_PREFIX_STR
1130 OSPF6_ROUTE_MATCH_STR
1131 "Display details of the prefixes\n")
508e53e2 1132{
d62a17ae 1133 int idx_ifname = 4;
1134 int idx_prefix = 6;
1135 struct interface *ifp;
1136 struct ospf6_interface *oi;
1137
a36898e7 1138 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 1139 if (ifp == NULL) {
1140 vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
1141 return CMD_WARNING;
1142 }
1143
1144 oi = ifp->info;
1145 if (oi == NULL) {
1146 vty_out(vty, "OSPFv3 is not enabled on %s\n",
1147 argv[idx_ifname]->arg);
1148 return CMD_WARNING;
1149 }
1150
1151 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1152 oi->route_connected);
1153
1154 return CMD_SUCCESS;
508e53e2 1155}
1156
508e53e2 1157DEFUN (show_ipv6_ospf6_interface_prefix,
1158 show_ipv6_ospf6_interface_prefix_cmd,
25ee05c9
RW
1159 "show ipv6 ospf6 interface prefix\
1160 [<\
1161 detail\
1162 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1163 >]",
508e53e2 1164 SHOW_STR
1165 IP6_STR
1166 OSPF6_STR
1167 INTERFACE_STR
1168 "Display connected prefixes to advertise\n"
25ee05c9 1169 "Display details of the prefixes\n"
093d7a3a
DW
1170 OSPF6_ROUTE_ADDRESS_STR
1171 OSPF6_ROUTE_PREFIX_STR
1172 OSPF6_ROUTE_MATCH_STR
1173 "Display details of the prefixes\n")
508e53e2 1174{
f4e14fdb 1175 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1176 int idx_prefix = 5;
d62a17ae 1177 struct ospf6_interface *oi;
1178 struct interface *ifp;
1179
451fda4f 1180 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1181 oi = (struct ospf6_interface *)ifp->info;
1182 if (oi == NULL)
1183 continue;
1184
1185 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1186 oi->route_connected);
1187 }
508e53e2 1188
d62a17ae 1189 return CMD_SUCCESS;
508e53e2 1190}
1191
718e3744 1192/* interface variable set command */
b596c71e 1193DEFUN (ipv6_ospf6_ifmtu,
1194 ipv6_ospf6_ifmtu_cmd,
6147e2c6 1195 "ipv6 ospf6 ifmtu (1-65535)",
b596c71e 1196 IP6_STR
1197 OSPF6_STR
1198 "Interface MTU\n"
1199 "OSPFv3 Interface MTU\n"
1200 )
1201{
d62a17ae 1202 VTY_DECLVAR_CONTEXT(interface, ifp);
1203 int idx_number = 3;
1204 struct ospf6_interface *oi;
1205 unsigned int ifmtu, iobuflen;
1206 struct listnode *node, *nnode;
1207 struct ospf6_neighbor *on;
1208
1209 assert(ifp);
1210
1211 oi = (struct ospf6_interface *)ifp->info;
1212 if (oi == NULL)
1213 oi = ospf6_interface_create(ifp);
1214 assert(oi);
1215
1216 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1217
1218 if (oi->c_ifmtu == ifmtu)
1219 return CMD_SUCCESS;
1220
1221 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1222 vty_out(vty,
1223 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1224 ifp->name, ifp->mtu6);
1225 return CMD_WARNING_CONFIG_FAILED;
1226 }
1227
1228 if (oi->ifmtu < ifmtu) {
1229 iobuflen = ospf6_iobuf_size(ifmtu);
1230 if (iobuflen < ifmtu) {
1231 vty_out(vty,
1232 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1233 ifp->name, iobuflen);
1234 oi->ifmtu = oi->c_ifmtu = iobuflen;
1235 } else
1236 oi->ifmtu = oi->c_ifmtu = ifmtu;
1237 } else
1238 oi->ifmtu = oi->c_ifmtu = ifmtu;
1239
1240 /* re-establish adjacencies */
1241 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1242 THREAD_OFF(on->inactivity_timer);
1243 thread_add_event(master, inactivity_timer, on, 0, NULL);
1244 }
1245
1246 return CMD_SUCCESS;
b596c71e 1247}
1248
049207c3 1249DEFUN (no_ipv6_ospf6_ifmtu,
1250 no_ipv6_ospf6_ifmtu_cmd,
0c7ef48a 1251 "no ipv6 ospf6 ifmtu [(1-65535)]",
049207c3 1252 NO_STR
1253 IP6_STR
1254 OSPF6_STR
1255 "Interface MTU\n"
0c7ef48a 1256 "OSPFv3 Interface MTU\n"
049207c3 1257 )
1258{
d62a17ae 1259 VTY_DECLVAR_CONTEXT(interface, ifp);
1260 struct ospf6_interface *oi;
1261 unsigned int iobuflen;
1262 struct listnode *node, *nnode;
1263 struct ospf6_neighbor *on;
1264
1265 assert(ifp);
1266
1267 oi = (struct ospf6_interface *)ifp->info;
1268 if (oi == NULL)
1269 oi = ospf6_interface_create(ifp);
1270 assert(oi);
1271
1272 if (oi->ifmtu < ifp->mtu) {
1273 iobuflen = ospf6_iobuf_size(ifp->mtu);
1274 if (iobuflen < ifp->mtu) {
1275 vty_out(vty,
1276 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1277 ifp->name, iobuflen);
1278 oi->ifmtu = iobuflen;
1279 } else
1280 oi->ifmtu = ifp->mtu;
1281 } else
1282 oi->ifmtu = ifp->mtu;
1283
1284 oi->c_ifmtu = 0;
1285
1286 /* re-establish adjacencies */
1287 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1288 THREAD_OFF(on->inactivity_timer);
1289 thread_add_event(master, inactivity_timer, on, 0, NULL);
1290 }
1291
1292 return CMD_SUCCESS;
049207c3 1293}
1294
718e3744 1295DEFUN (ipv6_ospf6_cost,
1296 ipv6_ospf6_cost_cmd,
6147e2c6 1297 "ipv6 ospf6 cost (1-65535)",
718e3744 1298 IP6_STR
1299 OSPF6_STR
1300 "Interface cost\n"
32573073 1301 "Outgoing metric of this interface\n")
718e3744 1302{
d62a17ae 1303 VTY_DECLVAR_CONTEXT(interface, ifp);
1304 int idx_number = 3;
1305 struct ospf6_interface *oi;
1306 unsigned long int lcost;
1307
1308 assert(ifp);
1309
1310 oi = (struct ospf6_interface *)ifp->info;
1311 if (oi == NULL)
1312 oi = ospf6_interface_create(ifp);
1313 assert(oi);
1314
1315 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1316
1317 if (lcost > UINT32_MAX) {
1318 vty_out(vty, "Cost %ld is out of range\n", lcost);
1319 return CMD_WARNING_CONFIG_FAILED;
1320 }
1321
1322 if (oi->cost == lcost)
1323 return CMD_SUCCESS;
1324
1325 oi->cost = lcost;
1326 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1327
0db8196a 1328 ospf6_interface_force_recalculate_cost(oi);
d62a17ae 1329
1330 return CMD_SUCCESS;
c19543b2
VB
1331}
1332
1333DEFUN (no_ipv6_ospf6_cost,
1334 no_ipv6_ospf6_cost_cmd,
32573073 1335 "no ipv6 ospf6 cost [(1-65535)]",
c19543b2
VB
1336 NO_STR
1337 IP6_STR
1338 OSPF6_STR
1339 "Calculate interface cost from bandwidth\n"
32573073 1340 "Outgoing metric of this interface\n")
c19543b2 1341{
d62a17ae 1342 VTY_DECLVAR_CONTEXT(interface, ifp);
1343 struct ospf6_interface *oi;
1344 assert(ifp);
c19543b2 1345
d62a17ae 1346 oi = (struct ospf6_interface *)ifp->info;
1347 if (oi == NULL)
1348 oi = ospf6_interface_create(ifp);
1349 assert(oi);
c19543b2 1350
d62a17ae 1351 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
c19543b2 1352
d62a17ae 1353 ospf6_interface_recalculate_cost(oi);
718e3744 1354
d62a17ae 1355 return CMD_SUCCESS;
718e3744 1356}
1357
fd500689
VB
1358DEFUN (auto_cost_reference_bandwidth,
1359 auto_cost_reference_bandwidth_cmd,
6147e2c6 1360 "auto-cost reference-bandwidth (1-4294967)",
fd500689
VB
1361 "Calculate OSPF interface cost according to bandwidth\n"
1362 "Use reference bandwidth method to assign OSPF cost\n"
1363 "The reference bandwidth in terms of Mbits per second\n")
1364{
d62a17ae 1365 VTY_DECLVAR_CONTEXT(ospf6, o);
1366 int idx_number = 2;
1367 struct ospf6_area *oa;
1368 struct ospf6_interface *oi;
1369 struct listnode *i, *j;
d7c0a89a 1370 uint32_t refbw;
d62a17ae 1371
1372 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1373 if (refbw < 1 || refbw > 4294967) {
1374 vty_out(vty, "reference-bandwidth value is invalid\n");
1375 return CMD_WARNING_CONFIG_FAILED;
1376 }
1377
1378 /* If reference bandwidth is changed. */
1379 if ((refbw) == o->ref_bandwidth)
1380 return CMD_SUCCESS;
1381
1382 o->ref_bandwidth = refbw;
1383 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1384 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1385 ospf6_interface_recalculate_cost(oi);
1386
1387 return CMD_SUCCESS;
fd500689
VB
1388}
1389
1390DEFUN (no_auto_cost_reference_bandwidth,
1391 no_auto_cost_reference_bandwidth_cmd,
ccb8e0c7 1392 "no auto-cost reference-bandwidth [(1-4294967)]",
fd500689
VB
1393 NO_STR
1394 "Calculate OSPF interface cost according to bandwidth\n"
1d68dbfe
DW
1395 "Use reference bandwidth method to assign OSPF cost\n"
1396 "The reference bandwidth in terms of Mbits per second\n")
fd500689 1397{
d62a17ae 1398 VTY_DECLVAR_CONTEXT(ospf6, o);
1399 struct ospf6_area *oa;
1400 struct ospf6_interface *oi;
1401 struct listnode *i, *j;
fd500689 1402
d62a17ae 1403 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1404 return CMD_SUCCESS;
fd500689 1405
d62a17ae 1406 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1407 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1408 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1409 ospf6_interface_recalculate_cost(oi);
fd500689 1410
d62a17ae 1411 return CMD_SUCCESS;
fd500689
VB
1412}
1413
813d4307 1414
718e3744 1415DEFUN (ipv6_ospf6_hellointerval,
1416 ipv6_ospf6_hellointerval_cmd,
6147e2c6 1417 "ipv6 ospf6 hello-interval (1-65535)",
718e3744 1418 IP6_STR
1419 OSPF6_STR
99a522c7 1420 "Time between HELLO packets\n"
d23d6de8 1421 SECONDS_STR)
718e3744 1422{
d62a17ae 1423 VTY_DECLVAR_CONTEXT(interface, ifp);
1424 int idx_number = 3;
1425 struct ospf6_interface *oi;
1426 assert(ifp);
1427
1428 oi = (struct ospf6_interface *)ifp->info;
1429 if (oi == NULL)
1430 oi = ospf6_interface_create(ifp);
1431 assert(oi);
1432
d23d6de8
QY
1433 oi->hello_interval = strmatch(argv[0]->text, "no")
1434 ? OSPF_HELLO_INTERVAL_DEFAULT
1435 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1436 return CMD_SUCCESS;
718e3744 1437}
1438
d23d6de8
QY
1439ALIAS (ipv6_ospf6_hellointerval,
1440 no_ipv6_ospf6_hellointerval_cmd,
1441 "no ipv6 ospf6 hello-interval [(1-65535)]",
1442 NO_STR
1443 IP6_STR
1444 OSPF6_STR
1445 "Time between HELLO packets\n"
1446 SECONDS_STR)
1447
718e3744 1448/* interface variable set command */
1449DEFUN (ipv6_ospf6_deadinterval,
1450 ipv6_ospf6_deadinterval_cmd,
6147e2c6 1451 "ipv6 ospf6 dead-interval (1-65535)",
718e3744 1452 IP6_STR
1453 OSPF6_STR
508e53e2 1454 "Interval time after which a neighbor is declared down\n"
d23d6de8 1455 SECONDS_STR)
718e3744 1456{
d62a17ae 1457 VTY_DECLVAR_CONTEXT(interface, ifp);
1458 int idx_number = 3;
1459 struct ospf6_interface *oi;
1460 assert(ifp);
1461
1462 oi = (struct ospf6_interface *)ifp->info;
1463 if (oi == NULL)
1464 oi = ospf6_interface_create(ifp);
1465 assert(oi);
1466
d23d6de8
QY
1467 oi->dead_interval = strmatch(argv[0]->arg, "no")
1468 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1469 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1470 return CMD_SUCCESS;
718e3744 1471}
1472
d23d6de8
QY
1473ALIAS (ipv6_ospf6_deadinterval,
1474 no_ipv6_ospf6_deadinterval_cmd,
1475 "no ipv6 ospf6 dead-interval [(1-65535)]",
1476 NO_STR
1477 IP6_STR
1478 OSPF6_STR
1479 "Interval time after which a neighbor is declared down\n"
1480 SECONDS_STR)
1481
718e3744 1482/* interface variable set command */
1483DEFUN (ipv6_ospf6_transmitdelay,
1484 ipv6_ospf6_transmitdelay_cmd,
6147e2c6 1485 "ipv6 ospf6 transmit-delay (1-3600)",
718e3744 1486 IP6_STR
1487 OSPF6_STR
99a522c7 1488 "Link state transmit delay\n"
98cfd06b 1489 SECONDS_STR)
718e3744 1490{
d62a17ae 1491 VTY_DECLVAR_CONTEXT(interface, ifp);
1492 int idx_number = 3;
1493 struct ospf6_interface *oi;
1494 assert(ifp);
1495
1496 oi = (struct ospf6_interface *)ifp->info;
1497 if (oi == NULL)
1498 oi = ospf6_interface_create(ifp);
1499 assert(oi);
1500
d23d6de8
QY
1501 oi->transdelay = strmatch(argv[0]->text, "no")
1502 ? OSPF6_INTERFACE_TRANSDELAY
1503 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1504 return CMD_SUCCESS;
718e3744 1505}
1506
d23d6de8
QY
1507ALIAS (ipv6_ospf6_transmitdelay,
1508 no_ipv6_ospf6_transmitdelay_cmd,
1509 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1510 NO_STR
1511 IP6_STR
1512 OSPF6_STR
1513 "Link state transmit delay\n"
1514 SECONDS_STR)
1515
718e3744 1516/* interface variable set command */
1517DEFUN (ipv6_ospf6_retransmitinterval,
1518 ipv6_ospf6_retransmitinterval_cmd,
6147e2c6 1519 "ipv6 ospf6 retransmit-interval (1-65535)",
718e3744 1520 IP6_STR
1521 OSPF6_STR
1522 "Time between retransmitting lost link state advertisements\n"
d23d6de8 1523 SECONDS_STR)
718e3744 1524{
d62a17ae 1525 VTY_DECLVAR_CONTEXT(interface, ifp);
1526 int idx_number = 3;
1527 struct ospf6_interface *oi;
1528 assert(ifp);
1529
1530 oi = (struct ospf6_interface *)ifp->info;
1531 if (oi == NULL)
1532 oi = ospf6_interface_create(ifp);
1533 assert(oi);
1534
d23d6de8
QY
1535 oi->rxmt_interval = strmatch(argv[0]->text, "no")
1536 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1537 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1538 return CMD_SUCCESS;
718e3744 1539}
1540
d23d6de8
QY
1541ALIAS (ipv6_ospf6_retransmitinterval,
1542 no_ipv6_ospf6_retransmitinterval_cmd,
1543 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1544 NO_STR
1545 IP6_STR
1546 OSPF6_STR
1547 "Time between retransmitting lost link state advertisements\n"
1548 SECONDS_STR)
1549
718e3744 1550/* interface variable set command */
1551DEFUN (ipv6_ospf6_priority,
1552 ipv6_ospf6_priority_cmd,
6147e2c6 1553 "ipv6 ospf6 priority (0-255)",
718e3744 1554 IP6_STR
1555 OSPF6_STR
1556 "Router priority\n"
d23d6de8 1557 "Priority value\n")
718e3744 1558{
d62a17ae 1559 VTY_DECLVAR_CONTEXT(interface, ifp);
1560 int idx_number = 3;
1561 struct ospf6_interface *oi;
1562 assert(ifp);
718e3744 1563
d62a17ae 1564 oi = (struct ospf6_interface *)ifp->info;
1565 if (oi == NULL)
1566 oi = ospf6_interface_create(ifp);
1567 assert(oi);
508e53e2 1568
d23d6de8
QY
1569 oi->priority = strmatch(argv[0]->text, "no")
1570 ? OSPF6_INTERFACE_PRIORITY
1571 : strtoul(argv[idx_number]->arg, NULL, 10);
718e3744 1572
9d303b37
DL
1573 if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
1574 || oi->state == OSPF6_INTERFACE_BDR
1575 || oi->state == OSPF6_INTERFACE_DR))
d62a17ae 1576 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 1577
d62a17ae 1578 return CMD_SUCCESS;
718e3744 1579}
1580
d23d6de8
QY
1581ALIAS (ipv6_ospf6_priority,
1582 no_ipv6_ospf6_priority_cmd,
1583 "no ipv6 ospf6 priority [(0-255)]",
1584 NO_STR
1585 IP6_STR
1586 OSPF6_STR
1587 "Router priority\n"
1588 "Priority value\n")
1589
718e3744 1590DEFUN (ipv6_ospf6_instance,
1591 ipv6_ospf6_instance_cmd,
6147e2c6 1592 "ipv6 ospf6 instance-id (0-255)",
718e3744 1593 IP6_STR
1594 OSPF6_STR
508e53e2 1595 "Instance ID for this interface\n"
d23d6de8 1596 "Instance ID value\n")
718e3744 1597{
d62a17ae 1598 VTY_DECLVAR_CONTEXT(interface, ifp);
1599 int idx_number = 3;
1600 struct ospf6_interface *oi;
1601 assert(ifp);
1602
1603 oi = (struct ospf6_interface *)ifp->info;
1604 if (oi == NULL)
1605 oi = ospf6_interface_create(ifp);
1606 assert(oi);
1607
d23d6de8
QY
1608 oi->instance_id = strmatch(argv[0]->text, "no")
1609 ? OSPF6_INTERFACE_INSTANCE_ID
1610 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1611 return CMD_SUCCESS;
718e3744 1612}
1613
d23d6de8
QY
1614ALIAS (ipv6_ospf6_instance,
1615 no_ipv6_ospf6_instance_cmd,
1616 "no ipv6 ospf6 instance-id [(0-255)]",
1617 NO_STR
1618 IP6_STR
1619 OSPF6_STR
1620 "Instance ID for this interface\n"
1621 "Instance ID value\n")
1622
718e3744 1623DEFUN (ipv6_ospf6_passive,
1624 ipv6_ospf6_passive_cmd,
1625 "ipv6 ospf6 passive",
1626 IP6_STR
1627 OSPF6_STR
99a522c7 1628 "Passive interface; no adjacency will be formed on this interface\n"
718e3744 1629 )
1630{
d62a17ae 1631 VTY_DECLVAR_CONTEXT(interface, ifp);
1632 struct ospf6_interface *oi;
1633 struct listnode *node, *nnode;
1634 struct ospf6_neighbor *on;
718e3744 1635
d62a17ae 1636 assert(ifp);
718e3744 1637
d62a17ae 1638 oi = (struct ospf6_interface *)ifp->info;
1639 if (oi == NULL)
1640 oi = ospf6_interface_create(ifp);
1641 assert(oi);
718e3744 1642
d62a17ae 1643 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1644 THREAD_OFF(oi->thread_send_hello);
f80003b0 1645 THREAD_OFF(oi->thread_sso);
508e53e2 1646
d62a17ae 1647 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1648 THREAD_OFF(on->inactivity_timer);
1649 thread_add_event(master, inactivity_timer, on, 0, NULL);
1650 }
718e3744 1651
d62a17ae 1652 return CMD_SUCCESS;
718e3744 1653}
1654
1655DEFUN (no_ipv6_ospf6_passive,
1656 no_ipv6_ospf6_passive_cmd,
1657 "no ipv6 ospf6 passive",
1658 NO_STR
1659 IP6_STR
1660 OSPF6_STR
1661 "passive interface: No Adjacency will be formed on this I/F\n"
1662 )
1663{
d62a17ae 1664 VTY_DECLVAR_CONTEXT(interface, ifp);
1665 struct ospf6_interface *oi;
1666 assert(ifp);
718e3744 1667
d62a17ae 1668 oi = (struct ospf6_interface *)ifp->info;
1669 if (oi == NULL)
1670 oi = ospf6_interface_create(ifp);
1671 assert(oi);
718e3744 1672
d62a17ae 1673 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1674 THREAD_OFF(oi->thread_send_hello);
f80003b0 1675 THREAD_OFF(oi->thread_sso);
d62a17ae 1676 thread_add_event(master, ospf6_hello_send, oi, 0,
1677 &oi->thread_send_hello);
718e3744 1678
d62a17ae 1679 return CMD_SUCCESS;
718e3744 1680}
1681
d42306d9
DT
1682DEFUN (ipv6_ospf6_mtu_ignore,
1683 ipv6_ospf6_mtu_ignore_cmd,
1684 "ipv6 ospf6 mtu-ignore",
1685 IP6_STR
1686 OSPF6_STR
99a522c7 1687 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1688 )
1689{
d62a17ae 1690 VTY_DECLVAR_CONTEXT(interface, ifp);
1691 struct ospf6_interface *oi;
1692 assert(ifp);
d42306d9 1693
d62a17ae 1694 oi = (struct ospf6_interface *)ifp->info;
1695 if (oi == NULL)
1696 oi = ospf6_interface_create(ifp);
1697 assert(oi);
d42306d9 1698
d62a17ae 1699 oi->mtu_ignore = 1;
d42306d9 1700
d62a17ae 1701 return CMD_SUCCESS;
d42306d9
DT
1702}
1703
1704DEFUN (no_ipv6_ospf6_mtu_ignore,
1705 no_ipv6_ospf6_mtu_ignore_cmd,
1706 "no ipv6 ospf6 mtu-ignore",
1707 NO_STR
1708 IP6_STR
1709 OSPF6_STR
99a522c7 1710 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1711 )
1712{
d62a17ae 1713 VTY_DECLVAR_CONTEXT(interface, ifp);
1714 struct ospf6_interface *oi;
1715 assert(ifp);
d42306d9 1716
d62a17ae 1717 oi = (struct ospf6_interface *)ifp->info;
1718 if (oi == NULL)
1719 oi = ospf6_interface_create(ifp);
1720 assert(oi);
d42306d9 1721
d62a17ae 1722 oi->mtu_ignore = 0;
d42306d9 1723
d62a17ae 1724 return CMD_SUCCESS;
d42306d9
DT
1725}
1726
718e3744 1727DEFUN (ipv6_ospf6_advertise_prefix_list,
1728 ipv6_ospf6_advertise_prefix_list_cmd,
1729 "ipv6 ospf6 advertise prefix-list WORD",
1730 IP6_STR
1731 OSPF6_STR
1732 "Advertising options\n"
1733 "Filter prefix using prefix-list\n"
1734 "Prefix list name\n"
1735 )
1736{
d62a17ae 1737 VTY_DECLVAR_CONTEXT(interface, ifp);
1738 int idx_word = 4;
1739 struct ospf6_interface *oi;
1740 assert(ifp);
1741
1742 oi = (struct ospf6_interface *)ifp->info;
1743 if (oi == NULL)
1744 oi = ospf6_interface_create(ifp);
1745 assert(oi);
1746
1747 if (oi->plist_name)
1748 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
1749 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
1750
1751 ospf6_interface_connected_route_update(oi->interface);
1752
1753 if (oi->area) {
1754 OSPF6_LINK_LSA_SCHEDULE(oi);
1755 if (oi->state == OSPF6_INTERFACE_DR) {
1756 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1757 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1758 }
1759 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1760 }
1761
1762 return CMD_SUCCESS;
718e3744 1763}
1764
1765DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1766 no_ipv6_ospf6_advertise_prefix_list_cmd,
d23d6de8 1767 "no ipv6 ospf6 advertise prefix-list [WORD]",
718e3744 1768 NO_STR
1769 IP6_STR
1770 OSPF6_STR
1771 "Advertising options\n"
1772 "Filter prefix using prefix-list\n"
d23d6de8 1773 "Prefix list name\n")
718e3744 1774{
d62a17ae 1775 VTY_DECLVAR_CONTEXT(interface, ifp);
1776 struct ospf6_interface *oi;
1777 assert(ifp);
1778
1779 oi = (struct ospf6_interface *)ifp->info;
1780 if (oi == NULL)
1781 oi = ospf6_interface_create(ifp);
1782 assert(oi);
1783
d23d6de8 1784 if (oi->plist_name)
d62a17ae 1785 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
d62a17ae 1786
1787 ospf6_interface_connected_route_update(oi->interface);
1788
1789 if (oi->area) {
1790 OSPF6_LINK_LSA_SCHEDULE(oi);
1791 if (oi->state == OSPF6_INTERFACE_DR) {
1792 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1793 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1794 }
1795 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1796 }
1797
1798 return CMD_SUCCESS;
718e3744 1799}
1800
c5926a92
DD
1801DEFUN (ipv6_ospf6_network,
1802 ipv6_ospf6_network_cmd,
6147e2c6 1803 "ipv6 ospf6 network <broadcast|point-to-point>",
c5926a92
DD
1804 IP6_STR
1805 OSPF6_STR
99a522c7 1806 "Network type\n"
b2d4d039 1807 "Specify OSPF6 broadcast network\n"
c5926a92
DD
1808 "Specify OSPF6 point-to-point network\n"
1809 )
1810{
d62a17ae 1811 VTY_DECLVAR_CONTEXT(interface, ifp);
1812 int idx_network = 3;
1813 struct ospf6_interface *oi;
1814 assert(ifp);
1815
1816 oi = (struct ospf6_interface *)ifp->info;
1817 if (oi == NULL) {
1818 oi = ospf6_interface_create(ifp);
1819 }
1820 assert(oi);
1821
5aeb4f3c
DL
1822 oi->type_cfg = true;
1823
d62a17ae 1824 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
1825 if (oi->type == OSPF_IFTYPE_BROADCAST)
1826 return CMD_SUCCESS;
1827
1828 oi->type = OSPF_IFTYPE_BROADCAST;
1829 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
1830 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
1831 return CMD_SUCCESS;
1832 }
1833 oi->type = OSPF_IFTYPE_POINTOPOINT;
c5926a92 1834 }
c5926a92 1835
d62a17ae 1836 /* Reset the interface */
849576ee
RZ
1837 thread_execute(master, interface_down, oi, 0);
1838 thread_execute(master, interface_up, oi, 0);
c5926a92 1839
d62a17ae 1840 return CMD_SUCCESS;
c5926a92
DD
1841}
1842
1843DEFUN (no_ipv6_ospf6_network,
1844 no_ipv6_ospf6_network_cmd,
32573073 1845 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
c5926a92
DD
1846 NO_STR
1847 IP6_STR
1848 OSPF6_STR
32573073
QY
1849 "Set default network type\n"
1850 "Specify OSPF6 broadcast network\n"
1851 "Specify OSPF6 point-to-point network\n")
c5926a92 1852{
d62a17ae 1853 VTY_DECLVAR_CONTEXT(interface, ifp);
1854 struct ospf6_interface *oi;
1855 int type;
c5926a92 1856
d62a17ae 1857 assert(ifp);
c5926a92 1858
d62a17ae 1859 oi = (struct ospf6_interface *)ifp->info;
1860 if (oi == NULL) {
1861 return CMD_SUCCESS;
1862 }
c5926a92 1863
5aeb4f3c
DL
1864 oi->type_cfg = false;
1865
d62a17ae 1866 type = ospf6_default_iftype(ifp);
1867 if (oi->type == type) {
1868 return CMD_SUCCESS;
1869 }
1870 oi->type = type;
c5926a92 1871
d62a17ae 1872 /* Reset the interface */
849576ee
RZ
1873 thread_execute(master, interface_down, oi, 0);
1874 thread_execute(master, interface_up, oi, 0);
c5926a92 1875
d62a17ae 1876 return CMD_SUCCESS;
c5926a92
DD
1877}
1878
d62a17ae 1879static int config_write_ospf6_interface(struct vty *vty)
718e3744 1880{
f4e14fdb 1881 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1882 struct ospf6_interface *oi;
1883 struct interface *ifp;
1884
451fda4f 1885 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1886 oi = (struct ospf6_interface *)ifp->info;
1887 if (oi == NULL)
1888 continue;
1889
a8b828f3 1890 vty_frame(vty, "interface %s\n", oi->interface->name);
d62a17ae 1891
1892 if (ifp->desc)
1893 vty_out(vty, " description %s\n", ifp->desc);
1894 if (oi->c_ifmtu)
1895 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
1896
1897 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
1898 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
1899
1900 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1901 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
1902 oi->hello_interval);
1903
1904 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1905 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
1906 oi->dead_interval);
1907
1908 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1909 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
1910 oi->rxmt_interval);
1911
1912 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1913 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
1914
1915 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1916 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
1917 oi->transdelay);
1918
1919 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1920 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
1921 oi->instance_id);
1922
1923 if (oi->plist_name)
1924 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
1925 oi->plist_name);
1926
1927 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
1928 vty_out(vty, " ipv6 ospf6 passive\n");
1929
1930 if (oi->mtu_ignore)
1931 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
1932
5aeb4f3c
DL
1933 if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
1934 vty_out(vty, " ipv6 ospf6 network point-to-point\n");
1935 else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
1936 vty_out(vty, " ipv6 ospf6 network broadcast\n");
d62a17ae 1937
1938 ospf6_bfd_write_config(vty, oi);
1939
a8b828f3 1940 vty_endframe(vty, "!\n");
d62a17ae 1941 }
1942 return 0;
718e3744 1943}
1944
d62a17ae 1945static struct cmd_node interface_node = {
1946 INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */
718e3744 1947};
1948
d62a17ae 1949void ospf6_interface_init(void)
718e3744 1950{
d62a17ae 1951 /* Install interface node. */
1952 install_node(&interface_node, config_write_ospf6_interface);
1953 if_cmd_init();
1954
1955 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
1956 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1957 install_element(VIEW_NODE,
1958 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
996c9314 1959 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
d62a17ae 1960
1961 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
1962 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
1963 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
1964 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
d23d6de8 1965
d62a17ae 1966 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1967 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1968 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1969 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1970 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1971 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
d23d6de8
QY
1972 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
1973 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
1974 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
1975 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
1976 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
1977 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
d62a17ae 1978
1979 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1980 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
1981
1982 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
1983 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
1984
1985 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1986 install_element(INTERFACE_NODE,
1987 &no_ipv6_ospf6_advertise_prefix_list_cmd);
1988
1989 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
1990 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
1991
1992 /* reference bandwidth commands */
1993 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
1994 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
508e53e2 1995}
1996
a1b11f9b 1997/* Clear the specified interface structure */
d62a17ae 1998static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
a1b11f9b 1999{
d62a17ae 2000 struct ospf6_interface *oi;
a1b11f9b 2001
d62a17ae 2002 if (!if_is_operative(ifp))
2003 return;
a1b11f9b 2004
d62a17ae 2005 if (ifp->info == NULL)
2006 return;
a1b11f9b 2007
d62a17ae 2008 oi = (struct ospf6_interface *)ifp->info;
a1b11f9b 2009
d62a17ae 2010 if (IS_OSPF6_DEBUG_INTERFACE)
2011 zlog_debug("Interface %s: clear by reset", ifp->name);
a1b11f9b 2012
d62a17ae 2013 /* Reset the interface */
849576ee
RZ
2014 thread_execute(master, interface_down, oi, 0);
2015 thread_execute(master, interface_up, oi, 0);
a1b11f9b
DS
2016}
2017
2018/* Clear interface */
2019DEFUN (clear_ipv6_ospf6_interface,
2020 clear_ipv6_ospf6_interface_cmd,
2021 "clear ipv6 ospf6 interface [IFNAME]",
2022 CLEAR_STR
2023 IP6_STR
2024 OSPF6_STR
2025 INTERFACE_STR
2026 IFNAME_STR
2027 )
2028{
f4e14fdb 2029 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 2030 int idx_ifname = 4;
2031 struct interface *ifp;
d62a17ae 2032
2033 if (argc == 4) /* Clear all the ospfv3 interfaces. */
2034 {
451fda4f 2035 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 2036 ospf6_interface_clear(vty, ifp);
2037 } else /* Interface name is specified. */
2038 {
2039 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
a36898e7 2040 VRF_DEFAULT))
d62a17ae 2041 == NULL) {
2042 vty_out(vty, "No such Interface: %s\n",
2043 argv[idx_ifname]->arg);
2044 return CMD_WARNING;
2045 }
2046 ospf6_interface_clear(vty, ifp);
2047 }
2048
2049 return CMD_SUCCESS;
a1b11f9b
DS
2050}
2051
d62a17ae 2052void install_element_ospf6_clear_interface(void)
a1b11f9b 2053{
d62a17ae 2054 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
a1b11f9b
DS
2055}
2056
508e53e2 2057DEFUN (debug_ospf6_interface,
2058 debug_ospf6_interface_cmd,
2059 "debug ospf6 interface",
2060 DEBUG_STR
2061 OSPF6_STR
2062 "Debug OSPFv3 Interface\n"
2063 )
2064{
d62a17ae 2065 OSPF6_DEBUG_INTERFACE_ON();
2066 return CMD_SUCCESS;
508e53e2 2067}
2068
2069DEFUN (no_debug_ospf6_interface,
2070 no_debug_ospf6_interface_cmd,
2071 "no debug ospf6 interface",
2072 NO_STR
2073 DEBUG_STR
2074 OSPF6_STR
2075 "Debug OSPFv3 Interface\n"
2076 )
2077{
d62a17ae 2078 OSPF6_DEBUG_INTERFACE_OFF();
2079 return CMD_SUCCESS;
508e53e2 2080}
2081
d62a17ae 2082int config_write_ospf6_debug_interface(struct vty *vty)
508e53e2 2083{
d62a17ae 2084 if (IS_OSPF6_DEBUG_INTERFACE)
2085 vty_out(vty, "debug ospf6 interface\n");
2086 return 0;
508e53e2 2087}
2088
d62a17ae 2089void install_element_ospf6_debug_interface(void)
508e53e2 2090{
d62a17ae 2091 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2092 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2093 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2094 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
718e3744 2095}