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