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