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