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 /* disable from area list if possible */
276 ospf6_area_interface_delete(oi
);
278 /* Free BFD allocated data. */
279 XFREE(MTYPE_TMP
, oi
->bfd_config
.profile
);
281 XFREE(MTYPE_OSPF6_IF
, oi
);
284 void ospf6_interface_enable(struct ospf6_interface
*oi
)
286 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
287 ospf6_interface_state_update(oi
->interface
);
290 void ospf6_interface_disable(struct ospf6_interface
*oi
)
292 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
294 thread_execute(master
, interface_down
, oi
, 0);
296 ospf6_lsdb_remove_all(oi
->lsdb
);
297 ospf6_lsdb_remove_all(oi
->lsdb_self
);
298 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
299 ospf6_lsdb_remove_all(oi
->lsack_list
);
301 THREAD_OFF(oi
->thread_send_hello
);
302 THREAD_OFF(oi
->thread_send_lsupdate
);
303 THREAD_OFF(oi
->thread_send_lsack
);
304 THREAD_OFF(oi
->thread_sso
);
306 THREAD_OFF(oi
->thread_network_lsa
);
307 THREAD_OFF(oi
->thread_link_lsa
);
308 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
309 THREAD_OFF(oi
->thread_as_extern_lsa
);
310 THREAD_OFF(oi
->thread_wait_timer
);
313 static struct in6_addr
*
314 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
318 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
320 /* for each connected address */
321 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
322 /* if family not AF_INET6, ignore */
323 if (c
->address
->family
!= AF_INET6
)
326 /* linklocal scope check */
327 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
328 l
= &c
->address
->u
.prefix6
;
333 void ospf6_interface_if_add(struct interface
*ifp
)
335 struct ospf6_interface
*oi
;
336 unsigned int iobuflen
;
338 oi
= (struct ospf6_interface
*)ifp
->info
;
342 /* Try to adjust I/O buffer size with IfMtu */
344 oi
->ifmtu
= ifp
->mtu6
;
345 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
346 if (oi
->ifmtu
> iobuflen
) {
347 if (IS_OSPF6_DEBUG_INTERFACE
)
349 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
350 ifp
->name
, iobuflen
);
351 oi
->ifmtu
= iobuflen
;
354 /* interface start */
355 ospf6_interface_state_update(oi
->interface
);
358 void ospf6_interface_state_update(struct interface
*ifp
)
360 struct ospf6_interface
*oi
;
361 unsigned int iobuflen
;
363 oi
= (struct ospf6_interface
*)ifp
->info
;
366 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
369 /* Adjust the mtu values if the kernel told us something new */
370 if (ifp
->mtu6
!= oi
->ifmtu
) {
371 /* If nothing configured, accept it and check for buffer size */
373 oi
->ifmtu
= ifp
->mtu6
;
374 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
375 if (oi
->ifmtu
> iobuflen
) {
376 if (IS_OSPF6_DEBUG_INTERFACE
)
378 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
379 ifp
->name
, iobuflen
);
380 oi
->ifmtu
= iobuflen
;
382 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
383 oi
->ifmtu
= ifp
->mtu6
;
385 "Configured mtu %u on %s overridden by kernel %u",
386 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
388 oi
->ifmtu
= oi
->c_ifmtu
;
391 if (if_is_operative(ifp
)
392 && (ospf6_interface_get_linklocal_address(oi
->interface
)
393 || if_is_loopback(oi
->interface
)))
394 thread_execute(master
, interface_up
, oi
, 0);
396 thread_execute(master
, interface_down
, oi
, 0);
401 void ospf6_interface_connected_route_update(struct interface
*ifp
)
403 struct ospf6_interface
*oi
;
404 struct ospf6_route
*route
;
406 struct listnode
*node
, *nnode
;
407 struct in6_addr nh_addr
;
409 oi
= (struct ospf6_interface
*)ifp
->info
;
413 /* reset linklocal pointer */
414 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
416 /* if area is null, do not make connected-route list */
417 if (oi
->area
== NULL
)
420 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
423 /* update "route to advertise" interface route table */
424 ospf6_route_remove_all(oi
->route_connected
);
426 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
427 if (c
->address
->family
!= AF_INET6
)
430 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
432 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
434 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
436 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
438 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
442 if (oi
->plist_name
) {
443 struct prefix_list
*plist
;
444 enum prefix_list_type ret
;
446 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
447 ret
= prefix_list_apply(plist
, (void *)c
->address
);
448 if (ret
== PREFIX_DENY
) {
449 if (IS_OSPF6_DEBUG_INTERFACE
)
451 "%pFX on %s filtered by prefix-list %s ",
452 c
->address
, oi
->interface
->name
,
458 route
= ospf6_route_create();
459 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
460 apply_mask(&route
->prefix
);
461 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
462 route
->path
.area_id
= oi
->area
->area_id
;
463 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
464 route
->path
.cost
= oi
->cost
;
465 inet_pton(AF_INET6
, "::1", &nh_addr
);
466 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
468 ospf6_route_add(route
, oi
->route_connected
);
471 /* create new Link-LSA */
472 OSPF6_LINK_LSA_SCHEDULE(oi
);
473 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
474 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
477 static void ospf6_interface_state_change(uint8_t next_state
,
478 struct ospf6_interface
*oi
)
483 prev_state
= oi
->state
;
484 oi
->state
= next_state
;
486 if (prev_state
== next_state
)
490 if (IS_OSPF6_DEBUG_INTERFACE
) {
491 zlog_debug("Interface state change %s: %s -> %s",
493 ospf6_interface_state_str
[prev_state
],
494 ospf6_interface_state_str
[next_state
]);
497 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
499 if ((prev_state
== OSPF6_INTERFACE_DR
500 || prev_state
== OSPF6_INTERFACE_BDR
)
501 && (next_state
!= OSPF6_INTERFACE_DR
502 && next_state
!= OSPF6_INTERFACE_BDR
))
503 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
504 IPV6_LEAVE_GROUP
, ospf6
->fd
);
506 if ((prev_state
!= OSPF6_INTERFACE_DR
507 && prev_state
!= OSPF6_INTERFACE_BDR
)
508 && (next_state
== OSPF6_INTERFACE_DR
509 || next_state
== OSPF6_INTERFACE_BDR
))
510 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
511 IPV6_JOIN_GROUP
, ospf6
->fd
);
513 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
514 OSPF6_LINK_LSA_SCHEDULE(oi
);
515 if (next_state
== OSPF6_INTERFACE_DOWN
) {
516 OSPF6_NETWORK_LSA_EXECUTE(oi
);
517 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
518 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
519 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
520 } else if (prev_state
== OSPF6_INTERFACE_DR
521 || next_state
== OSPF6_INTERFACE_DR
) {
522 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
523 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
524 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
527 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
531 /* DR Election, RFC2328 section 9.4 */
533 #define IS_ELIGIBLE(n) \
534 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
536 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
537 struct ospf6_neighbor
*b
)
539 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
540 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
542 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
544 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
547 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
549 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
552 if (a
->priority
> b
->priority
)
554 if (a
->priority
< b
->priority
)
557 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
559 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
562 zlog_warn("Router-ID duplicate ?");
566 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
567 struct ospf6_neighbor
*b
)
569 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
570 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
572 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
574 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
577 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
579 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
582 if (a
->priority
> b
->priority
)
584 if (a
->priority
< b
->priority
)
587 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
589 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
592 zlog_warn("Router-ID duplicate ?");
596 static uint8_t dr_election(struct ospf6_interface
*oi
)
598 struct listnode
*node
, *nnode
;
599 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
600 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
601 uint8_t next_state
= 0;
603 drouter
= bdrouter
= NULL
;
604 best_drouter
= best_bdrouter
= NULL
;
606 /* pseudo neighbor myself, including noting current DR/BDR (1) */
607 memset(&myself
, 0, sizeof(myself
));
608 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
609 sizeof(myself
.name
));
610 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
611 myself
.drouter
= oi
->drouter
;
612 myself
.bdrouter
= oi
->bdrouter
;
613 myself
.priority
= oi
->priority
;
614 myself
.router_id
= oi
->area
->ospf6
->router_id
;
616 /* Electing BDR (2) */
617 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
618 bdrouter
= better_bdrouter(bdrouter
, on
);
620 best_bdrouter
= bdrouter
;
621 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
623 /* Electing DR (3) */
624 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
625 drouter
= better_drouter(drouter
, on
);
627 best_drouter
= drouter
;
628 drouter
= better_drouter(best_drouter
, &myself
);
632 /* the router itself is newly/no longer DR/BDR (4) */
633 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
634 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
635 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
636 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
637 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
638 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
640 /* compatible to Electing BDR (2) */
641 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
643 /* compatible to Electing DR (3) */
644 drouter
= better_drouter(best_drouter
, &myself
);
649 /* Set interface state accordingly (5) */
650 if (drouter
&& drouter
== &myself
)
651 next_state
= OSPF6_INTERFACE_DR
;
652 else if (bdrouter
&& bdrouter
== &myself
)
653 next_state
= OSPF6_INTERFACE_BDR
;
655 next_state
= OSPF6_INTERFACE_DROTHER
;
657 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
660 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
661 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
662 accordingly after AdjOK */
663 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
664 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
665 if (IS_OSPF6_DEBUG_INTERFACE
)
666 zlog_debug("DR Election on %s: DR: %s BDR: %s",
668 (drouter
? drouter
->name
: "0.0.0.0"),
669 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
671 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
672 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
674 /* Schedule AdjOK. */
675 thread_add_event(master
, adj_ok
, on
, 0, NULL
);
679 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
680 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
685 /* Interface State Machine */
686 int interface_up(struct thread
*thread
)
688 struct ospf6_interface
*oi
;
691 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
692 assert(oi
&& oi
->interface
);
695 oi
->type
= ospf6_default_iftype(oi
->interface
);
698 * Remove old pointer. If this thread wasn't a timer this
699 * operation won't make a difference, because it is already NULL.
701 oi
->thread_sso
= NULL
;
703 if (IS_OSPF6_DEBUG_INTERFACE
)
704 zlog_debug("Interface Event %s: [InterfaceUp]",
705 oi
->interface
->name
);
707 /* check physical interface is up */
708 if (!if_is_operative(oi
->interface
)) {
709 if (IS_OSPF6_DEBUG_INTERFACE
)
711 "Interface %s is down, can't execute [InterfaceUp]",
712 oi
->interface
->name
);
716 /* check interface has a link-local address */
717 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
718 || if_is_loopback(oi
->interface
))) {
719 if (IS_OSPF6_DEBUG_INTERFACE
)
721 "Interface %s has no link local address, can't execute [InterfaceUp]",
722 oi
->interface
->name
);
727 ospf6_interface_recalculate_cost(oi
);
729 /* if already enabled, do nothing */
730 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
731 if (IS_OSPF6_DEBUG_INTERFACE
)
732 zlog_debug("Interface %s already enabled",
733 oi
->interface
->name
);
737 /* If no area assigned, return */
738 if (oi
->area
== NULL
) {
740 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
741 __func__
, oi
->interface
->name
);
747 * XXX: Schedule IPv6 group join for later, otherwise we might
748 * lose the multicast group registration caused by IPv6 group
751 if (oi
->sso_try_cnt
== 0) {
753 zlog_info("Scheduling %s for sso", oi
->interface
->name
);
754 thread_add_timer(master
, interface_up
, oi
,
755 OSPF6_INTERFACE_SSO_RETRY_INT
,
759 #endif /* __FreeBSD__ */
761 ospf6
= oi
->area
->ospf6
;
763 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
765 /* Join AllSPFRouters */
766 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
,
769 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
771 "Scheduling %s for sso retry, trial count: %d",
772 oi
->interface
->name
, oi
->sso_try_cnt
);
773 thread_add_timer(master
, interface_up
, oi
,
774 OSPF6_INTERFACE_SSO_RETRY_INT
,
779 oi
->sso_try_cnt
= 0; /* Reset on success */
781 /* Update interface route */
782 ospf6_interface_connected_route_update(oi
->interface
);
785 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
786 && !if_is_loopback(oi
->interface
)) {
787 oi
->thread_send_hello
= NULL
;
788 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
789 &oi
->thread_send_hello
);
792 /* decide next interface state */
793 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
794 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
795 } else if (oi
->priority
== 0)
796 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
798 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
799 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
800 &oi
->thread_wait_timer
);
806 int wait_timer(struct thread
*thread
)
808 struct ospf6_interface
*oi
;
810 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
811 assert(oi
&& oi
->interface
);
813 if (IS_OSPF6_DEBUG_INTERFACE
)
814 zlog_debug("Interface Event %s: [WaitTimer]",
815 oi
->interface
->name
);
817 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
818 ospf6_interface_state_change(dr_election(oi
), oi
);
823 int backup_seen(struct thread
*thread
)
825 struct ospf6_interface
*oi
;
827 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
828 assert(oi
&& oi
->interface
);
830 if (IS_OSPF6_DEBUG_INTERFACE
)
831 zlog_debug("Interface Event %s: [BackupSeen]",
832 oi
->interface
->name
);
834 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
835 ospf6_interface_state_change(dr_election(oi
), oi
);
840 int neighbor_change(struct thread
*thread
)
842 struct ospf6_interface
*oi
;
844 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
845 assert(oi
&& oi
->interface
);
847 if (IS_OSPF6_DEBUG_INTERFACE
)
848 zlog_debug("Interface Event %s: [NeighborChange]",
849 oi
->interface
->name
);
851 if (oi
->state
== OSPF6_INTERFACE_DROTHER
852 || oi
->state
== OSPF6_INTERFACE_BDR
853 || oi
->state
== OSPF6_INTERFACE_DR
)
854 ospf6_interface_state_change(dr_election(oi
), oi
);
859 int interface_down(struct thread
*thread
)
861 struct ospf6_interface
*oi
;
862 struct listnode
*node
, *nnode
;
863 struct ospf6_neighbor
*on
;
866 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
867 assert(oi
&& oi
->interface
);
869 if (IS_OSPF6_DEBUG_INTERFACE
)
870 zlog_debug("Interface Event %s: [InterfaceDown]",
871 oi
->interface
->name
);
874 THREAD_OFF(oi
->thread_send_hello
);
876 /* Stop trying to set socket options. */
877 THREAD_OFF(oi
->thread_sso
);
878 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
879 /* Leave AllSPFRouters */
880 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
881 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
882 IPV6_LEAVE_GROUP
, ospf6
->fd
);
884 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
886 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
887 ospf6_neighbor_delete(on
);
889 list_delete_all_node(oi
->neighbor_list
);
891 /* When interface state is reset, also reset information about
892 * DR election, as it is no longer valid. */
893 oi
->drouter
= oi
->prev_drouter
= htonl(0);
894 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
899 static const char *ospf6_iftype_str(uint8_t iftype
)
902 case OSPF_IFTYPE_LOOPBACK
:
904 case OSPF_IFTYPE_BROADCAST
:
906 case OSPF_IFTYPE_POINTOPOINT
:
907 return "POINTOPOINT";
912 /* show specified interface structure */
913 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
,
914 json_object
*json_obj
, bool use_json
)
916 struct ospf6_interface
*oi
;
920 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
921 uint8_t default_iftype
;
922 struct timeval res
, now
;
924 struct ospf6_lsa
*lsa
, *lsanext
;
925 json_object
*json_arr
;
926 json_object
*json_addr
;
928 default_iftype
= ospf6_default_iftype(ifp
);
931 json_object_string_add(json_obj
, "status",
932 (if_is_operative(ifp
) ? "up" : "down"));
933 json_object_string_add(json_obj
, "type",
934 ospf6_iftype_str(default_iftype
));
935 json_object_int_add(json_obj
, "interfaceId", ifp
->ifindex
);
937 if (ifp
->info
== NULL
) {
938 json_object_boolean_false_add(json_obj
, "ospf6Enabled");
941 json_object_boolean_true_add(json_obj
, "ospf6Enabled");
943 oi
= (struct ospf6_interface
*)ifp
->info
;
945 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
946 json_object_string_add(json_obj
, "operatingAsType",
947 ospf6_iftype_str(oi
->type
));
950 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
951 (if_is_operative(ifp
) ? "up" : "down"),
952 ospf6_iftype_str(default_iftype
));
953 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
955 if (ifp
->info
== NULL
) {
956 vty_out(vty
, " OSPF not enabled on this interface\n");
959 oi
= (struct ospf6_interface
*)ifp
->info
;
961 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
962 vty_out(vty
, " Operating as type %s\n",
963 ospf6_iftype_str(oi
->type
));
967 json_arr
= json_object_new_array();
968 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
969 json_addr
= json_object_new_object();
971 prefix2str(p
, strbuf
, sizeof(strbuf
));
974 json_object_string_add(json_addr
, "type",
976 json_object_string_add(json_addr
, "address",
978 json_object_array_add(json_arr
, json_addr
);
981 json_object_string_add(json_addr
, "type",
983 json_object_string_add(json_addr
, "address",
985 json_object_array_add(json_arr
, json_addr
);
988 json_object_string_add(json_addr
, "type",
990 json_object_string_add(json_addr
, "address",
992 json_object_array_add(json_arr
, json_addr
);
996 json_object_object_add(json_obj
, "internetAddress", json_arr
);
998 vty_out(vty
, " Internet Address:\n");
1000 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1002 prefix2str(p
, strbuf
, sizeof(strbuf
));
1003 switch (p
->family
) {
1005 vty_out(vty
, " inet : %pFX\n", p
);
1008 vty_out(vty
, " inet6: %pFX\n", p
);
1011 vty_out(vty
, " ??? : %pFX\n", p
);
1019 json_object_boolean_true_add(json_obj
,
1021 json_object_int_add(json_obj
, "instanceId",
1023 json_object_int_add(json_obj
, "interfaceMtu",
1025 json_object_int_add(json_obj
, "autoDetect", ifp
->mtu6
);
1026 json_object_string_add(json_obj
, "mtuMismatchDetection",
1027 oi
->mtu_ignore
? "disabled"
1029 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1031 json_object_string_add(json_obj
, "areaId", strbuf
);
1032 json_object_int_add(json_obj
, "cost", oi
->cost
);
1034 json_object_boolean_false_add(json_obj
,
1040 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1041 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
1042 vty_out(vty
, " MTU mismatch detection: %s\n",
1043 oi
->mtu_ignore
? "disabled" : "enabled");
1044 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1046 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
,
1049 vty_out(vty
, " Not Attached to Area\n");
1053 json_object_string_add(json_obj
, "ospf6InterfaceState",
1054 ospf6_interface_state_str
[oi
->state
]);
1055 json_object_int_add(json_obj
, "transmitDelaySec",
1057 json_object_int_add(json_obj
, "priority", oi
->priority
);
1058 json_object_int_add(json_obj
, "timerIntervalsConfigHello",
1059 oi
->hello_interval
);
1060 json_object_int_add(json_obj
, "timerIntervalsConfigDead",
1062 json_object_int_add(json_obj
, "timerIntervalsConfigRetransmit",
1065 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
1066 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
1068 vty_out(vty
, " Timer intervals configured:\n");
1069 vty_out(vty
, " Hello %d, Dead %d, Retransmit %d\n",
1070 oi
->hello_interval
, oi
->dead_interval
,
1074 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
1075 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
1077 json_object_string_add(json_obj
, "dr", drouter
);
1078 json_object_string_add(json_obj
, "bdr", bdrouter
);
1079 json_object_int_add(json_obj
, "numberOfInterfaceScopedLsa",
1082 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
1083 vty_out(vty
, " Number of I/F scoped LSAs is %u\n",
1091 if (oi
->thread_send_lsupdate
)
1092 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1094 timerstring(&res
, duration
, sizeof(duration
));
1095 json_object_int_add(json_obj
, "pendingLsaLsUpdateCount",
1096 oi
->lsupdate_list
->count
);
1097 json_object_string_add(json_obj
, "pendingLsaLsUpdateTime",
1099 json_object_string_add(
1100 json_obj
, "lsUpdateSendThread",
1101 (oi
->thread_send_lsupdate
? "on" : "off"));
1103 json_arr
= json_object_new_array();
1104 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1105 json_object_array_add(
1106 json_arr
, json_object_new_string(lsa
->name
));
1107 json_object_object_add(json_obj
, "pendingLsaLsUpdate",
1111 if (oi
->thread_send_lsack
)
1112 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1113 timerstring(&res
, duration
, sizeof(duration
));
1115 json_object_int_add(json_obj
, "pendingLsaLsAckCount",
1116 oi
->lsack_list
->count
);
1117 json_object_string_add(json_obj
, "pendingLsaLsAckTime",
1119 json_object_string_add(json_obj
, "lsAckSendThread",
1120 (oi
->thread_send_lsack
? "on" : "off"));
1122 json_arr
= json_object_new_array();
1123 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1124 json_object_array_add(
1125 json_arr
, json_object_new_string(lsa
->name
));
1126 json_object_object_add(json_obj
, "pendingLsaLsAck", json_arr
);
1130 if (oi
->thread_send_lsupdate
)
1131 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1133 timerstring(&res
, duration
, sizeof(duration
));
1135 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1136 oi
->lsupdate_list
->count
, duration
,
1137 (oi
->thread_send_lsupdate
? "on" : "off"));
1138 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1139 vty_out(vty
, " %s\n", lsa
->name
);
1142 if (oi
->thread_send_lsack
)
1143 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1144 timerstring(&res
, duration
, sizeof(duration
));
1146 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1147 oi
->lsack_list
->count
, duration
,
1148 (oi
->thread_send_lsack
? "on" : "off"));
1149 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1150 vty_out(vty
, " %s\n", lsa
->name
);
1154 if (oi
->bfd_config
.enabled
) {
1156 struct json_object
*json_bfd
= json_object_new_object();
1158 json_object_int_add(
1159 json_bfd
, "detectMultiplier",
1160 oi
->bfd_config
.detection_multiplier
);
1161 json_object_int_add(json_bfd
, "rxMinInterval",
1162 oi
->bfd_config
.min_rx
);
1163 json_object_int_add(json_bfd
, "txMinInterval",
1164 oi
->bfd_config
.min_tx
);
1165 json_object_object_add(json_obj
, "peerBfdInfo",
1169 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1170 oi
->bfd_config
.detection_multiplier
,
1171 oi
->bfd_config
.min_rx
, oi
->bfd_config
.min_tx
);
1178 /* show interface */
1179 DEFUN(show_ipv6_ospf6_interface
,
1180 show_ipv6_ospf6_interface_ifname_cmd
,
1181 "show ipv6 ospf6 interface [IFNAME] [json]",
1189 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1191 struct interface
*ifp
;
1193 json_object
*json_int
;
1194 bool uj
= use_json(argc
, argv
);
1197 json
= json_object_new_object();
1199 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1201 json_int
= json_object_new_object();
1203 json_object_string_add(json
, "noSuchInterface",
1204 argv
[idx_ifname
]->arg
);
1205 vty_out(vty
, "%s\n",
1206 json_object_to_json_string_ext(
1207 json
, JSON_C_TO_STRING_PRETTY
));
1208 json_object_free(json
);
1209 json_object_free(json_int
);
1212 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1213 json_object_object_add(json
, ifp
->name
, json_int
);
1215 FOR_ALL_INTERFACES (vrf
, ifp
) {
1216 json_int
= json_object_new_object();
1217 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1218 json_object_object_add(json
, ifp
->name
,
1222 vty_out(vty
, "%s\n",
1223 json_object_to_json_string_ext(
1224 json
, JSON_C_TO_STRING_PRETTY
));
1225 json_object_free(json
);
1228 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1231 vty_out(vty
, "No such Interface: %s\n",
1232 argv
[idx_ifname
]->arg
);
1235 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1237 FOR_ALL_INTERFACES (vrf
, ifp
)
1238 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1245 static int ospf6_interface_show_traffic(struct vty
*vty
,
1246 struct interface
*intf_ifp
,
1247 int display_once
, json_object
*json
,
1250 struct interface
*ifp
;
1251 struct vrf
*vrf
= NULL
;
1252 struct ospf6_interface
*oi
= NULL
;
1253 json_object
*json_interface
;
1256 vrf
= vrf_lookup_by_id(intf_ifp
->vrf_id
);
1258 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1260 if (!display_once
&& !use_json
) {
1262 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1263 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1265 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1266 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1269 "--------------------------------------------------------------------------------------------\n");
1272 if (intf_ifp
== NULL
) {
1273 FOR_ALL_INTERFACES (vrf
, ifp
) {
1275 oi
= (struct ospf6_interface
*)ifp
->info
;
1280 json_interface
= json_object_new_object();
1281 json_object_int_add(json_interface
, "helloRx",
1283 json_object_int_add(json_interface
, "helloTx",
1285 json_object_int_add(json_interface
, "dbDescRx",
1287 json_object_int_add(json_interface
, "dbDescTx",
1289 json_object_int_add(json_interface
, "lsReqRx",
1291 json_object_int_add(json_interface
, "lsReqTx",
1293 json_object_int_add(json_interface
,
1296 json_object_int_add(json_interface
,
1299 json_object_int_add(json_interface
, "lsAckRx",
1301 json_object_int_add(json_interface
, "lsAckTx",
1304 json_object_object_add(json
,
1305 oi
->interface
->name
,
1309 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1310 oi
->interface
->name
, oi
->hello_in
,
1311 oi
->hello_out
, oi
->db_desc_in
,
1312 oi
->db_desc_out
, oi
->ls_req_in
,
1313 oi
->ls_req_out
, oi
->ls_upd_in
,
1314 oi
->ls_upd_out
, oi
->ls_ack_in
,
1318 oi
= intf_ifp
->info
;
1323 json_interface
= json_object_new_object();
1324 json_object_int_add(json_interface
, "helloRx",
1326 json_object_int_add(json_interface
, "helloTx",
1328 json_object_int_add(json_interface
, "dbDescRx",
1330 json_object_int_add(json_interface
, "dbDescTx",
1332 json_object_int_add(json_interface
, "lsReqRx",
1334 json_object_int_add(json_interface
, "lsReqTx",
1336 json_object_int_add(json_interface
, "lsUpdateRx",
1338 json_object_int_add(json_interface
, "lsUpdateTx",
1340 json_object_int_add(json_interface
, "lsAckRx",
1342 json_object_int_add(json_interface
, "lsAckTx",
1345 json_object_object_add(json
, oi
->interface
->name
,
1349 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1350 oi
->interface
->name
, oi
->hello_in
,
1351 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1352 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1353 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1359 /* show interface */
1360 DEFUN(show_ipv6_ospf6_interface_traffic
,
1361 show_ipv6_ospf6_interface_traffic_cmd
,
1362 "show ipv6 ospf6 interface traffic [IFNAME] [json]",
1367 "Protocol Packet counters\n"
1372 int display_once
= 0;
1373 char *intf_name
= NULL
;
1374 struct interface
*ifp
= NULL
;
1375 json_object
*json
= NULL
;
1376 bool uj
= use_json(argc
, argv
);
1379 json
= json_object_new_object();
1381 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1382 intf_name
= argv
[idx_ifname
]->arg
;
1383 ifp
= if_lookup_by_name(intf_name
, VRF_DEFAULT
);
1386 json_object_string_add(json
, "status",
1387 "No Such Interface");
1388 json_object_string_add(json
, "interface",
1390 vty_out(vty
, "%s\n",
1391 json_object_to_json_string_ext(
1392 json
, JSON_C_TO_STRING_PRETTY
));
1393 json_object_free(json
);
1396 if (ifp
->info
== NULL
) {
1397 json_object_string_add(
1399 "OSPF not enabled on this interface");
1400 json_object_string_add(json
, "interface",
1402 vty_out(vty
, "%s\n",
1403 json_object_to_json_string_ext(
1404 json
, JSON_C_TO_STRING_PRETTY
));
1405 json_object_free(json
);
1410 vty_out(vty
, "No such Interface: %s\n",
1414 if (ifp
->info
== NULL
) {
1416 " OSPF not enabled on this interface %s\n",
1423 ospf6_interface_show_traffic(vty
, ifp
, display_once
, json
, uj
);
1426 vty_out(vty
, "%s\n",
1427 json_object_to_json_string_ext(
1428 json
, JSON_C_TO_STRING_PRETTY
));
1429 json_object_free(json
);
1437 DEFUN (show_ipv6_ospf6_interface_ifname_prefix
,
1438 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1439 "show ipv6 ospf6 interface IFNAME prefix\
1442 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1449 "Display connected prefixes to advertise\n"
1450 "Display details of the prefixes\n"
1451 OSPF6_ROUTE_ADDRESS_STR
1452 OSPF6_ROUTE_PREFIX_STR
1453 OSPF6_ROUTE_MATCH_STR
1454 "Display details of the prefixes\n"
1459 struct interface
*ifp
;
1460 struct ospf6_interface
*oi
;
1461 bool uj
= use_json(argc
, argv
);
1463 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
1465 vty_out(vty
, "No such Interface: %s\n", argv
[idx_ifname
]->arg
);
1471 vty_out(vty
, "OSPFv3 is not enabled on %s\n",
1472 argv
[idx_ifname
]->arg
);
1476 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
1477 vty_out(vty
, "Interface %s not attached to area\n",
1478 argv
[idx_ifname
]->arg
);
1482 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
, oi
->route_connected
,
1488 DEFUN (show_ipv6_ospf6_interface_prefix
,
1489 show_ipv6_ospf6_interface_prefix_cmd
,
1490 "show ipv6 ospf6 interface prefix\
1493 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1499 "Display connected prefixes to advertise\n"
1500 "Display details of the prefixes\n"
1501 OSPF6_ROUTE_ADDRESS_STR
1502 OSPF6_ROUTE_PREFIX_STR
1503 OSPF6_ROUTE_MATCH_STR
1504 "Display details of the prefixes\n"
1507 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1509 struct ospf6_interface
*oi
;
1510 struct interface
*ifp
;
1511 bool uj
= use_json(argc
, argv
);
1513 FOR_ALL_INTERFACES (vrf
, ifp
) {
1514 oi
= (struct ospf6_interface
*)ifp
->info
;
1515 if (oi
== NULL
|| CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
1518 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1519 oi
->route_connected
, uj
);
1525 /* interface variable set command */
1526 DEFUN (ipv6_ospf6_ifmtu
,
1527 ipv6_ospf6_ifmtu_cmd
,
1528 "ipv6 ospf6 ifmtu (1-65535)",
1532 "OSPFv3 Interface MTU\n"
1535 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1537 struct ospf6_interface
*oi
;
1538 unsigned int ifmtu
, iobuflen
;
1539 struct listnode
*node
, *nnode
;
1540 struct ospf6_neighbor
*on
;
1544 oi
= (struct ospf6_interface
*)ifp
->info
;
1546 oi
= ospf6_interface_create(ifp
);
1549 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1551 if (oi
->c_ifmtu
== ifmtu
)
1554 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1556 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1557 ifp
->name
, ifp
->mtu6
);
1558 return CMD_WARNING_CONFIG_FAILED
;
1561 if (oi
->ifmtu
< ifmtu
) {
1562 iobuflen
= ospf6_iobuf_size(ifmtu
);
1563 if (iobuflen
< ifmtu
) {
1565 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1566 ifp
->name
, iobuflen
);
1567 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1569 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1571 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1573 /* re-establish adjacencies */
1574 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1575 THREAD_OFF(on
->inactivity_timer
);
1576 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1582 DEFUN (no_ipv6_ospf6_ifmtu
,
1583 no_ipv6_ospf6_ifmtu_cmd
,
1584 "no ipv6 ospf6 ifmtu [(1-65535)]",
1589 "OSPFv3 Interface MTU\n"
1592 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1593 struct ospf6_interface
*oi
;
1594 unsigned int iobuflen
;
1595 struct listnode
*node
, *nnode
;
1596 struct ospf6_neighbor
*on
;
1600 oi
= (struct ospf6_interface
*)ifp
->info
;
1602 oi
= ospf6_interface_create(ifp
);
1605 if (oi
->ifmtu
< ifp
->mtu
) {
1606 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1607 if (iobuflen
< ifp
->mtu
) {
1609 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1610 ifp
->name
, iobuflen
);
1611 oi
->ifmtu
= iobuflen
;
1613 oi
->ifmtu
= ifp
->mtu
;
1615 oi
->ifmtu
= ifp
->mtu
;
1619 /* re-establish adjacencies */
1620 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1621 THREAD_OFF(on
->inactivity_timer
);
1622 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1628 DEFUN (ipv6_ospf6_cost
,
1629 ipv6_ospf6_cost_cmd
,
1630 "ipv6 ospf6 cost (1-65535)",
1634 "Outgoing metric of this interface\n")
1636 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1638 struct ospf6_interface
*oi
;
1639 unsigned long int lcost
;
1643 oi
= (struct ospf6_interface
*)ifp
->info
;
1645 oi
= ospf6_interface_create(ifp
);
1648 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1650 if (lcost
> UINT32_MAX
) {
1651 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1652 return CMD_WARNING_CONFIG_FAILED
;
1655 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1656 if (oi
->cost
== lcost
)
1660 ospf6_interface_force_recalculate_cost(oi
);
1665 DEFUN (no_ipv6_ospf6_cost
,
1666 no_ipv6_ospf6_cost_cmd
,
1667 "no ipv6 ospf6 cost [(1-65535)]",
1671 "Calculate interface cost from bandwidth\n"
1672 "Outgoing metric of this interface\n")
1674 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1675 struct ospf6_interface
*oi
;
1678 oi
= (struct ospf6_interface
*)ifp
->info
;
1680 oi
= ospf6_interface_create(ifp
);
1683 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1685 ospf6_interface_recalculate_cost(oi
);
1690 DEFUN (auto_cost_reference_bandwidth
,
1691 auto_cost_reference_bandwidth_cmd
,
1692 "auto-cost reference-bandwidth (1-4294967)",
1693 "Calculate OSPF interface cost according to bandwidth\n"
1694 "Use reference bandwidth method to assign OSPF cost\n"
1695 "The reference bandwidth in terms of Mbits per second\n")
1697 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1699 struct ospf6_area
*oa
;
1700 struct ospf6_interface
*oi
;
1701 struct listnode
*i
, *j
;
1704 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1705 if (refbw
< 1 || refbw
> 4294967) {
1706 vty_out(vty
, "reference-bandwidth value is invalid\n");
1707 return CMD_WARNING_CONFIG_FAILED
;
1710 /* If reference bandwidth is changed. */
1711 if ((refbw
) == o
->ref_bandwidth
)
1714 o
->ref_bandwidth
= refbw
;
1715 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1716 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1717 ospf6_interface_recalculate_cost(oi
);
1722 DEFUN (no_auto_cost_reference_bandwidth
,
1723 no_auto_cost_reference_bandwidth_cmd
,
1724 "no auto-cost reference-bandwidth [(1-4294967)]",
1726 "Calculate OSPF interface cost according to bandwidth\n"
1727 "Use reference bandwidth method to assign OSPF cost\n"
1728 "The reference bandwidth in terms of Mbits per second\n")
1730 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1731 struct ospf6_area
*oa
;
1732 struct ospf6_interface
*oi
;
1733 struct listnode
*i
, *j
;
1735 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
1738 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
1739 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1740 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1741 ospf6_interface_recalculate_cost(oi
);
1747 DEFUN (ipv6_ospf6_hellointerval
,
1748 ipv6_ospf6_hellointerval_cmd
,
1749 "ipv6 ospf6 hello-interval (1-65535)",
1752 "Time between HELLO packets\n"
1755 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1757 struct ospf6_interface
*oi
;
1760 oi
= (struct ospf6_interface
*)ifp
->info
;
1762 oi
= ospf6_interface_create(ifp
);
1765 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
1766 ? OSPF_HELLO_INTERVAL_DEFAULT
1767 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1771 ALIAS (ipv6_ospf6_hellointerval
,
1772 no_ipv6_ospf6_hellointerval_cmd
,
1773 "no ipv6 ospf6 hello-interval [(1-65535)]",
1777 "Time between HELLO packets\n"
1780 /* interface variable set command */
1781 DEFUN (ipv6_ospf6_deadinterval
,
1782 ipv6_ospf6_deadinterval_cmd
,
1783 "ipv6 ospf6 dead-interval (1-65535)",
1786 "Interval time after which a neighbor is declared down\n"
1789 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1791 struct ospf6_interface
*oi
;
1794 oi
= (struct ospf6_interface
*)ifp
->info
;
1796 oi
= ospf6_interface_create(ifp
);
1799 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
1800 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1801 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1805 ALIAS (ipv6_ospf6_deadinterval
,
1806 no_ipv6_ospf6_deadinterval_cmd
,
1807 "no ipv6 ospf6 dead-interval [(1-65535)]",
1811 "Interval time after which a neighbor is declared down\n"
1814 /* interface variable set command */
1815 DEFUN (ipv6_ospf6_transmitdelay
,
1816 ipv6_ospf6_transmitdelay_cmd
,
1817 "ipv6 ospf6 transmit-delay (1-3600)",
1820 "Link state transmit delay\n"
1823 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1825 struct ospf6_interface
*oi
;
1828 oi
= (struct ospf6_interface
*)ifp
->info
;
1830 oi
= ospf6_interface_create(ifp
);
1833 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
1834 ? OSPF6_INTERFACE_TRANSDELAY
1835 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1839 ALIAS (ipv6_ospf6_transmitdelay
,
1840 no_ipv6_ospf6_transmitdelay_cmd
,
1841 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1845 "Link state transmit delay\n"
1848 /* interface variable set command */
1849 DEFUN (ipv6_ospf6_retransmitinterval
,
1850 ipv6_ospf6_retransmitinterval_cmd
,
1851 "ipv6 ospf6 retransmit-interval (1-65535)",
1854 "Time between retransmitting lost link state advertisements\n"
1857 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1859 struct ospf6_interface
*oi
;
1862 oi
= (struct ospf6_interface
*)ifp
->info
;
1864 oi
= ospf6_interface_create(ifp
);
1867 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
1868 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1869 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1873 ALIAS (ipv6_ospf6_retransmitinterval
,
1874 no_ipv6_ospf6_retransmitinterval_cmd
,
1875 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1879 "Time between retransmitting lost link state advertisements\n"
1882 /* interface variable set command */
1883 DEFUN (ipv6_ospf6_priority
,
1884 ipv6_ospf6_priority_cmd
,
1885 "ipv6 ospf6 priority (0-255)",
1891 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1893 struct ospf6_interface
*oi
;
1896 oi
= (struct ospf6_interface
*)ifp
->info
;
1898 oi
= ospf6_interface_create(ifp
);
1901 oi
->priority
= strmatch(argv
[0]->text
, "no")
1902 ? OSPF6_INTERFACE_PRIORITY
1903 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1905 if (oi
->area
&& (oi
->state
== OSPF6_INTERFACE_DROTHER
1906 || oi
->state
== OSPF6_INTERFACE_BDR
1907 || oi
->state
== OSPF6_INTERFACE_DR
))
1908 ospf6_interface_state_change(dr_election(oi
), oi
);
1913 ALIAS (ipv6_ospf6_priority
,
1914 no_ipv6_ospf6_priority_cmd
,
1915 "no ipv6 ospf6 priority [(0-255)]",
1922 DEFUN (ipv6_ospf6_instance
,
1923 ipv6_ospf6_instance_cmd
,
1924 "ipv6 ospf6 instance-id (0-255)",
1927 "Instance ID for this interface\n"
1928 "Instance ID value\n")
1930 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1932 struct ospf6_interface
*oi
;
1935 oi
= (struct ospf6_interface
*)ifp
->info
;
1937 oi
= ospf6_interface_create(ifp
);
1940 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
1941 ? OSPF6_INTERFACE_INSTANCE_ID
1942 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1946 ALIAS (ipv6_ospf6_instance
,
1947 no_ipv6_ospf6_instance_cmd
,
1948 "no ipv6 ospf6 instance-id [(0-255)]",
1952 "Instance ID for this interface\n"
1953 "Instance ID value\n")
1955 DEFUN (ipv6_ospf6_passive
,
1956 ipv6_ospf6_passive_cmd
,
1957 "ipv6 ospf6 passive",
1960 "Passive interface; no adjacency will be formed on this interface\n"
1963 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1964 struct ospf6_interface
*oi
;
1965 struct listnode
*node
, *nnode
;
1966 struct ospf6_neighbor
*on
;
1970 oi
= (struct ospf6_interface
*)ifp
->info
;
1972 oi
= ospf6_interface_create(ifp
);
1975 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1976 THREAD_OFF(oi
->thread_send_hello
);
1977 THREAD_OFF(oi
->thread_sso
);
1979 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1980 THREAD_OFF(on
->inactivity_timer
);
1981 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1987 DEFUN (no_ipv6_ospf6_passive
,
1988 no_ipv6_ospf6_passive_cmd
,
1989 "no ipv6 ospf6 passive",
1993 "passive interface: No Adjacency will be formed on this I/F\n"
1996 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1997 struct ospf6_interface
*oi
;
2000 oi
= (struct ospf6_interface
*)ifp
->info
;
2002 oi
= ospf6_interface_create(ifp
);
2005 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2006 THREAD_OFF(oi
->thread_send_hello
);
2007 THREAD_OFF(oi
->thread_sso
);
2009 /* don't send hellos over loopback interface */
2010 if (!if_is_loopback(oi
->interface
))
2011 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
2012 &oi
->thread_send_hello
);
2017 DEFUN (ipv6_ospf6_mtu_ignore
,
2018 ipv6_ospf6_mtu_ignore_cmd
,
2019 "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 (no_ipv6_ospf6_mtu_ignore
,
2040 no_ipv6_ospf6_mtu_ignore_cmd
,
2041 "no ipv6 ospf6 mtu-ignore",
2045 "Disable MTU mismatch detection on this interface\n"
2048 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2049 struct ospf6_interface
*oi
;
2052 oi
= (struct ospf6_interface
*)ifp
->info
;
2054 oi
= ospf6_interface_create(ifp
);
2062 DEFUN (ipv6_ospf6_advertise_prefix_list
,
2063 ipv6_ospf6_advertise_prefix_list_cmd
,
2064 "ipv6 ospf6 advertise prefix-list WORD",
2067 "Advertising options\n"
2068 "Filter prefix using prefix-list\n"
2069 "Prefix list name\n"
2072 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2074 struct ospf6_interface
*oi
;
2077 oi
= (struct ospf6_interface
*)ifp
->info
;
2079 oi
= ospf6_interface_create(ifp
);
2083 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2084 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
2086 ospf6_interface_connected_route_update(oi
->interface
);
2089 OSPF6_LINK_LSA_SCHEDULE(oi
);
2090 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2091 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2092 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2094 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2100 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
2101 no_ipv6_ospf6_advertise_prefix_list_cmd
,
2102 "no ipv6 ospf6 advertise prefix-list [WORD]",
2106 "Advertising options\n"
2107 "Filter prefix using prefix-list\n"
2108 "Prefix list name\n")
2110 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2111 struct ospf6_interface
*oi
;
2114 oi
= (struct ospf6_interface
*)ifp
->info
;
2116 oi
= ospf6_interface_create(ifp
);
2120 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2122 ospf6_interface_connected_route_update(oi
->interface
);
2125 OSPF6_LINK_LSA_SCHEDULE(oi
);
2126 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2127 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2128 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2130 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2136 DEFUN (ipv6_ospf6_network
,
2137 ipv6_ospf6_network_cmd
,
2138 "ipv6 ospf6 network <broadcast|point-to-point>",
2142 "Specify OSPF6 broadcast network\n"
2143 "Specify OSPF6 point-to-point network\n"
2146 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2147 int idx_network
= 3;
2148 struct ospf6_interface
*oi
;
2151 oi
= (struct ospf6_interface
*)ifp
->info
;
2153 oi
= ospf6_interface_create(ifp
);
2157 oi
->type_cfg
= true;
2159 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
2160 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
2163 oi
->type
= OSPF_IFTYPE_BROADCAST
;
2164 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
2165 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
2168 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
2171 /* Reset the interface */
2172 thread_execute(master
, interface_down
, oi
, 0);
2173 thread_execute(master
, interface_up
, oi
, 0);
2178 DEFUN (no_ipv6_ospf6_network
,
2179 no_ipv6_ospf6_network_cmd
,
2180 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2184 "Set default network type\n"
2185 "Specify OSPF6 broadcast network\n"
2186 "Specify OSPF6 point-to-point network\n")
2188 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2189 struct ospf6_interface
*oi
;
2194 oi
= (struct ospf6_interface
*)ifp
->info
;
2199 oi
->type_cfg
= false;
2201 type
= ospf6_default_iftype(ifp
);
2202 if (oi
->type
== type
) {
2207 /* Reset the interface */
2208 thread_execute(master
, interface_down
, oi
, 0);
2209 thread_execute(master
, interface_up
, oi
, 0);
2214 static int config_write_ospf6_interface(struct vty
*vty
)
2216 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2217 struct ospf6_interface
*oi
;
2218 struct interface
*ifp
;
2220 FOR_ALL_INTERFACES (vrf
, ifp
) {
2221 oi
= (struct ospf6_interface
*)ifp
->info
;
2225 vty_frame(vty
, "interface %s\n", oi
->interface
->name
);
2228 vty_out(vty
, " description %s\n", ifp
->desc
);
2230 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
2232 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
2233 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
2235 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
2236 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
2237 oi
->hello_interval
);
2239 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
2240 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
2243 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
2244 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
2247 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
2248 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
2250 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
2251 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
2254 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
2255 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
2259 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
2262 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
2263 vty_out(vty
, " ipv6 ospf6 passive\n");
2266 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
2268 if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
2269 vty_out(vty
, " ipv6 ospf6 network point-to-point\n");
2270 else if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_BROADCAST
)
2271 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
2273 ospf6_bfd_write_config(vty
, oi
);
2275 vty_endframe(vty
, "!\n");
2280 static int config_write_ospf6_interface(struct vty
*vty
);
2281 static struct cmd_node interface_node
= {
2282 .name
= "interface",
2283 .node
= INTERFACE_NODE
,
2284 .parent_node
= CONFIG_NODE
,
2285 .prompt
= "%s(config-if)# ",
2286 .config_write
= config_write_ospf6_interface
,
2289 static int ospf6_ifp_create(struct interface
*ifp
)
2291 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2292 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp
->name
,
2293 ifp
->ifindex
, ifp
->mtu6
);
2294 ospf6_interface_if_add(ifp
);
2299 static int ospf6_ifp_up(struct interface
*ifp
)
2301 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2303 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2304 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2305 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2307 ospf6_interface_state_update(ifp
);
2312 static int ospf6_ifp_down(struct interface
*ifp
)
2314 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2316 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2317 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2318 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2320 ospf6_interface_state_update(ifp
);
2325 static int ospf6_ifp_destroy(struct interface
*ifp
)
2328 zlog_warn("Zebra: got delete of %s, but interface is still up",
2331 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2332 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2333 ifp
->name
, ifp
->ifindex
, ifp
->mtu6
);
2338 void ospf6_interface_init(void)
2340 /* Install interface node. */
2341 install_node(&interface_node
);
2343 if_zapi_callbacks(ospf6_ifp_create
, ospf6_ifp_up
,
2344 ospf6_ifp_down
, ospf6_ifp_destroy
);
2346 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
2347 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
2348 install_element(VIEW_NODE
,
2349 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
2350 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
2352 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
2353 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
2354 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
2355 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
2357 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
2358 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
2359 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
2360 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
2361 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
2362 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
2363 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
2364 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
2365 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
2366 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
2367 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
2368 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
2370 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
2371 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
2373 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
2374 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
2376 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
2377 install_element(INTERFACE_NODE
,
2378 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
2380 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
2381 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
2383 /* reference bandwidth commands */
2384 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
2385 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
2388 /* Clear the specified interface structure */
2389 static void ospf6_interface_clear(struct vty
*vty
, struct interface
*ifp
)
2391 struct ospf6_interface
*oi
;
2393 if (!if_is_operative(ifp
))
2396 if (ifp
->info
== NULL
)
2399 oi
= (struct ospf6_interface
*)ifp
->info
;
2401 if (IS_OSPF6_DEBUG_INTERFACE
)
2402 zlog_debug("Interface %s: clear by reset", ifp
->name
);
2404 /* Reset the interface */
2405 thread_execute(master
, interface_down
, oi
, 0);
2406 thread_execute(master
, interface_up
, oi
, 0);
2409 /* Clear interface */
2410 DEFUN (clear_ipv6_ospf6_interface
,
2411 clear_ipv6_ospf6_interface_cmd
,
2412 "clear ipv6 ospf6 interface [IFNAME]",
2420 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2422 struct interface
*ifp
;
2424 if (argc
== 4) /* Clear all the ospfv3 interfaces. */
2426 FOR_ALL_INTERFACES (vrf
, ifp
)
2427 ospf6_interface_clear(vty
, ifp
);
2428 } else /* Interface name is specified. */
2430 if ((ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
2433 vty_out(vty
, "No such Interface: %s\n",
2434 argv
[idx_ifname
]->arg
);
2437 ospf6_interface_clear(vty
, ifp
);
2443 void install_element_ospf6_clear_interface(void)
2445 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2448 DEFUN (debug_ospf6_interface
,
2449 debug_ospf6_interface_cmd
,
2450 "debug ospf6 interface",
2453 "Debug OSPFv3 Interface\n"
2456 OSPF6_DEBUG_INTERFACE_ON();
2460 DEFUN (no_debug_ospf6_interface
,
2461 no_debug_ospf6_interface_cmd
,
2462 "no debug ospf6 interface",
2466 "Debug OSPFv3 Interface\n"
2469 OSPF6_DEBUG_INTERFACE_OFF();
2473 int config_write_ospf6_debug_interface(struct vty
*vty
)
2475 if (IS_OSPF6_DEBUG_INTERFACE
)
2476 vty_out(vty
, "debug ospf6 interface\n");
2480 void install_element_ospf6_debug_interface(void)
2482 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2483 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2484 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2485 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);