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