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