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