2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
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
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.
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
32 #include "ospf6_lsa.h"
33 #include "ospf6_lsdb.h"
34 #include "ospf6_top.h"
35 #include "ospf6_network.h"
36 #include "ospf6_message.h"
37 #include "ospf6_route.h"
38 #include "ospf6_area.h"
39 #include "ospf6_interface.h"
40 #include "ospf6_neighbor.h"
41 #include "ospf6_intra.h"
42 #include "ospf6_spf.h"
44 #include "ospf6_bfd.h"
45 #include "ospf6_zebra.h"
47 DEFINE_MTYPE_STATIC(OSPF6D
, CFG_PLIST_NAME
, "configured prefix list names")
48 DEFINE_QOBJ_TYPE(ospf6_interface
)
49 DEFINE_HOOK(ospf6_interface_change
,
50 (struct ospf6_interface
* oi
, int state
, int old_state
),
51 (oi
, state
, old_state
))
53 unsigned char conf_debug_ospf6_interface
= 0;
55 const char *const ospf6_interface_state_str
[] = {
56 "None", "Down", "Loopback", "Waiting", "PointToPoint",
57 "DROther", "BDR", "DR", NULL
};
59 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
,
62 struct ospf6_interface
*oi
;
63 struct interface
*ifp
;
65 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
67 return (struct ospf6_interface
*)NULL
;
69 oi
= (struct ospf6_interface
*)ifp
->info
;
73 /* schedule routing table recalculation */
74 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
77 struct ospf6_interface
*oi
;
83 switch (ntohs(lsa
->header
->type
)) {
84 case OSPF6_LSTYPE_LINK
:
85 if (oi
->state
== OSPF6_INTERFACE_DR
)
86 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
88 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
96 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
98 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
101 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
103 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
106 static uint8_t ospf6_default_iftype(struct interface
*ifp
)
108 if (if_is_pointopoint(ifp
))
109 return OSPF_IFTYPE_POINTOPOINT
;
110 else if (if_is_loopback(ifp
))
111 return OSPF_IFTYPE_LOOPBACK
;
113 return OSPF_IFTYPE_BROADCAST
;
116 static uint32_t ospf6_interface_get_cost(struct ospf6_interface
*oi
)
118 /* If all else fails, use default OSPF cost */
122 /* interface speed and bw can be 0 in some platforms,
123 * use ospf default bw. If bw is configured then it would
126 if (!oi
->interface
->bandwidth
&& oi
->interface
->speed
) {
127 bw
= oi
->interface
->speed
;
129 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
130 : OSPF6_INTERFACE_BANDWIDTH
;
133 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
134 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
136 /* A specifed ip ospf cost overrides a calculated one. */
137 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
140 cost
= (uint32_t)((double)refbw
/ (double)bw
+ (double)0.5);
143 else if (cost
> UINT32_MAX
)
150 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface
*oi
)
152 /* update cost held in route_connected list in ospf6_interface */
153 ospf6_interface_connected_route_update(oi
->interface
);
155 /* execute LSA hooks */
157 OSPF6_LINK_LSA_SCHEDULE(oi
);
158 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
159 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
160 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
161 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
165 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
169 newcost
= ospf6_interface_get_cost(oi
);
170 if (newcost
== oi
->cost
)
174 ospf6_interface_force_recalculate_cost(oi
);
177 /* Create new ospf6 interface structure */
178 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
180 struct ospf6_interface
*oi
;
181 unsigned int iobuflen
;
183 oi
= XCALLOC(MTYPE_OSPF6_IF
, sizeof(struct ospf6_interface
));
185 oi
->area
= (struct ospf6_area
*)NULL
;
186 oi
->neighbor_list
= list_new();
187 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
188 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
189 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
190 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
191 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
193 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
194 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
195 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
196 oi
->type
= ospf6_default_iftype(ifp
);
197 oi
->state
= OSPF6_INTERFACE_DOWN
;
202 /* Try to adjust I/O buffer size with IfMtu */
203 oi
->ifmtu
= ifp
->mtu6
;
204 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
205 if (oi
->ifmtu
> iobuflen
) {
206 if (IS_OSPF6_DEBUG_INTERFACE
)
208 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
209 ifp
->name
, iobuflen
);
210 oi
->ifmtu
= iobuflen
;
213 QOBJ_REG(oi
, ospf6_interface
);
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
);
222 oi
->route_connected
=
223 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
224 oi
->route_connected
->scope
= oi
;
231 oi
->cost
= ospf6_interface_get_cost(oi
);
236 void ospf6_interface_delete(struct ospf6_interface
*oi
)
238 struct listnode
*node
, *nnode
;
239 struct ospf6_neighbor
*on
;
243 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
244 ospf6_neighbor_delete(on
);
246 list_delete(&oi
->neighbor_list
);
248 THREAD_OFF(oi
->thread_send_hello
);
249 THREAD_OFF(oi
->thread_send_lsupdate
);
250 THREAD_OFF(oi
->thread_send_lsack
);
251 THREAD_OFF(oi
->thread_sso
);
253 ospf6_lsdb_remove_all(oi
->lsdb
);
254 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
255 ospf6_lsdb_remove_all(oi
->lsack_list
);
257 ospf6_lsdb_delete(oi
->lsdb
);
258 ospf6_lsdb_delete(oi
->lsdb_self
);
260 ospf6_lsdb_delete(oi
->lsupdate_list
);
261 ospf6_lsdb_delete(oi
->lsack_list
);
263 ospf6_route_table_delete(oi
->route_connected
, oi
->area
->ospf6
);
266 oi
->interface
->info
= NULL
;
270 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
272 ospf6_bfd_info_free(&(oi
->bfd_info
));
274 /* disable from area list if possible */
275 ospf6_area_interface_delete(oi
);
277 XFREE(MTYPE_OSPF6_IF
, oi
);
280 void ospf6_interface_enable(struct ospf6_interface
*oi
)
282 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
283 ospf6_interface_state_update(oi
->interface
);
286 void ospf6_interface_disable(struct ospf6_interface
*oi
)
288 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
290 thread_execute(master
, interface_down
, oi
, 0);
292 ospf6_lsdb_remove_all(oi
->lsdb
);
293 ospf6_lsdb_remove_all(oi
->lsdb_self
);
294 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
295 ospf6_lsdb_remove_all(oi
->lsack_list
);
297 THREAD_OFF(oi
->thread_send_hello
);
298 THREAD_OFF(oi
->thread_send_lsupdate
);
299 THREAD_OFF(oi
->thread_send_lsack
);
300 THREAD_OFF(oi
->thread_sso
);
302 THREAD_OFF(oi
->thread_network_lsa
);
303 THREAD_OFF(oi
->thread_link_lsa
);
304 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
305 THREAD_OFF(oi
->thread_as_extern_lsa
);
308 static struct in6_addr
*
309 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
313 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
315 /* for each connected address */
316 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
317 /* if family not AF_INET6, ignore */
318 if (c
->address
->family
!= AF_INET6
)
321 /* linklocal scope check */
322 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
323 l
= &c
->address
->u
.prefix6
;
328 void ospf6_interface_if_add(struct interface
*ifp
)
330 struct ospf6_interface
*oi
;
331 unsigned int iobuflen
;
333 oi
= (struct ospf6_interface
*)ifp
->info
;
337 /* Try to adjust I/O buffer size with IfMtu */
339 oi
->ifmtu
= ifp
->mtu6
;
340 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
341 if (oi
->ifmtu
> iobuflen
) {
342 if (IS_OSPF6_DEBUG_INTERFACE
)
344 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
345 ifp
->name
, iobuflen
);
346 oi
->ifmtu
= iobuflen
;
349 /* interface start */
350 ospf6_interface_state_update(oi
->interface
);
353 void ospf6_interface_state_update(struct interface
*ifp
)
355 struct ospf6_interface
*oi
;
356 unsigned int iobuflen
;
358 oi
= (struct ospf6_interface
*)ifp
->info
;
361 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
364 /* Adjust the mtu values if the kernel told us something new */
365 if (ifp
->mtu6
!= oi
->ifmtu
) {
366 /* If nothing configured, accept it and check for buffer size */
368 oi
->ifmtu
= ifp
->mtu6
;
369 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
370 if (oi
->ifmtu
> iobuflen
) {
371 if (IS_OSPF6_DEBUG_INTERFACE
)
373 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
374 ifp
->name
, iobuflen
);
375 oi
->ifmtu
= iobuflen
;
377 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
378 oi
->ifmtu
= ifp
->mtu6
;
380 "Configured mtu %u on %s overridden by kernel %u",
381 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
383 oi
->ifmtu
= oi
->c_ifmtu
;
386 if (if_is_operative(ifp
)
387 && (ospf6_interface_get_linklocal_address(oi
->interface
)
388 || if_is_loopback(oi
->interface
)))
389 thread_execute(master
, interface_up
, oi
, 0);
391 thread_execute(master
, interface_down
, oi
, 0);
396 void ospf6_interface_connected_route_update(struct interface
*ifp
)
398 struct ospf6_interface
*oi
;
399 struct ospf6_route
*route
;
401 struct listnode
*node
, *nnode
;
402 struct in6_addr nh_addr
;
404 oi
= (struct ospf6_interface
*)ifp
->info
;
408 /* reset linklocal pointer */
409 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
411 /* if area is null, do not make connected-route list */
412 if (oi
->area
== NULL
)
415 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
418 /* update "route to advertise" interface route table */
419 ospf6_route_remove_all(oi
->route_connected
, oi
->area
->ospf6
);
421 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
422 if (c
->address
->family
!= AF_INET6
)
425 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
427 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
429 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
431 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
433 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
437 if (oi
->plist_name
) {
438 struct prefix_list
*plist
;
439 enum prefix_list_type ret
;
441 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
442 ret
= prefix_list_apply(plist
, (void *)c
->address
);
443 if (ret
== PREFIX_DENY
) {
444 if (IS_OSPF6_DEBUG_INTERFACE
)
446 "%pFX on %s filtered by prefix-list %s ",
447 c
->address
, oi
->interface
->name
,
453 route
= ospf6_route_create();
454 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
455 apply_mask(&route
->prefix
);
456 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
457 route
->path
.area_id
= oi
->area
->area_id
;
458 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
459 route
->path
.cost
= oi
->cost
;
460 inet_pton(AF_INET6
, "::1", &nh_addr
);
461 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
463 ospf6_route_add(route
, oi
->route_connected
, oi
->area
->ospf6
);
466 /* create new Link-LSA */
467 OSPF6_LINK_LSA_SCHEDULE(oi
);
468 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
469 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
472 static void ospf6_interface_state_change(uint8_t next_state
,
473 struct ospf6_interface
*oi
)
478 prev_state
= oi
->state
;
479 oi
->state
= next_state
;
481 if (prev_state
== next_state
)
485 if (IS_OSPF6_DEBUG_INTERFACE
) {
486 zlog_debug("Interface state change %s: %s -> %s",
488 ospf6_interface_state_str
[prev_state
],
489 ospf6_interface_state_str
[next_state
]);
492 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
494 if ((prev_state
== OSPF6_INTERFACE_DR
495 || prev_state
== OSPF6_INTERFACE_BDR
)
496 && (next_state
!= OSPF6_INTERFACE_DR
497 && next_state
!= OSPF6_INTERFACE_BDR
))
498 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
499 IPV6_LEAVE_GROUP
, ospf6
->fd
);
501 if ((prev_state
!= OSPF6_INTERFACE_DR
502 && prev_state
!= OSPF6_INTERFACE_BDR
)
503 && (next_state
== OSPF6_INTERFACE_DR
504 || next_state
== OSPF6_INTERFACE_BDR
))
505 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
506 IPV6_JOIN_GROUP
, ospf6
->fd
);
508 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
509 if (next_state
== OSPF6_INTERFACE_DOWN
) {
510 OSPF6_NETWORK_LSA_EXECUTE(oi
);
511 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
512 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
513 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
514 } else if (prev_state
== OSPF6_INTERFACE_DR
515 || next_state
== OSPF6_INTERFACE_DR
) {
516 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
517 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
518 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
521 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
525 /* DR Election, RFC2328 section 9.4 */
527 #define IS_ELIGIBLE(n) \
528 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
530 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
531 struct ospf6_neighbor
*b
)
533 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
534 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
536 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
538 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
541 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
543 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
546 if (a
->priority
> b
->priority
)
548 if (a
->priority
< b
->priority
)
551 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
553 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
556 zlog_warn("Router-ID duplicate ?");
560 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
561 struct ospf6_neighbor
*b
)
563 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
564 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
566 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
568 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
571 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
573 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
576 if (a
->priority
> b
->priority
)
578 if (a
->priority
< b
->priority
)
581 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
583 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
586 zlog_warn("Router-ID duplicate ?");
590 static uint8_t dr_election(struct ospf6_interface
*oi
)
592 struct listnode
*node
, *nnode
;
593 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
594 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
595 uint8_t next_state
= 0;
597 drouter
= bdrouter
= NULL
;
598 best_drouter
= best_bdrouter
= NULL
;
600 /* pseudo neighbor myself, including noting current DR/BDR (1) */
601 memset(&myself
, 0, sizeof(myself
));
602 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
603 sizeof(myself
.name
));
604 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
605 myself
.drouter
= oi
->drouter
;
606 myself
.bdrouter
= oi
->bdrouter
;
607 myself
.priority
= oi
->priority
;
608 myself
.router_id
= oi
->area
->ospf6
->router_id
;
610 /* Electing BDR (2) */
611 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
612 bdrouter
= better_bdrouter(bdrouter
, on
);
614 best_bdrouter
= bdrouter
;
615 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
617 /* Electing DR (3) */
618 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
619 drouter
= better_drouter(drouter
, on
);
621 best_drouter
= drouter
;
622 drouter
= better_drouter(best_drouter
, &myself
);
626 /* the router itself is newly/no longer DR/BDR (4) */
627 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
628 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
629 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
630 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
631 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
632 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
634 /* compatible to Electing BDR (2) */
635 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
637 /* compatible to Electing DR (3) */
638 drouter
= better_drouter(best_drouter
, &myself
);
643 /* Set interface state accordingly (5) */
644 if (drouter
&& drouter
== &myself
)
645 next_state
= OSPF6_INTERFACE_DR
;
646 else if (bdrouter
&& bdrouter
== &myself
)
647 next_state
= OSPF6_INTERFACE_BDR
;
649 next_state
= OSPF6_INTERFACE_DROTHER
;
651 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
654 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
655 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
656 accordingly after AdjOK */
657 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
658 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
659 if (IS_OSPF6_DEBUG_INTERFACE
)
660 zlog_debug("DR Election on %s: DR: %s BDR: %s",
662 (drouter
? drouter
->name
: "0.0.0.0"),
663 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
665 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
666 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
668 /* Schedule AdjOK. */
669 thread_add_event(master
, adj_ok
, on
, 0, NULL
);
673 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
674 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
679 /* Interface State Machine */
680 int interface_up(struct thread
*thread
)
682 struct ospf6_interface
*oi
;
685 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
686 assert(oi
&& oi
->interface
);
689 oi
->type
= ospf6_default_iftype(oi
->interface
);
692 * Remove old pointer. If this thread wasn't a timer this
693 * operation won't make a difference, because it is already NULL.
695 oi
->thread_sso
= NULL
;
697 if (IS_OSPF6_DEBUG_INTERFACE
)
698 zlog_debug("Interface Event %s: [InterfaceUp]",
699 oi
->interface
->name
);
701 /* check physical interface is up */
702 if (!if_is_operative(oi
->interface
)) {
703 if (IS_OSPF6_DEBUG_INTERFACE
)
705 "Interface %s is down, can't execute [InterfaceUp]",
706 oi
->interface
->name
);
710 /* check interface has a link-local address */
711 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
712 || if_is_loopback(oi
->interface
))) {
713 if (IS_OSPF6_DEBUG_INTERFACE
)
715 "Interface %s has no link local address, can't execute [InterfaceUp]",
716 oi
->interface
->name
);
721 ospf6_interface_recalculate_cost(oi
);
723 /* if already enabled, do nothing */
724 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
725 if (IS_OSPF6_DEBUG_INTERFACE
)
726 zlog_debug("Interface %s already enabled",
727 oi
->interface
->name
);
731 /* If no area assigned, return */
732 if (oi
->area
== NULL
) {
734 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
735 __func__
, oi
->interface
->name
);
741 * XXX: Schedule IPv6 group join for later, otherwise we might
742 * lose the multicast group registration caused by IPv6 group
745 if (oi
->sso_try_cnt
== 0) {
747 zlog_info("Scheduling %s for sso", oi
->interface
->name
);
748 thread_add_timer(master
, interface_up
, oi
,
749 OSPF6_INTERFACE_SSO_RETRY_INT
,
753 #endif /* __FreeBSD__ */
755 ospf6
= oi
->area
->ospf6
;
757 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
759 /* Join AllSPFRouters */
760 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
,
763 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
765 "Scheduling %s for sso retry, trial count: %d",
766 oi
->interface
->name
, oi
->sso_try_cnt
);
767 thread_add_timer(master
, interface_up
, oi
,
768 OSPF6_INTERFACE_SSO_RETRY_INT
,
773 oi
->sso_try_cnt
= 0; /* Reset on success */
775 /* Update interface route */
776 ospf6_interface_connected_route_update(oi
->interface
);
779 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
780 && !if_is_loopback(oi
->interface
)) {
781 oi
->thread_send_hello
= NULL
;
782 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
783 &oi
->thread_send_hello
);
786 /* decide next interface state */
787 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
788 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
789 } else if (oi
->priority
== 0)
790 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
792 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
793 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
800 int wait_timer(struct thread
*thread
)
802 struct ospf6_interface
*oi
;
804 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
805 assert(oi
&& oi
->interface
);
807 if (IS_OSPF6_DEBUG_INTERFACE
)
808 zlog_debug("Interface Event %s: [WaitTimer]",
809 oi
->interface
->name
);
811 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
812 ospf6_interface_state_change(dr_election(oi
), oi
);
817 int backup_seen(struct thread
*thread
)
819 struct ospf6_interface
*oi
;
821 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
822 assert(oi
&& oi
->interface
);
824 if (IS_OSPF6_DEBUG_INTERFACE
)
825 zlog_debug("Interface Event %s: [BackupSeen]",
826 oi
->interface
->name
);
828 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
829 ospf6_interface_state_change(dr_election(oi
), oi
);
834 int neighbor_change(struct thread
*thread
)
836 struct ospf6_interface
*oi
;
838 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
839 assert(oi
&& oi
->interface
);
841 if (IS_OSPF6_DEBUG_INTERFACE
)
842 zlog_debug("Interface Event %s: [NeighborChange]",
843 oi
->interface
->name
);
845 if (oi
->state
== OSPF6_INTERFACE_DROTHER
846 || oi
->state
== OSPF6_INTERFACE_BDR
847 || oi
->state
== OSPF6_INTERFACE_DR
)
848 ospf6_interface_state_change(dr_election(oi
), oi
);
853 int interface_down(struct thread
*thread
)
855 struct ospf6_interface
*oi
;
856 struct listnode
*node
, *nnode
;
857 struct ospf6_neighbor
*on
;
860 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
861 assert(oi
&& oi
->interface
);
863 if (IS_OSPF6_DEBUG_INTERFACE
)
864 zlog_debug("Interface Event %s: [InterfaceDown]",
865 oi
->interface
->name
);
868 THREAD_OFF(oi
->thread_send_hello
);
870 /* Stop trying to set socket options. */
871 THREAD_OFF(oi
->thread_sso
);
872 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
873 /* Leave AllSPFRouters */
874 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
875 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
876 IPV6_LEAVE_GROUP
, ospf6
->fd
);
878 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
880 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
881 ospf6_neighbor_delete(on
);
883 list_delete_all_node(oi
->neighbor_list
);
885 /* When interface state is reset, also reset information about
886 * DR election, as it is no longer valid. */
887 oi
->drouter
= oi
->prev_drouter
= htonl(0);
888 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
893 static const char *ospf6_iftype_str(uint8_t iftype
)
896 case OSPF_IFTYPE_LOOPBACK
:
898 case OSPF_IFTYPE_BROADCAST
:
900 case OSPF_IFTYPE_POINTOPOINT
:
901 return "POINTOPOINT";
906 /* show specified interface structure */
907 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
)
909 struct ospf6_interface
*oi
;
913 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
914 uint8_t default_iftype
;
915 struct timeval res
, now
;
917 struct ospf6_lsa
*lsa
, *lsanext
;
919 default_iftype
= ospf6_default_iftype(ifp
);
921 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
922 (if_is_operative(ifp
) ? "up" : "down"),
923 ospf6_iftype_str(default_iftype
));
924 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
926 if (ifp
->info
== NULL
) {
927 vty_out(vty
, " OSPF not enabled on this interface\n");
930 oi
= (struct ospf6_interface
*)ifp
->info
;
932 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
933 vty_out(vty
, " Operating as type %s\n",
934 ospf6_iftype_str(oi
->type
));
936 vty_out(vty
, " Internet Address:\n");
938 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
942 vty_out(vty
, " inet : %pFX\n", p
);
945 vty_out(vty
, " inet6: %pFX\n", p
);
948 vty_out(vty
, " ??? : %pFX\n", p
);
955 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
956 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
957 vty_out(vty
, " MTU mismatch detection: %s\n",
958 oi
->mtu_ignore
? "disabled" : "enabled");
959 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
, sizeof(strbuf
));
960 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
, oi
->cost
);
962 vty_out(vty
, " Not Attached to Area\n");
964 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
965 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
967 vty_out(vty
, " Timer intervals configured:\n");
968 vty_out(vty
, " Hello %d, Dead %d, Retransmit %d\n",
969 oi
->hello_interval
, oi
->dead_interval
, oi
->rxmt_interval
);
971 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
972 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
973 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
975 vty_out(vty
, " Number of I/F scoped LSAs is %u\n", oi
->lsdb
->count
);
980 if (oi
->thread_send_lsupdate
)
981 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
, &res
);
982 timerstring(&res
, duration
, sizeof(duration
));
984 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
985 oi
->lsupdate_list
->count
, duration
,
986 (oi
->thread_send_lsupdate
? "on" : "off"));
987 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
988 vty_out(vty
, " %s\n", lsa
->name
);
991 if (oi
->thread_send_lsack
)
992 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
993 timerstring(&res
, duration
, sizeof(duration
));
994 vty_out(vty
, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
995 oi
->lsack_list
->count
, duration
,
996 (oi
->thread_send_lsack
? "on" : "off"));
997 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
998 vty_out(vty
, " %s\n", lsa
->name
);
999 ospf6_bfd_show_info(vty
, oi
->bfd_info
, 1);
1003 /* show interface */
1004 DEFUN (show_ipv6_ospf6_interface
,
1005 show_ipv6_ospf6_interface_ifname_cmd
,
1006 "show ipv6 ospf6 interface [IFNAME]",
1013 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1015 struct interface
*ifp
;
1018 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
1020 vty_out(vty
, "No such Interface: %s\n",
1021 argv
[idx_ifname
]->arg
);
1024 ospf6_interface_show(vty
, ifp
);
1026 FOR_ALL_INTERFACES (vrf
, ifp
)
1027 ospf6_interface_show(vty
, ifp
);
1033 static int ospf6_interface_show_traffic(struct vty
*vty
,
1034 struct interface
*intf_ifp
,
1037 struct interface
*ifp
;
1038 struct vrf
*vrf
= NULL
;
1039 struct ospf6_interface
*oi
= NULL
;
1042 vrf
= vrf_lookup_by_id(intf_ifp
->vrf_id
);
1044 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1046 if (!display_once
) {
1048 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1049 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1051 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1052 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1055 "--------------------------------------------------------------------------------------------\n");
1058 if (intf_ifp
== NULL
) {
1059 FOR_ALL_INTERFACES (vrf
, ifp
) {
1061 oi
= (struct ospf6_interface
*)ifp
->info
;
1066 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1067 oi
->interface
->name
, oi
->hello_in
,
1068 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1069 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1070 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1073 oi
= intf_ifp
->info
;
1078 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1079 oi
->interface
->name
, oi
->hello_in
, oi
->hello_out
,
1080 oi
->db_desc_in
, oi
->db_desc_out
, oi
->ls_req_in
,
1081 oi
->ls_req_out
, oi
->ls_upd_in
, oi
->ls_upd_out
,
1082 oi
->ls_ack_in
, oi
->ls_ack_out
);
1088 /* show interface */
1089 DEFUN (show_ipv6_ospf6_interface_traffic
,
1090 show_ipv6_ospf6_interface_traffic_cmd
,
1091 "show ipv6 ospf6 interface traffic [IFNAME]",
1096 "Protocol Packet counters\n"
1100 int display_once
= 0;
1101 char *intf_name
= NULL
;
1102 struct interface
*ifp
= NULL
;
1104 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1105 intf_name
= argv
[idx_ifname
]->arg
;
1106 ifp
= if_lookup_by_name(intf_name
, VRF_DEFAULT
);
1108 vty_out(vty
, "No such Interface: %s\n", intf_name
);
1111 if (ifp
->info
== NULL
) {
1113 " OSPF not enabled on this interface %s\n",
1119 ospf6_interface_show_traffic(vty
, ifp
, display_once
);
1126 DEFUN (show_ipv6_ospf6_interface_ifname_prefix
,
1127 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1128 "show ipv6 ospf6 interface IFNAME prefix\
1131 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1138 "Display connected prefixes to advertise\n"
1139 "Display details of the prefixes\n"
1140 OSPF6_ROUTE_ADDRESS_STR
1141 OSPF6_ROUTE_PREFIX_STR
1142 OSPF6_ROUTE_MATCH_STR
1143 "Display details of the prefixes\n")
1147 struct interface
*ifp
;
1148 struct ospf6_interface
*oi
;
1150 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
1152 vty_out(vty
, "No such Interface: %s\n", argv
[idx_ifname
]->arg
);
1158 vty_out(vty
, "OSPFv3 is not enabled on %s\n",
1159 argv
[idx_ifname
]->arg
);
1163 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1164 oi
->route_connected
);
1169 DEFUN (show_ipv6_ospf6_interface_prefix
,
1170 show_ipv6_ospf6_interface_prefix_cmd
,
1171 "show ipv6 ospf6 interface prefix\
1174 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1180 "Display connected prefixes to advertise\n"
1181 "Display details of the prefixes\n"
1182 OSPF6_ROUTE_ADDRESS_STR
1183 OSPF6_ROUTE_PREFIX_STR
1184 OSPF6_ROUTE_MATCH_STR
1185 "Display details of the prefixes\n")
1187 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1189 struct ospf6_interface
*oi
;
1190 struct interface
*ifp
;
1192 FOR_ALL_INTERFACES (vrf
, ifp
) {
1193 oi
= (struct ospf6_interface
*)ifp
->info
;
1197 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1198 oi
->route_connected
);
1204 /* interface variable set command */
1205 DEFUN (ipv6_ospf6_ifmtu
,
1206 ipv6_ospf6_ifmtu_cmd
,
1207 "ipv6 ospf6 ifmtu (1-65535)",
1211 "OSPFv3 Interface MTU\n"
1214 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1216 struct ospf6_interface
*oi
;
1217 unsigned int ifmtu
, iobuflen
;
1218 struct listnode
*node
, *nnode
;
1219 struct ospf6_neighbor
*on
;
1223 oi
= (struct ospf6_interface
*)ifp
->info
;
1225 oi
= ospf6_interface_create(ifp
);
1228 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1230 if (oi
->c_ifmtu
== ifmtu
)
1233 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1235 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1236 ifp
->name
, ifp
->mtu6
);
1237 return CMD_WARNING_CONFIG_FAILED
;
1240 if (oi
->ifmtu
< ifmtu
) {
1241 iobuflen
= ospf6_iobuf_size(ifmtu
);
1242 if (iobuflen
< ifmtu
) {
1244 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1245 ifp
->name
, iobuflen
);
1246 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1248 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1250 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1252 /* re-establish adjacencies */
1253 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1254 THREAD_OFF(on
->inactivity_timer
);
1255 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1261 DEFUN (no_ipv6_ospf6_ifmtu
,
1262 no_ipv6_ospf6_ifmtu_cmd
,
1263 "no ipv6 ospf6 ifmtu [(1-65535)]",
1268 "OSPFv3 Interface MTU\n"
1271 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1272 struct ospf6_interface
*oi
;
1273 unsigned int iobuflen
;
1274 struct listnode
*node
, *nnode
;
1275 struct ospf6_neighbor
*on
;
1279 oi
= (struct ospf6_interface
*)ifp
->info
;
1281 oi
= ospf6_interface_create(ifp
);
1284 if (oi
->ifmtu
< ifp
->mtu
) {
1285 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1286 if (iobuflen
< ifp
->mtu
) {
1288 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1289 ifp
->name
, iobuflen
);
1290 oi
->ifmtu
= iobuflen
;
1292 oi
->ifmtu
= ifp
->mtu
;
1294 oi
->ifmtu
= ifp
->mtu
;
1298 /* re-establish adjacencies */
1299 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1300 THREAD_OFF(on
->inactivity_timer
);
1301 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1307 DEFUN (ipv6_ospf6_cost
,
1308 ipv6_ospf6_cost_cmd
,
1309 "ipv6 ospf6 cost (1-65535)",
1313 "Outgoing metric of this interface\n")
1315 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1317 struct ospf6_interface
*oi
;
1318 unsigned long int lcost
;
1322 oi
= (struct ospf6_interface
*)ifp
->info
;
1324 oi
= ospf6_interface_create(ifp
);
1327 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1329 if (lcost
> UINT32_MAX
) {
1330 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1331 return CMD_WARNING_CONFIG_FAILED
;
1334 if (oi
->cost
== lcost
)
1338 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1340 ospf6_interface_force_recalculate_cost(oi
);
1345 DEFUN (no_ipv6_ospf6_cost
,
1346 no_ipv6_ospf6_cost_cmd
,
1347 "no ipv6 ospf6 cost [(1-65535)]",
1351 "Calculate interface cost from bandwidth\n"
1352 "Outgoing metric of this interface\n")
1354 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1355 struct ospf6_interface
*oi
;
1358 oi
= (struct ospf6_interface
*)ifp
->info
;
1360 oi
= ospf6_interface_create(ifp
);
1363 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1365 ospf6_interface_recalculate_cost(oi
);
1370 DEFUN (auto_cost_reference_bandwidth
,
1371 auto_cost_reference_bandwidth_cmd
,
1372 "auto-cost reference-bandwidth (1-4294967)",
1373 "Calculate OSPF interface cost according to bandwidth\n"
1374 "Use reference bandwidth method to assign OSPF cost\n"
1375 "The reference bandwidth in terms of Mbits per second\n")
1377 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1379 struct ospf6_area
*oa
;
1380 struct ospf6_interface
*oi
;
1381 struct listnode
*i
, *j
;
1384 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1385 if (refbw
< 1 || refbw
> 4294967) {
1386 vty_out(vty
, "reference-bandwidth value is invalid\n");
1387 return CMD_WARNING_CONFIG_FAILED
;
1390 /* If reference bandwidth is changed. */
1391 if ((refbw
) == o
->ref_bandwidth
)
1394 o
->ref_bandwidth
= refbw
;
1395 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1396 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1397 ospf6_interface_recalculate_cost(oi
);
1402 DEFUN (no_auto_cost_reference_bandwidth
,
1403 no_auto_cost_reference_bandwidth_cmd
,
1404 "no auto-cost reference-bandwidth [(1-4294967)]",
1406 "Calculate OSPF interface cost according to bandwidth\n"
1407 "Use reference bandwidth method to assign OSPF cost\n"
1408 "The reference bandwidth in terms of Mbits per second\n")
1410 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1411 struct ospf6_area
*oa
;
1412 struct ospf6_interface
*oi
;
1413 struct listnode
*i
, *j
;
1415 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
1418 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
1419 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1420 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1421 ospf6_interface_recalculate_cost(oi
);
1427 DEFUN (ipv6_ospf6_hellointerval
,
1428 ipv6_ospf6_hellointerval_cmd
,
1429 "ipv6 ospf6 hello-interval (1-65535)",
1432 "Time between HELLO packets\n"
1435 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1437 struct ospf6_interface
*oi
;
1440 oi
= (struct ospf6_interface
*)ifp
->info
;
1442 oi
= ospf6_interface_create(ifp
);
1445 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
1446 ? OSPF_HELLO_INTERVAL_DEFAULT
1447 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1451 ALIAS (ipv6_ospf6_hellointerval
,
1452 no_ipv6_ospf6_hellointerval_cmd
,
1453 "no ipv6 ospf6 hello-interval [(1-65535)]",
1457 "Time between HELLO packets\n"
1460 /* interface variable set command */
1461 DEFUN (ipv6_ospf6_deadinterval
,
1462 ipv6_ospf6_deadinterval_cmd
,
1463 "ipv6 ospf6 dead-interval (1-65535)",
1466 "Interval time after which a neighbor is declared down\n"
1469 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1471 struct ospf6_interface
*oi
;
1474 oi
= (struct ospf6_interface
*)ifp
->info
;
1476 oi
= ospf6_interface_create(ifp
);
1479 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
1480 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1481 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1485 ALIAS (ipv6_ospf6_deadinterval
,
1486 no_ipv6_ospf6_deadinterval_cmd
,
1487 "no ipv6 ospf6 dead-interval [(1-65535)]",
1491 "Interval time after which a neighbor is declared down\n"
1494 /* interface variable set command */
1495 DEFUN (ipv6_ospf6_transmitdelay
,
1496 ipv6_ospf6_transmitdelay_cmd
,
1497 "ipv6 ospf6 transmit-delay (1-3600)",
1500 "Link state transmit delay\n"
1503 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1505 struct ospf6_interface
*oi
;
1508 oi
= (struct ospf6_interface
*)ifp
->info
;
1510 oi
= ospf6_interface_create(ifp
);
1513 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
1514 ? OSPF6_INTERFACE_TRANSDELAY
1515 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1519 ALIAS (ipv6_ospf6_transmitdelay
,
1520 no_ipv6_ospf6_transmitdelay_cmd
,
1521 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1525 "Link state transmit delay\n"
1528 /* interface variable set command */
1529 DEFUN (ipv6_ospf6_retransmitinterval
,
1530 ipv6_ospf6_retransmitinterval_cmd
,
1531 "ipv6 ospf6 retransmit-interval (1-65535)",
1534 "Time between retransmitting lost link state advertisements\n"
1537 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1539 struct ospf6_interface
*oi
;
1542 oi
= (struct ospf6_interface
*)ifp
->info
;
1544 oi
= ospf6_interface_create(ifp
);
1547 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
1548 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1549 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1553 ALIAS (ipv6_ospf6_retransmitinterval
,
1554 no_ipv6_ospf6_retransmitinterval_cmd
,
1555 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1559 "Time between retransmitting lost link state advertisements\n"
1562 /* interface variable set command */
1563 DEFUN (ipv6_ospf6_priority
,
1564 ipv6_ospf6_priority_cmd
,
1565 "ipv6 ospf6 priority (0-255)",
1571 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1573 struct ospf6_interface
*oi
;
1576 oi
= (struct ospf6_interface
*)ifp
->info
;
1578 oi
= ospf6_interface_create(ifp
);
1581 oi
->priority
= strmatch(argv
[0]->text
, "no")
1582 ? OSPF6_INTERFACE_PRIORITY
1583 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1585 if (oi
->area
&& (oi
->state
== OSPF6_INTERFACE_DROTHER
1586 || oi
->state
== OSPF6_INTERFACE_BDR
1587 || oi
->state
== OSPF6_INTERFACE_DR
))
1588 ospf6_interface_state_change(dr_election(oi
), oi
);
1593 ALIAS (ipv6_ospf6_priority
,
1594 no_ipv6_ospf6_priority_cmd
,
1595 "no ipv6 ospf6 priority [(0-255)]",
1602 DEFUN (ipv6_ospf6_instance
,
1603 ipv6_ospf6_instance_cmd
,
1604 "ipv6 ospf6 instance-id (0-255)",
1607 "Instance ID for this interface\n"
1608 "Instance ID value\n")
1610 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1612 struct ospf6_interface
*oi
;
1615 oi
= (struct ospf6_interface
*)ifp
->info
;
1617 oi
= ospf6_interface_create(ifp
);
1620 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
1621 ? OSPF6_INTERFACE_INSTANCE_ID
1622 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1626 ALIAS (ipv6_ospf6_instance
,
1627 no_ipv6_ospf6_instance_cmd
,
1628 "no ipv6 ospf6 instance-id [(0-255)]",
1632 "Instance ID for this interface\n"
1633 "Instance ID value\n")
1635 DEFUN (ipv6_ospf6_passive
,
1636 ipv6_ospf6_passive_cmd
,
1637 "ipv6 ospf6 passive",
1640 "Passive interface; no adjacency will be formed on this interface\n"
1643 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1644 struct ospf6_interface
*oi
;
1645 struct listnode
*node
, *nnode
;
1646 struct ospf6_neighbor
*on
;
1650 oi
= (struct ospf6_interface
*)ifp
->info
;
1652 oi
= ospf6_interface_create(ifp
);
1655 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1656 THREAD_OFF(oi
->thread_send_hello
);
1657 THREAD_OFF(oi
->thread_sso
);
1659 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1660 THREAD_OFF(on
->inactivity_timer
);
1661 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1667 DEFUN (no_ipv6_ospf6_passive
,
1668 no_ipv6_ospf6_passive_cmd
,
1669 "no ipv6 ospf6 passive",
1673 "passive interface: No Adjacency will be formed on this I/F\n"
1676 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1677 struct ospf6_interface
*oi
;
1680 oi
= (struct ospf6_interface
*)ifp
->info
;
1682 oi
= ospf6_interface_create(ifp
);
1685 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1686 THREAD_OFF(oi
->thread_send_hello
);
1687 THREAD_OFF(oi
->thread_sso
);
1688 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
1689 &oi
->thread_send_hello
);
1694 DEFUN (ipv6_ospf6_mtu_ignore
,
1695 ipv6_ospf6_mtu_ignore_cmd
,
1696 "ipv6 ospf6 mtu-ignore",
1699 "Disable MTU mismatch detection on this interface\n"
1702 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1703 struct ospf6_interface
*oi
;
1706 oi
= (struct ospf6_interface
*)ifp
->info
;
1708 oi
= ospf6_interface_create(ifp
);
1716 DEFUN (no_ipv6_ospf6_mtu_ignore
,
1717 no_ipv6_ospf6_mtu_ignore_cmd
,
1718 "no ipv6 ospf6 mtu-ignore",
1722 "Disable MTU mismatch detection on this interface\n"
1725 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1726 struct ospf6_interface
*oi
;
1729 oi
= (struct ospf6_interface
*)ifp
->info
;
1731 oi
= ospf6_interface_create(ifp
);
1739 DEFUN (ipv6_ospf6_advertise_prefix_list
,
1740 ipv6_ospf6_advertise_prefix_list_cmd
,
1741 "ipv6 ospf6 advertise prefix-list WORD",
1744 "Advertising options\n"
1745 "Filter prefix using prefix-list\n"
1746 "Prefix list name\n"
1749 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1751 struct ospf6_interface
*oi
;
1754 oi
= (struct ospf6_interface
*)ifp
->info
;
1756 oi
= ospf6_interface_create(ifp
);
1760 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
1761 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
1763 ospf6_interface_connected_route_update(oi
->interface
);
1766 OSPF6_LINK_LSA_SCHEDULE(oi
);
1767 if (oi
->state
== OSPF6_INTERFACE_DR
) {
1768 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
1769 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
1771 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
1777 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
1778 no_ipv6_ospf6_advertise_prefix_list_cmd
,
1779 "no ipv6 ospf6 advertise prefix-list [WORD]",
1783 "Advertising options\n"
1784 "Filter prefix using prefix-list\n"
1785 "Prefix list name\n")
1787 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1788 struct ospf6_interface
*oi
;
1791 oi
= (struct ospf6_interface
*)ifp
->info
;
1793 oi
= ospf6_interface_create(ifp
);
1797 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
1799 ospf6_interface_connected_route_update(oi
->interface
);
1802 OSPF6_LINK_LSA_SCHEDULE(oi
);
1803 if (oi
->state
== OSPF6_INTERFACE_DR
) {
1804 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
1805 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
1807 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
1813 DEFUN (ipv6_ospf6_network
,
1814 ipv6_ospf6_network_cmd
,
1815 "ipv6 ospf6 network <broadcast|point-to-point>",
1819 "Specify OSPF6 broadcast network\n"
1820 "Specify OSPF6 point-to-point network\n"
1823 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1824 int idx_network
= 3;
1825 struct ospf6_interface
*oi
;
1828 oi
= (struct ospf6_interface
*)ifp
->info
;
1830 oi
= ospf6_interface_create(ifp
);
1834 oi
->type_cfg
= true;
1836 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
1837 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1840 oi
->type
= OSPF_IFTYPE_BROADCAST
;
1841 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
1842 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
1845 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
1848 /* Reset the interface */
1849 thread_execute(master
, interface_down
, oi
, 0);
1850 thread_execute(master
, interface_up
, oi
, 0);
1855 DEFUN (no_ipv6_ospf6_network
,
1856 no_ipv6_ospf6_network_cmd
,
1857 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
1861 "Set default network type\n"
1862 "Specify OSPF6 broadcast network\n"
1863 "Specify OSPF6 point-to-point network\n")
1865 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1866 struct ospf6_interface
*oi
;
1871 oi
= (struct ospf6_interface
*)ifp
->info
;
1876 oi
->type_cfg
= false;
1878 type
= ospf6_default_iftype(ifp
);
1879 if (oi
->type
== type
) {
1884 /* Reset the interface */
1885 thread_execute(master
, interface_down
, oi
, 0);
1886 thread_execute(master
, interface_up
, oi
, 0);
1891 static int config_write_ospf6_interface(struct vty
*vty
)
1893 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1894 struct ospf6_interface
*oi
;
1895 struct interface
*ifp
;
1897 FOR_ALL_INTERFACES (vrf
, ifp
) {
1898 oi
= (struct ospf6_interface
*)ifp
->info
;
1902 vty_frame(vty
, "interface %s\n", oi
->interface
->name
);
1905 vty_out(vty
, " description %s\n", ifp
->desc
);
1907 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
1909 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
1910 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
1912 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
1913 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
1914 oi
->hello_interval
);
1916 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
1917 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
1920 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
1921 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
1924 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
1925 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
1927 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
1928 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
1931 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
1932 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
1936 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
1939 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
1940 vty_out(vty
, " ipv6 ospf6 passive\n");
1943 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
1945 if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
1946 vty_out(vty
, " ipv6 ospf6 network point-to-point\n");
1947 else if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_BROADCAST
)
1948 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
1950 ospf6_bfd_write_config(vty
, oi
);
1952 vty_endframe(vty
, "!\n");
1957 static int config_write_ospf6_interface(struct vty
*vty
);
1958 static struct cmd_node interface_node
= {
1959 .name
= "interface",
1960 .node
= INTERFACE_NODE
,
1961 .parent_node
= CONFIG_NODE
,
1962 .prompt
= "%s(config-if)# ",
1963 .config_write
= config_write_ospf6_interface
,
1966 static int ospf6_ifp_create(struct interface
*ifp
)
1968 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
1969 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp
->name
,
1970 ifp
->ifindex
, ifp
->mtu6
);
1971 ospf6_interface_if_add(ifp
);
1976 static int ospf6_ifp_up(struct interface
*ifp
)
1978 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
1980 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
1981 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
1982 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
1984 ospf6_interface_state_update(ifp
);
1989 static int ospf6_ifp_down(struct interface
*ifp
)
1991 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
1993 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
1994 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
1995 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
1997 ospf6_interface_state_update(ifp
);
2002 static int ospf6_ifp_destroy(struct interface
*ifp
)
2005 zlog_warn("Zebra: got delete of %s, but interface is still up",
2008 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2009 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2010 ifp
->name
, ifp
->ifindex
, ifp
->mtu6
);
2015 void ospf6_interface_init(void)
2017 /* Install interface node. */
2018 install_node(&interface_node
);
2020 if_zapi_callbacks(ospf6_ifp_create
, ospf6_ifp_up
,
2021 ospf6_ifp_down
, ospf6_ifp_destroy
);
2023 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
2024 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
2025 install_element(VIEW_NODE
,
2026 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
2027 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
2029 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
2030 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
2031 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
2032 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
2034 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
2035 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
2036 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
2037 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
2038 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
2039 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
2040 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
2041 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
2042 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
2043 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
2044 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
2045 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
2047 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
2048 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
2050 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
2051 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
2053 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
2054 install_element(INTERFACE_NODE
,
2055 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
2057 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
2058 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
2060 /* reference bandwidth commands */
2061 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
2062 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
2065 /* Clear the specified interface structure */
2066 static void ospf6_interface_clear(struct vty
*vty
, struct interface
*ifp
)
2068 struct ospf6_interface
*oi
;
2070 if (!if_is_operative(ifp
))
2073 if (ifp
->info
== NULL
)
2076 oi
= (struct ospf6_interface
*)ifp
->info
;
2078 if (IS_OSPF6_DEBUG_INTERFACE
)
2079 zlog_debug("Interface %s: clear by reset", ifp
->name
);
2081 /* Reset the interface */
2082 thread_execute(master
, interface_down
, oi
, 0);
2083 thread_execute(master
, interface_up
, oi
, 0);
2086 /* Clear interface */
2087 DEFUN (clear_ipv6_ospf6_interface
,
2088 clear_ipv6_ospf6_interface_cmd
,
2089 "clear ipv6 ospf6 interface [IFNAME]",
2097 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2099 struct interface
*ifp
;
2101 if (argc
== 4) /* Clear all the ospfv3 interfaces. */
2103 FOR_ALL_INTERFACES (vrf
, ifp
)
2104 ospf6_interface_clear(vty
, ifp
);
2105 } else /* Interface name is specified. */
2107 if ((ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
2110 vty_out(vty
, "No such Interface: %s\n",
2111 argv
[idx_ifname
]->arg
);
2114 ospf6_interface_clear(vty
, ifp
);
2120 void install_element_ospf6_clear_interface(void)
2122 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2125 DEFUN (debug_ospf6_interface
,
2126 debug_ospf6_interface_cmd
,
2127 "debug ospf6 interface",
2130 "Debug OSPFv3 Interface\n"
2133 OSPF6_DEBUG_INTERFACE_ON();
2137 DEFUN (no_debug_ospf6_interface
,
2138 no_debug_ospf6_interface_cmd
,
2139 "no debug ospf6 interface",
2143 "Debug OSPFv3 Interface\n"
2146 OSPF6_DEBUG_INTERFACE_OFF();
2150 int config_write_ospf6_debug_interface(struct vty
*vty
)
2152 if (IS_OSPF6_DEBUG_INTERFACE
)
2153 vty_out(vty
, "debug ospf6 interface\n");
2157 void install_element_ospf6_debug_interface(void)
2159 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2160 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2161 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2162 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);