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