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"
48 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_IF
, "OSPF6 interface");
49 DEFINE_MTYPE_STATIC(OSPF6D
, CFG_PLIST_NAME
, "configured prefix list names");
50 DEFINE_QOBJ_TYPE(ospf6_interface
);
51 DEFINE_HOOK(ospf6_interface_change
,
52 (struct ospf6_interface
* oi
, int state
, int old_state
),
53 (oi
, state
, old_state
));
55 unsigned char conf_debug_ospf6_interface
= 0;
57 const char *const ospf6_interface_state_str
[] = {
58 "None", "Down", "Loopback", "Waiting", "PointToPoint",
59 "DROther", "BDR", "DR", NULL
};
61 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
,
64 struct ospf6_interface
*oi
;
65 struct interface
*ifp
;
67 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
69 return (struct ospf6_interface
*)NULL
;
71 oi
= (struct ospf6_interface
*)ifp
->info
;
75 /* schedule routing table recalculation */
76 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
79 struct ospf6_interface
*oi
;
85 switch (ntohs(lsa
->header
->type
)) {
86 case OSPF6_LSTYPE_LINK
:
87 if (oi
->state
== OSPF6_INTERFACE_DR
)
88 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
90 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
98 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
100 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
103 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
105 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
108 static uint8_t ospf6_default_iftype(struct interface
*ifp
)
110 if (if_is_pointopoint(ifp
))
111 return OSPF_IFTYPE_POINTOPOINT
;
112 else if (if_is_loopback(ifp
))
113 return OSPF_IFTYPE_LOOPBACK
;
115 return OSPF_IFTYPE_BROADCAST
;
118 static uint32_t ospf6_interface_get_cost(struct ospf6_interface
*oi
)
120 /* If all else fails, use default OSPF cost */
124 /* interface speed and bw can be 0 in some platforms,
125 * use ospf default bw. If bw is configured then it would
128 if (!oi
->interface
->bandwidth
&& oi
->interface
->speed
) {
129 bw
= oi
->interface
->speed
;
131 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
132 : OSPF6_INTERFACE_BANDWIDTH
;
135 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
136 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
138 /* A specifed ip ospf cost overrides a calculated one. */
139 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
142 cost
= (uint32_t)((double)refbw
/ (double)bw
+ (double)0.5);
145 else if (cost
> UINT32_MAX
)
152 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface
*oi
)
154 /* update cost held in route_connected list in ospf6_interface */
155 ospf6_interface_connected_route_update(oi
->interface
);
157 /* execute LSA hooks */
159 OSPF6_LINK_LSA_SCHEDULE(oi
);
160 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
161 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
162 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
163 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
167 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
171 newcost
= ospf6_interface_get_cost(oi
);
172 if (newcost
== oi
->cost
)
176 ospf6_interface_force_recalculate_cost(oi
);
179 /* Create new ospf6 interface structure */
180 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
182 struct ospf6_interface
*oi
;
183 unsigned int iobuflen
;
185 oi
= XCALLOC(MTYPE_OSPF6_IF
, sizeof(struct ospf6_interface
));
187 oi
->area
= (struct ospf6_area
*)NULL
;
188 oi
->neighbor_list
= list_new();
189 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
190 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
191 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
192 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
193 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
195 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
196 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
197 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
198 oi
->type
= ospf6_default_iftype(ifp
);
199 oi
->state
= OSPF6_INTERFACE_DOWN
;
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 if (IS_OSPF6_DEBUG_INTERFACE
)
210 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
211 ifp
->name
, iobuflen
);
212 oi
->ifmtu
= iobuflen
;
215 QOBJ_REG(oi
, ospf6_interface
);
217 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
218 oi
->lsack_list
= ospf6_lsdb_create(oi
);
219 oi
->lsdb
= ospf6_lsdb_create(oi
);
220 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
221 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
222 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
224 oi
->route_connected
=
225 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
226 oi
->route_connected
->scope
= oi
;
233 oi
->cost
= ospf6_interface_get_cost(oi
);
238 void ospf6_interface_delete(struct ospf6_interface
*oi
)
240 struct listnode
*node
, *nnode
;
241 struct ospf6_neighbor
*on
;
245 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
246 ospf6_neighbor_delete(on
);
248 list_delete(&oi
->neighbor_list
);
250 THREAD_OFF(oi
->thread_send_hello
);
251 THREAD_OFF(oi
->thread_send_lsupdate
);
252 THREAD_OFF(oi
->thread_send_lsack
);
253 THREAD_OFF(oi
->thread_sso
);
254 THREAD_OFF(oi
->thread_wait_timer
);
256 ospf6_lsdb_remove_all(oi
->lsdb
);
257 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
258 ospf6_lsdb_remove_all(oi
->lsack_list
);
260 ospf6_lsdb_delete(oi
->lsdb
);
261 ospf6_lsdb_delete(oi
->lsdb_self
);
263 ospf6_lsdb_delete(oi
->lsupdate_list
);
264 ospf6_lsdb_delete(oi
->lsack_list
);
266 ospf6_route_table_delete(oi
->route_connected
);
269 oi
->interface
->info
= NULL
;
273 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
275 ospf6_bfd_info_free(&(oi
->bfd_info
));
277 /* disable from area list if possible */
278 ospf6_area_interface_delete(oi
);
280 XFREE(MTYPE_OSPF6_IF
, oi
);
283 void ospf6_interface_enable(struct ospf6_interface
*oi
)
285 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
286 ospf6_interface_state_update(oi
->interface
);
289 void ospf6_interface_disable(struct ospf6_interface
*oi
)
291 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
293 thread_execute(master
, interface_down
, oi
, 0);
295 ospf6_lsdb_remove_all(oi
->lsdb
);
296 ospf6_lsdb_remove_all(oi
->lsdb_self
);
297 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
298 ospf6_lsdb_remove_all(oi
->lsack_list
);
300 THREAD_OFF(oi
->thread_send_hello
);
301 THREAD_OFF(oi
->thread_send_lsupdate
);
302 THREAD_OFF(oi
->thread_send_lsack
);
303 THREAD_OFF(oi
->thread_sso
);
305 THREAD_OFF(oi
->thread_network_lsa
);
306 THREAD_OFF(oi
->thread_link_lsa
);
307 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
308 THREAD_OFF(oi
->thread_as_extern_lsa
);
309 THREAD_OFF(oi
->thread_wait_timer
);
312 static struct in6_addr
*
313 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
317 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
319 /* for each connected address */
320 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
321 /* if family not AF_INET6, ignore */
322 if (c
->address
->family
!= AF_INET6
)
325 /* linklocal scope check */
326 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
327 l
= &c
->address
->u
.prefix6
;
332 void ospf6_interface_if_add(struct interface
*ifp
)
334 struct ospf6_interface
*oi
;
335 unsigned int iobuflen
;
337 oi
= (struct ospf6_interface
*)ifp
->info
;
341 /* Try to adjust I/O buffer size with IfMtu */
343 oi
->ifmtu
= ifp
->mtu6
;
344 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
345 if (oi
->ifmtu
> iobuflen
) {
346 if (IS_OSPF6_DEBUG_INTERFACE
)
348 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
349 ifp
->name
, iobuflen
);
350 oi
->ifmtu
= iobuflen
;
353 /* interface start */
354 ospf6_interface_state_update(oi
->interface
);
357 void ospf6_interface_state_update(struct interface
*ifp
)
359 struct ospf6_interface
*oi
;
360 unsigned int iobuflen
;
362 oi
= (struct ospf6_interface
*)ifp
->info
;
365 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
368 /* Adjust the mtu values if the kernel told us something new */
369 if (ifp
->mtu6
!= oi
->ifmtu
) {
370 /* If nothing configured, accept it and check for buffer size */
372 oi
->ifmtu
= ifp
->mtu6
;
373 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
374 if (oi
->ifmtu
> iobuflen
) {
375 if (IS_OSPF6_DEBUG_INTERFACE
)
377 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
378 ifp
->name
, iobuflen
);
379 oi
->ifmtu
= iobuflen
;
381 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
382 oi
->ifmtu
= ifp
->mtu6
;
384 "Configured mtu %u on %s overridden by kernel %u",
385 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
387 oi
->ifmtu
= oi
->c_ifmtu
;
390 if (if_is_operative(ifp
)
391 && (ospf6_interface_get_linklocal_address(oi
->interface
)
392 || if_is_loopback(oi
->interface
)))
393 thread_execute(master
, interface_up
, oi
, 0);
395 thread_execute(master
, interface_down
, oi
, 0);
400 void ospf6_interface_connected_route_update(struct interface
*ifp
)
402 struct ospf6_interface
*oi
;
403 struct ospf6_route
*route
;
405 struct listnode
*node
, *nnode
;
406 struct in6_addr nh_addr
;
408 oi
= (struct ospf6_interface
*)ifp
->info
;
412 /* reset linklocal pointer */
413 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
415 /* if area is null, do not make connected-route list */
416 if (oi
->area
== NULL
)
419 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
422 /* update "route to advertise" interface route table */
423 ospf6_route_remove_all(oi
->route_connected
);
425 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
426 if (c
->address
->family
!= AF_INET6
)
429 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
431 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
433 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
435 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
437 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
441 if (oi
->plist_name
) {
442 struct prefix_list
*plist
;
443 enum prefix_list_type ret
;
445 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
446 ret
= prefix_list_apply(plist
, (void *)c
->address
);
447 if (ret
== PREFIX_DENY
) {
448 if (IS_OSPF6_DEBUG_INTERFACE
)
450 "%pFX on %s filtered by prefix-list %s ",
451 c
->address
, oi
->interface
->name
,
457 route
= ospf6_route_create();
458 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
459 apply_mask(&route
->prefix
);
460 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
461 route
->path
.area_id
= oi
->area
->area_id
;
462 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
463 route
->path
.cost
= oi
->cost
;
464 inet_pton(AF_INET6
, "::1", &nh_addr
);
465 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
467 ospf6_route_add(route
, oi
->route_connected
);
470 /* create new Link-LSA */
471 OSPF6_LINK_LSA_SCHEDULE(oi
);
472 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
473 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
476 static void ospf6_interface_state_change(uint8_t next_state
,
477 struct ospf6_interface
*oi
)
482 prev_state
= oi
->state
;
483 oi
->state
= next_state
;
485 if (prev_state
== next_state
)
489 if (IS_OSPF6_DEBUG_INTERFACE
) {
490 zlog_debug("Interface state change %s: %s -> %s",
492 ospf6_interface_state_str
[prev_state
],
493 ospf6_interface_state_str
[next_state
]);
496 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
498 if ((prev_state
== OSPF6_INTERFACE_DR
499 || prev_state
== OSPF6_INTERFACE_BDR
)
500 && (next_state
!= OSPF6_INTERFACE_DR
501 && next_state
!= OSPF6_INTERFACE_BDR
))
502 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
503 IPV6_LEAVE_GROUP
, ospf6
->fd
);
505 if ((prev_state
!= OSPF6_INTERFACE_DR
506 && prev_state
!= OSPF6_INTERFACE_BDR
)
507 && (next_state
== OSPF6_INTERFACE_DR
508 || next_state
== OSPF6_INTERFACE_BDR
))
509 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
510 IPV6_JOIN_GROUP
, ospf6
->fd
);
512 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
513 OSPF6_LINK_LSA_SCHEDULE(oi
);
514 if (next_state
== OSPF6_INTERFACE_DOWN
) {
515 OSPF6_NETWORK_LSA_EXECUTE(oi
);
516 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
517 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
518 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
519 } else if (prev_state
== OSPF6_INTERFACE_DR
520 || next_state
== OSPF6_INTERFACE_DR
) {
521 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
522 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
523 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
526 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
530 /* DR Election, RFC2328 section 9.4 */
532 #define IS_ELIGIBLE(n) \
533 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
535 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
536 struct ospf6_neighbor
*b
)
538 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
539 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
541 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
543 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
546 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
548 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
551 if (a
->priority
> b
->priority
)
553 if (a
->priority
< b
->priority
)
556 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
558 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
561 zlog_warn("Router-ID duplicate ?");
565 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
566 struct ospf6_neighbor
*b
)
568 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
569 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
571 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
573 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
576 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
578 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
581 if (a
->priority
> b
->priority
)
583 if (a
->priority
< b
->priority
)
586 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
588 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
591 zlog_warn("Router-ID duplicate ?");
595 static uint8_t dr_election(struct ospf6_interface
*oi
)
597 struct listnode
*node
, *nnode
;
598 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
599 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
600 uint8_t next_state
= 0;
602 drouter
= bdrouter
= NULL
;
603 best_drouter
= best_bdrouter
= NULL
;
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
;
615 /* Electing BDR (2) */
616 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
617 bdrouter
= better_bdrouter(bdrouter
, on
);
619 best_bdrouter
= bdrouter
;
620 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
622 /* Electing DR (3) */
623 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
624 drouter
= better_drouter(drouter
, on
);
626 best_drouter
= drouter
;
627 drouter
= better_drouter(best_drouter
, &myself
);
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 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
637 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
639 /* compatible to Electing BDR (2) */
640 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
642 /* compatible to Electing DR (3) */
643 drouter
= better_drouter(best_drouter
, &myself
);
648 /* Set interface state accordingly (5) */
649 if (drouter
&& drouter
== &myself
)
650 next_state
= OSPF6_INTERFACE_DR
;
651 else if (bdrouter
&& bdrouter
== &myself
)
652 next_state
= OSPF6_INTERFACE_BDR
;
654 next_state
= OSPF6_INTERFACE_DROTHER
;
656 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
659 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
660 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
661 accordingly after AdjOK */
662 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
663 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
664 if (IS_OSPF6_DEBUG_INTERFACE
)
665 zlog_debug("DR Election on %s: DR: %s BDR: %s",
667 (drouter
? drouter
->name
: "0.0.0.0"),
668 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
670 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
671 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
673 /* Schedule AdjOK. */
674 thread_add_event(master
, adj_ok
, on
, 0, NULL
);
678 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
679 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
684 /* Interface State Machine */
685 int interface_up(struct thread
*thread
)
687 struct ospf6_interface
*oi
;
690 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
691 assert(oi
&& oi
->interface
);
694 oi
->type
= ospf6_default_iftype(oi
->interface
);
697 * Remove old pointer. If this thread wasn't a timer this
698 * operation won't make a difference, because it is already NULL.
700 oi
->thread_sso
= NULL
;
702 if (IS_OSPF6_DEBUG_INTERFACE
)
703 zlog_debug("Interface Event %s: [InterfaceUp]",
704 oi
->interface
->name
);
706 /* check physical interface is up */
707 if (!if_is_operative(oi
->interface
)) {
708 if (IS_OSPF6_DEBUG_INTERFACE
)
710 "Interface %s is down, can't execute [InterfaceUp]",
711 oi
->interface
->name
);
715 /* check interface has a link-local address */
716 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
717 || if_is_loopback(oi
->interface
))) {
718 if (IS_OSPF6_DEBUG_INTERFACE
)
720 "Interface %s has no link local address, can't execute [InterfaceUp]",
721 oi
->interface
->name
);
726 ospf6_interface_recalculate_cost(oi
);
728 /* if already enabled, do nothing */
729 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
730 if (IS_OSPF6_DEBUG_INTERFACE
)
731 zlog_debug("Interface %s already enabled",
732 oi
->interface
->name
);
736 /* If no area assigned, return */
737 if (oi
->area
== NULL
) {
739 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
740 __func__
, oi
->interface
->name
);
746 * XXX: Schedule IPv6 group join for later, otherwise we might
747 * lose the multicast group registration caused by IPv6 group
750 if (oi
->sso_try_cnt
== 0) {
752 zlog_info("Scheduling %s for sso", oi
->interface
->name
);
753 thread_add_timer(master
, interface_up
, oi
,
754 OSPF6_INTERFACE_SSO_RETRY_INT
,
758 #endif /* __FreeBSD__ */
760 ospf6
= oi
->area
->ospf6
;
762 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
764 /* Join AllSPFRouters */
765 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
,
768 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
770 "Scheduling %s for sso retry, trial count: %d",
771 oi
->interface
->name
, oi
->sso_try_cnt
);
772 thread_add_timer(master
, interface_up
, oi
,
773 OSPF6_INTERFACE_SSO_RETRY_INT
,
778 oi
->sso_try_cnt
= 0; /* Reset on success */
780 /* Update interface route */
781 ospf6_interface_connected_route_update(oi
->interface
);
784 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
785 && !if_is_loopback(oi
->interface
)) {
786 oi
->thread_send_hello
= NULL
;
787 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
788 &oi
->thread_send_hello
);
791 /* decide next interface state */
792 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
793 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
794 } else if (oi
->priority
== 0)
795 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
797 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
798 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
799 &oi
->thread_wait_timer
);
805 int wait_timer(struct thread
*thread
)
807 struct ospf6_interface
*oi
;
809 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
810 assert(oi
&& oi
->interface
);
812 if (IS_OSPF6_DEBUG_INTERFACE
)
813 zlog_debug("Interface Event %s: [WaitTimer]",
814 oi
->interface
->name
);
816 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
817 ospf6_interface_state_change(dr_election(oi
), oi
);
822 int backup_seen(struct thread
*thread
)
824 struct ospf6_interface
*oi
;
826 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
827 assert(oi
&& oi
->interface
);
829 if (IS_OSPF6_DEBUG_INTERFACE
)
830 zlog_debug("Interface Event %s: [BackupSeen]",
831 oi
->interface
->name
);
833 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
834 ospf6_interface_state_change(dr_election(oi
), oi
);
839 int neighbor_change(struct thread
*thread
)
841 struct ospf6_interface
*oi
;
843 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
844 assert(oi
&& oi
->interface
);
846 if (IS_OSPF6_DEBUG_INTERFACE
)
847 zlog_debug("Interface Event %s: [NeighborChange]",
848 oi
->interface
->name
);
850 if (oi
->state
== OSPF6_INTERFACE_DROTHER
851 || oi
->state
== OSPF6_INTERFACE_BDR
852 || oi
->state
== OSPF6_INTERFACE_DR
)
853 ospf6_interface_state_change(dr_election(oi
), oi
);
858 int interface_down(struct thread
*thread
)
860 struct ospf6_interface
*oi
;
861 struct listnode
*node
, *nnode
;
862 struct ospf6_neighbor
*on
;
865 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
866 assert(oi
&& oi
->interface
);
868 if (IS_OSPF6_DEBUG_INTERFACE
)
869 zlog_debug("Interface Event %s: [InterfaceDown]",
870 oi
->interface
->name
);
873 THREAD_OFF(oi
->thread_send_hello
);
875 /* Stop trying to set socket options. */
876 THREAD_OFF(oi
->thread_sso
);
877 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
878 /* Leave AllSPFRouters */
879 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
880 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
881 IPV6_LEAVE_GROUP
, ospf6
->fd
);
883 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
885 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
886 ospf6_neighbor_delete(on
);
888 list_delete_all_node(oi
->neighbor_list
);
890 /* When interface state is reset, also reset information about
891 * DR election, as it is no longer valid. */
892 oi
->drouter
= oi
->prev_drouter
= htonl(0);
893 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
898 static const char *ospf6_iftype_str(uint8_t iftype
)
901 case OSPF_IFTYPE_LOOPBACK
:
903 case OSPF_IFTYPE_BROADCAST
:
905 case OSPF_IFTYPE_POINTOPOINT
:
906 return "POINTOPOINT";
911 /* show specified interface structure */
912 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
,
913 json_object
*json_obj
, bool use_json
)
915 struct ospf6_interface
*oi
;
919 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
920 uint8_t default_iftype
;
921 struct timeval res
, now
;
923 struct ospf6_lsa
*lsa
, *lsanext
;
924 json_object
*json_arr
;
925 json_object
*json_addr
;
927 default_iftype
= ospf6_default_iftype(ifp
);
930 json_object_string_add(json_obj
, "status",
931 (if_is_operative(ifp
) ? "up" : "down"));
932 json_object_string_add(json_obj
, "type",
933 ospf6_iftype_str(default_iftype
));
934 json_object_int_add(json_obj
, "interfaceId", ifp
->ifindex
);
936 if (ifp
->info
== NULL
) {
937 json_object_boolean_false_add(json_obj
, "ospf6Enabled");
940 json_object_boolean_true_add(json_obj
, "ospf6Enabled");
942 oi
= (struct ospf6_interface
*)ifp
->info
;
944 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
945 json_object_string_add(json_obj
, "operatingAsType",
946 ospf6_iftype_str(oi
->type
));
949 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
950 (if_is_operative(ifp
) ? "up" : "down"),
951 ospf6_iftype_str(default_iftype
));
952 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
954 if (ifp
->info
== NULL
) {
955 vty_out(vty
, " OSPF not enabled on this interface\n");
958 oi
= (struct ospf6_interface
*)ifp
->info
;
960 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
961 vty_out(vty
, " Operating as type %s\n",
962 ospf6_iftype_str(oi
->type
));
966 json_arr
= json_object_new_array();
967 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
968 json_addr
= json_object_new_object();
970 prefix2str(p
, strbuf
, sizeof(strbuf
));
973 json_object_string_add(json_addr
, "type",
975 json_object_string_add(json_addr
, "address",
977 json_object_array_add(json_arr
, json_addr
);
980 json_object_string_add(json_addr
, "type",
982 json_object_string_add(json_addr
, "address",
984 json_object_array_add(json_arr
, json_addr
);
987 json_object_string_add(json_addr
, "type",
989 json_object_string_add(json_addr
, "address",
991 json_object_array_add(json_arr
, json_addr
);
995 json_object_object_add(json_obj
, "internetAddress", json_arr
);
997 vty_out(vty
, " Internet Address:\n");
999 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1001 prefix2str(p
, strbuf
, sizeof(strbuf
));
1002 switch (p
->family
) {
1004 vty_out(vty
, " inet : %pFX\n", p
);
1007 vty_out(vty
, " inet6: %pFX\n", p
);
1010 vty_out(vty
, " ??? : %pFX\n", p
);
1018 json_object_boolean_true_add(json_obj
,
1020 json_object_int_add(json_obj
, "instanceId",
1022 json_object_int_add(json_obj
, "interfaceMtu",
1024 json_object_int_add(json_obj
, "autoDetect", ifp
->mtu6
);
1025 json_object_string_add(json_obj
, "mtuMismatchDetection",
1026 oi
->mtu_ignore
? "disabled"
1028 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1030 json_object_string_add(json_obj
, "areaId", strbuf
);
1031 json_object_int_add(json_obj
, "cost", oi
->cost
);
1033 json_object_boolean_false_add(json_obj
,
1039 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1040 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
1041 vty_out(vty
, " MTU mismatch detection: %s\n",
1042 oi
->mtu_ignore
? "disabled" : "enabled");
1043 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1045 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
,
1048 vty_out(vty
, " Not Attached to Area\n");
1052 json_object_string_add(json_obj
, "ospf6InterfaceState",
1053 ospf6_interface_state_str
[oi
->state
]);
1054 json_object_int_add(json_obj
, "transmitDelaySec",
1056 json_object_int_add(json_obj
, "priority", oi
->priority
);
1057 json_object_int_add(json_obj
, "timerIntervalsConfigHello",
1058 oi
->hello_interval
);
1059 json_object_int_add(json_obj
, "timerIntervalsConfigDead",
1061 json_object_int_add(json_obj
, "timerIntervalsConfigRetransmit",
1064 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
1065 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
1067 vty_out(vty
, " Timer intervals configured:\n");
1068 vty_out(vty
, " Hello %d, Dead %d, Retransmit %d\n",
1069 oi
->hello_interval
, oi
->dead_interval
,
1073 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
1074 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
1076 json_object_string_add(json_obj
, "dr", drouter
);
1077 json_object_string_add(json_obj
, "bdr", bdrouter
);
1078 json_object_int_add(json_obj
, "numberOfInterfaceScopedLsa",
1081 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
1082 vty_out(vty
, " Number of I/F scoped LSAs is %u\n",
1090 if (oi
->thread_send_lsupdate
)
1091 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1093 timerstring(&res
, duration
, sizeof(duration
));
1094 json_object_int_add(json_obj
, "pendingLsaLsUpdateCount",
1095 oi
->lsupdate_list
->count
);
1096 json_object_string_add(json_obj
, "pendingLsaLsUpdateTime",
1098 json_object_string_add(
1099 json_obj
, "lsUpdateSendThread",
1100 (oi
->thread_send_lsupdate
? "on" : "off"));
1102 json_arr
= json_object_new_array();
1103 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1104 json_object_array_add(
1105 json_arr
, json_object_new_string(lsa
->name
));
1106 json_object_object_add(json_obj
, "pendingLsaLsUpdate",
1110 if (oi
->thread_send_lsack
)
1111 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1112 timerstring(&res
, duration
, sizeof(duration
));
1114 json_object_int_add(json_obj
, "pendingLsaLsAckCount",
1115 oi
->lsack_list
->count
);
1116 json_object_string_add(json_obj
, "pendingLsaLsAckTime",
1118 json_object_string_add(json_obj
, "lsAckSendThread",
1119 (oi
->thread_send_lsack
? "on" : "off"));
1121 json_arr
= json_object_new_array();
1122 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1123 json_object_array_add(
1124 json_arr
, json_object_new_string(lsa
->name
));
1125 json_object_object_add(json_obj
, "pendingLsaLsAck", json_arr
);
1129 if (oi
->thread_send_lsupdate
)
1130 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1132 timerstring(&res
, duration
, sizeof(duration
));
1134 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1135 oi
->lsupdate_list
->count
, duration
,
1136 (oi
->thread_send_lsupdate
? "on" : "off"));
1137 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1138 vty_out(vty
, " %s\n", lsa
->name
);
1141 if (oi
->thread_send_lsack
)
1142 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1143 timerstring(&res
, duration
, sizeof(duration
));
1145 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1146 oi
->lsack_list
->count
, duration
,
1147 (oi
->thread_send_lsack
? "on" : "off"));
1148 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1149 vty_out(vty
, " %s\n", lsa
->name
);
1151 ospf6_bfd_show_info(vty
, oi
->bfd_info
, 1, json_obj
, use_json
);
1155 /* show interface */
1156 DEFUN(show_ipv6_ospf6_interface
,
1157 show_ipv6_ospf6_interface_ifname_cmd
,
1158 "show ipv6 ospf6 interface [IFNAME] [json]",
1166 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1168 struct interface
*ifp
;
1170 json_object
*json_int
;
1171 bool uj
= use_json(argc
, argv
);
1174 json
= json_object_new_object();
1176 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1178 json_int
= json_object_new_object();
1180 json_object_string_add(json
, "noSuchInterface",
1181 argv
[idx_ifname
]->arg
);
1182 vty_out(vty
, "%s\n",
1183 json_object_to_json_string_ext(
1184 json
, JSON_C_TO_STRING_PRETTY
));
1185 json_object_free(json
);
1186 json_object_free(json_int
);
1189 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1190 json_object_object_add(json
, ifp
->name
, json_int
);
1192 FOR_ALL_INTERFACES (vrf
, ifp
) {
1193 json_int
= json_object_new_object();
1194 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1195 json_object_object_add(json
, ifp
->name
,
1199 vty_out(vty
, "%s\n",
1200 json_object_to_json_string_ext(
1201 json
, JSON_C_TO_STRING_PRETTY
));
1202 json_object_free(json
);
1205 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1208 vty_out(vty
, "No such Interface: %s\n",
1209 argv
[idx_ifname
]->arg
);
1212 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1214 FOR_ALL_INTERFACES (vrf
, ifp
)
1215 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1222 static int ospf6_interface_show_traffic(struct vty
*vty
,
1223 struct interface
*intf_ifp
,
1224 int display_once
, json_object
*json
,
1227 struct interface
*ifp
;
1228 struct vrf
*vrf
= NULL
;
1229 struct ospf6_interface
*oi
= NULL
;
1230 json_object
*json_interface
;
1233 vrf
= vrf_lookup_by_id(intf_ifp
->vrf_id
);
1235 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1237 if (!display_once
&& !use_json
) {
1239 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1240 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1242 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1243 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1246 "--------------------------------------------------------------------------------------------\n");
1249 if (intf_ifp
== NULL
) {
1250 FOR_ALL_INTERFACES (vrf
, ifp
) {
1252 oi
= (struct ospf6_interface
*)ifp
->info
;
1257 json_interface
= json_object_new_object();
1258 json_object_int_add(json_interface
, "helloRx",
1260 json_object_int_add(json_interface
, "helloTx",
1262 json_object_int_add(json_interface
, "dbDescRx",
1264 json_object_int_add(json_interface
, "dbDescTx",
1266 json_object_int_add(json_interface
, "lsReqRx",
1268 json_object_int_add(json_interface
, "lsReqTx",
1270 json_object_int_add(json_interface
,
1273 json_object_int_add(json_interface
,
1276 json_object_int_add(json_interface
, "lsAckRx",
1278 json_object_int_add(json_interface
, "lsAckTx",
1281 json_object_object_add(json
,
1282 oi
->interface
->name
,
1286 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1287 oi
->interface
->name
, oi
->hello_in
,
1288 oi
->hello_out
, oi
->db_desc_in
,
1289 oi
->db_desc_out
, oi
->ls_req_in
,
1290 oi
->ls_req_out
, oi
->ls_upd_in
,
1291 oi
->ls_upd_out
, oi
->ls_ack_in
,
1295 oi
= intf_ifp
->info
;
1300 json_interface
= json_object_new_object();
1301 json_object_int_add(json_interface
, "helloRx",
1303 json_object_int_add(json_interface
, "helloTx",
1305 json_object_int_add(json_interface
, "dbDescRx",
1307 json_object_int_add(json_interface
, "dbDescTx",
1309 json_object_int_add(json_interface
, "lsReqRx",
1311 json_object_int_add(json_interface
, "lsReqTx",
1313 json_object_int_add(json_interface
, "lsUpdateRx",
1315 json_object_int_add(json_interface
, "lsUpdateTx",
1317 json_object_int_add(json_interface
, "lsAckRx",
1319 json_object_int_add(json_interface
, "lsAckTx",
1322 json_object_object_add(json
, oi
->interface
->name
,
1326 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1327 oi
->interface
->name
, oi
->hello_in
,
1328 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1329 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1330 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1336 /* show interface */
1337 DEFUN(show_ipv6_ospf6_interface_traffic
,
1338 show_ipv6_ospf6_interface_traffic_cmd
,
1339 "show ipv6 ospf6 interface traffic [IFNAME] [json]",
1344 "Protocol Packet counters\n"
1349 int display_once
= 0;
1350 char *intf_name
= NULL
;
1351 struct interface
*ifp
= NULL
;
1352 json_object
*json
= NULL
;
1353 bool uj
= use_json(argc
, argv
);
1356 json
= json_object_new_object();
1358 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1359 intf_name
= argv
[idx_ifname
]->arg
;
1360 ifp
= if_lookup_by_name(intf_name
, VRF_DEFAULT
);
1363 json_object_string_add(json
, "status",
1364 "No Such Interface");
1365 json_object_string_add(json
, "interface",
1367 vty_out(vty
, "%s\n",
1368 json_object_to_json_string_ext(
1369 json
, JSON_C_TO_STRING_PRETTY
));
1370 json_object_free(json
);
1373 if (ifp
->info
== NULL
) {
1374 json_object_string_add(
1376 "OSPF not enabled on this interface");
1377 json_object_string_add(json
, "interface",
1379 vty_out(vty
, "%s\n",
1380 json_object_to_json_string_ext(
1381 json
, JSON_C_TO_STRING_PRETTY
));
1382 json_object_free(json
);
1387 vty_out(vty
, "No such Interface: %s\n",
1391 if (ifp
->info
== NULL
) {
1393 " OSPF not enabled on this interface %s\n",
1400 ospf6_interface_show_traffic(vty
, ifp
, display_once
, json
, uj
);
1403 vty_out(vty
, "%s\n",
1404 json_object_to_json_string_ext(
1405 json
, JSON_C_TO_STRING_PRETTY
));
1406 json_object_free(json
);
1414 DEFUN (show_ipv6_ospf6_interface_ifname_prefix
,
1415 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1416 "show ipv6 ospf6 interface IFNAME prefix\
1419 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1426 "Display connected prefixes to advertise\n"
1427 "Display details of the prefixes\n"
1428 OSPF6_ROUTE_ADDRESS_STR
1429 OSPF6_ROUTE_PREFIX_STR
1430 OSPF6_ROUTE_MATCH_STR
1431 "Display details of the prefixes\n"
1436 struct interface
*ifp
;
1437 struct ospf6_interface
*oi
;
1438 bool uj
= use_json(argc
, argv
);
1440 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
1442 vty_out(vty
, "No such Interface: %s\n", argv
[idx_ifname
]->arg
);
1448 vty_out(vty
, "OSPFv3 is not enabled on %s\n",
1449 argv
[idx_ifname
]->arg
);
1453 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
1454 vty_out(vty
, "Interface %s not attached to area\n",
1455 argv
[idx_ifname
]->arg
);
1459 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
, oi
->route_connected
,
1465 DEFUN (show_ipv6_ospf6_interface_prefix
,
1466 show_ipv6_ospf6_interface_prefix_cmd
,
1467 "show ipv6 ospf6 interface prefix\
1470 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1476 "Display connected prefixes to advertise\n"
1477 "Display details of the prefixes\n"
1478 OSPF6_ROUTE_ADDRESS_STR
1479 OSPF6_ROUTE_PREFIX_STR
1480 OSPF6_ROUTE_MATCH_STR
1481 "Display details of the prefixes\n"
1484 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1486 struct ospf6_interface
*oi
;
1487 struct interface
*ifp
;
1488 bool uj
= use_json(argc
, argv
);
1490 FOR_ALL_INTERFACES (vrf
, ifp
) {
1491 oi
= (struct ospf6_interface
*)ifp
->info
;
1492 if (oi
== NULL
|| CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
1495 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1496 oi
->route_connected
, uj
);
1502 /* interface variable set command */
1503 DEFUN (ipv6_ospf6_ifmtu
,
1504 ipv6_ospf6_ifmtu_cmd
,
1505 "ipv6 ospf6 ifmtu (1-65535)",
1509 "OSPFv3 Interface MTU\n"
1512 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1514 struct ospf6_interface
*oi
;
1515 unsigned int ifmtu
, iobuflen
;
1516 struct listnode
*node
, *nnode
;
1517 struct ospf6_neighbor
*on
;
1521 oi
= (struct ospf6_interface
*)ifp
->info
;
1523 oi
= ospf6_interface_create(ifp
);
1526 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1528 if (oi
->c_ifmtu
== ifmtu
)
1531 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1533 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1534 ifp
->name
, ifp
->mtu6
);
1535 return CMD_WARNING_CONFIG_FAILED
;
1538 if (oi
->ifmtu
< ifmtu
) {
1539 iobuflen
= ospf6_iobuf_size(ifmtu
);
1540 if (iobuflen
< ifmtu
) {
1542 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1543 ifp
->name
, iobuflen
);
1544 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1546 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1548 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1550 /* re-establish adjacencies */
1551 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1552 THREAD_OFF(on
->inactivity_timer
);
1553 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1559 DEFUN (no_ipv6_ospf6_ifmtu
,
1560 no_ipv6_ospf6_ifmtu_cmd
,
1561 "no ipv6 ospf6 ifmtu [(1-65535)]",
1566 "OSPFv3 Interface MTU\n"
1569 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1570 struct ospf6_interface
*oi
;
1571 unsigned int iobuflen
;
1572 struct listnode
*node
, *nnode
;
1573 struct ospf6_neighbor
*on
;
1577 oi
= (struct ospf6_interface
*)ifp
->info
;
1579 oi
= ospf6_interface_create(ifp
);
1582 if (oi
->ifmtu
< ifp
->mtu
) {
1583 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1584 if (iobuflen
< ifp
->mtu
) {
1586 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1587 ifp
->name
, iobuflen
);
1588 oi
->ifmtu
= iobuflen
;
1590 oi
->ifmtu
= ifp
->mtu
;
1592 oi
->ifmtu
= ifp
->mtu
;
1596 /* re-establish adjacencies */
1597 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1598 THREAD_OFF(on
->inactivity_timer
);
1599 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1605 DEFUN (ipv6_ospf6_cost
,
1606 ipv6_ospf6_cost_cmd
,
1607 "ipv6 ospf6 cost (1-65535)",
1611 "Outgoing metric of this interface\n")
1613 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1615 struct ospf6_interface
*oi
;
1616 unsigned long int lcost
;
1620 oi
= (struct ospf6_interface
*)ifp
->info
;
1622 oi
= ospf6_interface_create(ifp
);
1625 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1627 if (lcost
> UINT32_MAX
) {
1628 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1629 return CMD_WARNING_CONFIG_FAILED
;
1632 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1633 if (oi
->cost
== lcost
)
1637 ospf6_interface_force_recalculate_cost(oi
);
1642 DEFUN (no_ipv6_ospf6_cost
,
1643 no_ipv6_ospf6_cost_cmd
,
1644 "no ipv6 ospf6 cost [(1-65535)]",
1648 "Calculate interface cost from bandwidth\n"
1649 "Outgoing metric of this interface\n")
1651 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1652 struct ospf6_interface
*oi
;
1655 oi
= (struct ospf6_interface
*)ifp
->info
;
1657 oi
= ospf6_interface_create(ifp
);
1660 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1662 ospf6_interface_recalculate_cost(oi
);
1667 DEFUN (auto_cost_reference_bandwidth
,
1668 auto_cost_reference_bandwidth_cmd
,
1669 "auto-cost reference-bandwidth (1-4294967)",
1670 "Calculate OSPF interface cost according to bandwidth\n"
1671 "Use reference bandwidth method to assign OSPF cost\n"
1672 "The reference bandwidth in terms of Mbits per second\n")
1674 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1676 struct ospf6_area
*oa
;
1677 struct ospf6_interface
*oi
;
1678 struct listnode
*i
, *j
;
1681 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1682 if (refbw
< 1 || refbw
> 4294967) {
1683 vty_out(vty
, "reference-bandwidth value is invalid\n");
1684 return CMD_WARNING_CONFIG_FAILED
;
1687 /* If reference bandwidth is changed. */
1688 if ((refbw
) == o
->ref_bandwidth
)
1691 o
->ref_bandwidth
= refbw
;
1692 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1693 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1694 ospf6_interface_recalculate_cost(oi
);
1699 DEFUN (no_auto_cost_reference_bandwidth
,
1700 no_auto_cost_reference_bandwidth_cmd
,
1701 "no auto-cost reference-bandwidth [(1-4294967)]",
1703 "Calculate OSPF interface cost according to bandwidth\n"
1704 "Use reference bandwidth method to assign OSPF cost\n"
1705 "The reference bandwidth in terms of Mbits per second\n")
1707 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1708 struct ospf6_area
*oa
;
1709 struct ospf6_interface
*oi
;
1710 struct listnode
*i
, *j
;
1712 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
1715 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
1716 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1717 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1718 ospf6_interface_recalculate_cost(oi
);
1724 DEFUN (ipv6_ospf6_hellointerval
,
1725 ipv6_ospf6_hellointerval_cmd
,
1726 "ipv6 ospf6 hello-interval (1-65535)",
1729 "Time between HELLO packets\n"
1732 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1734 struct ospf6_interface
*oi
;
1737 oi
= (struct ospf6_interface
*)ifp
->info
;
1739 oi
= ospf6_interface_create(ifp
);
1742 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
1743 ? OSPF_HELLO_INTERVAL_DEFAULT
1744 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1748 ALIAS (ipv6_ospf6_hellointerval
,
1749 no_ipv6_ospf6_hellointerval_cmd
,
1750 "no ipv6 ospf6 hello-interval [(1-65535)]",
1754 "Time between HELLO packets\n"
1757 /* interface variable set command */
1758 DEFUN (ipv6_ospf6_deadinterval
,
1759 ipv6_ospf6_deadinterval_cmd
,
1760 "ipv6 ospf6 dead-interval (1-65535)",
1763 "Interval time after which a neighbor is declared down\n"
1766 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1768 struct ospf6_interface
*oi
;
1771 oi
= (struct ospf6_interface
*)ifp
->info
;
1773 oi
= ospf6_interface_create(ifp
);
1776 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
1777 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1778 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1782 ALIAS (ipv6_ospf6_deadinterval
,
1783 no_ipv6_ospf6_deadinterval_cmd
,
1784 "no ipv6 ospf6 dead-interval [(1-65535)]",
1788 "Interval time after which a neighbor is declared down\n"
1791 /* interface variable set command */
1792 DEFUN (ipv6_ospf6_transmitdelay
,
1793 ipv6_ospf6_transmitdelay_cmd
,
1794 "ipv6 ospf6 transmit-delay (1-3600)",
1797 "Link state transmit delay\n"
1800 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1802 struct ospf6_interface
*oi
;
1805 oi
= (struct ospf6_interface
*)ifp
->info
;
1807 oi
= ospf6_interface_create(ifp
);
1810 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
1811 ? OSPF6_INTERFACE_TRANSDELAY
1812 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1816 ALIAS (ipv6_ospf6_transmitdelay
,
1817 no_ipv6_ospf6_transmitdelay_cmd
,
1818 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1822 "Link state transmit delay\n"
1825 /* interface variable set command */
1826 DEFUN (ipv6_ospf6_retransmitinterval
,
1827 ipv6_ospf6_retransmitinterval_cmd
,
1828 "ipv6 ospf6 retransmit-interval (1-65535)",
1831 "Time between retransmitting lost link state advertisements\n"
1834 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1836 struct ospf6_interface
*oi
;
1839 oi
= (struct ospf6_interface
*)ifp
->info
;
1841 oi
= ospf6_interface_create(ifp
);
1844 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
1845 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1846 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1850 ALIAS (ipv6_ospf6_retransmitinterval
,
1851 no_ipv6_ospf6_retransmitinterval_cmd
,
1852 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1856 "Time between retransmitting lost link state advertisements\n"
1859 /* interface variable set command */
1860 DEFUN (ipv6_ospf6_priority
,
1861 ipv6_ospf6_priority_cmd
,
1862 "ipv6 ospf6 priority (0-255)",
1868 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1870 struct ospf6_interface
*oi
;
1873 oi
= (struct ospf6_interface
*)ifp
->info
;
1875 oi
= ospf6_interface_create(ifp
);
1878 oi
->priority
= strmatch(argv
[0]->text
, "no")
1879 ? OSPF6_INTERFACE_PRIORITY
1880 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1882 if (oi
->area
&& (oi
->state
== OSPF6_INTERFACE_DROTHER
1883 || oi
->state
== OSPF6_INTERFACE_BDR
1884 || oi
->state
== OSPF6_INTERFACE_DR
))
1885 ospf6_interface_state_change(dr_election(oi
), oi
);
1890 ALIAS (ipv6_ospf6_priority
,
1891 no_ipv6_ospf6_priority_cmd
,
1892 "no ipv6 ospf6 priority [(0-255)]",
1899 DEFUN (ipv6_ospf6_instance
,
1900 ipv6_ospf6_instance_cmd
,
1901 "ipv6 ospf6 instance-id (0-255)",
1904 "Instance ID for this interface\n"
1905 "Instance ID value\n")
1907 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1909 struct ospf6_interface
*oi
;
1912 oi
= (struct ospf6_interface
*)ifp
->info
;
1914 oi
= ospf6_interface_create(ifp
);
1917 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
1918 ? OSPF6_INTERFACE_INSTANCE_ID
1919 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1923 ALIAS (ipv6_ospf6_instance
,
1924 no_ipv6_ospf6_instance_cmd
,
1925 "no ipv6 ospf6 instance-id [(0-255)]",
1929 "Instance ID for this interface\n"
1930 "Instance ID value\n")
1932 DEFUN (ipv6_ospf6_passive
,
1933 ipv6_ospf6_passive_cmd
,
1934 "ipv6 ospf6 passive",
1937 "Passive interface; no adjacency will be formed on this interface\n"
1940 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1941 struct ospf6_interface
*oi
;
1942 struct listnode
*node
, *nnode
;
1943 struct ospf6_neighbor
*on
;
1947 oi
= (struct ospf6_interface
*)ifp
->info
;
1949 oi
= ospf6_interface_create(ifp
);
1952 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1953 THREAD_OFF(oi
->thread_send_hello
);
1954 THREAD_OFF(oi
->thread_sso
);
1956 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1957 THREAD_OFF(on
->inactivity_timer
);
1958 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1964 DEFUN (no_ipv6_ospf6_passive
,
1965 no_ipv6_ospf6_passive_cmd
,
1966 "no ipv6 ospf6 passive",
1970 "passive interface: No Adjacency will be formed on this I/F\n"
1973 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1974 struct ospf6_interface
*oi
;
1977 oi
= (struct ospf6_interface
*)ifp
->info
;
1979 oi
= ospf6_interface_create(ifp
);
1982 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1983 THREAD_OFF(oi
->thread_send_hello
);
1984 THREAD_OFF(oi
->thread_sso
);
1986 /* don't send hellos over loopback interface */
1987 if (!if_is_loopback(oi
->interface
))
1988 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
1989 &oi
->thread_send_hello
);
1994 DEFUN (ipv6_ospf6_mtu_ignore
,
1995 ipv6_ospf6_mtu_ignore_cmd
,
1996 "ipv6 ospf6 mtu-ignore",
1999 "Disable MTU mismatch detection on this interface\n"
2002 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2003 struct ospf6_interface
*oi
;
2006 oi
= (struct ospf6_interface
*)ifp
->info
;
2008 oi
= ospf6_interface_create(ifp
);
2016 DEFUN (no_ipv6_ospf6_mtu_ignore
,
2017 no_ipv6_ospf6_mtu_ignore_cmd
,
2018 "no ipv6 ospf6 mtu-ignore",
2022 "Disable MTU mismatch detection on this interface\n"
2025 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2026 struct ospf6_interface
*oi
;
2029 oi
= (struct ospf6_interface
*)ifp
->info
;
2031 oi
= ospf6_interface_create(ifp
);
2039 DEFUN (ipv6_ospf6_advertise_prefix_list
,
2040 ipv6_ospf6_advertise_prefix_list_cmd
,
2041 "ipv6 ospf6 advertise prefix-list WORD",
2044 "Advertising options\n"
2045 "Filter prefix using prefix-list\n"
2046 "Prefix list name\n"
2049 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2051 struct ospf6_interface
*oi
;
2054 oi
= (struct ospf6_interface
*)ifp
->info
;
2056 oi
= ospf6_interface_create(ifp
);
2060 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2061 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
2063 ospf6_interface_connected_route_update(oi
->interface
);
2066 OSPF6_LINK_LSA_SCHEDULE(oi
);
2067 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2068 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2069 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2071 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2077 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
2078 no_ipv6_ospf6_advertise_prefix_list_cmd
,
2079 "no ipv6 ospf6 advertise prefix-list [WORD]",
2083 "Advertising options\n"
2084 "Filter prefix using prefix-list\n"
2085 "Prefix list name\n")
2087 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2088 struct ospf6_interface
*oi
;
2091 oi
= (struct ospf6_interface
*)ifp
->info
;
2093 oi
= ospf6_interface_create(ifp
);
2097 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2099 ospf6_interface_connected_route_update(oi
->interface
);
2102 OSPF6_LINK_LSA_SCHEDULE(oi
);
2103 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2104 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2105 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2107 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2113 DEFUN (ipv6_ospf6_network
,
2114 ipv6_ospf6_network_cmd
,
2115 "ipv6 ospf6 network <broadcast|point-to-point>",
2119 "Specify OSPF6 broadcast network\n"
2120 "Specify OSPF6 point-to-point network\n"
2123 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2124 int idx_network
= 3;
2125 struct ospf6_interface
*oi
;
2128 oi
= (struct ospf6_interface
*)ifp
->info
;
2130 oi
= ospf6_interface_create(ifp
);
2134 oi
->type_cfg
= true;
2136 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
2137 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
2140 oi
->type
= OSPF_IFTYPE_BROADCAST
;
2141 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
2142 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
2145 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
2148 /* Reset the interface */
2149 thread_execute(master
, interface_down
, oi
, 0);
2150 thread_execute(master
, interface_up
, oi
, 0);
2155 DEFUN (no_ipv6_ospf6_network
,
2156 no_ipv6_ospf6_network_cmd
,
2157 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2161 "Set default network type\n"
2162 "Specify OSPF6 broadcast network\n"
2163 "Specify OSPF6 point-to-point network\n")
2165 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2166 struct ospf6_interface
*oi
;
2171 oi
= (struct ospf6_interface
*)ifp
->info
;
2176 oi
->type_cfg
= false;
2178 type
= ospf6_default_iftype(ifp
);
2179 if (oi
->type
== type
) {
2184 /* Reset the interface */
2185 thread_execute(master
, interface_down
, oi
, 0);
2186 thread_execute(master
, interface_up
, oi
, 0);
2191 static int config_write_ospf6_interface(struct vty
*vty
)
2193 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2194 struct ospf6_interface
*oi
;
2195 struct interface
*ifp
;
2197 FOR_ALL_INTERFACES (vrf
, ifp
) {
2198 oi
= (struct ospf6_interface
*)ifp
->info
;
2202 vty_frame(vty
, "interface %s\n", oi
->interface
->name
);
2205 vty_out(vty
, " description %s\n", ifp
->desc
);
2207 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
2209 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
2210 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
2212 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
2213 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
2214 oi
->hello_interval
);
2216 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
2217 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
2220 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
2221 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
2224 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
2225 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
2227 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
2228 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
2231 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
2232 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
2236 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
2239 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
2240 vty_out(vty
, " ipv6 ospf6 passive\n");
2243 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
2245 if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
2246 vty_out(vty
, " ipv6 ospf6 network point-to-point\n");
2247 else if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_BROADCAST
)
2248 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
2250 ospf6_bfd_write_config(vty
, oi
);
2252 vty_endframe(vty
, "!\n");
2257 static int config_write_ospf6_interface(struct vty
*vty
);
2258 static struct cmd_node interface_node
= {
2259 .name
= "interface",
2260 .node
= INTERFACE_NODE
,
2261 .parent_node
= CONFIG_NODE
,
2262 .prompt
= "%s(config-if)# ",
2263 .config_write
= config_write_ospf6_interface
,
2266 static int ospf6_ifp_create(struct interface
*ifp
)
2268 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2269 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp
->name
,
2270 ifp
->ifindex
, ifp
->mtu6
);
2271 ospf6_interface_if_add(ifp
);
2276 static int ospf6_ifp_up(struct interface
*ifp
)
2278 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2280 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2281 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2282 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2284 ospf6_interface_state_update(ifp
);
2289 static int ospf6_ifp_down(struct interface
*ifp
)
2291 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2293 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2294 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2295 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2297 ospf6_interface_state_update(ifp
);
2302 static int ospf6_ifp_destroy(struct interface
*ifp
)
2305 zlog_warn("Zebra: got delete of %s, but interface is still up",
2308 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2309 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2310 ifp
->name
, ifp
->ifindex
, ifp
->mtu6
);
2315 void ospf6_interface_init(void)
2317 /* Install interface node. */
2318 install_node(&interface_node
);
2320 if_zapi_callbacks(ospf6_ifp_create
, ospf6_ifp_up
,
2321 ospf6_ifp_down
, ospf6_ifp_destroy
);
2323 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
2324 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
2325 install_element(VIEW_NODE
,
2326 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
2327 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
2329 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
2330 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
2331 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
2332 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
2334 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
2335 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
2336 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
2337 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
2338 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
2339 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
2340 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
2341 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
2342 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
2343 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
2344 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
2345 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
2347 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
2348 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
2350 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
2351 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
2353 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
2354 install_element(INTERFACE_NODE
,
2355 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
2357 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
2358 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
2360 /* reference bandwidth commands */
2361 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
2362 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
2365 /* Clear the specified interface structure */
2366 static void ospf6_interface_clear(struct vty
*vty
, struct interface
*ifp
)
2368 struct ospf6_interface
*oi
;
2370 if (!if_is_operative(ifp
))
2373 if (ifp
->info
== NULL
)
2376 oi
= (struct ospf6_interface
*)ifp
->info
;
2378 if (IS_OSPF6_DEBUG_INTERFACE
)
2379 zlog_debug("Interface %s: clear by reset", ifp
->name
);
2381 /* Reset the interface */
2382 thread_execute(master
, interface_down
, oi
, 0);
2383 thread_execute(master
, interface_up
, oi
, 0);
2386 /* Clear interface */
2387 DEFUN (clear_ipv6_ospf6_interface
,
2388 clear_ipv6_ospf6_interface_cmd
,
2389 "clear ipv6 ospf6 interface [IFNAME]",
2397 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2399 struct interface
*ifp
;
2401 if (argc
== 4) /* Clear all the ospfv3 interfaces. */
2403 FOR_ALL_INTERFACES (vrf
, ifp
)
2404 ospf6_interface_clear(vty
, ifp
);
2405 } else /* Interface name is specified. */
2407 if ((ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
2410 vty_out(vty
, "No such Interface: %s\n",
2411 argv
[idx_ifname
]->arg
);
2414 ospf6_interface_clear(vty
, ifp
);
2420 void install_element_ospf6_clear_interface(void)
2422 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2425 DEFUN (debug_ospf6_interface
,
2426 debug_ospf6_interface_cmd
,
2427 "debug ospf6 interface",
2430 "Debug OSPFv3 Interface\n"
2433 OSPF6_DEBUG_INTERFACE_ON();
2437 DEFUN (no_debug_ospf6_interface
,
2438 no_debug_ospf6_interface_cmd
,
2439 "no debug ospf6 interface",
2443 "Debug OSPFv3 Interface\n"
2446 OSPF6_DEBUG_INTERFACE_OFF();
2450 int config_write_ospf6_debug_interface(struct vty
*vty
)
2452 if (IS_OSPF6_DEBUG_INTERFACE
)
2453 vty_out(vty
, "debug ospf6 interface\n");
2457 void install_element_ospf6_debug_interface(void)
2459 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2460 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2461 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2462 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);