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