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