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