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