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