]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_interface.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / ospf6d / ospf6_interface.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 19 */
20
508e53e2 21#include <zebra.h>
718e3744 22
508e53e2 23#include "memory.h"
718e3744 24#include "if.h"
25#include "log.h"
26#include "command.h"
508e53e2 27#include "thread.h"
28#include "prefix.h"
29#include "plist.h"
88177fe3 30#include "zclient.h"
718e3744 31
508e53e2 32#include "ospf6_lsa.h"
718e3744 33#include "ospf6_lsdb.h"
508e53e2 34#include "ospf6_network.h"
35#include "ospf6_message.h"
36#include "ospf6_route.h"
718e3744 37#include "ospf6_top.h"
38#include "ospf6_area.h"
39#include "ospf6_interface.h"
508e53e2 40#include "ospf6_neighbor.h"
41#include "ospf6_intra.h"
42#include "ospf6_spf.h"
049207c3 43#include "ospf6d.h"
7f342629 44#include "ospf6_bfd.h"
718e3744 45
4a1ab8e4 46DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
ae19c240 47DEFINE_QOBJ_TYPE(ospf6_interface)
3012671f 48DEFINE_HOOK(ospf6_interface_change,
d62a17ae 49 (struct ospf6_interface * oi, int state, int old_state),
50 (oi, state, old_state))
4a1ab8e4 51
508e53e2 52unsigned char conf_debug_ospf6_interface = 0;
53
d62a17ae 54const char *ospf6_interface_state_str[] = {
55 "None", "Down", "Loopback", "Waiting", "PointToPoint",
56 "DROther", "BDR", "DR", NULL};
718e3744 57
d62a17ae 58struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex)
718e3744 59{
d62a17ae 60 struct ospf6_interface *oi;
61 struct interface *ifp;
718e3744 62
d62a17ae 63 ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
64 if (ifp == NULL)
65 return (struct ospf6_interface *)NULL;
508e53e2 66
d62a17ae 67 oi = (struct ospf6_interface *)ifp->info;
68 return oi;
718e3744 69}
70
508e53e2 71/* schedule routing table recalculation */
d62a17ae 72static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa,
73 unsigned int reason)
718e3744 74{
d62a17ae 75 struct ospf6_interface *oi;
76
77 if (lsa == NULL)
78 return;
79
80 oi = lsa->lsdb->data;
81 switch (ntohs(lsa->header->type)) {
82 case OSPF6_LSTYPE_LINK:
83 if (oi->state == OSPF6_INTERFACE_DR)
84 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
85 if (oi->area)
86 ospf6_spf_schedule(oi->area->ospf6, reason);
87 break;
88
89 default:
90 break;
91 }
718e3744 92}
93
d62a17ae 94static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa *lsa)
a0edf674 95{
d62a17ae 96 ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa));
a0edf674
DD
97}
98
d62a17ae 99static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa *lsa)
a0edf674 100{
d62a17ae 101 ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa));
a0edf674
DD
102}
103
d7c0a89a 104static uint8_t ospf6_default_iftype(struct interface *ifp)
c5926a92 105{
d62a17ae 106 if (if_is_pointopoint(ifp))
107 return OSPF_IFTYPE_POINTOPOINT;
108 else if (if_is_loopback(ifp))
109 return OSPF_IFTYPE_LOOPBACK;
110 else
111 return OSPF_IFTYPE_BROADCAST;
c5926a92
DD
112}
113
d7c0a89a 114static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
c19543b2 115{
d62a17ae 116 /* If all else fails, use default OSPF cost */
d7c0a89a
QY
117 uint32_t cost;
118 uint32_t bw, refbw;
d62a17ae 119
27ae9bcd
CS
120 /* interface speed and bw can be 0 in some platforms,
121 * use ospf default bw. If bw is configured then it would
122 * be used.
123 */
124 if (!oi->interface->bandwidth && oi->interface->speed) {
125 bw = oi->interface->speed;
126 } else {
127 bw = oi->interface->bandwidth ? oi->interface->bandwidth
996c9314 128 : OSPF6_INTERFACE_BANDWIDTH;
27ae9bcd
CS
129 }
130
d62a17ae 131 refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
132
133 /* A specifed ip ospf cost overrides a calculated one. */
134 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
135 cost = oi->cost;
136 else {
d7c0a89a 137 cost = (uint32_t)((double)refbw / (double)bw + (double)0.5);
d62a17ae 138 if (cost < 1)
139 cost = 1;
140 else if (cost > UINT32_MAX)
141 cost = UINT32_MAX;
142 }
143
144 return cost;
c19543b2
VB
145}
146
0db8196a 147static void ospf6_interface_force_recalculate_cost(struct ospf6_interface *oi)
c19543b2 148{
d62a17ae 149 /* update cost held in route_connected list in ospf6_interface */
150 ospf6_interface_connected_route_update(oi->interface);
151
152 /* execute LSA hooks */
153 if (oi->area) {
154 OSPF6_LINK_LSA_SCHEDULE(oi);
155 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
156 OSPF6_NETWORK_LSA_SCHEDULE(oi);
157 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
158 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
159 }
c19543b2
VB
160}
161
0db8196a
JK
162static void ospf6_interface_recalculate_cost(struct ospf6_interface *oi)
163{
d7c0a89a 164 uint32_t newcost;
0db8196a
JK
165
166 newcost = ospf6_interface_get_cost(oi);
167 if (newcost == oi->cost)
168 return;
169 oi->cost = newcost;
170
171 ospf6_interface_force_recalculate_cost(oi);
172}
173
718e3744 174/* Create new ospf6 interface structure */
d62a17ae 175struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
718e3744 176{
d62a17ae 177 struct ospf6_interface *oi;
178 unsigned int iobuflen;
179
180 oi = (struct ospf6_interface *)XCALLOC(MTYPE_OSPF6_IF,
181 sizeof(struct ospf6_interface));
182
d62a17ae 183 oi->area = (struct ospf6_area *)NULL;
184 oi->neighbor_list = list_new();
185 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
186 oi->linklocal_addr = (struct in6_addr *)NULL;
187 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
188 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
189 oi->priority = OSPF6_INTERFACE_PRIORITY;
190
191 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
192 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
193 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
194 oi->type = ospf6_default_iftype(ifp);
195 oi->state = OSPF6_INTERFACE_DOWN;
196 oi->flag = 0;
197 oi->mtu_ignore = 0;
198 oi->c_ifmtu = 0;
199
200 /* Try to adjust I/O buffer size with IfMtu */
201 oi->ifmtu = ifp->mtu6;
202 iobuflen = ospf6_iobuf_size(ifp->mtu6);
203 if (oi->ifmtu > iobuflen) {
204 if (IS_OSPF6_DEBUG_INTERFACE)
205 zlog_debug(
206 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
207 ifp->name, iobuflen);
208 oi->ifmtu = iobuflen;
209 }
210
211 QOBJ_REG(oi, ospf6_interface);
212
213 oi->lsupdate_list = ospf6_lsdb_create(oi);
214 oi->lsack_list = ospf6_lsdb_create(oi);
215 oi->lsdb = ospf6_lsdb_create(oi);
216 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
217 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
218 oi->lsdb_self = ospf6_lsdb_create(oi);
219
220 oi->route_connected =
221 OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
222 oi->route_connected->scope = oi;
223
224 /* link both */
225 oi->interface = ifp;
226 ifp->info = oi;
227
228 /* Compute cost. */
229 oi->cost = ospf6_interface_get_cost(oi);
230
231 return oi;
718e3744 232}
233
d62a17ae 234void ospf6_interface_delete(struct ospf6_interface *oi)
718e3744 235{
d62a17ae 236 struct listnode *node, *nnode;
237 struct ospf6_neighbor *on;
238
239 QOBJ_UNREG(oi);
718e3744 240
d62a17ae 241 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
242 ospf6_neighbor_delete(on);
ae19c240 243
6a154c88 244 list_delete(&oi->neighbor_list);
718e3744 245
d62a17ae 246 THREAD_OFF(oi->thread_send_hello);
247 THREAD_OFF(oi->thread_send_lsupdate);
248 THREAD_OFF(oi->thread_send_lsack);
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,
25ee05c9
RW
1076 "show ipv6 ospf6 interface IFNAME prefix\
1077 [<\
1078 detail\
1079 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1080 >]",
508e53e2 1081 SHOW_STR
1082 IP6_STR
1083 OSPF6_STR
1084 INTERFACE_STR
1085 IFNAME_STR
093d7a3a 1086 "Display connected prefixes to advertise\n"
25ee05c9 1087 "Display details of the prefixes\n"
093d7a3a
DW
1088 OSPF6_ROUTE_ADDRESS_STR
1089 OSPF6_ROUTE_PREFIX_STR
1090 OSPF6_ROUTE_MATCH_STR
1091 "Display details of the prefixes\n")
508e53e2 1092{
d62a17ae 1093 int idx_ifname = 4;
1094 int idx_prefix = 6;
1095 struct interface *ifp;
1096 struct ospf6_interface *oi;
1097
1098 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
1099 if (ifp == NULL) {
1100 vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
1101 return CMD_WARNING;
1102 }
1103
1104 oi = ifp->info;
1105 if (oi == NULL) {
1106 vty_out(vty, "OSPFv3 is not enabled on %s\n",
1107 argv[idx_ifname]->arg);
1108 return CMD_WARNING;
1109 }
1110
1111 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1112 oi->route_connected);
1113
1114 return CMD_SUCCESS;
508e53e2 1115}
1116
508e53e2 1117DEFUN (show_ipv6_ospf6_interface_prefix,
1118 show_ipv6_ospf6_interface_prefix_cmd,
25ee05c9
RW
1119 "show ipv6 ospf6 interface prefix\
1120 [<\
1121 detail\
1122 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1123 >]",
508e53e2 1124 SHOW_STR
1125 IP6_STR
1126 OSPF6_STR
1127 INTERFACE_STR
1128 "Display connected prefixes to advertise\n"
25ee05c9 1129 "Display details of the prefixes\n"
093d7a3a
DW
1130 OSPF6_ROUTE_ADDRESS_STR
1131 OSPF6_ROUTE_PREFIX_STR
1132 OSPF6_ROUTE_MATCH_STR
1133 "Display details of the prefixes\n")
508e53e2 1134{
f4e14fdb 1135 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1136 int idx_prefix = 5;
d62a17ae 1137 struct ospf6_interface *oi;
1138 struct interface *ifp;
1139
451fda4f 1140 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1141 oi = (struct ospf6_interface *)ifp->info;
1142 if (oi == NULL)
1143 continue;
1144
1145 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1146 oi->route_connected);
1147 }
508e53e2 1148
d62a17ae 1149 return CMD_SUCCESS;
508e53e2 1150}
1151
718e3744 1152/* interface variable set command */
b596c71e 1153DEFUN (ipv6_ospf6_ifmtu,
1154 ipv6_ospf6_ifmtu_cmd,
6147e2c6 1155 "ipv6 ospf6 ifmtu (1-65535)",
b596c71e 1156 IP6_STR
1157 OSPF6_STR
1158 "Interface MTU\n"
1159 "OSPFv3 Interface MTU\n"
1160 )
1161{
d62a17ae 1162 VTY_DECLVAR_CONTEXT(interface, ifp);
1163 int idx_number = 3;
1164 struct ospf6_interface *oi;
1165 unsigned int ifmtu, iobuflen;
1166 struct listnode *node, *nnode;
1167 struct ospf6_neighbor *on;
1168
1169 assert(ifp);
1170
1171 oi = (struct ospf6_interface *)ifp->info;
1172 if (oi == NULL)
1173 oi = ospf6_interface_create(ifp);
1174 assert(oi);
1175
1176 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1177
1178 if (oi->c_ifmtu == ifmtu)
1179 return CMD_SUCCESS;
1180
1181 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1182 vty_out(vty,
1183 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1184 ifp->name, ifp->mtu6);
1185 return CMD_WARNING_CONFIG_FAILED;
1186 }
1187
1188 if (oi->ifmtu < ifmtu) {
1189 iobuflen = ospf6_iobuf_size(ifmtu);
1190 if (iobuflen < ifmtu) {
1191 vty_out(vty,
1192 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1193 ifp->name, iobuflen);
1194 oi->ifmtu = oi->c_ifmtu = iobuflen;
1195 } else
1196 oi->ifmtu = oi->c_ifmtu = ifmtu;
1197 } else
1198 oi->ifmtu = oi->c_ifmtu = ifmtu;
1199
1200 /* re-establish adjacencies */
1201 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1202 THREAD_OFF(on->inactivity_timer);
1203 thread_add_event(master, inactivity_timer, on, 0, NULL);
1204 }
1205
1206 return CMD_SUCCESS;
b596c71e 1207}
1208
049207c3 1209DEFUN (no_ipv6_ospf6_ifmtu,
1210 no_ipv6_ospf6_ifmtu_cmd,
0c7ef48a 1211 "no ipv6 ospf6 ifmtu [(1-65535)]",
049207c3 1212 NO_STR
1213 IP6_STR
1214 OSPF6_STR
1215 "Interface MTU\n"
0c7ef48a 1216 "OSPFv3 Interface MTU\n"
049207c3 1217 )
1218{
d62a17ae 1219 VTY_DECLVAR_CONTEXT(interface, ifp);
1220 struct ospf6_interface *oi;
1221 unsigned int iobuflen;
1222 struct listnode *node, *nnode;
1223 struct ospf6_neighbor *on;
1224
1225 assert(ifp);
1226
1227 oi = (struct ospf6_interface *)ifp->info;
1228 if (oi == NULL)
1229 oi = ospf6_interface_create(ifp);
1230 assert(oi);
1231
1232 if (oi->ifmtu < ifp->mtu) {
1233 iobuflen = ospf6_iobuf_size(ifp->mtu);
1234 if (iobuflen < ifp->mtu) {
1235 vty_out(vty,
1236 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1237 ifp->name, iobuflen);
1238 oi->ifmtu = iobuflen;
1239 } else
1240 oi->ifmtu = ifp->mtu;
1241 } else
1242 oi->ifmtu = ifp->mtu;
1243
1244 oi->c_ifmtu = 0;
1245
1246 /* re-establish adjacencies */
1247 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1248 THREAD_OFF(on->inactivity_timer);
1249 thread_add_event(master, inactivity_timer, on, 0, NULL);
1250 }
1251
1252 return CMD_SUCCESS;
049207c3 1253}
1254
718e3744 1255DEFUN (ipv6_ospf6_cost,
1256 ipv6_ospf6_cost_cmd,
6147e2c6 1257 "ipv6 ospf6 cost (1-65535)",
718e3744 1258 IP6_STR
1259 OSPF6_STR
1260 "Interface cost\n"
32573073 1261 "Outgoing metric of this interface\n")
718e3744 1262{
d62a17ae 1263 VTY_DECLVAR_CONTEXT(interface, ifp);
1264 int idx_number = 3;
1265 struct ospf6_interface *oi;
1266 unsigned long int lcost;
1267
1268 assert(ifp);
1269
1270 oi = (struct ospf6_interface *)ifp->info;
1271 if (oi == NULL)
1272 oi = ospf6_interface_create(ifp);
1273 assert(oi);
1274
1275 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1276
1277 if (lcost > UINT32_MAX) {
1278 vty_out(vty, "Cost %ld is out of range\n", lcost);
1279 return CMD_WARNING_CONFIG_FAILED;
1280 }
1281
1282 if (oi->cost == lcost)
1283 return CMD_SUCCESS;
1284
1285 oi->cost = lcost;
1286 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1287
0db8196a 1288 ospf6_interface_force_recalculate_cost(oi);
d62a17ae 1289
1290 return CMD_SUCCESS;
c19543b2
VB
1291}
1292
1293DEFUN (no_ipv6_ospf6_cost,
1294 no_ipv6_ospf6_cost_cmd,
32573073 1295 "no ipv6 ospf6 cost [(1-65535)]",
c19543b2
VB
1296 NO_STR
1297 IP6_STR
1298 OSPF6_STR
1299 "Calculate interface cost from bandwidth\n"
32573073 1300 "Outgoing metric of this interface\n")
c19543b2 1301{
d62a17ae 1302 VTY_DECLVAR_CONTEXT(interface, ifp);
1303 struct ospf6_interface *oi;
1304 assert(ifp);
c19543b2 1305
d62a17ae 1306 oi = (struct ospf6_interface *)ifp->info;
1307 if (oi == NULL)
1308 oi = ospf6_interface_create(ifp);
1309 assert(oi);
c19543b2 1310
d62a17ae 1311 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
c19543b2 1312
d62a17ae 1313 ospf6_interface_recalculate_cost(oi);
718e3744 1314
d62a17ae 1315 return CMD_SUCCESS;
718e3744 1316}
1317
fd500689
VB
1318DEFUN (auto_cost_reference_bandwidth,
1319 auto_cost_reference_bandwidth_cmd,
6147e2c6 1320 "auto-cost reference-bandwidth (1-4294967)",
fd500689
VB
1321 "Calculate OSPF interface cost according to bandwidth\n"
1322 "Use reference bandwidth method to assign OSPF cost\n"
1323 "The reference bandwidth in terms of Mbits per second\n")
1324{
d62a17ae 1325 VTY_DECLVAR_CONTEXT(ospf6, o);
1326 int idx_number = 2;
1327 struct ospf6_area *oa;
1328 struct ospf6_interface *oi;
1329 struct listnode *i, *j;
d7c0a89a 1330 uint32_t refbw;
d62a17ae 1331
1332 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1333 if (refbw < 1 || refbw > 4294967) {
1334 vty_out(vty, "reference-bandwidth value is invalid\n");
1335 return CMD_WARNING_CONFIG_FAILED;
1336 }
1337
1338 /* If reference bandwidth is changed. */
1339 if ((refbw) == o->ref_bandwidth)
1340 return CMD_SUCCESS;
1341
1342 o->ref_bandwidth = refbw;
1343 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1344 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1345 ospf6_interface_recalculate_cost(oi);
1346
1347 return CMD_SUCCESS;
fd500689
VB
1348}
1349
1350DEFUN (no_auto_cost_reference_bandwidth,
1351 no_auto_cost_reference_bandwidth_cmd,
ccb8e0c7 1352 "no auto-cost reference-bandwidth [(1-4294967)]",
fd500689
VB
1353 NO_STR
1354 "Calculate OSPF interface cost according to bandwidth\n"
1d68dbfe
DW
1355 "Use reference bandwidth method to assign OSPF cost\n"
1356 "The reference bandwidth in terms of Mbits per second\n")
fd500689 1357{
d62a17ae 1358 VTY_DECLVAR_CONTEXT(ospf6, o);
1359 struct ospf6_area *oa;
1360 struct ospf6_interface *oi;
1361 struct listnode *i, *j;
fd500689 1362
d62a17ae 1363 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1364 return CMD_SUCCESS;
fd500689 1365
d62a17ae 1366 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1367 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1368 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1369 ospf6_interface_recalculate_cost(oi);
fd500689 1370
d62a17ae 1371 return CMD_SUCCESS;
fd500689
VB
1372}
1373
813d4307 1374
718e3744 1375DEFUN (ipv6_ospf6_hellointerval,
1376 ipv6_ospf6_hellointerval_cmd,
6147e2c6 1377 "ipv6 ospf6 hello-interval (1-65535)",
718e3744 1378 IP6_STR
1379 OSPF6_STR
99a522c7 1380 "Time between HELLO packets\n"
d23d6de8 1381 SECONDS_STR)
718e3744 1382{
d62a17ae 1383 VTY_DECLVAR_CONTEXT(interface, ifp);
1384 int idx_number = 3;
1385 struct ospf6_interface *oi;
1386 assert(ifp);
1387
1388 oi = (struct ospf6_interface *)ifp->info;
1389 if (oi == NULL)
1390 oi = ospf6_interface_create(ifp);
1391 assert(oi);
1392
d23d6de8
QY
1393 oi->hello_interval = strmatch(argv[0]->text, "no")
1394 ? OSPF_HELLO_INTERVAL_DEFAULT
1395 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1396 return CMD_SUCCESS;
718e3744 1397}
1398
d23d6de8
QY
1399ALIAS (ipv6_ospf6_hellointerval,
1400 no_ipv6_ospf6_hellointerval_cmd,
1401 "no ipv6 ospf6 hello-interval [(1-65535)]",
1402 NO_STR
1403 IP6_STR
1404 OSPF6_STR
1405 "Time between HELLO packets\n"
1406 SECONDS_STR)
1407
718e3744 1408/* interface variable set command */
1409DEFUN (ipv6_ospf6_deadinterval,
1410 ipv6_ospf6_deadinterval_cmd,
6147e2c6 1411 "ipv6 ospf6 dead-interval (1-65535)",
718e3744 1412 IP6_STR
1413 OSPF6_STR
508e53e2 1414 "Interval time after which a neighbor is declared down\n"
d23d6de8 1415 SECONDS_STR)
718e3744 1416{
d62a17ae 1417 VTY_DECLVAR_CONTEXT(interface, ifp);
1418 int idx_number = 3;
1419 struct ospf6_interface *oi;
1420 assert(ifp);
1421
1422 oi = (struct ospf6_interface *)ifp->info;
1423 if (oi == NULL)
1424 oi = ospf6_interface_create(ifp);
1425 assert(oi);
1426
d23d6de8
QY
1427 oi->dead_interval = strmatch(argv[0]->arg, "no")
1428 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1429 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1430 return CMD_SUCCESS;
718e3744 1431}
1432
d23d6de8
QY
1433ALIAS (ipv6_ospf6_deadinterval,
1434 no_ipv6_ospf6_deadinterval_cmd,
1435 "no ipv6 ospf6 dead-interval [(1-65535)]",
1436 NO_STR
1437 IP6_STR
1438 OSPF6_STR
1439 "Interval time after which a neighbor is declared down\n"
1440 SECONDS_STR)
1441
718e3744 1442/* interface variable set command */
1443DEFUN (ipv6_ospf6_transmitdelay,
1444 ipv6_ospf6_transmitdelay_cmd,
6147e2c6 1445 "ipv6 ospf6 transmit-delay (1-3600)",
718e3744 1446 IP6_STR
1447 OSPF6_STR
99a522c7 1448 "Link state transmit delay\n"
98cfd06b 1449 SECONDS_STR)
718e3744 1450{
d62a17ae 1451 VTY_DECLVAR_CONTEXT(interface, ifp);
1452 int idx_number = 3;
1453 struct ospf6_interface *oi;
1454 assert(ifp);
1455
1456 oi = (struct ospf6_interface *)ifp->info;
1457 if (oi == NULL)
1458 oi = ospf6_interface_create(ifp);
1459 assert(oi);
1460
d23d6de8
QY
1461 oi->transdelay = strmatch(argv[0]->text, "no")
1462 ? OSPF6_INTERFACE_TRANSDELAY
1463 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1464 return CMD_SUCCESS;
718e3744 1465}
1466
d23d6de8
QY
1467ALIAS (ipv6_ospf6_transmitdelay,
1468 no_ipv6_ospf6_transmitdelay_cmd,
1469 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1470 NO_STR
1471 IP6_STR
1472 OSPF6_STR
1473 "Link state transmit delay\n"
1474 SECONDS_STR)
1475
718e3744 1476/* interface variable set command */
1477DEFUN (ipv6_ospf6_retransmitinterval,
1478 ipv6_ospf6_retransmitinterval_cmd,
6147e2c6 1479 "ipv6 ospf6 retransmit-interval (1-65535)",
718e3744 1480 IP6_STR
1481 OSPF6_STR
1482 "Time between retransmitting lost link state advertisements\n"
d23d6de8 1483 SECONDS_STR)
718e3744 1484{
d62a17ae 1485 VTY_DECLVAR_CONTEXT(interface, ifp);
1486 int idx_number = 3;
1487 struct ospf6_interface *oi;
1488 assert(ifp);
1489
1490 oi = (struct ospf6_interface *)ifp->info;
1491 if (oi == NULL)
1492 oi = ospf6_interface_create(ifp);
1493 assert(oi);
1494
d23d6de8
QY
1495 oi->rxmt_interval = strmatch(argv[0]->text, "no")
1496 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1497 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1498 return CMD_SUCCESS;
718e3744 1499}
1500
d23d6de8
QY
1501ALIAS (ipv6_ospf6_retransmitinterval,
1502 no_ipv6_ospf6_retransmitinterval_cmd,
1503 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1504 NO_STR
1505 IP6_STR
1506 OSPF6_STR
1507 "Time between retransmitting lost link state advertisements\n"
1508 SECONDS_STR)
1509
718e3744 1510/* interface variable set command */
1511DEFUN (ipv6_ospf6_priority,
1512 ipv6_ospf6_priority_cmd,
6147e2c6 1513 "ipv6 ospf6 priority (0-255)",
718e3744 1514 IP6_STR
1515 OSPF6_STR
1516 "Router priority\n"
d23d6de8 1517 "Priority value\n")
718e3744 1518{
d62a17ae 1519 VTY_DECLVAR_CONTEXT(interface, ifp);
1520 int idx_number = 3;
1521 struct ospf6_interface *oi;
1522 assert(ifp);
718e3744 1523
d62a17ae 1524 oi = (struct ospf6_interface *)ifp->info;
1525 if (oi == NULL)
1526 oi = ospf6_interface_create(ifp);
1527 assert(oi);
508e53e2 1528
d23d6de8
QY
1529 oi->priority = strmatch(argv[0]->text, "no")
1530 ? OSPF6_INTERFACE_PRIORITY
1531 : strtoul(argv[idx_number]->arg, NULL, 10);
718e3744 1532
9d303b37
DL
1533 if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
1534 || oi->state == OSPF6_INTERFACE_BDR
1535 || oi->state == OSPF6_INTERFACE_DR))
d62a17ae 1536 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 1537
d62a17ae 1538 return CMD_SUCCESS;
718e3744 1539}
1540
d23d6de8
QY
1541ALIAS (ipv6_ospf6_priority,
1542 no_ipv6_ospf6_priority_cmd,
1543 "no ipv6 ospf6 priority [(0-255)]",
1544 NO_STR
1545 IP6_STR
1546 OSPF6_STR
1547 "Router priority\n"
1548 "Priority value\n")
1549
718e3744 1550DEFUN (ipv6_ospf6_instance,
1551 ipv6_ospf6_instance_cmd,
6147e2c6 1552 "ipv6 ospf6 instance-id (0-255)",
718e3744 1553 IP6_STR
1554 OSPF6_STR
508e53e2 1555 "Instance ID for this interface\n"
d23d6de8 1556 "Instance ID value\n")
718e3744 1557{
d62a17ae 1558 VTY_DECLVAR_CONTEXT(interface, ifp);
1559 int idx_number = 3;
1560 struct ospf6_interface *oi;
1561 assert(ifp);
1562
1563 oi = (struct ospf6_interface *)ifp->info;
1564 if (oi == NULL)
1565 oi = ospf6_interface_create(ifp);
1566 assert(oi);
1567
d23d6de8
QY
1568 oi->instance_id = strmatch(argv[0]->text, "no")
1569 ? OSPF6_INTERFACE_INSTANCE_ID
1570 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1571 return CMD_SUCCESS;
718e3744 1572}
1573
d23d6de8
QY
1574ALIAS (ipv6_ospf6_instance,
1575 no_ipv6_ospf6_instance_cmd,
1576 "no ipv6 ospf6 instance-id [(0-255)]",
1577 NO_STR
1578 IP6_STR
1579 OSPF6_STR
1580 "Instance ID for this interface\n"
1581 "Instance ID value\n")
1582
718e3744 1583DEFUN (ipv6_ospf6_passive,
1584 ipv6_ospf6_passive_cmd,
1585 "ipv6 ospf6 passive",
1586 IP6_STR
1587 OSPF6_STR
99a522c7 1588 "Passive interface; no adjacency will be formed on this interface\n"
718e3744 1589 )
1590{
d62a17ae 1591 VTY_DECLVAR_CONTEXT(interface, ifp);
1592 struct ospf6_interface *oi;
1593 struct listnode *node, *nnode;
1594 struct ospf6_neighbor *on;
718e3744 1595
d62a17ae 1596 assert(ifp);
718e3744 1597
d62a17ae 1598 oi = (struct ospf6_interface *)ifp->info;
1599 if (oi == NULL)
1600 oi = ospf6_interface_create(ifp);
1601 assert(oi);
718e3744 1602
d62a17ae 1603 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1604 THREAD_OFF(oi->thread_send_hello);
508e53e2 1605
d62a17ae 1606 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1607 THREAD_OFF(on->inactivity_timer);
1608 thread_add_event(master, inactivity_timer, on, 0, NULL);
1609 }
718e3744 1610
d62a17ae 1611 return CMD_SUCCESS;
718e3744 1612}
1613
1614DEFUN (no_ipv6_ospf6_passive,
1615 no_ipv6_ospf6_passive_cmd,
1616 "no ipv6 ospf6 passive",
1617 NO_STR
1618 IP6_STR
1619 OSPF6_STR
1620 "passive interface: No Adjacency will be formed on this I/F\n"
1621 )
1622{
d62a17ae 1623 VTY_DECLVAR_CONTEXT(interface, ifp);
1624 struct ospf6_interface *oi;
1625 assert(ifp);
718e3744 1626
d62a17ae 1627 oi = (struct ospf6_interface *)ifp->info;
1628 if (oi == NULL)
1629 oi = ospf6_interface_create(ifp);
1630 assert(oi);
718e3744 1631
d62a17ae 1632 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1633 THREAD_OFF(oi->thread_send_hello);
1634 oi->thread_send_hello = NULL;
1635 thread_add_event(master, ospf6_hello_send, oi, 0,
1636 &oi->thread_send_hello);
718e3744 1637
d62a17ae 1638 return CMD_SUCCESS;
718e3744 1639}
1640
d42306d9
DT
1641DEFUN (ipv6_ospf6_mtu_ignore,
1642 ipv6_ospf6_mtu_ignore_cmd,
1643 "ipv6 ospf6 mtu-ignore",
1644 IP6_STR
1645 OSPF6_STR
99a522c7 1646 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1647 )
1648{
d62a17ae 1649 VTY_DECLVAR_CONTEXT(interface, ifp);
1650 struct ospf6_interface *oi;
1651 assert(ifp);
d42306d9 1652
d62a17ae 1653 oi = (struct ospf6_interface *)ifp->info;
1654 if (oi == NULL)
1655 oi = ospf6_interface_create(ifp);
1656 assert(oi);
d42306d9 1657
d62a17ae 1658 oi->mtu_ignore = 1;
d42306d9 1659
d62a17ae 1660 return CMD_SUCCESS;
d42306d9
DT
1661}
1662
1663DEFUN (no_ipv6_ospf6_mtu_ignore,
1664 no_ipv6_ospf6_mtu_ignore_cmd,
1665 "no ipv6 ospf6 mtu-ignore",
1666 NO_STR
1667 IP6_STR
1668 OSPF6_STR
99a522c7 1669 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1670 )
1671{
d62a17ae 1672 VTY_DECLVAR_CONTEXT(interface, ifp);
1673 struct ospf6_interface *oi;
1674 assert(ifp);
d42306d9 1675
d62a17ae 1676 oi = (struct ospf6_interface *)ifp->info;
1677 if (oi == NULL)
1678 oi = ospf6_interface_create(ifp);
1679 assert(oi);
d42306d9 1680
d62a17ae 1681 oi->mtu_ignore = 0;
d42306d9 1682
d62a17ae 1683 return CMD_SUCCESS;
d42306d9
DT
1684}
1685
718e3744 1686DEFUN (ipv6_ospf6_advertise_prefix_list,
1687 ipv6_ospf6_advertise_prefix_list_cmd,
1688 "ipv6 ospf6 advertise prefix-list WORD",
1689 IP6_STR
1690 OSPF6_STR
1691 "Advertising options\n"
1692 "Filter prefix using prefix-list\n"
1693 "Prefix list name\n"
1694 )
1695{
d62a17ae 1696 VTY_DECLVAR_CONTEXT(interface, ifp);
1697 int idx_word = 4;
1698 struct ospf6_interface *oi;
1699 assert(ifp);
1700
1701 oi = (struct ospf6_interface *)ifp->info;
1702 if (oi == NULL)
1703 oi = ospf6_interface_create(ifp);
1704 assert(oi);
1705
1706 if (oi->plist_name)
1707 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
1708 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
1709
1710 ospf6_interface_connected_route_update(oi->interface);
1711
1712 if (oi->area) {
1713 OSPF6_LINK_LSA_SCHEDULE(oi);
1714 if (oi->state == OSPF6_INTERFACE_DR) {
1715 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1716 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1717 }
1718 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1719 }
1720
1721 return CMD_SUCCESS;
718e3744 1722}
1723
1724DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1725 no_ipv6_ospf6_advertise_prefix_list_cmd,
d23d6de8 1726 "no ipv6 ospf6 advertise prefix-list [WORD]",
718e3744 1727 NO_STR
1728 IP6_STR
1729 OSPF6_STR
1730 "Advertising options\n"
1731 "Filter prefix using prefix-list\n"
d23d6de8 1732 "Prefix list name\n")
718e3744 1733{
d62a17ae 1734 VTY_DECLVAR_CONTEXT(interface, ifp);
1735 struct ospf6_interface *oi;
1736 assert(ifp);
1737
1738 oi = (struct ospf6_interface *)ifp->info;
1739 if (oi == NULL)
1740 oi = ospf6_interface_create(ifp);
1741 assert(oi);
1742
d23d6de8 1743 if (oi->plist_name)
d62a17ae 1744 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
d62a17ae 1745
1746 ospf6_interface_connected_route_update(oi->interface);
1747
1748 if (oi->area) {
1749 OSPF6_LINK_LSA_SCHEDULE(oi);
1750 if (oi->state == OSPF6_INTERFACE_DR) {
1751 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1752 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1753 }
1754 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1755 }
1756
1757 return CMD_SUCCESS;
718e3744 1758}
1759
c5926a92
DD
1760DEFUN (ipv6_ospf6_network,
1761 ipv6_ospf6_network_cmd,
6147e2c6 1762 "ipv6 ospf6 network <broadcast|point-to-point>",
c5926a92
DD
1763 IP6_STR
1764 OSPF6_STR
99a522c7 1765 "Network type\n"
b2d4d039 1766 "Specify OSPF6 broadcast network\n"
c5926a92
DD
1767 "Specify OSPF6 point-to-point network\n"
1768 )
1769{
d62a17ae 1770 VTY_DECLVAR_CONTEXT(interface, ifp);
1771 int idx_network = 3;
1772 struct ospf6_interface *oi;
1773 assert(ifp);
1774
1775 oi = (struct ospf6_interface *)ifp->info;
1776 if (oi == NULL) {
1777 oi = ospf6_interface_create(ifp);
1778 }
1779 assert(oi);
1780
1781 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
1782 if (oi->type == OSPF_IFTYPE_BROADCAST)
1783 return CMD_SUCCESS;
1784
1785 oi->type = OSPF_IFTYPE_BROADCAST;
1786 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
1787 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
1788 return CMD_SUCCESS;
1789 }
1790 oi->type = OSPF_IFTYPE_POINTOPOINT;
c5926a92 1791 }
c5926a92 1792
d62a17ae 1793 /* Reset the interface */
1794 thread_add_event(master, interface_down, oi, 0, NULL);
1795 thread_add_event(master, interface_up, oi, 0, NULL);
c5926a92 1796
d62a17ae 1797 return CMD_SUCCESS;
c5926a92
DD
1798}
1799
1800DEFUN (no_ipv6_ospf6_network,
1801 no_ipv6_ospf6_network_cmd,
32573073 1802 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
c5926a92
DD
1803 NO_STR
1804 IP6_STR
1805 OSPF6_STR
32573073
QY
1806 "Set default network type\n"
1807 "Specify OSPF6 broadcast network\n"
1808 "Specify OSPF6 point-to-point network\n")
c5926a92 1809{
d62a17ae 1810 VTY_DECLVAR_CONTEXT(interface, ifp);
1811 struct ospf6_interface *oi;
1812 int type;
c5926a92 1813
d62a17ae 1814 assert(ifp);
c5926a92 1815
d62a17ae 1816 oi = (struct ospf6_interface *)ifp->info;
1817 if (oi == NULL) {
1818 return CMD_SUCCESS;
1819 }
c5926a92 1820
d62a17ae 1821 type = ospf6_default_iftype(ifp);
1822 if (oi->type == type) {
1823 return CMD_SUCCESS;
1824 }
1825 oi->type = type;
c5926a92 1826
d62a17ae 1827 /* Reset the interface */
1828 thread_add_event(master, interface_down, oi, 0, NULL);
1829 thread_add_event(master, interface_up, oi, 0, NULL);
c5926a92 1830
d62a17ae 1831 return CMD_SUCCESS;
c5926a92
DD
1832}
1833
d62a17ae 1834static int config_write_ospf6_interface(struct vty *vty)
718e3744 1835{
f4e14fdb 1836 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1837 struct ospf6_interface *oi;
1838 struct interface *ifp;
1839
451fda4f 1840 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1841 oi = (struct ospf6_interface *)ifp->info;
1842 if (oi == NULL)
1843 continue;
1844
a8b828f3 1845 vty_frame(vty, "interface %s\n", oi->interface->name);
d62a17ae 1846
1847 if (ifp->desc)
1848 vty_out(vty, " description %s\n", ifp->desc);
1849 if (oi->c_ifmtu)
1850 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
1851
1852 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
1853 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
1854
1855 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1856 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
1857 oi->hello_interval);
1858
1859 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1860 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
1861 oi->dead_interval);
1862
1863 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1864 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
1865 oi->rxmt_interval);
1866
1867 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1868 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
1869
1870 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1871 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
1872 oi->transdelay);
1873
1874 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1875 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
1876 oi->instance_id);
1877
1878 if (oi->plist_name)
1879 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
1880 oi->plist_name);
1881
1882 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
1883 vty_out(vty, " ipv6 ospf6 passive\n");
1884
1885 if (oi->mtu_ignore)
1886 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
1887
1888 if (oi->type != ospf6_default_iftype(ifp)) {
1889 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
1890 vty_out(vty,
1891 " ipv6 ospf6 network point-to-point\n");
1892 else if (oi->type == OSPF_IFTYPE_BROADCAST)
1893 vty_out(vty, " ipv6 ospf6 network broadcast\n");
1894 }
1895
1896 ospf6_bfd_write_config(vty, oi);
1897
a8b828f3 1898 vty_endframe(vty, "!\n");
d62a17ae 1899 }
1900 return 0;
718e3744 1901}
1902
d62a17ae 1903static struct cmd_node interface_node = {
1904 INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */
718e3744 1905};
1906
d62a17ae 1907void ospf6_interface_init(void)
718e3744 1908{
d62a17ae 1909 /* Install interface node. */
1910 install_node(&interface_node, config_write_ospf6_interface);
1911 if_cmd_init();
1912
1913 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
1914 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1915 install_element(VIEW_NODE,
1916 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
996c9314 1917 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
d62a17ae 1918
1919 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
1920 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
1921 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
1922 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
d23d6de8 1923
d62a17ae 1924 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1925 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1926 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1927 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1928 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1929 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
d23d6de8
QY
1930 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
1931 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
1932 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
1933 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
1934 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
1935 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
d62a17ae 1936
1937 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1938 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
1939
1940 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
1941 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
1942
1943 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1944 install_element(INTERFACE_NODE,
1945 &no_ipv6_ospf6_advertise_prefix_list_cmd);
1946
1947 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
1948 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
1949
1950 /* reference bandwidth commands */
1951 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
1952 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
508e53e2 1953}
1954
a1b11f9b 1955/* Clear the specified interface structure */
d62a17ae 1956static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
a1b11f9b 1957{
d62a17ae 1958 struct ospf6_interface *oi;
a1b11f9b 1959
d62a17ae 1960 if (!if_is_operative(ifp))
1961 return;
a1b11f9b 1962
d62a17ae 1963 if (ifp->info == NULL)
1964 return;
a1b11f9b 1965
d62a17ae 1966 oi = (struct ospf6_interface *)ifp->info;
a1b11f9b 1967
d62a17ae 1968 if (IS_OSPF6_DEBUG_INTERFACE)
1969 zlog_debug("Interface %s: clear by reset", ifp->name);
a1b11f9b 1970
d62a17ae 1971 /* Reset the interface */
1972 thread_add_event(master, interface_down, oi, 0, NULL);
1973 thread_add_event(master, interface_up, oi, 0, NULL);
a1b11f9b
DS
1974}
1975
1976/* Clear interface */
1977DEFUN (clear_ipv6_ospf6_interface,
1978 clear_ipv6_ospf6_interface_cmd,
1979 "clear ipv6 ospf6 interface [IFNAME]",
1980 CLEAR_STR
1981 IP6_STR
1982 OSPF6_STR
1983 INTERFACE_STR
1984 IFNAME_STR
1985 )
1986{
f4e14fdb 1987 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1988 int idx_ifname = 4;
1989 struct interface *ifp;
d62a17ae 1990
1991 if (argc == 4) /* Clear all the ospfv3 interfaces. */
1992 {
451fda4f 1993 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1994 ospf6_interface_clear(vty, ifp);
1995 } else /* Interface name is specified. */
1996 {
1997 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
1998 VRF_DEFAULT))
1999 == NULL) {
2000 vty_out(vty, "No such Interface: %s\n",
2001 argv[idx_ifname]->arg);
2002 return CMD_WARNING;
2003 }
2004 ospf6_interface_clear(vty, ifp);
2005 }
2006
2007 return CMD_SUCCESS;
a1b11f9b
DS
2008}
2009
d62a17ae 2010void install_element_ospf6_clear_interface(void)
a1b11f9b 2011{
d62a17ae 2012 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
a1b11f9b
DS
2013}
2014
508e53e2 2015DEFUN (debug_ospf6_interface,
2016 debug_ospf6_interface_cmd,
2017 "debug ospf6 interface",
2018 DEBUG_STR
2019 OSPF6_STR
2020 "Debug OSPFv3 Interface\n"
2021 )
2022{
d62a17ae 2023 OSPF6_DEBUG_INTERFACE_ON();
2024 return CMD_SUCCESS;
508e53e2 2025}
2026
2027DEFUN (no_debug_ospf6_interface,
2028 no_debug_ospf6_interface_cmd,
2029 "no debug ospf6 interface",
2030 NO_STR
2031 DEBUG_STR
2032 OSPF6_STR
2033 "Debug OSPFv3 Interface\n"
2034 )
2035{
d62a17ae 2036 OSPF6_DEBUG_INTERFACE_OFF();
2037 return CMD_SUCCESS;
508e53e2 2038}
2039
d62a17ae 2040int config_write_ospf6_debug_interface(struct vty *vty)
508e53e2 2041{
d62a17ae 2042 if (IS_OSPF6_DEBUG_INTERFACE)
2043 vty_out(vty, "debug ospf6 interface\n");
2044 return 0;
508e53e2 2045}
2046
d62a17ae 2047void install_element_ospf6_debug_interface(void)
508e53e2 2048{
d62a17ae 2049 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2050 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2051 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2052 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
718e3744 2053}