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_abr.h"
40 #include "ospf6_interface.h"
41 #include "ospf6_neighbor.h"
42 #include "ospf6_intra.h"
43 #include "ospf6_spf.h"
45 #include "ospf6_bfd.h"
46 #include "ospf6_zebra.h"
49 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_IF
, "OSPF6 interface");
50 DEFINE_MTYPE_STATIC(OSPF6D
, CFG_PLIST_NAME
, "configured prefix list names");
51 DEFINE_QOBJ_TYPE(ospf6_interface
);
52 DEFINE_HOOK(ospf6_interface_change
,
53 (struct ospf6_interface
* oi
, int state
, int old_state
),
54 (oi
, state
, old_state
));
56 unsigned char conf_debug_ospf6_interface
= 0;
58 const char *const ospf6_interface_state_str
[] = {
59 "None", "Down", "Loopback", "Waiting", "PointToPoint",
60 "DROther", "BDR", "DR", NULL
};
62 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
,
65 struct ospf6_interface
*oi
;
66 struct interface
*ifp
;
68 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
70 return (struct ospf6_interface
*)NULL
;
72 oi
= (struct ospf6_interface
*)ifp
->info
;
76 /* schedule routing table recalculation */
77 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
80 struct ospf6_interface
*oi
;
86 switch (ntohs(lsa
->header
->type
)) {
87 case OSPF6_LSTYPE_LINK
:
88 if (oi
->state
== OSPF6_INTERFACE_DR
)
89 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
91 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
99 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
101 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
104 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
106 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
109 static uint8_t ospf6_default_iftype(struct interface
*ifp
)
111 if (if_is_pointopoint(ifp
))
112 return OSPF_IFTYPE_POINTOPOINT
;
113 else if (if_is_loopback_or_vrf(ifp
))
114 return OSPF_IFTYPE_LOOPBACK
;
116 return OSPF_IFTYPE_BROADCAST
;
119 static uint32_t ospf6_interface_get_cost(struct ospf6_interface
*oi
)
121 /* If all else fails, use default OSPF cost */
125 /* interface speed and bw can be 0 in some platforms,
126 * use ospf default bw. If bw is configured then it would
129 if (!oi
->interface
->bandwidth
&& oi
->interface
->speed
) {
130 bw
= oi
->interface
->speed
;
132 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
133 : OSPF6_INTERFACE_BANDWIDTH
;
136 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
137 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
139 /* A specifed ip ospf cost overrides a calculated one. */
140 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
143 cost
= (uint32_t)((double)refbw
/ (double)bw
+ (double)0.5);
146 else if (cost
> UINT32_MAX
)
153 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface
*oi
)
155 /* update cost held in route_connected list in ospf6_interface */
156 ospf6_interface_connected_route_update(oi
->interface
);
158 /* execute LSA hooks */
160 OSPF6_LINK_LSA_SCHEDULE(oi
);
161 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
162 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
163 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
164 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
168 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
172 newcost
= ospf6_interface_get_cost(oi
);
173 if (newcost
== oi
->cost
)
177 ospf6_interface_force_recalculate_cost(oi
);
180 /* Create new ospf6 interface structure */
181 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
183 struct ospf6_interface
*oi
;
184 unsigned int iobuflen
;
186 oi
= XCALLOC(MTYPE_OSPF6_IF
, sizeof(struct ospf6_interface
));
188 oi
->obuf
= ospf6_fifo_new();
190 oi
->area
= (struct ospf6_area
*)NULL
;
191 oi
->neighbor_list
= list_new();
192 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
193 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
194 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
195 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
196 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
198 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
199 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
200 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
201 oi
->type
= ospf6_default_iftype(ifp
);
202 oi
->state
= OSPF6_INTERFACE_DOWN
;
207 /* Try to adjust I/O buffer size with IfMtu */
208 oi
->ifmtu
= ifp
->mtu6
;
209 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
210 if (oi
->ifmtu
> iobuflen
) {
211 if (IS_OSPF6_DEBUG_INTERFACE
)
213 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
214 ifp
->name
, iobuflen
);
215 oi
->ifmtu
= iobuflen
;
218 QOBJ_REG(oi
, ospf6_interface
);
220 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
221 oi
->lsack_list
= ospf6_lsdb_create(oi
);
222 oi
->lsdb
= ospf6_lsdb_create(oi
);
223 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
224 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
225 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
227 oi
->route_connected
=
228 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
229 oi
->route_connected
->scope
= oi
;
236 oi
->cost
= ospf6_interface_get_cost(oi
);
241 void ospf6_interface_delete(struct ospf6_interface
*oi
)
243 struct listnode
*node
, *nnode
;
244 struct ospf6_neighbor
*on
;
248 ospf6_fifo_free(oi
->obuf
);
250 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
251 ospf6_neighbor_delete(on
);
253 list_delete(&oi
->neighbor_list
);
255 THREAD_OFF(oi
->thread_send_hello
);
256 THREAD_OFF(oi
->thread_send_lsupdate
);
257 THREAD_OFF(oi
->thread_send_lsack
);
258 THREAD_OFF(oi
->thread_sso
);
259 THREAD_OFF(oi
->thread_wait_timer
);
261 ospf6_lsdb_remove_all(oi
->lsdb
);
262 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
263 ospf6_lsdb_remove_all(oi
->lsack_list
);
265 ospf6_lsdb_delete(oi
->lsdb
);
266 ospf6_lsdb_delete(oi
->lsdb_self
);
268 ospf6_lsdb_delete(oi
->lsupdate_list
);
269 ospf6_lsdb_delete(oi
->lsack_list
);
271 ospf6_route_table_delete(oi
->route_connected
);
274 oi
->interface
->info
= NULL
;
278 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
280 /* disable from area list if possible */
281 ospf6_area_interface_delete(oi
);
283 /* Free BFD allocated data. */
284 XFREE(MTYPE_TMP
, oi
->bfd_config
.profile
);
286 XFREE(MTYPE_OSPF6_IF
, oi
);
289 void ospf6_interface_enable(struct ospf6_interface
*oi
)
291 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
292 ospf6_interface_state_update(oi
->interface
);
295 void ospf6_interface_disable(struct ospf6_interface
*oi
)
297 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
299 thread_execute(master
, interface_down
, oi
, 0);
301 ospf6_lsdb_remove_all(oi
->lsdb
);
302 ospf6_lsdb_remove_all(oi
->lsdb_self
);
303 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
304 ospf6_lsdb_remove_all(oi
->lsack_list
);
306 THREAD_OFF(oi
->thread_send_hello
);
307 THREAD_OFF(oi
->thread_send_lsupdate
);
308 THREAD_OFF(oi
->thread_send_lsack
);
309 THREAD_OFF(oi
->thread_sso
);
311 THREAD_OFF(oi
->thread_network_lsa
);
312 THREAD_OFF(oi
->thread_link_lsa
);
313 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
314 THREAD_OFF(oi
->thread_as_extern_lsa
);
315 THREAD_OFF(oi
->thread_wait_timer
);
318 static struct in6_addr
*
319 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
323 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
325 /* for each connected address */
326 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
327 /* if family not AF_INET6, ignore */
328 if (c
->address
->family
!= AF_INET6
)
331 /* linklocal scope check */
332 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
333 l
= &c
->address
->u
.prefix6
;
338 void ospf6_interface_state_update(struct interface
*ifp
)
340 struct ospf6_interface
*oi
;
341 unsigned int iobuflen
;
343 oi
= (struct ospf6_interface
*)ifp
->info
;
346 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
349 /* Adjust the mtu values if the kernel told us something new */
350 if (ifp
->mtu6
!= oi
->ifmtu
) {
351 /* If nothing configured, accept it and check for buffer size */
353 oi
->ifmtu
= ifp
->mtu6
;
354 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
355 if (oi
->ifmtu
> iobuflen
) {
356 if (IS_OSPF6_DEBUG_INTERFACE
)
358 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
359 ifp
->name
, iobuflen
);
360 oi
->ifmtu
= iobuflen
;
362 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
363 oi
->ifmtu
= ifp
->mtu6
;
365 "Configured mtu %u on %s overridden by kernel %u",
366 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
368 oi
->ifmtu
= oi
->c_ifmtu
;
371 if (if_is_operative(ifp
)
372 && (ospf6_interface_get_linklocal_address(oi
->interface
)
373 || if_is_loopback_or_vrf(oi
->interface
)))
374 thread_execute(master
, interface_up
, oi
, 0);
376 thread_execute(master
, interface_down
, oi
, 0);
381 void ospf6_interface_connected_route_update(struct interface
*ifp
)
383 struct ospf6_interface
*oi
;
384 struct ospf6_route
*route
;
386 struct listnode
*node
, *nnode
;
387 struct in6_addr nh_addr
;
388 int count
= 0, max_addr_count
;
390 oi
= (struct ospf6_interface
*)ifp
->info
;
394 /* reset linklocal pointer */
395 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
397 /* if area is null, do not make connected-route list */
398 if (oi
->area
== NULL
)
401 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
404 /* update "route to advertise" interface route table */
405 ospf6_route_remove_all(oi
->route_connected
);
407 if (oi
->ifmtu
>= OSPF6_JUMBO_MTU
)
408 max_addr_count
= OSPF6_MAX_IF_ADDRS_JUMBO
;
410 max_addr_count
= OSPF6_MAX_IF_ADDRS
;
412 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
413 if (c
->address
->family
!= AF_INET6
)
416 /* number of interface addresses supported is based on MTU
417 * size of OSPFv3 packet
420 if (count
>= max_addr_count
)
423 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
425 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
427 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
429 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
431 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
435 if (oi
->plist_name
) {
436 struct prefix_list
*plist
;
437 enum prefix_list_type ret
;
439 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
440 ret
= prefix_list_apply(plist
, (void *)c
->address
);
441 if (ret
== PREFIX_DENY
) {
442 if (IS_OSPF6_DEBUG_INTERFACE
)
444 "%pFX on %s filtered by prefix-list %s ",
445 c
->address
, oi
->interface
->name
,
451 route
= ospf6_route_create();
452 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
453 apply_mask(&route
->prefix
);
454 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
455 route
->path
.area_id
= oi
->area
->area_id
;
456 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
457 route
->path
.cost
= oi
->cost
;
458 inet_pton(AF_INET6
, "::1", &nh_addr
);
459 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
461 ospf6_route_add(route
, oi
->route_connected
);
464 /* create new Link-LSA */
465 OSPF6_LINK_LSA_SCHEDULE(oi
);
466 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
467 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
470 static int ospf6_interface_state_change(uint8_t next_state
,
471 struct ospf6_interface
*oi
)
476 prev_state
= oi
->state
;
477 oi
->state
= next_state
;
479 if (prev_state
== next_state
)
486 if (IS_OSPF6_DEBUG_INTERFACE
) {
487 zlog_debug("Interface state change %s: %s -> %s",
489 ospf6_interface_state_str
[prev_state
],
490 ospf6_interface_state_str
[next_state
]);
494 ospf6
= oi
->area
->ospf6
;
496 if ((prev_state
== OSPF6_INTERFACE_DR
497 || prev_state
== OSPF6_INTERFACE_BDR
)
498 && (next_state
!= OSPF6_INTERFACE_DR
499 && next_state
!= OSPF6_INTERFACE_BDR
))
500 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
501 IPV6_LEAVE_GROUP
, ospf6
->fd
);
503 if ((prev_state
!= OSPF6_INTERFACE_DR
504 && prev_state
!= OSPF6_INTERFACE_BDR
)
505 && (next_state
== OSPF6_INTERFACE_DR
506 || next_state
== OSPF6_INTERFACE_BDR
))
507 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
508 IPV6_JOIN_GROUP
, ospf6
->fd
);
510 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
511 OSPF6_LINK_LSA_SCHEDULE(oi
);
512 if (next_state
== OSPF6_INTERFACE_DOWN
) {
513 OSPF6_NETWORK_LSA_EXECUTE(oi
);
514 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
515 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
516 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
517 } else if (prev_state
== OSPF6_INTERFACE_DR
518 || next_state
== OSPF6_INTERFACE_DR
) {
519 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
520 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
521 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
524 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 zlog_warn("Interface %s is down, can't execute [InterfaceUp]",
709 oi
->interface
->name
);
713 /* check interface has a link-local address */
714 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
715 || if_is_loopback_or_vrf(oi
->interface
))) {
717 "Interface %s has no link local address, can't execute [InterfaceUp]",
718 oi
->interface
->name
);
723 ospf6_interface_recalculate_cost(oi
);
725 /* if already enabled, do nothing */
726 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
727 if (IS_OSPF6_DEBUG_INTERFACE
)
728 zlog_debug("Interface %s already enabled",
729 oi
->interface
->name
);
733 /* If no area assigned, return */
734 if (oi
->area
== NULL
) {
736 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
737 __func__
, oi
->interface
->name
);
743 * XXX: Schedule IPv6 group join for later, otherwise we might
744 * lose the multicast group registration caused by IPv6 group
747 if (oi
->sso_try_cnt
== 0) {
749 zlog_info("Scheduling %s for sso", oi
->interface
->name
);
750 thread_add_timer(master
, interface_up
, oi
,
751 OSPF6_INTERFACE_SSO_RETRY_INT
,
755 #endif /* __FreeBSD__ */
757 ospf6
= oi
->area
->ospf6
;
759 /* Join AllSPFRouters */
760 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
,
763 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
765 "Scheduling %s for sso retry, trial count: %d",
766 oi
->interface
->name
, oi
->sso_try_cnt
);
767 thread_add_timer(master
, interface_up
, oi
,
768 OSPF6_INTERFACE_SSO_RETRY_INT
,
773 oi
->sso_try_cnt
= 0; /* Reset on success */
775 /* Update interface route */
776 ospf6_interface_connected_route_update(oi
->interface
);
779 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
780 && !if_is_loopback_or_vrf(oi
->interface
)) {
781 oi
->thread_send_hello
= NULL
;
782 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
783 &oi
->thread_send_hello
);
786 /* decide next interface state */
787 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
788 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
789 } else if (oi
->priority
== 0)
790 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
792 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
793 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
794 &oi
->thread_wait_timer
);
800 int wait_timer(struct thread
*thread
)
802 struct ospf6_interface
*oi
;
804 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
805 assert(oi
&& oi
->interface
);
807 if (IS_OSPF6_DEBUG_INTERFACE
)
808 zlog_debug("Interface Event %s: [WaitTimer]",
809 oi
->interface
->name
);
811 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
812 ospf6_interface_state_change(dr_election(oi
), oi
);
817 int backup_seen(struct thread
*thread
)
819 struct ospf6_interface
*oi
;
821 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
822 assert(oi
&& oi
->interface
);
824 if (IS_OSPF6_DEBUG_INTERFACE
)
825 zlog_debug("Interface Event %s: [BackupSeen]",
826 oi
->interface
->name
);
828 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
829 ospf6_interface_state_change(dr_election(oi
), oi
);
834 int neighbor_change(struct thread
*thread
)
836 struct ospf6_interface
*oi
;
838 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
839 assert(oi
&& oi
->interface
);
841 if (IS_OSPF6_DEBUG_INTERFACE
)
842 zlog_debug("Interface Event %s: [NeighborChange]",
843 oi
->interface
->name
);
845 if (oi
->state
== OSPF6_INTERFACE_DROTHER
846 || oi
->state
== OSPF6_INTERFACE_BDR
847 || oi
->state
== OSPF6_INTERFACE_DR
)
848 ospf6_interface_state_change(dr_election(oi
), oi
);
853 int interface_down(struct thread
*thread
)
855 struct ospf6_interface
*oi
;
856 struct listnode
*node
, *nnode
;
857 struct ospf6_neighbor
*on
;
860 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
861 assert(oi
&& oi
->interface
);
863 if (IS_OSPF6_DEBUG_INTERFACE
)
864 zlog_debug("Interface Event %s: [InterfaceDown]",
865 oi
->interface
->name
);
868 THREAD_OFF(oi
->thread_send_hello
);
870 /* Stop trying to set socket options. */
871 THREAD_OFF(oi
->thread_sso
);
873 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
874 ospf6_neighbor_delete(on
);
876 list_delete_all_node(oi
->neighbor_list
);
878 /* When interface state is reset, also reset information about
879 * DR election, as it is no longer valid. */
880 oi
->drouter
= oi
->prev_drouter
= htonl(0);
881 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
883 if (oi
->area
== NULL
)
886 ospf6
= oi
->area
->ospf6
;
887 /* Leave AllSPFRouters */
888 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
889 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
890 IPV6_LEAVE_GROUP
, ospf6
->fd
);
892 /* deal with write fifo */
893 ospf6_fifo_flush(oi
->obuf
);
894 if (oi
->on_write_q
) {
895 listnode_delete(ospf6
->oi_write_q
, oi
);
896 if (list_isempty(ospf6
->oi_write_q
))
897 thread_cancel(&ospf6
->t_write
);
901 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
907 static const char *ospf6_iftype_str(uint8_t iftype
)
910 case OSPF_IFTYPE_LOOPBACK
:
912 case OSPF_IFTYPE_BROADCAST
:
914 case OSPF_IFTYPE_POINTOPOINT
:
915 return "POINTOPOINT";
920 /* show specified interface structure */
921 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
,
922 json_object
*json_obj
, bool use_json
)
924 struct ospf6_interface
*oi
;
928 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
929 uint8_t default_iftype
;
930 struct timeval res
, now
;
932 struct ospf6_lsa
*lsa
, *lsanext
;
933 json_object
*json_arr
;
934 json_object
*json_addr
;
936 default_iftype
= ospf6_default_iftype(ifp
);
939 json_object_string_add(json_obj
, "status",
940 (if_is_operative(ifp
) ? "up" : "down"));
941 json_object_string_add(json_obj
, "type",
942 ospf6_iftype_str(default_iftype
));
943 json_object_int_add(json_obj
, "interfaceId", ifp
->ifindex
);
945 if (ifp
->info
== NULL
) {
946 json_object_boolean_false_add(json_obj
, "ospf6Enabled");
949 json_object_boolean_true_add(json_obj
, "ospf6Enabled");
951 oi
= (struct ospf6_interface
*)ifp
->info
;
953 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
954 json_object_string_add(json_obj
, "operatingAsType",
955 ospf6_iftype_str(oi
->type
));
958 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
959 (if_is_operative(ifp
) ? "up" : "down"),
960 ospf6_iftype_str(default_iftype
));
961 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
963 if (ifp
->info
== NULL
) {
964 vty_out(vty
, " OSPF not enabled on this interface\n");
967 oi
= (struct ospf6_interface
*)ifp
->info
;
969 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
970 vty_out(vty
, " Operating as type %s\n",
971 ospf6_iftype_str(oi
->type
));
975 json_arr
= json_object_new_array();
976 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
977 json_addr
= json_object_new_object();
979 prefix2str(p
, strbuf
, sizeof(strbuf
));
982 json_object_string_add(json_addr
, "type",
984 json_object_string_add(json_addr
, "address",
986 json_object_array_add(json_arr
, json_addr
);
989 json_object_string_add(json_addr
, "type",
991 json_object_string_add(json_addr
, "address",
993 json_object_array_add(json_arr
, json_addr
);
996 json_object_string_add(json_addr
, "type",
998 json_object_string_add(json_addr
, "address",
1000 json_object_array_add(json_arr
, json_addr
);
1004 json_object_object_add(json_obj
, "internetAddress", json_arr
);
1006 vty_out(vty
, " Internet Address:\n");
1008 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1010 prefix2str(p
, strbuf
, sizeof(strbuf
));
1011 switch (p
->family
) {
1013 vty_out(vty
, " inet : %pFX\n", p
);
1016 vty_out(vty
, " inet6: %pFX\n", p
);
1019 vty_out(vty
, " ??? : %pFX\n", p
);
1027 json_object_boolean_true_add(json_obj
,
1029 json_object_int_add(json_obj
, "instanceId",
1031 json_object_int_add(json_obj
, "interfaceMtu",
1033 json_object_int_add(json_obj
, "autoDetect", ifp
->mtu6
);
1034 json_object_string_add(json_obj
, "mtuMismatchDetection",
1035 oi
->mtu_ignore
? "disabled"
1037 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1039 json_object_string_add(json_obj
, "areaId", strbuf
);
1040 json_object_int_add(json_obj
, "cost", oi
->cost
);
1042 json_object_boolean_false_add(json_obj
,
1048 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1049 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
1050 vty_out(vty
, " MTU mismatch detection: %s\n",
1051 oi
->mtu_ignore
? "disabled" : "enabled");
1052 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1054 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
,
1057 vty_out(vty
, " Not Attached to Area\n");
1061 json_object_string_add(json_obj
, "ospf6InterfaceState",
1062 ospf6_interface_state_str
[oi
->state
]);
1063 json_object_int_add(json_obj
, "transmitDelaySec",
1065 json_object_int_add(json_obj
, "priority", oi
->priority
);
1066 json_object_int_add(json_obj
, "timerIntervalsConfigHello",
1067 oi
->hello_interval
);
1068 json_object_int_add(json_obj
, "timerIntervalsConfigDead",
1070 json_object_int_add(json_obj
, "timerIntervalsConfigRetransmit",
1073 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
1074 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
1076 vty_out(vty
, " Timer intervals configured:\n");
1077 vty_out(vty
, " Hello %d, Dead %d, Retransmit %d\n",
1078 oi
->hello_interval
, oi
->dead_interval
,
1082 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
1083 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
1085 json_object_string_add(json_obj
, "dr", drouter
);
1086 json_object_string_add(json_obj
, "bdr", bdrouter
);
1087 json_object_int_add(json_obj
, "numberOfInterfaceScopedLsa",
1090 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
1091 vty_out(vty
, " Number of I/F scoped LSAs is %u\n",
1099 if (oi
->thread_send_lsupdate
)
1100 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1102 timerstring(&res
, duration
, sizeof(duration
));
1103 json_object_int_add(json_obj
, "pendingLsaLsUpdateCount",
1104 oi
->lsupdate_list
->count
);
1105 json_object_string_add(json_obj
, "pendingLsaLsUpdateTime",
1107 json_object_string_add(
1108 json_obj
, "lsUpdateSendThread",
1109 (oi
->thread_send_lsupdate
? "on" : "off"));
1111 json_arr
= json_object_new_array();
1112 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1113 json_object_array_add(
1114 json_arr
, json_object_new_string(lsa
->name
));
1115 json_object_object_add(json_obj
, "pendingLsaLsUpdate",
1119 if (oi
->thread_send_lsack
)
1120 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1121 timerstring(&res
, duration
, sizeof(duration
));
1123 json_object_int_add(json_obj
, "pendingLsaLsAckCount",
1124 oi
->lsack_list
->count
);
1125 json_object_string_add(json_obj
, "pendingLsaLsAckTime",
1127 json_object_string_add(json_obj
, "lsAckSendThread",
1128 (oi
->thread_send_lsack
? "on" : "off"));
1130 json_arr
= json_object_new_array();
1131 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1132 json_object_array_add(
1133 json_arr
, json_object_new_string(lsa
->name
));
1134 json_object_object_add(json_obj
, "pendingLsaLsAck", json_arr
);
1138 if (oi
->thread_send_lsupdate
)
1139 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1141 timerstring(&res
, duration
, sizeof(duration
));
1143 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1144 oi
->lsupdate_list
->count
, duration
,
1145 (oi
->thread_send_lsupdate
? "on" : "off"));
1146 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1147 vty_out(vty
, " %s\n", lsa
->name
);
1150 if (oi
->thread_send_lsack
)
1151 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1152 timerstring(&res
, duration
, sizeof(duration
));
1154 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1155 oi
->lsack_list
->count
, duration
,
1156 (oi
->thread_send_lsack
? "on" : "off"));
1157 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1158 vty_out(vty
, " %s\n", lsa
->name
);
1162 if (oi
->bfd_config
.enabled
) {
1164 struct json_object
*json_bfd
= json_object_new_object();
1166 json_object_int_add(
1167 json_bfd
, "detectMultiplier",
1168 oi
->bfd_config
.detection_multiplier
);
1169 json_object_int_add(json_bfd
, "rxMinInterval",
1170 oi
->bfd_config
.min_rx
);
1171 json_object_int_add(json_bfd
, "txMinInterval",
1172 oi
->bfd_config
.min_tx
);
1173 json_object_object_add(json_obj
, "peerBfdInfo",
1177 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1178 oi
->bfd_config
.detection_multiplier
,
1179 oi
->bfd_config
.min_rx
, oi
->bfd_config
.min_tx
);
1186 /* Find the global address to be used as a forwarding address in NSSA LSA.*/
1187 struct in6_addr
*ospf6_interface_get_global_address(struct interface
*ifp
)
1190 struct connected
*c
;
1191 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
1193 /* for each connected address */
1194 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
1195 /* if family not AF_INET6, ignore */
1196 if (c
->address
->family
!= AF_INET6
)
1199 if (!IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
1200 l
= &c
->address
->u
.prefix6
;
1206 static int show_ospf6_interface_common(struct vty
*vty
, vrf_id_t vrf_id
,
1207 int argc
, struct cmd_token
**argv
,
1208 int idx_ifname
, int intf_idx
,
1212 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
1213 struct interface
*ifp
;
1215 json_object
*json_int
;
1216 bool uj
= use_json(argc
, argv
);
1219 json
= json_object_new_object();
1220 if (argc
== json_idx
) {
1221 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1222 json_int
= json_object_new_object();
1224 json_object_string_add(json
, "noSuchInterface",
1225 argv
[idx_ifname
]->arg
);
1226 vty_out(vty
, "%s\n",
1227 json_object_to_json_string_ext(
1228 json
, JSON_C_TO_STRING_PRETTY
));
1229 json_object_free(json
);
1230 json_object_free(json_int
);
1233 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1234 json_object_object_add(json
, ifp
->name
, json_int
);
1236 FOR_ALL_INTERFACES (vrf
, ifp
) {
1237 json_int
= json_object_new_object();
1238 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1239 json_object_object_add(json
, ifp
->name
,
1243 vty_out(vty
, "%s\n",
1244 json_object_to_json_string_ext(
1245 json
, JSON_C_TO_STRING_PRETTY
));
1246 json_object_free(json
);
1248 if (argc
== intf_idx
) {
1249 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1251 vty_out(vty
, "No such Interface: %s\n",
1252 argv
[idx_ifname
]->arg
);
1255 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1257 FOR_ALL_INTERFACES (vrf
, ifp
)
1258 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1264 /* show interface */
1265 DEFUN(show_ipv6_ospf6_interface
, show_ipv6_ospf6_interface_ifname_cmd
,
1266 "show ipv6 ospf6 [vrf <NAME|all>] interface [IFNAME] [json]",
1267 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1268 "All VRFs\n" INTERFACE_STR IFNAME_STR JSON_STR
)
1273 struct listnode
*node
;
1274 struct ospf6
*ospf6
;
1275 const char *vrf_name
= NULL
;
1276 bool all_vrf
= false;
1279 OSPF6_CMD_CHECK_RUNNING();
1280 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1287 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1288 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1289 show_ospf6_interface_common(vty
, ospf6
->vrf_id
, argc
,
1290 argv
, idx_ifname
, intf_idx
,
1301 static int ospf6_interface_show_traffic(struct vty
*vty
,
1302 struct interface
*intf_ifp
,
1303 int display_once
, json_object
*json
,
1304 bool use_json
, vrf_id_t vrf_id
)
1306 struct interface
*ifp
;
1307 struct vrf
*vrf
= NULL
;
1308 struct ospf6_interface
*oi
= NULL
;
1309 json_object
*json_interface
;
1312 vrf
= vrf_lookup_by_id(intf_ifp
->vrf_id
);
1314 vrf
= vrf_lookup_by_id(vrf_id
);
1316 if (!display_once
&& !use_json
) {
1318 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1319 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1321 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1322 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1325 "--------------------------------------------------------------------------------------------\n");
1328 if (intf_ifp
== NULL
) {
1329 FOR_ALL_INTERFACES (vrf
, ifp
) {
1331 oi
= (struct ospf6_interface
*)ifp
->info
;
1336 json_interface
= json_object_new_object();
1337 json_object_int_add(json_interface
, "helloRx",
1339 json_object_int_add(json_interface
, "helloTx",
1341 json_object_int_add(json_interface
, "dbDescRx",
1343 json_object_int_add(json_interface
, "dbDescTx",
1345 json_object_int_add(json_interface
, "lsReqRx",
1347 json_object_int_add(json_interface
, "lsReqTx",
1349 json_object_int_add(json_interface
,
1352 json_object_int_add(json_interface
,
1355 json_object_int_add(json_interface
, "lsAckRx",
1357 json_object_int_add(json_interface
, "lsAckTx",
1360 json_object_object_add(json
,
1361 oi
->interface
->name
,
1365 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1366 oi
->interface
->name
, oi
->hello_in
,
1367 oi
->hello_out
, oi
->db_desc_in
,
1368 oi
->db_desc_out
, oi
->ls_req_in
,
1369 oi
->ls_req_out
, oi
->ls_upd_in
,
1370 oi
->ls_upd_out
, oi
->ls_ack_in
,
1374 oi
= intf_ifp
->info
;
1379 json_interface
= json_object_new_object();
1380 json_object_int_add(json_interface
, "helloRx",
1382 json_object_int_add(json_interface
, "helloTx",
1384 json_object_int_add(json_interface
, "dbDescRx",
1386 json_object_int_add(json_interface
, "dbDescTx",
1388 json_object_int_add(json_interface
, "lsReqRx",
1390 json_object_int_add(json_interface
, "lsReqTx",
1392 json_object_int_add(json_interface
, "lsUpdateRx",
1394 json_object_int_add(json_interface
, "lsUpdateTx",
1396 json_object_int_add(json_interface
, "lsAckRx",
1398 json_object_int_add(json_interface
, "lsAckTx",
1401 json_object_object_add(json
, oi
->interface
->name
,
1405 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1406 oi
->interface
->name
, oi
->hello_in
,
1407 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1408 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1409 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1415 static int ospf6_interface_show_traffic_common(struct vty
*vty
, int argc
,
1416 struct cmd_token
**argv
,
1420 int display_once
= 0;
1421 char *intf_name
= NULL
;
1422 struct interface
*ifp
= NULL
;
1423 json_object
*json
= NULL
;
1424 bool uj
= use_json(argc
, argv
);
1427 json
= json_object_new_object();
1429 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1430 intf_name
= argv
[idx_ifname
]->arg
;
1431 ifp
= if_lookup_by_name(intf_name
, vrf_id
);
1434 json_object_string_add(json
, "status",
1435 "No Such Interface");
1436 json_object_string_add(json
, "interface",
1438 vty_out(vty
, "%s\n",
1439 json_object_to_json_string_ext(
1440 json
, JSON_C_TO_STRING_PRETTY
));
1441 json_object_free(json
);
1444 if (ifp
->info
== NULL
) {
1445 json_object_string_add(
1447 "OSPF not enabled on this interface");
1448 json_object_string_add(json
, "interface",
1450 vty_out(vty
, "%s\n",
1451 json_object_to_json_string_ext(
1452 json
, JSON_C_TO_STRING_PRETTY
));
1453 json_object_free(json
);
1458 vty_out(vty
, "No such Interface: %s\n",
1462 if (ifp
->info
== NULL
) {
1464 " OSPF not enabled on this interface %s\n",
1471 ospf6_interface_show_traffic(vty
, ifp
, display_once
, json
, uj
, vrf_id
);
1474 vty_out(vty
, "%s\n",
1475 json_object_to_json_string_ext(
1476 json
, JSON_C_TO_STRING_PRETTY
));
1477 json_object_free(json
);
1483 /* show interface */
1484 DEFUN(show_ipv6_ospf6_interface_traffic
, show_ipv6_ospf6_interface_traffic_cmd
,
1485 "show ipv6 ospf6 [vrf <NAME|all>] interface traffic [IFNAME] [json]",
1486 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1487 "All VRFs\n" INTERFACE_STR
1488 "Protocol Packet counters\n" IFNAME_STR JSON_STR
)
1490 struct ospf6
*ospf6
;
1491 struct listnode
*node
;
1492 const char *vrf_name
= NULL
;
1493 bool all_vrf
= false;
1496 OSPF6_CMD_CHECK_RUNNING();
1497 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1499 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1500 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1501 ospf6_interface_show_traffic_common(vty
, argc
, argv
,
1513 DEFUN(show_ipv6_ospf6_interface_ifname_prefix
,
1514 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1515 "show ipv6 ospf6 [vrf <NAME|all>] interface IFNAME prefix\
1518 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1520 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1521 "All VRFs\n" INTERFACE_STR IFNAME_STR
1522 "Display connected prefixes to advertise\n"
1523 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1524 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1525 "Display details of the prefixes\n" JSON_STR
)
1529 struct ospf6_interface
*oi
;
1530 bool uj
= use_json(argc
, argv
);
1532 struct ospf6
*ospf6
;
1533 struct listnode
*node
;
1534 struct interface
*ifp
;
1535 const char *vrf_name
= NULL
;
1536 bool all_vrf
= false;
1539 OSPF6_CMD_CHECK_RUNNING();
1540 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1546 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1547 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1548 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1551 vty_out(vty
, "No such Interface: %s\n",
1552 argv
[idx_ifname
]->arg
);
1558 || CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
1560 "Interface %s not attached to area\n",
1561 argv
[idx_ifname
]->arg
);
1565 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1566 oi
->route_connected
, uj
);
1576 DEFUN(show_ipv6_ospf6_interface_prefix
, show_ipv6_ospf6_interface_prefix_cmd
,
1577 "show ipv6 ospf6 [vrf <NAME|all>] interface prefix\
1580 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1582 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1583 "All VRFs\n" INTERFACE_STR
1584 "Display connected prefixes to advertise\n"
1585 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1586 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1587 "Display details of the prefixes\n" JSON_STR
)
1589 struct vrf
*vrf
= NULL
;
1591 struct ospf6_interface
*oi
;
1592 struct interface
*ifp
;
1593 bool uj
= use_json(argc
, argv
);
1594 struct listnode
*node
;
1595 struct ospf6
*ospf6
;
1596 const char *vrf_name
= NULL
;
1597 bool all_vrf
= false;
1600 OSPF6_CMD_CHECK_RUNNING();
1601 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1605 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1606 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1607 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
1608 FOR_ALL_INTERFACES (vrf
, ifp
) {
1609 oi
= (struct ospf6_interface
*)ifp
->info
;
1611 || CHECK_FLAG(oi
->flag
,
1612 OSPF6_INTERFACE_DISABLE
))
1615 ospf6_route_table_show(vty
, idx_prefix
, argc
,
1617 oi
->route_connected
, uj
);
1627 void ospf6_interface_start(struct ospf6_interface
*oi
)
1629 struct ospf6
*ospf6
;
1630 struct ospf6_area
*oa
;
1632 if (oi
->area_id_format
== OSPF6_AREA_FMT_UNSET
)
1638 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
1642 oa
= ospf6_area_lookup(oi
->area_id
, ospf6
);
1644 oa
= ospf6_area_create(oi
->area_id
, ospf6
, oi
->area_id_format
);
1646 /* attach interface to area */
1647 listnode_add(oa
->if_list
, oi
);
1650 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1653 ospf6_interface_enable(oi
);
1655 /* If the router is ABR, originate summary routes */
1656 if (ospf6_check_and_set_router_abr(ospf6
))
1657 ospf6_abr_enable_area(oa
);
1660 void ospf6_interface_stop(struct ospf6_interface
*oi
)
1662 struct ospf6_area
*oa
;
1668 ospf6_interface_disable(oi
);
1670 listnode_delete(oa
->if_list
, oi
);
1673 if (oa
->if_list
->count
== 0) {
1674 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1675 ospf6_abr_disable_area(oa
);
1679 /* interface variable set command */
1680 DEFUN (ipv6_ospf6_area
,
1681 ipv6_ospf6_area_cmd
,
1682 "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
1685 "Specify the OSPF6 area ID\n"
1686 "OSPF6 area ID in IPv4 address notation\n"
1687 "OSPF6 area ID in decimal notation\n")
1689 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1690 struct ospf6_interface
*oi
;
1698 oi
= (struct ospf6_interface
*)ifp
->info
;
1700 oi
= ospf6_interface_create(ifp
);
1704 vty_out(vty
, "%s already attached to Area %s\n",
1705 oi
->interface
->name
, oi
->area
->name
);
1709 /* if more than OSPF6_MAX_IF_ADDRS are configured on this interface
1710 * then don't allow ospfv3 to be configured
1712 ipv6_count
= connected_count_by_family(ifp
, AF_INET6
);
1713 if (oi
->ifmtu
== OSPF6_DEFAULT_MTU
&& ipv6_count
> OSPF6_MAX_IF_ADDRS
) {
1715 "can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n",
1716 ifp
->name
, OSPF6_MAX_IF_ADDRS
, ipv6_count
);
1717 return CMD_WARNING_CONFIG_FAILED
;
1718 } else if (oi
->ifmtu
>= OSPF6_JUMBO_MTU
1719 && ipv6_count
> OSPF6_MAX_IF_ADDRS_JUMBO
) {
1721 "can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n",
1722 ifp
->name
, OSPF6_MAX_IF_ADDRS_JUMBO
, ipv6_count
);
1723 return CMD_WARNING_CONFIG_FAILED
;
1726 if (str2area_id(argv
[idx_ipv4
]->arg
, &area_id
, &format
)) {
1727 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1728 return CMD_WARNING_CONFIG_FAILED
;
1731 oi
->area_id
= area_id
;
1732 oi
->area_id_format
= format
;
1734 ospf6_interface_start(oi
);
1739 DEFUN (no_ipv6_ospf6_area
,
1740 no_ipv6_ospf6_area_cmd
,
1741 "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
1745 "Specify the OSPF6 area ID\n"
1746 "OSPF6 area ID in IPv4 address notation\n"
1747 "OSPF6 area ID in decimal notation\n")
1749 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1750 struct ospf6_interface
*oi
;
1754 oi
= (struct ospf6_interface
*)ifp
->info
;
1756 oi
= ospf6_interface_create(ifp
);
1759 ospf6_interface_stop(oi
);
1762 oi
->area_id_format
= OSPF6_AREA_FMT_UNSET
;
1767 DEFUN (ipv6_ospf6_ifmtu
,
1768 ipv6_ospf6_ifmtu_cmd
,
1769 "ipv6 ospf6 ifmtu (1-65535)",
1773 "OSPFv3 Interface MTU\n"
1776 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1778 struct ospf6_interface
*oi
;
1779 unsigned int ifmtu
, iobuflen
;
1780 struct listnode
*node
, *nnode
;
1781 struct ospf6_neighbor
*on
;
1785 oi
= (struct ospf6_interface
*)ifp
->info
;
1787 oi
= ospf6_interface_create(ifp
);
1790 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1792 if (oi
->c_ifmtu
== ifmtu
)
1795 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1797 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1798 ifp
->name
, ifp
->mtu6
);
1799 return CMD_WARNING_CONFIG_FAILED
;
1802 if (oi
->ifmtu
< ifmtu
) {
1803 iobuflen
= ospf6_iobuf_size(ifmtu
);
1804 if (iobuflen
< ifmtu
) {
1806 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1807 ifp
->name
, iobuflen
);
1808 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1810 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1812 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1814 /* re-establish adjacencies */
1815 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1816 THREAD_OFF(on
->inactivity_timer
);
1817 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1823 DEFUN (no_ipv6_ospf6_ifmtu
,
1824 no_ipv6_ospf6_ifmtu_cmd
,
1825 "no ipv6 ospf6 ifmtu [(1-65535)]",
1830 "OSPFv3 Interface MTU\n"
1833 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1834 struct ospf6_interface
*oi
;
1835 unsigned int iobuflen
;
1836 struct listnode
*node
, *nnode
;
1837 struct ospf6_neighbor
*on
;
1841 oi
= (struct ospf6_interface
*)ifp
->info
;
1843 oi
= ospf6_interface_create(ifp
);
1846 if (oi
->ifmtu
< ifp
->mtu
) {
1847 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1848 if (iobuflen
< ifp
->mtu
) {
1850 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1851 ifp
->name
, iobuflen
);
1852 oi
->ifmtu
= iobuflen
;
1854 oi
->ifmtu
= ifp
->mtu
;
1856 oi
->ifmtu
= ifp
->mtu
;
1860 /* re-establish adjacencies */
1861 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1862 THREAD_OFF(on
->inactivity_timer
);
1863 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1869 DEFUN (ipv6_ospf6_cost
,
1870 ipv6_ospf6_cost_cmd
,
1871 "ipv6 ospf6 cost (1-65535)",
1875 "Outgoing metric of this interface\n")
1877 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1879 struct ospf6_interface
*oi
;
1880 unsigned long int lcost
;
1884 oi
= (struct ospf6_interface
*)ifp
->info
;
1886 oi
= ospf6_interface_create(ifp
);
1889 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1891 if (lcost
> UINT32_MAX
) {
1892 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1893 return CMD_WARNING_CONFIG_FAILED
;
1896 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1897 if (oi
->cost
== lcost
)
1901 ospf6_interface_force_recalculate_cost(oi
);
1906 DEFUN (no_ipv6_ospf6_cost
,
1907 no_ipv6_ospf6_cost_cmd
,
1908 "no ipv6 ospf6 cost [(1-65535)]",
1912 "Calculate interface cost from bandwidth\n"
1913 "Outgoing metric of this interface\n")
1915 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1916 struct ospf6_interface
*oi
;
1919 oi
= (struct ospf6_interface
*)ifp
->info
;
1921 oi
= ospf6_interface_create(ifp
);
1924 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1926 ospf6_interface_recalculate_cost(oi
);
1931 DEFUN (auto_cost_reference_bandwidth
,
1932 auto_cost_reference_bandwidth_cmd
,
1933 "auto-cost reference-bandwidth (1-4294967)",
1934 "Calculate OSPF interface cost according to bandwidth\n"
1935 "Use reference bandwidth method to assign OSPF cost\n"
1936 "The reference bandwidth in terms of Mbits per second\n")
1938 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1940 struct ospf6_area
*oa
;
1941 struct ospf6_interface
*oi
;
1942 struct listnode
*i
, *j
;
1945 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1946 if (refbw
< 1 || refbw
> 4294967) {
1947 vty_out(vty
, "reference-bandwidth value is invalid\n");
1948 return CMD_WARNING_CONFIG_FAILED
;
1951 /* If reference bandwidth is changed. */
1952 if ((refbw
) == o
->ref_bandwidth
)
1955 o
->ref_bandwidth
= refbw
;
1956 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1957 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1958 ospf6_interface_recalculate_cost(oi
);
1963 DEFUN (no_auto_cost_reference_bandwidth
,
1964 no_auto_cost_reference_bandwidth_cmd
,
1965 "no auto-cost reference-bandwidth [(1-4294967)]",
1967 "Calculate OSPF interface cost according to bandwidth\n"
1968 "Use reference bandwidth method to assign OSPF cost\n"
1969 "The reference bandwidth in terms of Mbits per second\n")
1971 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1972 struct ospf6_area
*oa
;
1973 struct ospf6_interface
*oi
;
1974 struct listnode
*i
, *j
;
1976 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
1979 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
1980 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1981 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1982 ospf6_interface_recalculate_cost(oi
);
1988 DEFUN (ospf6_write_multiplier
,
1989 ospf6_write_multiplier_cmd
,
1990 "write-multiplier (1-100)",
1991 "Write multiplier\n"
1992 "Maximum number of interface serviced per write\n")
1994 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1995 uint32_t write_oi_count
;
1997 write_oi_count
= strtol(argv
[1]->arg
, NULL
, 10);
1998 if (write_oi_count
< 1 || write_oi_count
> 100) {
1999 vty_out(vty
, "write-multiplier value is invalid\n");
2000 return CMD_WARNING_CONFIG_FAILED
;
2003 o
->write_oi_count
= write_oi_count
;
2007 DEFUN (no_ospf6_write_multiplier
,
2008 no_ospf6_write_multiplier_cmd
,
2009 "no write-multiplier (1-100)",
2011 "Write multiplier\n"
2012 "Maximum number of interface serviced per write\n")
2014 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2016 o
->write_oi_count
= OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
;
2020 DEFUN (ipv6_ospf6_hellointerval
,
2021 ipv6_ospf6_hellointerval_cmd
,
2022 "ipv6 ospf6 hello-interval (1-65535)",
2025 "Time between HELLO packets\n"
2028 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2030 struct ospf6_interface
*oi
;
2033 oi
= (struct ospf6_interface
*)ifp
->info
;
2035 oi
= ospf6_interface_create(ifp
);
2038 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
2039 ? OSPF_HELLO_INTERVAL_DEFAULT
2040 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2044 ALIAS (ipv6_ospf6_hellointerval
,
2045 no_ipv6_ospf6_hellointerval_cmd
,
2046 "no ipv6 ospf6 hello-interval [(1-65535)]",
2050 "Time between HELLO packets\n"
2053 /* interface variable set command */
2054 DEFUN (ipv6_ospf6_deadinterval
,
2055 ipv6_ospf6_deadinterval_cmd
,
2056 "ipv6 ospf6 dead-interval (1-65535)",
2059 "Interval time after which a neighbor is declared down\n"
2062 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2064 struct ospf6_interface
*oi
;
2067 oi
= (struct ospf6_interface
*)ifp
->info
;
2069 oi
= ospf6_interface_create(ifp
);
2072 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
2073 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
2074 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2078 ALIAS (ipv6_ospf6_deadinterval
,
2079 no_ipv6_ospf6_deadinterval_cmd
,
2080 "no ipv6 ospf6 dead-interval [(1-65535)]",
2084 "Interval time after which a neighbor is declared down\n"
2087 /* interface variable set command */
2088 DEFUN (ipv6_ospf6_transmitdelay
,
2089 ipv6_ospf6_transmitdelay_cmd
,
2090 "ipv6 ospf6 transmit-delay (1-3600)",
2093 "Link state transmit delay\n"
2096 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2098 struct ospf6_interface
*oi
;
2101 oi
= (struct ospf6_interface
*)ifp
->info
;
2103 oi
= ospf6_interface_create(ifp
);
2106 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
2107 ? OSPF6_INTERFACE_TRANSDELAY
2108 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2112 ALIAS (ipv6_ospf6_transmitdelay
,
2113 no_ipv6_ospf6_transmitdelay_cmd
,
2114 "no ipv6 ospf6 transmit-delay [(1-3600)]",
2118 "Link state transmit delay\n"
2121 /* interface variable set command */
2122 DEFUN (ipv6_ospf6_retransmitinterval
,
2123 ipv6_ospf6_retransmitinterval_cmd
,
2124 "ipv6 ospf6 retransmit-interval (1-65535)",
2127 "Time between retransmitting lost link state advertisements\n"
2130 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2132 struct ospf6_interface
*oi
;
2135 oi
= (struct ospf6_interface
*)ifp
->info
;
2137 oi
= ospf6_interface_create(ifp
);
2140 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
2141 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
2142 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2146 ALIAS (ipv6_ospf6_retransmitinterval
,
2147 no_ipv6_ospf6_retransmitinterval_cmd
,
2148 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
2152 "Time between retransmitting lost link state advertisements\n"
2155 /* interface variable set command */
2156 DEFUN (ipv6_ospf6_priority
,
2157 ipv6_ospf6_priority_cmd
,
2158 "ipv6 ospf6 priority (0-255)",
2164 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2166 struct ospf6_interface
*oi
;
2169 oi
= (struct ospf6_interface
*)ifp
->info
;
2171 oi
= ospf6_interface_create(ifp
);
2174 oi
->priority
= strmatch(argv
[0]->text
, "no")
2175 ? OSPF6_INTERFACE_PRIORITY
2176 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2179 && (oi
->state
== OSPF6_INTERFACE_DROTHER
2180 || oi
->state
== OSPF6_INTERFACE_BDR
2181 || oi
->state
== OSPF6_INTERFACE_DR
)) {
2182 if (ospf6_interface_state_change(dr_election(oi
), oi
) == -1)
2183 OSPF6_LINK_LSA_SCHEDULE(oi
);
2189 ALIAS (ipv6_ospf6_priority
,
2190 no_ipv6_ospf6_priority_cmd
,
2191 "no ipv6 ospf6 priority [(0-255)]",
2198 DEFUN (ipv6_ospf6_instance
,
2199 ipv6_ospf6_instance_cmd
,
2200 "ipv6 ospf6 instance-id (0-255)",
2203 "Instance ID for this interface\n"
2204 "Instance ID value\n")
2206 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2208 struct ospf6_interface
*oi
;
2211 oi
= (struct ospf6_interface
*)ifp
->info
;
2213 oi
= ospf6_interface_create(ifp
);
2216 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
2217 ? OSPF6_INTERFACE_INSTANCE_ID
2218 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2222 ALIAS (ipv6_ospf6_instance
,
2223 no_ipv6_ospf6_instance_cmd
,
2224 "no ipv6 ospf6 instance-id [(0-255)]",
2228 "Instance ID for this interface\n"
2229 "Instance ID value\n")
2231 DEFUN (ipv6_ospf6_passive
,
2232 ipv6_ospf6_passive_cmd
,
2233 "ipv6 ospf6 passive",
2236 "Passive interface; no adjacency will be formed on this interface\n"
2239 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2240 struct ospf6_interface
*oi
;
2241 struct listnode
*node
, *nnode
;
2242 struct ospf6_neighbor
*on
;
2246 oi
= (struct ospf6_interface
*)ifp
->info
;
2248 oi
= ospf6_interface_create(ifp
);
2251 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2252 THREAD_OFF(oi
->thread_send_hello
);
2253 THREAD_OFF(oi
->thread_sso
);
2255 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
2256 THREAD_OFF(on
->inactivity_timer
);
2257 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
2263 DEFUN (no_ipv6_ospf6_passive
,
2264 no_ipv6_ospf6_passive_cmd
,
2265 "no ipv6 ospf6 passive",
2269 "passive interface: No Adjacency will be formed on this I/F\n"
2272 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2273 struct ospf6_interface
*oi
;
2276 oi
= (struct ospf6_interface
*)ifp
->info
;
2278 oi
= ospf6_interface_create(ifp
);
2281 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2282 THREAD_OFF(oi
->thread_send_hello
);
2283 THREAD_OFF(oi
->thread_sso
);
2285 /* don't send hellos over loopback interface */
2286 if (!if_is_loopback_or_vrf(oi
->interface
))
2287 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
2288 &oi
->thread_send_hello
);
2293 DEFUN (ipv6_ospf6_mtu_ignore
,
2294 ipv6_ospf6_mtu_ignore_cmd
,
2295 "ipv6 ospf6 mtu-ignore",
2298 "Disable MTU mismatch detection on this interface\n"
2301 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2302 struct ospf6_interface
*oi
;
2305 oi
= (struct ospf6_interface
*)ifp
->info
;
2307 oi
= ospf6_interface_create(ifp
);
2315 DEFUN (no_ipv6_ospf6_mtu_ignore
,
2316 no_ipv6_ospf6_mtu_ignore_cmd
,
2317 "no ipv6 ospf6 mtu-ignore",
2321 "Disable MTU mismatch detection on this interface\n"
2324 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2325 struct ospf6_interface
*oi
;
2328 oi
= (struct ospf6_interface
*)ifp
->info
;
2330 oi
= ospf6_interface_create(ifp
);
2338 DEFUN (ipv6_ospf6_advertise_prefix_list
,
2339 ipv6_ospf6_advertise_prefix_list_cmd
,
2340 "ipv6 ospf6 advertise prefix-list WORD",
2343 "Advertising options\n"
2344 "Filter prefix using prefix-list\n"
2345 "Prefix list name\n"
2348 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2350 struct ospf6_interface
*oi
;
2353 oi
= (struct ospf6_interface
*)ifp
->info
;
2355 oi
= ospf6_interface_create(ifp
);
2359 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2360 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
2362 ospf6_interface_connected_route_update(oi
->interface
);
2365 OSPF6_LINK_LSA_SCHEDULE(oi
);
2366 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2367 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2368 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2370 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2376 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
2377 no_ipv6_ospf6_advertise_prefix_list_cmd
,
2378 "no ipv6 ospf6 advertise prefix-list [WORD]",
2382 "Advertising options\n"
2383 "Filter prefix using prefix-list\n"
2384 "Prefix list name\n")
2386 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2387 struct ospf6_interface
*oi
;
2390 oi
= (struct ospf6_interface
*)ifp
->info
;
2392 oi
= ospf6_interface_create(ifp
);
2396 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2398 ospf6_interface_connected_route_update(oi
->interface
);
2401 OSPF6_LINK_LSA_SCHEDULE(oi
);
2402 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2403 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2404 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2406 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2412 DEFUN (ipv6_ospf6_network
,
2413 ipv6_ospf6_network_cmd
,
2414 "ipv6 ospf6 network <broadcast|point-to-point>",
2418 "Specify OSPF6 broadcast network\n"
2419 "Specify OSPF6 point-to-point network\n"
2422 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2423 int idx_network
= 3;
2424 struct ospf6_interface
*oi
;
2427 oi
= (struct ospf6_interface
*)ifp
->info
;
2429 oi
= ospf6_interface_create(ifp
);
2433 oi
->type_cfg
= true;
2435 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
2436 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
2439 oi
->type
= OSPF_IFTYPE_BROADCAST
;
2440 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
2441 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
2444 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
2447 /* Reset the interface */
2448 thread_execute(master
, interface_down
, oi
, 0);
2449 thread_execute(master
, interface_up
, oi
, 0);
2454 DEFUN (no_ipv6_ospf6_network
,
2455 no_ipv6_ospf6_network_cmd
,
2456 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2460 "Set default network type\n"
2461 "Specify OSPF6 broadcast network\n"
2462 "Specify OSPF6 point-to-point network\n")
2464 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2465 struct ospf6_interface
*oi
;
2470 oi
= (struct ospf6_interface
*)ifp
->info
;
2475 oi
->type_cfg
= false;
2477 type
= ospf6_default_iftype(ifp
);
2478 if (oi
->type
== type
) {
2483 /* Reset the interface */
2484 thread_execute(master
, interface_down
, oi
, 0);
2485 thread_execute(master
, interface_up
, oi
, 0);
2490 static int config_write_ospf6_interface(struct vty
*vty
, struct vrf
*vrf
)
2492 struct ospf6_interface
*oi
;
2493 struct interface
*ifp
;
2494 char buf
[INET_ADDRSTRLEN
];
2496 FOR_ALL_INTERFACES (vrf
, ifp
) {
2497 oi
= (struct ospf6_interface
*)ifp
->info
;
2501 if (vrf
->vrf_id
== VRF_DEFAULT
)
2502 vty_frame(vty
, "interface %s\n", oi
->interface
->name
);
2504 vty_frame(vty
, "interface %s vrf %s\n",
2505 oi
->interface
->name
, vrf
->name
);
2508 vty_out(vty
, " description %s\n", ifp
->desc
);
2509 if (oi
->area_id_format
!= OSPF6_AREA_FMT_UNSET
) {
2510 area_id2str(buf
, sizeof(buf
), oi
->area_id
,
2511 oi
->area_id_format
);
2512 vty_out(vty
, " ipv6 ospf6 area %s\n", buf
);
2515 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
2517 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
2518 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
2520 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
2521 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
2522 oi
->hello_interval
);
2524 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
2525 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
2528 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
2529 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
2532 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
2533 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
2535 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
2536 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
2539 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
2540 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
2544 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
2547 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
2548 vty_out(vty
, " ipv6 ospf6 passive\n");
2551 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
2553 if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
2554 vty_out(vty
, " ipv6 ospf6 network point-to-point\n");
2555 else if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_BROADCAST
)
2556 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
2558 ospf6_bfd_write_config(vty
, oi
);
2560 vty_endframe(vty
, "!\n");
2565 /* Configuration write function for ospfd. */
2566 static int config_write_interface(struct vty
*vty
)
2569 struct vrf
*vrf
= NULL
;
2571 /* Display all VRF aware OSPF interface configuration */
2572 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2573 write
+= config_write_ospf6_interface(vty
, vrf
);
2579 static int config_write_ospf6_interface(struct vty
*vty
, struct vrf
*vrf
);
2580 static struct cmd_node interface_node
= {
2581 .name
= "interface",
2582 .node
= INTERFACE_NODE
,
2583 .parent_node
= CONFIG_NODE
,
2584 .prompt
= "%s(config-if)# ",
2585 .config_write
= config_write_interface
,
2588 static int ospf6_ifp_create(struct interface
*ifp
)
2590 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2591 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp
->name
,
2592 ifp
->ifindex
, ifp
->mtu6
);
2595 ospf6_interface_start(ifp
->info
);
2600 static int ospf6_ifp_up(struct interface
*ifp
)
2602 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2604 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2605 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2606 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2608 ospf6_interface_state_update(ifp
);
2613 static int ospf6_ifp_down(struct interface
*ifp
)
2615 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2617 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2618 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2619 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2621 ospf6_interface_state_update(ifp
);
2626 static int ospf6_ifp_destroy(struct interface
*ifp
)
2629 zlog_warn("Zebra: got delete of %s, but interface is still up",
2632 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2633 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2634 ifp
->name
, ifp
->ifindex
, ifp
->mtu6
);
2637 ospf6_interface_stop(ifp
->info
);
2642 void ospf6_interface_init(void)
2644 /* Install interface node. */
2645 install_node(&interface_node
);
2647 if_zapi_callbacks(ospf6_ifp_create
, ospf6_ifp_up
,
2648 ospf6_ifp_down
, ospf6_ifp_destroy
);
2650 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
2651 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
2652 install_element(VIEW_NODE
,
2653 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
2654 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
2656 install_element(INTERFACE_NODE
, &ipv6_ospf6_area_cmd
);
2657 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_area_cmd
);
2658 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
2659 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
2660 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
2661 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
2663 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
2664 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
2665 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
2666 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
2667 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
2668 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
2669 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
2670 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
2671 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
2672 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
2673 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
2674 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
2676 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
2677 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
2679 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
2680 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
2682 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
2683 install_element(INTERFACE_NODE
,
2684 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
2686 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
2687 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
2689 /* reference bandwidth commands */
2690 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
2691 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
2692 /* write-multiplier commands */
2693 install_element(OSPF6_NODE
, &ospf6_write_multiplier_cmd
);
2694 install_element(OSPF6_NODE
, &no_ospf6_write_multiplier_cmd
);
2697 /* Clear the specified interface structure */
2698 void ospf6_interface_clear(struct interface
*ifp
)
2700 struct ospf6_interface
*oi
;
2702 if (!if_is_operative(ifp
))
2705 if (ifp
->info
== NULL
)
2708 oi
= (struct ospf6_interface
*)ifp
->info
;
2710 if (IS_OSPF6_DEBUG_INTERFACE
)
2711 zlog_debug("Interface %s: clear by reset", ifp
->name
);
2713 /* Reset the interface */
2714 thread_execute(master
, interface_down
, oi
, 0);
2715 thread_execute(master
, interface_up
, oi
, 0);
2718 /* Clear interface */
2719 DEFUN (clear_ipv6_ospf6_interface
,
2720 clear_ipv6_ospf6_interface_cmd
,
2721 "clear ipv6 ospf6 interface [IFNAME]",
2729 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2731 struct interface
*ifp
;
2733 if (argc
== 4) /* Clear all the ospfv3 interfaces. */
2735 FOR_ALL_INTERFACES (vrf
, ifp
)
2736 ospf6_interface_clear(ifp
);
2737 } else /* Interface name is specified. */
2739 if ((ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
2742 vty_out(vty
, "No such Interface: %s\n",
2743 argv
[idx_ifname
]->arg
);
2746 ospf6_interface_clear(ifp
);
2752 void install_element_ospf6_clear_interface(void)
2754 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2757 DEFUN (debug_ospf6_interface
,
2758 debug_ospf6_interface_cmd
,
2759 "debug ospf6 interface",
2762 "Debug OSPFv3 Interface\n"
2765 OSPF6_DEBUG_INTERFACE_ON();
2769 DEFUN (no_debug_ospf6_interface
,
2770 no_debug_ospf6_interface_cmd
,
2771 "no debug ospf6 interface",
2775 "Debug OSPFv3 Interface\n"
2778 OSPF6_DEBUG_INTERFACE_OFF();
2782 int config_write_ospf6_debug_interface(struct vty
*vty
)
2784 if (IS_OSPF6_DEBUG_INTERFACE
)
2785 vty_out(vty
, "debug ospf6 interface\n");
2789 void install_element_ospf6_debug_interface(void)
2791 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2792 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2793 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2794 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);