]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_interface.c
tools: argv_translator convert <1-255> to (1-255), ()s to <>s, etc
[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 */
f412b39a
DW
989/*
990 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
991 * "show ipv6 ospf6 interface",
992 * SHOW_STR
993 * IP6_STR
994 * OSPF6_STR
995 * INTERFACE_STR
996 *
997 *
998 */
718e3744 999DEFUN (show_ipv6_ospf6_interface,
1000 show_ipv6_ospf6_interface_ifname_cmd,
1001 "show ipv6 ospf6 interface IFNAME",
1002 SHOW_STR
1003 IP6_STR
1004 OSPF6_STR
1005 INTERFACE_STR
1006 IFNAME_STR
1007 )
1008{
1009 struct interface *ifp;
52dc7ee6 1010 struct listnode *i;
718e3744 1011
1012 if (argc)
1013 {
cc9de1ba 1014 ifp = if_lookup_by_name (argv[4]->arg);
508e53e2 1015 if (ifp == NULL)
718e3744 1016 {
cc9de1ba 1017 vty_out (vty, "No such Interface: %s%s", argv[4]->arg,
049207c3 1018 VNL);
718e3744 1019 return CMD_WARNING;
1020 }
1021 ospf6_interface_show (vty, ifp);
1022 }
1023 else
1024 {
b2d7c082 1025 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp))
1eb8ef25 1026 ospf6_interface_show (vty, ifp);
718e3744 1027 }
508e53e2 1028
718e3744 1029 return CMD_SUCCESS;
1030}
1031
508e53e2 1032
f412b39a
DW
1033/*
1034 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1035 * "show ipv6 ospf6 interface IFNAME prefix (X:X::X:X|X:X::X:X/M|detail)",
1036 * SHOW_STR
1037 * IP6_STR
1038 * OSPF6_STR
1039 * INTERFACE_STR
1040 * IFNAME_STR
1041 * "Display connected prefixes to advertise\n"
1042 * OSPF6_ROUTE_ADDRESS_STR
1043 * OSPF6_ROUTE_PREFIX_STR
1044 * "Display details of the prefixes\n"
1045 *
1046 *
1047 * "show ipv6 ospf6 interface IFNAME prefix X:X::X:X/M (match|detail)",
1048 * SHOW_STR
1049 * IP6_STR
1050 * OSPF6_STR
1051 * INTERFACE_STR
1052 * IFNAME_STR
1053 * "Display connected prefixes to advertise\n"
1054 * OSPF6_ROUTE_PREFIX_STR
1055 * OSPF6_ROUTE_MATCH_STR
1056 * "Display details of the prefixes\n"
1057 *
1058 *
1059 */
508e53e2 1060DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
1061 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1062 "show ipv6 ospf6 interface IFNAME prefix",
1063 SHOW_STR
1064 IP6_STR
1065 OSPF6_STR
1066 INTERFACE_STR
1067 IFNAME_STR
1068 "Display connected prefixes to advertise\n"
718e3744 1069 )
508e53e2 1070{
1071 struct interface *ifp;
1072 struct ospf6_interface *oi;
1073
cc9de1ba 1074 ifp = if_lookup_by_name (argv[4]->arg);
508e53e2 1075 if (ifp == NULL)
1076 {
cc9de1ba 1077 vty_out (vty, "No such Interface: %s%s", argv[4]->arg, VNL);
508e53e2 1078 return CMD_WARNING;
1079 }
1080
1081 oi = ifp->info;
1082 if (oi == NULL)
1083 {
cc9de1ba 1084 vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[4]->arg, VNL);
508e53e2 1085 return CMD_WARNING;
1086 }
1087
1088 argc--;
1089 argv++;
1090 ospf6_route_table_show (vty, argc, argv, oi->route_connected);
1091
1092 return CMD_SUCCESS;
1093}
1094
508e53e2 1095
508e53e2 1096
f412b39a
DW
1097/*
1098 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1099 * "show ipv6 ospf6 interface prefix X:X::X:X/M (match|detail)",
1100 * SHOW_STR
1101 * IP6_STR
1102 * OSPF6_STR
1103 * INTERFACE_STR
1104 * "Display connected prefixes to advertise\n"
1105 * OSPF6_ROUTE_PREFIX_STR
1106 * OSPF6_ROUTE_MATCH_STR
1107 * "Display details of the prefixes\n"
1108 *
1109 *
1110 * "show ipv6 ospf6 interface prefix (X:X::X:X|X:X::X:X/M|detail)",
1111 * SHOW_STR
1112 * IP6_STR
1113 * OSPF6_STR
1114 * INTERFACE_STR
1115 * "Display connected prefixes to advertise\n"
1116 * OSPF6_ROUTE_ADDRESS_STR
1117 * OSPF6_ROUTE_PREFIX_STR
1118 * "Display details of the prefixes\n"
1119 *
1120 *
1121 */
508e53e2 1122DEFUN (show_ipv6_ospf6_interface_prefix,
1123 show_ipv6_ospf6_interface_prefix_cmd,
1124 "show ipv6 ospf6 interface prefix",
1125 SHOW_STR
1126 IP6_STR
1127 OSPF6_STR
1128 INTERFACE_STR
1129 "Display connected prefixes to advertise\n"
1130 )
1131{
52dc7ee6 1132 struct listnode *i;
508e53e2 1133 struct ospf6_interface *oi;
1134 struct interface *ifp;
1135
b2d7c082 1136 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp))
508e53e2 1137 {
508e53e2 1138 oi = (struct ospf6_interface *) ifp->info;
1139 if (oi == NULL)
1140 continue;
1141
1142 ospf6_route_table_show (vty, argc, argv, oi->route_connected);
1143 }
1144
1145 return CMD_SUCCESS;
1146}
1147
508e53e2 1148
508e53e2 1149
718e3744 1150
1151/* interface variable set command */
b596c71e 1152DEFUN (ipv6_ospf6_ifmtu,
1153 ipv6_ospf6_ifmtu_cmd,
1154 "ipv6 ospf6 ifmtu <1-65535>",
1155 IP6_STR
1156 OSPF6_STR
1157 "Interface MTU\n"
1158 "OSPFv3 Interface MTU\n"
1159 )
1160{
1161 struct ospf6_interface *oi;
1162 struct interface *ifp;
0c083ee9 1163 unsigned int ifmtu, iobuflen;
1eb8ef25 1164 struct listnode *node, *nnode;
b596c71e 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
cc9de1ba 1175 ifmtu = strtol (argv[3]->arg, NULL, 10);
b596c71e 1176
1177 if (oi->ifmtu == ifmtu)
1178 return CMD_SUCCESS;
1179
1203e1c0 1180 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu)
b596c71e 1181 {
1182 vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s",
049207c3 1183 ifp->name, ifp->mtu6, VNL);
b596c71e 1184 return CMD_WARNING;
1185 }
1186
1187 if (oi->ifmtu < ifmtu)
1188 {
1189 iobuflen = ospf6_iobuf_size (ifmtu);
1190 if (iobuflen < ifmtu)
1191 {
1192 vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
049207c3 1193 ifp->name, iobuflen, VNL);
b596c71e 1194 oi->ifmtu = iobuflen;
1195 }
1196 else
1197 oi->ifmtu = ifmtu;
1198 }
1199 else
1200 oi->ifmtu = ifmtu;
1201
1202 /* re-establish adjacencies */
1eb8ef25 1203 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
b596c71e 1204 {
b596c71e 1205 THREAD_OFF (on->inactivity_timer);
3e834b12 1206 thread_add_event (master, inactivity_timer, on, 0);
b596c71e 1207 }
1208
1209 return CMD_SUCCESS;
1210}
1211
049207c3 1212DEFUN (no_ipv6_ospf6_ifmtu,
1213 no_ipv6_ospf6_ifmtu_cmd,
1214 "no ipv6 ospf6 ifmtu",
1215 NO_STR
1216 IP6_STR
1217 OSPF6_STR
1218 "Interface MTU\n"
1219 )
1220{
1221 struct ospf6_interface *oi;
1222 struct interface *ifp;
0c083ee9 1223 unsigned int iobuflen;
1eb8ef25 1224 struct listnode *node, *nnode;
049207c3 1225 struct ospf6_neighbor *on;
1226
1227 ifp = (struct interface *) vty->index;
1228 assert (ifp);
1229
1230 oi = (struct ospf6_interface *) ifp->info;
1231 if (oi == NULL)
1232 oi = ospf6_interface_create (ifp);
1233 assert (oi);
1234
1235 if (oi->ifmtu < ifp->mtu)
1236 {
1237 iobuflen = ospf6_iobuf_size (ifp->mtu);
1238 if (iobuflen < ifp->mtu)
1239 {
1240 vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
1241 ifp->name, iobuflen, VNL);
1242 oi->ifmtu = iobuflen;
1243 }
1244 else
1245 oi->ifmtu = ifp->mtu;
1246 }
1247 else
1248 oi->ifmtu = ifp->mtu;
1249
1250 /* re-establish adjacencies */
1eb8ef25 1251 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
049207c3 1252 {
049207c3 1253 THREAD_OFF (on->inactivity_timer);
3e834b12 1254 thread_add_event (master, inactivity_timer, on, 0);
049207c3 1255 }
1256
1257 return CMD_SUCCESS;
1258}
1259
718e3744 1260DEFUN (ipv6_ospf6_cost,
1261 ipv6_ospf6_cost_cmd,
508e53e2 1262 "ipv6 ospf6 cost <1-65535>",
718e3744 1263 IP6_STR
1264 OSPF6_STR
1265 "Interface cost\n"
508e53e2 1266 "Outgoing metric of this interface\n"
718e3744 1267 )
1268{
508e53e2 1269 struct ospf6_interface *oi;
718e3744 1270 struct interface *ifp;
0c083ee9 1271 unsigned long int lcost;
718e3744 1272
508e53e2 1273 ifp = (struct interface *) vty->index;
718e3744 1274 assert (ifp);
1275
508e53e2 1276 oi = (struct ospf6_interface *) ifp->info;
1277 if (oi == NULL)
1278 oi = ospf6_interface_create (ifp);
1279 assert (oi);
718e3744 1280
cc9de1ba 1281 lcost = strtol (argv[3]->arg, NULL, 10);
718e3744 1282
0c083ee9 1283 if (lcost > UINT32_MAX)
1284 {
1285 vty_out (vty, "Cost %ld is out of range%s", lcost, VNL);
1286 return CMD_WARNING;
1287 }
1288
1289 if (oi->cost == lcost)
1290 return CMD_SUCCESS;
1291
1292 oi->cost = lcost;
c19543b2 1293 SET_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
718e3744 1294
c19543b2
VB
1295 ospf6_interface_recalculate_cost(oi);
1296
1297 return CMD_SUCCESS;
1298}
1299
1300DEFUN (no_ipv6_ospf6_cost,
1301 no_ipv6_ospf6_cost_cmd,
1302 "no ipv6 ospf6 cost",
1303 NO_STR
1304 IP6_STR
1305 OSPF6_STR
1306 "Calculate interface cost from bandwidth\n"
1307 )
1308{
1309 struct ospf6_interface *oi;
1310 struct interface *ifp;
c19543b2
VB
1311
1312 ifp = (struct interface *) vty->index;
1313 assert (ifp);
1314
1315 oi = (struct ospf6_interface *) ifp->info;
1316 if (oi == NULL)
1317 oi = ospf6_interface_create (ifp);
1318 assert (oi);
1319
1320 UNSET_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1321
1322 ospf6_interface_recalculate_cost(oi);
718e3744 1323
1324 return CMD_SUCCESS;
1325}
1326
fd500689
VB
1327DEFUN (auto_cost_reference_bandwidth,
1328 auto_cost_reference_bandwidth_cmd,
1329 "auto-cost reference-bandwidth <1-4294967>",
1330 "Calculate OSPF interface cost according to bandwidth\n"
1331 "Use reference bandwidth method to assign OSPF cost\n"
1332 "The reference bandwidth in terms of Mbits per second\n")
1333{
1334 struct ospf6 *o = vty->index;
1335 struct ospf6_area *oa;
1336 struct ospf6_interface *oi;
1337 struct listnode *i, *j;
1338 u_int32_t refbw;
1339
cc9de1ba 1340 refbw = strtol (argv[2]->arg, NULL, 10);
fd500689
VB
1341 if (refbw < 1 || refbw > 4294967)
1342 {
1343 vty_out (vty, "reference-bandwidth value is invalid%s", VTY_NEWLINE);
1344 return CMD_WARNING;
1345 }
1346
1347 /* If reference bandwidth is changed. */
70bd3c43 1348 if ((refbw) == o->ref_bandwidth)
fd500689
VB
1349 return CMD_SUCCESS;
1350
70bd3c43 1351 o->ref_bandwidth = refbw;
fd500689
VB
1352 for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
1353 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
1354 ospf6_interface_recalculate_cost (oi);
1355
1356 return CMD_SUCCESS;
1357}
1358
f412b39a
DW
1359/*
1360 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1361 * "no auto-cost reference-bandwidth <1-4294967>",
1362 * NO_STR
1363 * "Calculate OSPF interface cost according to bandwidth\n"
1364 * "Use reference bandwidth method to assign OSPF cost\n"
1365 * "The reference bandwidth in terms of Mbits per second\n"
1366 *
1367 */
fd500689
VB
1368DEFUN (no_auto_cost_reference_bandwidth,
1369 no_auto_cost_reference_bandwidth_cmd,
1370 "no auto-cost reference-bandwidth",
1371 NO_STR
1372 "Calculate OSPF interface cost according to bandwidth\n"
1373 "Use reference bandwidth method to assign OSPF cost\n")
1374{
1375 struct ospf6 *o = vty->index;
1376 struct ospf6_area *oa;
1377 struct ospf6_interface *oi;
1378 struct listnode *i, *j;
1379
1380 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1381 return CMD_SUCCESS;
1382
1383 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1384 for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
1385 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
1386 ospf6_interface_recalculate_cost (oi);
1387
1388 return CMD_SUCCESS;
1389}
1390
813d4307 1391
718e3744 1392DEFUN (ipv6_ospf6_hellointerval,
1393 ipv6_ospf6_hellointerval_cmd,
508e53e2 1394 "ipv6 ospf6 hello-interval <1-65535>",
718e3744 1395 IP6_STR
1396 OSPF6_STR
508e53e2 1397 "Interval time of Hello packets\n"
718e3744 1398 SECONDS_STR
1399 )
1400{
508e53e2 1401 struct ospf6_interface *oi;
718e3744 1402 struct interface *ifp;
1403
1404 ifp = (struct interface *) vty->index;
1405 assert (ifp);
718e3744 1406
508e53e2 1407 oi = (struct ospf6_interface *) ifp->info;
1408 if (oi == NULL)
1409 oi = ospf6_interface_create (ifp);
1410 assert (oi);
1411
cc9de1ba 1412 oi->hello_interval = strtol (argv[3]->arg, NULL, 10);
718e3744 1413 return CMD_SUCCESS;
1414}
1415
1416/* interface variable set command */
1417DEFUN (ipv6_ospf6_deadinterval,
1418 ipv6_ospf6_deadinterval_cmd,
508e53e2 1419 "ipv6 ospf6 dead-interval <1-65535>",
718e3744 1420 IP6_STR
1421 OSPF6_STR
508e53e2 1422 "Interval time after which a neighbor is declared down\n"
718e3744 1423 SECONDS_STR
1424 )
1425{
508e53e2 1426 struct ospf6_interface *oi;
718e3744 1427 struct interface *ifp;
1428
1429 ifp = (struct interface *) vty->index;
1430 assert (ifp);
718e3744 1431
508e53e2 1432 oi = (struct ospf6_interface *) ifp->info;
1433 if (oi == NULL)
1434 oi = ospf6_interface_create (ifp);
1435 assert (oi);
1436
cc9de1ba 1437 oi->dead_interval = strtol (argv[3]->arg, NULL, 10);
718e3744 1438 return CMD_SUCCESS;
1439}
1440
1441/* interface variable set command */
1442DEFUN (ipv6_ospf6_transmitdelay,
1443 ipv6_ospf6_transmitdelay_cmd,
508e53e2 1444 "ipv6 ospf6 transmit-delay <1-3600>",
718e3744 1445 IP6_STR
1446 OSPF6_STR
508e53e2 1447 "Transmit delay of this interface\n"
718e3744 1448 SECONDS_STR
1449 )
1450{
508e53e2 1451 struct ospf6_interface *oi;
718e3744 1452 struct interface *ifp;
1453
1454 ifp = (struct interface *) vty->index;
1455 assert (ifp);
718e3744 1456
508e53e2 1457 oi = (struct ospf6_interface *) ifp->info;
1458 if (oi == NULL)
1459 oi = ospf6_interface_create (ifp);
1460 assert (oi);
1461
cc9de1ba 1462 oi->transdelay = strtol (argv[3]->arg, NULL, 10);
718e3744 1463 return CMD_SUCCESS;
1464}
1465
1466/* interface variable set command */
1467DEFUN (ipv6_ospf6_retransmitinterval,
1468 ipv6_ospf6_retransmitinterval_cmd,
508e53e2 1469 "ipv6 ospf6 retransmit-interval <1-65535>",
718e3744 1470 IP6_STR
1471 OSPF6_STR
1472 "Time between retransmitting lost link state advertisements\n"
1473 SECONDS_STR
1474 )
1475{
508e53e2 1476 struct ospf6_interface *oi;
718e3744 1477 struct interface *ifp;
1478
1479 ifp = (struct interface *) vty->index;
1480 assert (ifp);
718e3744 1481
508e53e2 1482 oi = (struct ospf6_interface *) ifp->info;
1483 if (oi == NULL)
1484 oi = ospf6_interface_create (ifp);
1485 assert (oi);
1486
cc9de1ba 1487 oi->rxmt_interval = strtol (argv[3]->arg, NULL, 10);
718e3744 1488 return CMD_SUCCESS;
1489}
1490
1491/* interface variable set command */
1492DEFUN (ipv6_ospf6_priority,
1493 ipv6_ospf6_priority_cmd,
508e53e2 1494 "ipv6 ospf6 priority <0-255>",
718e3744 1495 IP6_STR
1496 OSPF6_STR
1497 "Router priority\n"
508e53e2 1498 "Priority value\n"
718e3744 1499 )
1500{
508e53e2 1501 struct ospf6_interface *oi;
718e3744 1502 struct interface *ifp;
1503
1504 ifp = (struct interface *) vty->index;
1505 assert (ifp);
718e3744 1506
508e53e2 1507 oi = (struct ospf6_interface *) ifp->info;
1508 if (oi == NULL)
1509 oi = ospf6_interface_create (ifp);
1510 assert (oi);
1511
cc9de1ba 1512 oi->priority = strtol (argv[3]->arg, NULL, 10);
718e3744 1513
7d4aa1d5
CF
1514 if (oi->area &&
1515 (oi->state == OSPF6_INTERFACE_DROTHER ||
1516 oi->state == OSPF6_INTERFACE_BDR ||
1517 oi->state == OSPF6_INTERFACE_DR))
508e53e2 1518 ospf6_interface_state_change (dr_election (oi), oi);
718e3744 1519
1520 return CMD_SUCCESS;
1521}
1522
1523DEFUN (ipv6_ospf6_instance,
1524 ipv6_ospf6_instance_cmd,
508e53e2 1525 "ipv6 ospf6 instance-id <0-255>",
718e3744 1526 IP6_STR
1527 OSPF6_STR
508e53e2 1528 "Instance ID for this interface\n"
1529 "Instance ID value\n"
718e3744 1530 )
1531{
508e53e2 1532 struct ospf6_interface *oi;
718e3744 1533 struct interface *ifp;
1534
1535 ifp = (struct interface *)vty->index;
1536 assert (ifp);
1537
508e53e2 1538 oi = (struct ospf6_interface *)ifp->info;
1539 if (oi == NULL)
1540 oi = ospf6_interface_create (ifp);
1541 assert (oi);
718e3744 1542
cc9de1ba 1543 oi->instance_id = strtol (argv[3]->arg, NULL, 10);
718e3744 1544 return CMD_SUCCESS;
1545}
1546
1547DEFUN (ipv6_ospf6_passive,
1548 ipv6_ospf6_passive_cmd,
1549 "ipv6 ospf6 passive",
1550 IP6_STR
1551 OSPF6_STR
508e53e2 1552 "passive interface, No adjacency will be formed on this interface\n"
718e3744 1553 )
1554{
508e53e2 1555 struct ospf6_interface *oi;
718e3744 1556 struct interface *ifp;
1eb8ef25 1557 struct listnode *node, *nnode;
508e53e2 1558 struct ospf6_neighbor *on;
718e3744 1559
1560 ifp = (struct interface *) vty->index;
1561 assert (ifp);
718e3744 1562
508e53e2 1563 oi = (struct ospf6_interface *) ifp->info;
1564 if (oi == NULL)
1565 oi = ospf6_interface_create (ifp);
1566 assert (oi);
718e3744 1567
508e53e2 1568 SET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
1569 THREAD_OFF (oi->thread_send_hello);
1570
1eb8ef25 1571 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
718e3744 1572 {
508e53e2 1573 THREAD_OFF (on->inactivity_timer);
3e834b12 1574 thread_add_event (master, inactivity_timer, on, 0);
718e3744 1575 }
1576
1577 return CMD_SUCCESS;
1578}
1579
1580DEFUN (no_ipv6_ospf6_passive,
1581 no_ipv6_ospf6_passive_cmd,
1582 "no ipv6 ospf6 passive",
1583 NO_STR
1584 IP6_STR
1585 OSPF6_STR
1586 "passive interface: No Adjacency will be formed on this I/F\n"
1587 )
1588{
508e53e2 1589 struct ospf6_interface *oi;
718e3744 1590 struct interface *ifp;
1591
1592 ifp = (struct interface *) vty->index;
1593 assert (ifp);
718e3744 1594
508e53e2 1595 oi = (struct ospf6_interface *) ifp->info;
1596 if (oi == NULL)
1597 oi = ospf6_interface_create (ifp);
1598 assert (oi);
718e3744 1599
508e53e2 1600 UNSET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
1601 THREAD_OFF (oi->thread_send_hello);
1602 oi->thread_send_hello =
1603 thread_add_event (master, ospf6_hello_send, oi, 0);
718e3744 1604
1605 return CMD_SUCCESS;
1606}
1607
d42306d9
DT
1608DEFUN (ipv6_ospf6_mtu_ignore,
1609 ipv6_ospf6_mtu_ignore_cmd,
1610 "ipv6 ospf6 mtu-ignore",
1611 IP6_STR
1612 OSPF6_STR
1613 "Ignore MTU mismatch on this interface\n"
1614 )
1615{
1616 struct ospf6_interface *oi;
1617 struct interface *ifp;
1618
1619 ifp = (struct interface *) vty->index;
1620 assert (ifp);
1621
1622 oi = (struct ospf6_interface *) ifp->info;
1623 if (oi == NULL)
1624 oi = ospf6_interface_create (ifp);
1625 assert (oi);
1626
1627 oi->mtu_ignore = 1;
1628
1629 return CMD_SUCCESS;
1630}
1631
1632DEFUN (no_ipv6_ospf6_mtu_ignore,
1633 no_ipv6_ospf6_mtu_ignore_cmd,
1634 "no ipv6 ospf6 mtu-ignore",
1635 NO_STR
1636 IP6_STR
1637 OSPF6_STR
1638 "Ignore MTU mismatch on this interface\n"
1639 )
1640{
1641 struct ospf6_interface *oi;
1642 struct interface *ifp;
1643
1644 ifp = (struct interface *) vty->index;
1645 assert (ifp);
1646
1647 oi = (struct ospf6_interface *) ifp->info;
1648 if (oi == NULL)
1649 oi = ospf6_interface_create (ifp);
1650 assert (oi);
1651
1652 oi->mtu_ignore = 0;
1653
1654 return CMD_SUCCESS;
1655}
1656
718e3744 1657DEFUN (ipv6_ospf6_advertise_prefix_list,
1658 ipv6_ospf6_advertise_prefix_list_cmd,
1659 "ipv6 ospf6 advertise prefix-list WORD",
1660 IP6_STR
1661 OSPF6_STR
1662 "Advertising options\n"
1663 "Filter prefix using prefix-list\n"
1664 "Prefix list name\n"
1665 )
1666{
508e53e2 1667 struct ospf6_interface *oi;
718e3744 1668 struct interface *ifp;
1669
1670 ifp = (struct interface *) vty->index;
1671 assert (ifp);
718e3744 1672
508e53e2 1673 oi = (struct ospf6_interface *) ifp->info;
1674 if (oi == NULL)
1675 oi = ospf6_interface_create (ifp);
1676 assert (oi);
718e3744 1677
508e53e2 1678 if (oi->plist_name)
4a1ab8e4 1679 XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name);
cc9de1ba 1680 oi->plist_name = XSTRDUP (MTYPE_CFG_PLIST_NAME, argv[4]->arg);
718e3744 1681
508e53e2 1682 ospf6_interface_connected_route_update (oi->interface);
2470e99e
DW
1683
1684 if (oi->area)
508e53e2 1685 {
2470e99e
DW
1686 OSPF6_LINK_LSA_SCHEDULE (oi);
1687 if (oi->state == OSPF6_INTERFACE_DR)
1688 {
1689 OSPF6_NETWORK_LSA_SCHEDULE (oi);
1690 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
1691 }
1692 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
508e53e2 1693 }
718e3744 1694
1695 return CMD_SUCCESS;
1696}
1697
1698DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1699 no_ipv6_ospf6_advertise_prefix_list_cmd,
1700 "no ipv6 ospf6 advertise prefix-list",
1701 NO_STR
1702 IP6_STR
1703 OSPF6_STR
1704 "Advertising options\n"
1705 "Filter prefix using prefix-list\n"
1706 )
1707{
508e53e2 1708 struct ospf6_interface *oi;
718e3744 1709 struct interface *ifp;
1710
1711 ifp = (struct interface *) vty->index;
1712 assert (ifp);
718e3744 1713
508e53e2 1714 oi = (struct ospf6_interface *) ifp->info;
1715 if (oi == NULL)
1716 oi = ospf6_interface_create (ifp);
1717 assert (oi);
1718
1719 if (oi->plist_name)
718e3744 1720 {
4a1ab8e4 1721 XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name);
508e53e2 1722 oi->plist_name = NULL;
718e3744 1723 }
1724
508e53e2 1725 ospf6_interface_connected_route_update (oi->interface);
2470e99e
DW
1726
1727 if (oi->area)
508e53e2 1728 {
2470e99e
DW
1729 OSPF6_LINK_LSA_SCHEDULE (oi);
1730 if (oi->state == OSPF6_INTERFACE_DR)
1731 {
1732 OSPF6_NETWORK_LSA_SCHEDULE (oi);
1733 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
1734 }
1735 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
508e53e2 1736 }
718e3744 1737
1738 return CMD_SUCCESS;
1739}
1740
c5926a92
DD
1741DEFUN (ipv6_ospf6_network,
1742 ipv6_ospf6_network_cmd,
1743 "ipv6 ospf6 network (broadcast|point-to-point)",
1744 IP6_STR
1745 OSPF6_STR
1746 "Network Type\n"
1747 "Specify OSPFv6 broadcast network\n"
1748 "Specify OSPF6 point-to-point network\n"
1749 )
1750{
1751 struct ospf6_interface *oi;
1752 struct interface *ifp;
1753
1754 ifp = (struct interface *) vty->index;
1755 assert (ifp);
1756
1757 oi = (struct ospf6_interface *) ifp->info;
1758 if (oi == NULL) {
1759 oi = ospf6_interface_create (ifp);
1760 }
1761 assert (oi);
1762
cc9de1ba 1763 if (strncmp (argv[3]->arg, "b", 1) == 0)
c5926a92
DD
1764 {
1765 if (oi->type == OSPF_IFTYPE_BROADCAST)
1766 return CMD_SUCCESS;
1767
1768 oi->type = OSPF_IFTYPE_BROADCAST;
1769 }
cc9de1ba 1770 else if (strncmp (argv[3]->arg, "point-to-p", 10) == 0)
c5926a92
DD
1771 {
1772 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
1773 return CMD_SUCCESS;
1774 }
1775 oi->type = OSPF_IFTYPE_POINTOPOINT;
1776 }
1777
1778 /* Reset the interface */
1779 thread_add_event (master, interface_down, oi, 0);
1780 thread_add_event (master, interface_up, oi, 0);
1781
1782 return CMD_SUCCESS;
1783}
1784
1785DEFUN (no_ipv6_ospf6_network,
1786 no_ipv6_ospf6_network_cmd,
1787 "no ipv6 ospf6 network",
1788 NO_STR
1789 IP6_STR
1790 OSPF6_STR
1791 "Network Type\n"
1792 "Default to whatever interface type system specifies"
1793 )
1794{
1795 struct ospf6_interface *oi;
1796 struct interface *ifp;
1797 int type;
1798
1799 ifp = (struct interface *) vty->index;
1800 assert (ifp);
1801
1802 oi = (struct ospf6_interface *) ifp->info;
1803 if (oi == NULL) {
1804 return CMD_SUCCESS;
1805 }
1806
1807 type = ospf6_default_iftype (ifp);
1808 if (oi->type == type)
1809 {
1810 return CMD_SUCCESS;
1811 }
1812 oi->type = type;
1813
1814 /* Reset the interface */
1815 thread_add_event (master, interface_down, oi, 0);
1816 thread_add_event (master, interface_up, oi, 0);
1817
1818 return CMD_SUCCESS;
1819}
1820
6ac29a51 1821static int
508e53e2 1822config_write_ospf6_interface (struct vty *vty)
718e3744 1823{
52dc7ee6 1824 struct listnode *i;
508e53e2 1825 struct ospf6_interface *oi;
718e3744 1826 struct interface *ifp;
1827
b2d7c082 1828 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp))
718e3744 1829 {
508e53e2 1830 oi = (struct ospf6_interface *) ifp->info;
1831 if (oi == NULL)
718e3744 1832 continue;
1833
1834 vty_out (vty, "interface %s%s",
049207c3 1835 oi->interface->name, VNL);
508e53e2 1836
1837 if (ifp->desc)
049207c3 1838 vty_out (vty, " description %s%s", ifp->desc, VNL);
1203e1c0 1839 if (ifp->mtu6 != oi->ifmtu)
049207c3 1840 vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL);
b51a3a31 1841
c19543b2 1842 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
b51a3a31
VT
1843 vty_out (vty, " ipv6 ospf6 cost %d%s",
1844 oi->cost, VNL);
1845
1846 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1847 vty_out (vty, " ipv6 ospf6 hello-interval %d%s",
1848 oi->hello_interval, VNL);
1849
1850 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1851 vty_out (vty, " ipv6 ospf6 dead-interval %d%s",
1852 oi->dead_interval, VNL);
1853
1854 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1855 vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s",
1856 oi->rxmt_interval, VNL);
1857
1858 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1859 vty_out (vty, " ipv6 ospf6 priority %d%s",
1860 oi->priority, VNL);
1861
1862 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1863 vty_out (vty, " ipv6 ospf6 transmit-delay %d%s",
1864 oi->transdelay, VNL);
1865
1866 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1867 vty_out (vty, " ipv6 ospf6 instance-id %d%s",
1868 oi->instance_id, VNL);
718e3744 1869
508e53e2 1870 if (oi->plist_name)
718e3744 1871 vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s",
049207c3 1872 oi->plist_name, VNL);
718e3744 1873
508e53e2 1874 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
049207c3 1875 vty_out (vty, " ipv6 ospf6 passive%s", VNL);
718e3744 1876
d42306d9
DT
1877 if (oi->mtu_ignore)
1878 vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
1879
1d374104 1880 if (oi->type != ospf6_default_iftype(ifp))
1881 {
1882 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
1883 vty_out (vty, " ipv6 ospf6 network point-to-point%s", VNL);
1884 else if (oi->type == OSPF_IFTYPE_BROADCAST)
1885 vty_out (vty, " ipv6 ospf6 network broadcast%s", VNL);
1886 }
c5926a92 1887
7f342629
DS
1888 ospf6_bfd_write_config(vty, oi);
1889
049207c3 1890 vty_out (vty, "!%s", VNL);
718e3744 1891 }
1892 return 0;
1893}
1894
7fc626de 1895static struct cmd_node interface_node =
718e3744 1896{
1897 INTERFACE_NODE,
1898 "%s(config-if)# ",
69b4a810 1899 1 /* VTYSH */
718e3744 1900};
1901
1902void
6ac29a51 1903ospf6_interface_init (void)
718e3744 1904{
1905 /* Install interface node. */
508e53e2 1906 install_node (&interface_node, config_write_ospf6_interface);
718e3744 1907
508e53e2 1908 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
718e3744 1909 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
508e53e2 1910 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
508e53e2 1911 install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_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);
718e3744 1914
508e53e2 1915 install_element (CONFIG_NODE, &interface_cmd);
718e3744 1916 install_default (INTERFACE_NODE);
1917 install_element (INTERFACE_NODE, &interface_desc_cmd);
1918 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1919 install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
c19543b2 1920 install_element (INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
b596c71e 1921 install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
049207c3 1922 install_element (INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
718e3744 1923 install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1924 install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1925 install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1926 install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1927 install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1928 install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
508e53e2 1929
718e3744 1930 install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1931 install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
508e53e2 1932
d42306d9
DT
1933 install_element (INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
1934 install_element (INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
1935
508e53e2 1936 install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1937 install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
c5926a92
DD
1938
1939 install_element (INTERFACE_NODE, &ipv6_ospf6_network_cmd);
1940 install_element (INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
fd500689
VB
1941
1942 /* reference bandwidth commands */
1943 install_element (OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
1944 install_element (OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
508e53e2 1945}
1946
a1b11f9b
DS
1947/* Clear the specified interface structure */
1948static void
1949ospf6_interface_clear (struct vty *vty, struct interface *ifp)
1950{
1951 struct ospf6_interface *oi;
1952
1953 if (!if_is_operative (ifp))
1954 return;
1955
1956 if (ifp->info == NULL)
1957 return;
1958
1959 oi = (struct ospf6_interface *) ifp->info;
1960
1961 if (IS_OSPF6_DEBUG_INTERFACE)
1962 zlog_debug ("Interface %s: clear by reset", ifp->name);
1963
1964 /* Reset the interface */
1965 thread_add_event (master, interface_down, oi, 0);
1966 thread_add_event (master, interface_up, oi, 0);
1967}
1968
1969/* Clear interface */
1970DEFUN (clear_ipv6_ospf6_interface,
1971 clear_ipv6_ospf6_interface_cmd,
1972 "clear ipv6 ospf6 interface [IFNAME]",
1973 CLEAR_STR
1974 IP6_STR
1975 OSPF6_STR
1976 INTERFACE_STR
1977 IFNAME_STR
1978 )
1979{
1980 struct interface *ifp;
1981 struct listnode *node;
1982
1983 if (argc == 0) /* Clear all the ospfv3 interfaces. */
1984 {
b2d7c082 1985 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
a1b11f9b
DS
1986 ospf6_interface_clear (vty, ifp);
1987 }
1988 else /* Interface name is specified. */
1989 {
cc9de1ba 1990 if ((ifp = if_lookup_by_name (argv[4]->arg)) == NULL)
a1b11f9b 1991 {
cc9de1ba 1992 vty_out (vty, "No such Interface: %s%s", argv[4]->arg, VNL);
a1b11f9b
DS
1993 return CMD_WARNING;
1994 }
1995 ospf6_interface_clear (vty, ifp);
1996 }
1997
1998 return CMD_SUCCESS;
1999}
2000
2001void
2002install_element_ospf6_clear_interface (void)
2003{
2004 install_element (ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
2005}
2006
508e53e2 2007DEFUN (debug_ospf6_interface,
2008 debug_ospf6_interface_cmd,
2009 "debug ospf6 interface",
2010 DEBUG_STR
2011 OSPF6_STR
2012 "Debug OSPFv3 Interface\n"
2013 )
2014{
2015 OSPF6_DEBUG_INTERFACE_ON ();
2016 return CMD_SUCCESS;
2017}
2018
2019DEFUN (no_debug_ospf6_interface,
2020 no_debug_ospf6_interface_cmd,
2021 "no debug ospf6 interface",
2022 NO_STR
2023 DEBUG_STR
2024 OSPF6_STR
2025 "Debug OSPFv3 Interface\n"
2026 )
2027{
3b68735f 2028 OSPF6_DEBUG_INTERFACE_OFF ();
508e53e2 2029 return CMD_SUCCESS;
2030}
2031
2032int
2033config_write_ospf6_debug_interface (struct vty *vty)
2034{
2035 if (IS_OSPF6_DEBUG_INTERFACE)
049207c3 2036 vty_out (vty, "debug ospf6 interface%s", VNL);
508e53e2 2037 return 0;
2038}
2039
2040void
6ac29a51 2041install_element_ospf6_debug_interface (void)
508e53e2 2042{
2043 install_element (ENABLE_NODE, &debug_ospf6_interface_cmd);
2044 install_element (ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2045 install_element (CONFIG_NODE, &debug_ospf6_interface_cmd);
2046 install_element (CONFIG_NODE, &no_debug_ospf6_interface_cmd);
718e3744 2047}
2048
2049