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
, CFG_PLIST_NAME
, "configured prefix list names")
49 DEFINE_QOBJ_TYPE(ospf6_interface
)
50 DEFINE_HOOK(ospf6_interface_change
,
51 (struct ospf6_interface
* oi
, int state
, int old_state
),
52 (oi
, state
, old_state
))
54 unsigned char conf_debug_ospf6_interface
= 0;
56 const char *const ospf6_interface_state_str
[] = {
57 "None", "Down", "Loopback", "Waiting", "PointToPoint",
58 "DROther", "BDR", "DR", NULL
};
60 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
,
63 struct ospf6_interface
*oi
;
64 struct interface
*ifp
;
66 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
68 return (struct ospf6_interface
*)NULL
;
70 oi
= (struct ospf6_interface
*)ifp
->info
;
74 /* schedule routing table recalculation */
75 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
78 struct ospf6_interface
*oi
;
84 switch (ntohs(lsa
->header
->type
)) {
85 case OSPF6_LSTYPE_LINK
:
86 if (oi
->state
== OSPF6_INTERFACE_DR
)
87 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
89 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
97 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
99 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
102 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
104 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
107 static uint8_t ospf6_default_iftype(struct interface
*ifp
)
109 if (if_is_pointopoint(ifp
))
110 return OSPF_IFTYPE_POINTOPOINT
;
111 else if (if_is_loopback(ifp
))
112 return OSPF_IFTYPE_LOOPBACK
;
114 return OSPF_IFTYPE_BROADCAST
;
117 static uint32_t ospf6_interface_get_cost(struct ospf6_interface
*oi
)
119 /* If all else fails, use default OSPF cost */
123 /* interface speed and bw can be 0 in some platforms,
124 * use ospf default bw. If bw is configured then it would
127 if (!oi
->interface
->bandwidth
&& oi
->interface
->speed
) {
128 bw
= oi
->interface
->speed
;
130 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
131 : OSPF6_INTERFACE_BANDWIDTH
;
134 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
135 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
137 /* A specifed ip ospf cost overrides a calculated one. */
138 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
141 cost
= (uint32_t)((double)refbw
/ (double)bw
+ (double)0.5);
144 else if (cost
> UINT32_MAX
)
151 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface
*oi
)
153 /* update cost held in route_connected list in ospf6_interface */
154 ospf6_interface_connected_route_update(oi
->interface
);
156 /* execute LSA hooks */
158 OSPF6_LINK_LSA_SCHEDULE(oi
);
159 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
160 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
161 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
162 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
166 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
170 newcost
= ospf6_interface_get_cost(oi
);
171 if (newcost
== oi
->cost
)
175 ospf6_interface_force_recalculate_cost(oi
);
178 /* Create new ospf6 interface structure */
179 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
181 struct ospf6_interface
*oi
;
182 unsigned int iobuflen
;
184 oi
= XCALLOC(MTYPE_OSPF6_IF
, sizeof(struct ospf6_interface
));
186 oi
->area
= (struct ospf6_area
*)NULL
;
187 oi
->neighbor_list
= list_new();
188 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
189 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
190 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
191 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
192 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
194 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
195 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
196 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
197 oi
->type
= ospf6_default_iftype(ifp
);
198 oi
->state
= OSPF6_INTERFACE_DOWN
;
203 /* Try to adjust I/O buffer size with IfMtu */
204 oi
->ifmtu
= ifp
->mtu6
;
205 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
206 if (oi
->ifmtu
> iobuflen
) {
207 if (IS_OSPF6_DEBUG_INTERFACE
)
209 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
210 ifp
->name
, iobuflen
);
211 oi
->ifmtu
= iobuflen
;
214 QOBJ_REG(oi
, ospf6_interface
);
216 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
217 oi
->lsack_list
= ospf6_lsdb_create(oi
);
218 oi
->lsdb
= ospf6_lsdb_create(oi
);
219 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
220 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
221 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
223 oi
->route_connected
=
224 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
225 oi
->route_connected
->scope
= oi
;
232 oi
->cost
= ospf6_interface_get_cost(oi
);
237 void ospf6_interface_delete(struct ospf6_interface
*oi
)
239 struct listnode
*node
, *nnode
;
240 struct ospf6_neighbor
*on
;
244 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
245 ospf6_neighbor_delete(on
);
247 list_delete(&oi
->neighbor_list
);
249 THREAD_OFF(oi
->thread_send_hello
);
250 THREAD_OFF(oi
->thread_send_lsupdate
);
251 THREAD_OFF(oi
->thread_send_lsack
);
252 THREAD_OFF(oi
->thread_sso
);
254 ospf6_lsdb_remove_all(oi
->lsdb
);
255 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
256 ospf6_lsdb_remove_all(oi
->lsack_list
);
258 ospf6_lsdb_delete(oi
->lsdb
);
259 ospf6_lsdb_delete(oi
->lsdb_self
);
261 ospf6_lsdb_delete(oi
->lsupdate_list
);
262 ospf6_lsdb_delete(oi
->lsack_list
);
264 ospf6_route_table_delete(oi
->route_connected
);
267 oi
->interface
->info
= NULL
;
271 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
273 ospf6_bfd_info_free(&(oi
->bfd_info
));
275 /* disable from area list if possible */
276 ospf6_area_interface_delete(oi
);
278 XFREE(MTYPE_OSPF6_IF
, oi
);
281 void ospf6_interface_enable(struct ospf6_interface
*oi
)
283 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
284 ospf6_interface_state_update(oi
->interface
);
287 void ospf6_interface_disable(struct ospf6_interface
*oi
)
289 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
291 thread_execute(master
, interface_down
, oi
, 0);
293 ospf6_lsdb_remove_all(oi
->lsdb
);
294 ospf6_lsdb_remove_all(oi
->lsdb_self
);
295 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
296 ospf6_lsdb_remove_all(oi
->lsack_list
);
298 THREAD_OFF(oi
->thread_send_hello
);
299 THREAD_OFF(oi
->thread_send_lsupdate
);
300 THREAD_OFF(oi
->thread_send_lsack
);
301 THREAD_OFF(oi
->thread_sso
);
303 THREAD_OFF(oi
->thread_network_lsa
);
304 THREAD_OFF(oi
->thread_link_lsa
);
305 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
306 THREAD_OFF(oi
->thread_as_extern_lsa
);
309 static struct in6_addr
*
310 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
314 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
316 /* for each connected address */
317 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
318 /* if family not AF_INET6, ignore */
319 if (c
->address
->family
!= AF_INET6
)
322 /* linklocal scope check */
323 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
324 l
= &c
->address
->u
.prefix6
;
329 void ospf6_interface_if_add(struct interface
*ifp
)
331 struct ospf6_interface
*oi
;
332 unsigned int iobuflen
;
334 oi
= (struct ospf6_interface
*)ifp
->info
;
338 /* Try to adjust I/O buffer size with IfMtu */
340 oi
->ifmtu
= ifp
->mtu6
;
341 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
342 if (oi
->ifmtu
> iobuflen
) {
343 if (IS_OSPF6_DEBUG_INTERFACE
)
345 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
346 ifp
->name
, iobuflen
);
347 oi
->ifmtu
= iobuflen
;
350 /* interface start */
351 ospf6_interface_state_update(oi
->interface
);
354 void ospf6_interface_state_update(struct interface
*ifp
)
356 struct ospf6_interface
*oi
;
357 unsigned int iobuflen
;
359 oi
= (struct ospf6_interface
*)ifp
->info
;
362 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
365 /* Adjust the mtu values if the kernel told us something new */
366 if (ifp
->mtu6
!= oi
->ifmtu
) {
367 /* If nothing configured, accept it and check for buffer size */
369 oi
->ifmtu
= ifp
->mtu6
;
370 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
371 if (oi
->ifmtu
> iobuflen
) {
372 if (IS_OSPF6_DEBUG_INTERFACE
)
374 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
375 ifp
->name
, iobuflen
);
376 oi
->ifmtu
= iobuflen
;
378 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
379 oi
->ifmtu
= ifp
->mtu6
;
381 "Configured mtu %u on %s overridden by kernel %u",
382 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
384 oi
->ifmtu
= oi
->c_ifmtu
;
387 if (if_is_operative(ifp
)
388 && (ospf6_interface_get_linklocal_address(oi
->interface
)
389 || if_is_loopback(oi
->interface
)))
390 thread_execute(master
, interface_up
, oi
, 0);
392 thread_execute(master
, interface_down
, oi
, 0);
397 void ospf6_interface_connected_route_update(struct interface
*ifp
)
399 struct ospf6_interface
*oi
;
400 struct ospf6_route
*route
;
402 struct listnode
*node
, *nnode
;
403 struct in6_addr nh_addr
;
405 oi
= (struct ospf6_interface
*)ifp
->info
;
409 /* reset linklocal pointer */
410 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
412 /* if area is null, do not make connected-route list */
413 if (oi
->area
== NULL
)
416 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
419 /* update "route to advertise" interface route table */
420 ospf6_route_remove_all(oi
->route_connected
);
422 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
423 if (c
->address
->family
!= AF_INET6
)
426 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
428 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
430 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
432 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
434 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
438 if (oi
->plist_name
) {
439 struct prefix_list
*plist
;
440 enum prefix_list_type ret
;
442 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
443 ret
= prefix_list_apply(plist
, (void *)c
->address
);
444 if (ret
== PREFIX_DENY
) {
445 if (IS_OSPF6_DEBUG_INTERFACE
)
447 "%pFX on %s filtered by prefix-list %s ",
448 c
->address
, oi
->interface
->name
,
454 route
= ospf6_route_create();
455 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
456 apply_mask(&route
->prefix
);
457 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
458 route
->path
.area_id
= oi
->area
->area_id
;
459 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
460 route
->path
.cost
= oi
->cost
;
461 inet_pton(AF_INET6
, "::1", &nh_addr
);
462 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
464 ospf6_route_add(route
, oi
->route_connected
);
467 /* create new Link-LSA */
468 OSPF6_LINK_LSA_SCHEDULE(oi
);
469 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
470 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
473 static void ospf6_interface_state_change(uint8_t next_state
,
474 struct ospf6_interface
*oi
)
479 prev_state
= oi
->state
;
480 oi
->state
= next_state
;
482 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
]);
493 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
495 if ((prev_state
== OSPF6_INTERFACE_DR
496 || prev_state
== OSPF6_INTERFACE_BDR
)
497 && (next_state
!= OSPF6_INTERFACE_DR
498 && next_state
!= OSPF6_INTERFACE_BDR
))
499 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
500 IPV6_LEAVE_GROUP
, ospf6
->fd
);
502 if ((prev_state
!= OSPF6_INTERFACE_DR
503 && prev_state
!= OSPF6_INTERFACE_BDR
)
504 && (next_state
== OSPF6_INTERFACE_DR
505 || next_state
== OSPF6_INTERFACE_BDR
))
506 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
507 IPV6_JOIN_GROUP
, ospf6
->fd
);
509 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
510 OSPF6_LINK_LSA_SCHEDULE(oi
);
511 if (next_state
== OSPF6_INTERFACE_DOWN
) {
512 OSPF6_NETWORK_LSA_EXECUTE(oi
);
513 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
514 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
515 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
516 } else if (prev_state
== OSPF6_INTERFACE_DR
517 || next_state
== OSPF6_INTERFACE_DR
) {
518 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
519 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
520 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
523 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
527 /* DR Election, RFC2328 section 9.4 */
529 #define IS_ELIGIBLE(n) \
530 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
532 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
533 struct ospf6_neighbor
*b
)
535 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
536 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
538 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
540 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
543 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
545 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
548 if (a
->priority
> b
->priority
)
550 if (a
->priority
< b
->priority
)
553 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
555 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
558 zlog_warn("Router-ID duplicate ?");
562 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
563 struct ospf6_neighbor
*b
)
565 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
566 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
568 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
570 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
573 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
575 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
578 if (a
->priority
> b
->priority
)
580 if (a
->priority
< b
->priority
)
583 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
585 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
588 zlog_warn("Router-ID duplicate ?");
592 static uint8_t dr_election(struct ospf6_interface
*oi
)
594 struct listnode
*node
, *nnode
;
595 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
596 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
597 uint8_t next_state
= 0;
599 drouter
= bdrouter
= NULL
;
600 best_drouter
= best_bdrouter
= NULL
;
602 /* pseudo neighbor myself, including noting current DR/BDR (1) */
603 memset(&myself
, 0, sizeof(myself
));
604 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
605 sizeof(myself
.name
));
606 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
607 myself
.drouter
= oi
->drouter
;
608 myself
.bdrouter
= oi
->bdrouter
;
609 myself
.priority
= oi
->priority
;
610 myself
.router_id
= oi
->area
->ospf6
->router_id
;
612 /* Electing BDR (2) */
613 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
614 bdrouter
= better_bdrouter(bdrouter
, on
);
616 best_bdrouter
= bdrouter
;
617 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
619 /* Electing DR (3) */
620 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
621 drouter
= better_drouter(drouter
, on
);
623 best_drouter
= drouter
;
624 drouter
= better_drouter(best_drouter
, &myself
);
628 /* the router itself is newly/no longer DR/BDR (4) */
629 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
630 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
631 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
632 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
633 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
634 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
636 /* compatible to Electing BDR (2) */
637 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
639 /* compatible to Electing DR (3) */
640 drouter
= better_drouter(best_drouter
, &myself
);
645 /* Set interface state accordingly (5) */
646 if (drouter
&& drouter
== &myself
)
647 next_state
= OSPF6_INTERFACE_DR
;
648 else if (bdrouter
&& bdrouter
== &myself
)
649 next_state
= OSPF6_INTERFACE_BDR
;
651 next_state
= OSPF6_INTERFACE_DROTHER
;
653 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
656 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
657 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
658 accordingly after AdjOK */
659 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
660 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
661 if (IS_OSPF6_DEBUG_INTERFACE
)
662 zlog_debug("DR Election on %s: DR: %s BDR: %s",
664 (drouter
? drouter
->name
: "0.0.0.0"),
665 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
667 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
668 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
670 /* Schedule AdjOK. */
671 thread_add_event(master
, adj_ok
, on
, 0, NULL
);
675 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
676 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
681 /* Interface State Machine */
682 int interface_up(struct thread
*thread
)
684 struct ospf6_interface
*oi
;
687 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
688 assert(oi
&& oi
->interface
);
691 oi
->type
= ospf6_default_iftype(oi
->interface
);
694 * Remove old pointer. If this thread wasn't a timer this
695 * operation won't make a difference, because it is already NULL.
697 oi
->thread_sso
= NULL
;
699 if (IS_OSPF6_DEBUG_INTERFACE
)
700 zlog_debug("Interface Event %s: [InterfaceUp]",
701 oi
->interface
->name
);
703 /* check physical interface is up */
704 if (!if_is_operative(oi
->interface
)) {
705 if (IS_OSPF6_DEBUG_INTERFACE
)
707 "Interface %s is down, can't execute [InterfaceUp]",
708 oi
->interface
->name
);
712 /* check interface has a link-local address */
713 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
714 || if_is_loopback(oi
->interface
))) {
715 if (IS_OSPF6_DEBUG_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 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
761 /* Join AllSPFRouters */
762 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
,
765 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
767 "Scheduling %s for sso retry, trial count: %d",
768 oi
->interface
->name
, oi
->sso_try_cnt
);
769 thread_add_timer(master
, interface_up
, oi
,
770 OSPF6_INTERFACE_SSO_RETRY_INT
,
775 oi
->sso_try_cnt
= 0; /* Reset on success */
777 /* Update interface route */
778 ospf6_interface_connected_route_update(oi
->interface
);
781 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
782 && !if_is_loopback(oi
->interface
)) {
783 oi
->thread_send_hello
= NULL
;
784 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
785 &oi
->thread_send_hello
);
788 /* decide next interface state */
789 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
790 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
791 } else if (oi
->priority
== 0)
792 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
794 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
795 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
802 int wait_timer(struct thread
*thread
)
804 struct ospf6_interface
*oi
;
806 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
807 assert(oi
&& oi
->interface
);
809 if (IS_OSPF6_DEBUG_INTERFACE
)
810 zlog_debug("Interface Event %s: [WaitTimer]",
811 oi
->interface
->name
);
813 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
814 ospf6_interface_state_change(dr_election(oi
), oi
);
819 int backup_seen(struct thread
*thread
)
821 struct ospf6_interface
*oi
;
823 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
824 assert(oi
&& oi
->interface
);
826 if (IS_OSPF6_DEBUG_INTERFACE
)
827 zlog_debug("Interface Event %s: [BackupSeen]",
828 oi
->interface
->name
);
830 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
831 ospf6_interface_state_change(dr_election(oi
), oi
);
836 int neighbor_change(struct thread
*thread
)
838 struct ospf6_interface
*oi
;
840 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
841 assert(oi
&& oi
->interface
);
843 if (IS_OSPF6_DEBUG_INTERFACE
)
844 zlog_debug("Interface Event %s: [NeighborChange]",
845 oi
->interface
->name
);
847 if (oi
->state
== OSPF6_INTERFACE_DROTHER
848 || oi
->state
== OSPF6_INTERFACE_BDR
849 || oi
->state
== OSPF6_INTERFACE_DR
)
850 ospf6_interface_state_change(dr_election(oi
), oi
);
855 int interface_down(struct thread
*thread
)
857 struct ospf6_interface
*oi
;
858 struct listnode
*node
, *nnode
;
859 struct ospf6_neighbor
*on
;
862 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
863 assert(oi
&& oi
->interface
);
865 if (IS_OSPF6_DEBUG_INTERFACE
)
866 zlog_debug("Interface Event %s: [InterfaceDown]",
867 oi
->interface
->name
);
870 THREAD_OFF(oi
->thread_send_hello
);
872 /* Stop trying to set socket options. */
873 THREAD_OFF(oi
->thread_sso
);
874 ospf6
= ospf6_lookup_by_vrf_id(oi
->interface
->vrf_id
);
875 /* Leave AllSPFRouters */
876 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
877 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
878 IPV6_LEAVE_GROUP
, ospf6
->fd
);
880 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
882 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
883 ospf6_neighbor_delete(on
);
885 list_delete_all_node(oi
->neighbor_list
);
887 /* When interface state is reset, also reset information about
888 * DR election, as it is no longer valid. */
889 oi
->drouter
= oi
->prev_drouter
= htonl(0);
890 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
895 static const char *ospf6_iftype_str(uint8_t iftype
)
898 case OSPF_IFTYPE_LOOPBACK
:
900 case OSPF_IFTYPE_BROADCAST
:
902 case OSPF_IFTYPE_POINTOPOINT
:
903 return "POINTOPOINT";
908 /* show specified interface structure */
909 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
,
910 json_object
*json_obj
, bool use_json
)
912 struct ospf6_interface
*oi
;
916 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
917 uint8_t default_iftype
;
918 struct timeval res
, now
;
920 struct ospf6_lsa
*lsa
, *lsanext
;
921 json_object
*json_arr
;
922 json_object
*json_addr
;
924 default_iftype
= ospf6_default_iftype(ifp
);
927 json_object_string_add(json_obj
, "status",
928 (if_is_operative(ifp
) ? "up" : "down"));
929 json_object_string_add(json_obj
, "type",
930 ospf6_iftype_str(default_iftype
));
931 json_object_int_add(json_obj
, "interfaceId", ifp
->ifindex
);
933 if (ifp
->info
== NULL
) {
934 json_object_boolean_false_add(json_obj
, "ospf6Enabled");
937 json_object_boolean_true_add(json_obj
, "ospf6Enabled");
939 oi
= (struct ospf6_interface
*)ifp
->info
;
941 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
942 json_object_string_add(json_obj
, "operatingAsType",
943 ospf6_iftype_str(oi
->type
));
946 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
947 (if_is_operative(ifp
) ? "up" : "down"),
948 ospf6_iftype_str(default_iftype
));
949 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
951 if (ifp
->info
== NULL
) {
952 vty_out(vty
, " OSPF not enabled on this interface\n");
955 oi
= (struct ospf6_interface
*)ifp
->info
;
957 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
958 vty_out(vty
, " Operating as type %s\n",
959 ospf6_iftype_str(oi
->type
));
963 json_arr
= json_object_new_array();
964 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
965 json_addr
= json_object_new_object();
967 prefix2str(p
, strbuf
, sizeof(strbuf
));
970 json_object_string_add(json_addr
, "type",
972 json_object_string_add(json_addr
, "address",
974 json_object_array_add(json_arr
, json_addr
);
977 json_object_string_add(json_addr
, "type",
979 json_object_string_add(json_addr
, "address",
981 json_object_array_add(json_arr
, json_addr
);
984 json_object_string_add(json_addr
, "type",
986 json_object_string_add(json_addr
, "address",
988 json_object_array_add(json_arr
, json_addr
);
992 json_object_object_add(json_obj
, "internetAddress", json_arr
);
994 vty_out(vty
, " Internet Address:\n");
996 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
998 prefix2str(p
, strbuf
, sizeof(strbuf
));
1001 vty_out(vty
, " inet : %pFX\n", p
);
1004 vty_out(vty
, " inet6: %pFX\n", p
);
1007 vty_out(vty
, " ??? : %pFX\n", p
);
1015 json_object_boolean_true_add(json_obj
,
1017 json_object_int_add(json_obj
, "instanceId",
1019 json_object_int_add(json_obj
, "interfaceMtu",
1021 json_object_int_add(json_obj
, "autoDetect", ifp
->mtu6
);
1022 json_object_string_add(json_obj
, "mtuMismatchDetection",
1023 oi
->mtu_ignore
? "disabled"
1025 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1027 json_object_string_add(json_obj
, "areaId", strbuf
);
1028 json_object_int_add(json_obj
, "cost", oi
->cost
);
1030 json_object_boolean_false_add(json_obj
,
1036 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1037 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
1038 vty_out(vty
, " MTU mismatch detection: %s\n",
1039 oi
->mtu_ignore
? "disabled" : "enabled");
1040 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1042 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
,
1045 vty_out(vty
, " Not Attached to Area\n");
1049 json_object_string_add(json_obj
, "ospf6InterfaceState",
1050 ospf6_interface_state_str
[oi
->state
]);
1051 json_object_int_add(json_obj
, "transmitDelaySec",
1053 json_object_int_add(json_obj
, "priority", oi
->priority
);
1054 json_object_int_add(json_obj
, "timerIntervalsConfigHello",
1055 oi
->hello_interval
);
1056 json_object_int_add(json_obj
, "timerIntervalsConfigDead",
1058 json_object_int_add(json_obj
, "timerIntervalsConfigRetransmit",
1061 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
1062 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
1064 vty_out(vty
, " Timer intervals configured:\n");
1065 vty_out(vty
, " Hello %d, Dead %d, Retransmit %d\n",
1066 oi
->hello_interval
, oi
->dead_interval
,
1070 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
1071 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
1073 json_object_string_add(json_obj
, "dr", drouter
);
1074 json_object_string_add(json_obj
, "bdr", bdrouter
);
1075 json_object_int_add(json_obj
, "numberOfInterfaceScopedLsa",
1078 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
1079 vty_out(vty
, " Number of I/F scoped LSAs is %u\n",
1087 if (oi
->thread_send_lsupdate
)
1088 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1090 timerstring(&res
, duration
, sizeof(duration
));
1091 json_object_int_add(json_obj
, "pendingLsaLsUpdateCount",
1092 oi
->lsupdate_list
->count
);
1093 json_object_string_add(json_obj
, "pendingLsaLsUpdateTime",
1095 json_object_string_add(
1096 json_obj
, "lsUpdateSendThread",
1097 (oi
->thread_send_lsupdate
? "on" : "off"));
1099 json_arr
= json_object_new_array();
1100 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1101 json_object_array_add(
1102 json_arr
, json_object_new_string(lsa
->name
));
1103 json_object_object_add(json_obj
, "pendingLsaLsUpdate",
1107 if (oi
->thread_send_lsack
)
1108 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1109 timerstring(&res
, duration
, sizeof(duration
));
1111 json_object_int_add(json_obj
, "pendingLsaLsAckCount",
1112 oi
->lsack_list
->count
);
1113 json_object_string_add(json_obj
, "pendingLsaLsAckTime",
1115 json_object_string_add(json_obj
, "lsAckSendThread",
1116 (oi
->thread_send_lsack
? "on" : "off"));
1118 json_arr
= json_object_new_array();
1119 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1120 json_object_array_add(
1121 json_arr
, json_object_new_string(lsa
->name
));
1122 json_object_object_add(json_obj
, "pendingLsaLsAck", json_arr
);
1126 if (oi
->thread_send_lsupdate
)
1127 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1129 timerstring(&res
, duration
, sizeof(duration
));
1131 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1132 oi
->lsupdate_list
->count
, duration
,
1133 (oi
->thread_send_lsupdate
? "on" : "off"));
1134 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1135 vty_out(vty
, " %s\n", lsa
->name
);
1138 if (oi
->thread_send_lsack
)
1139 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1140 timerstring(&res
, duration
, sizeof(duration
));
1142 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1143 oi
->lsack_list
->count
, duration
,
1144 (oi
->thread_send_lsack
? "on" : "off"));
1145 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1146 vty_out(vty
, " %s\n", lsa
->name
);
1148 ospf6_bfd_show_info(vty
, oi
->bfd_info
, 1, json_obj
, use_json
);
1152 /* show interface */
1153 DEFUN(show_ipv6_ospf6_interface
,
1154 show_ipv6_ospf6_interface_ifname_cmd
,
1155 "show ipv6 ospf6 interface [IFNAME] [json]",
1163 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1165 struct interface
*ifp
;
1167 json_object
*json_int
;
1168 bool uj
= use_json(argc
, argv
);
1171 json
= json_object_new_object();
1173 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1175 json_int
= json_object_new_object();
1177 json_object_string_add(json
, "noSuchInterface",
1178 argv
[idx_ifname
]->arg
);
1179 vty_out(vty
, "%s\n",
1180 json_object_to_json_string_ext(
1181 json
, JSON_C_TO_STRING_PRETTY
));
1182 json_object_free(json
);
1183 json_object_free(json_int
);
1186 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1187 json_object_object_add(json
, ifp
->name
, json_int
);
1189 FOR_ALL_INTERFACES (vrf
, ifp
) {
1190 json_int
= json_object_new_object();
1191 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1192 json_object_object_add(json
, ifp
->name
,
1196 vty_out(vty
, "%s\n",
1197 json_object_to_json_string_ext(
1198 json
, JSON_C_TO_STRING_PRETTY
));
1199 json_object_free(json
);
1202 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1205 vty_out(vty
, "No such Interface: %s\n",
1206 argv
[idx_ifname
]->arg
);
1209 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1211 FOR_ALL_INTERFACES (vrf
, ifp
)
1212 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1219 static int ospf6_interface_show_traffic(struct vty
*vty
,
1220 struct interface
*intf_ifp
,
1221 int display_once
, json_object
*json
,
1224 struct interface
*ifp
;
1225 struct vrf
*vrf
= NULL
;
1226 struct ospf6_interface
*oi
= NULL
;
1227 json_object
*json_interface
;
1230 vrf
= vrf_lookup_by_id(intf_ifp
->vrf_id
);
1232 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1234 if (!display_once
&& !use_json
) {
1236 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1237 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1239 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1240 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1243 "--------------------------------------------------------------------------------------------\n");
1246 if (intf_ifp
== NULL
) {
1247 FOR_ALL_INTERFACES (vrf
, ifp
) {
1249 oi
= (struct ospf6_interface
*)ifp
->info
;
1254 json_interface
= json_object_new_object();
1255 json_object_int_add(json_interface
, "helloRx",
1257 json_object_int_add(json_interface
, "helloTx",
1259 json_object_int_add(json_interface
, "dbDescRx",
1261 json_object_int_add(json_interface
, "dbDescTx",
1263 json_object_int_add(json_interface
, "lsReqRx",
1265 json_object_int_add(json_interface
, "lsReqTx",
1267 json_object_int_add(json_interface
,
1270 json_object_int_add(json_interface
,
1273 json_object_int_add(json_interface
, "lsAckRx",
1275 json_object_int_add(json_interface
, "lsAckTx",
1278 json_object_object_add(json
,
1279 oi
->interface
->name
,
1283 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1284 oi
->interface
->name
, oi
->hello_in
,
1285 oi
->hello_out
, oi
->db_desc_in
,
1286 oi
->db_desc_out
, oi
->ls_req_in
,
1287 oi
->ls_req_out
, oi
->ls_upd_in
,
1288 oi
->ls_upd_out
, oi
->ls_ack_in
,
1292 oi
= intf_ifp
->info
;
1297 json_interface
= json_object_new_object();
1298 json_object_int_add(json_interface
, "helloRx",
1300 json_object_int_add(json_interface
, "helloTx",
1302 json_object_int_add(json_interface
, "dbDescRx",
1304 json_object_int_add(json_interface
, "dbDescTx",
1306 json_object_int_add(json_interface
, "lsReqRx",
1308 json_object_int_add(json_interface
, "lsReqTx",
1310 json_object_int_add(json_interface
, "lsUpdateRx",
1312 json_object_int_add(json_interface
, "lsUpdateTx",
1314 json_object_int_add(json_interface
, "lsAckRx",
1316 json_object_int_add(json_interface
, "lsAckTx",
1319 json_object_object_add(json
, oi
->interface
->name
,
1323 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1324 oi
->interface
->name
, oi
->hello_in
,
1325 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1326 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1327 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1333 /* show interface */
1334 DEFUN(show_ipv6_ospf6_interface_traffic
,
1335 show_ipv6_ospf6_interface_traffic_cmd
,
1336 "show ipv6 ospf6 interface traffic [IFNAME] [json]",
1341 "Protocol Packet counters\n"
1346 int display_once
= 0;
1347 char *intf_name
= NULL
;
1348 struct interface
*ifp
= NULL
;
1349 json_object
*json
= NULL
;
1350 bool uj
= use_json(argc
, argv
);
1353 json
= json_object_new_object();
1355 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1356 intf_name
= argv
[idx_ifname
]->arg
;
1357 ifp
= if_lookup_by_name(intf_name
, VRF_DEFAULT
);
1360 json_object_string_add(json
, "status",
1361 "No Such Interface");
1362 json_object_string_add(json
, "interface",
1364 vty_out(vty
, "%s\n",
1365 json_object_to_json_string_ext(
1366 json
, JSON_C_TO_STRING_PRETTY
));
1367 json_object_free(json
);
1370 if (ifp
->info
== NULL
) {
1371 json_object_string_add(
1373 "OSPF not enabled on this interface");
1374 json_object_string_add(json
, "interface",
1376 vty_out(vty
, "%s\n",
1377 json_object_to_json_string_ext(
1378 json
, JSON_C_TO_STRING_PRETTY
));
1379 json_object_free(json
);
1384 vty_out(vty
, "No such Interface: %s\n",
1388 if (ifp
->info
== NULL
) {
1390 " OSPF not enabled on this interface %s\n",
1397 ospf6_interface_show_traffic(vty
, ifp
, display_once
, json
, uj
);
1400 vty_out(vty
, "%s\n",
1401 json_object_to_json_string_ext(
1402 json
, JSON_C_TO_STRING_PRETTY
));
1403 json_object_free(json
);
1411 DEFUN (show_ipv6_ospf6_interface_ifname_prefix
,
1412 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1413 "show ipv6 ospf6 interface IFNAME prefix\
1416 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1423 "Display connected prefixes to advertise\n"
1424 "Display details of the prefixes\n"
1425 OSPF6_ROUTE_ADDRESS_STR
1426 OSPF6_ROUTE_PREFIX_STR
1427 OSPF6_ROUTE_MATCH_STR
1428 "Display details of the prefixes\n")
1432 struct interface
*ifp
;
1433 struct ospf6_interface
*oi
;
1435 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
1437 vty_out(vty
, "No such Interface: %s\n", argv
[idx_ifname
]->arg
);
1443 vty_out(vty
, "OSPFv3 is not enabled on %s\n",
1444 argv
[idx_ifname
]->arg
);
1448 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1449 oi
->route_connected
);
1454 DEFUN (show_ipv6_ospf6_interface_prefix
,
1455 show_ipv6_ospf6_interface_prefix_cmd
,
1456 "show ipv6 ospf6 interface prefix\
1459 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1465 "Display connected prefixes to advertise\n"
1466 "Display details of the prefixes\n"
1467 OSPF6_ROUTE_ADDRESS_STR
1468 OSPF6_ROUTE_PREFIX_STR
1469 OSPF6_ROUTE_MATCH_STR
1470 "Display details of the prefixes\n")
1472 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1474 struct ospf6_interface
*oi
;
1475 struct interface
*ifp
;
1477 FOR_ALL_INTERFACES (vrf
, ifp
) {
1478 oi
= (struct ospf6_interface
*)ifp
->info
;
1482 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1483 oi
->route_connected
);
1489 /* interface variable set command */
1490 DEFUN (ipv6_ospf6_ifmtu
,
1491 ipv6_ospf6_ifmtu_cmd
,
1492 "ipv6 ospf6 ifmtu (1-65535)",
1496 "OSPFv3 Interface MTU\n"
1499 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1501 struct ospf6_interface
*oi
;
1502 unsigned int ifmtu
, iobuflen
;
1503 struct listnode
*node
, *nnode
;
1504 struct ospf6_neighbor
*on
;
1508 oi
= (struct ospf6_interface
*)ifp
->info
;
1510 oi
= ospf6_interface_create(ifp
);
1513 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1515 if (oi
->c_ifmtu
== ifmtu
)
1518 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1520 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1521 ifp
->name
, ifp
->mtu6
);
1522 return CMD_WARNING_CONFIG_FAILED
;
1525 if (oi
->ifmtu
< ifmtu
) {
1526 iobuflen
= ospf6_iobuf_size(ifmtu
);
1527 if (iobuflen
< ifmtu
) {
1529 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1530 ifp
->name
, iobuflen
);
1531 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1533 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1535 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1537 /* re-establish adjacencies */
1538 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1539 THREAD_OFF(on
->inactivity_timer
);
1540 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1546 DEFUN (no_ipv6_ospf6_ifmtu
,
1547 no_ipv6_ospf6_ifmtu_cmd
,
1548 "no ipv6 ospf6 ifmtu [(1-65535)]",
1553 "OSPFv3 Interface MTU\n"
1556 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1557 struct ospf6_interface
*oi
;
1558 unsigned int iobuflen
;
1559 struct listnode
*node
, *nnode
;
1560 struct ospf6_neighbor
*on
;
1564 oi
= (struct ospf6_interface
*)ifp
->info
;
1566 oi
= ospf6_interface_create(ifp
);
1569 if (oi
->ifmtu
< ifp
->mtu
) {
1570 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1571 if (iobuflen
< ifp
->mtu
) {
1573 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1574 ifp
->name
, iobuflen
);
1575 oi
->ifmtu
= iobuflen
;
1577 oi
->ifmtu
= ifp
->mtu
;
1579 oi
->ifmtu
= ifp
->mtu
;
1583 /* re-establish adjacencies */
1584 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1585 THREAD_OFF(on
->inactivity_timer
);
1586 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1592 DEFUN (ipv6_ospf6_cost
,
1593 ipv6_ospf6_cost_cmd
,
1594 "ipv6 ospf6 cost (1-65535)",
1598 "Outgoing metric of this interface\n")
1600 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1602 struct ospf6_interface
*oi
;
1603 unsigned long int lcost
;
1607 oi
= (struct ospf6_interface
*)ifp
->info
;
1609 oi
= ospf6_interface_create(ifp
);
1612 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1614 if (lcost
> UINT32_MAX
) {
1615 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1616 return CMD_WARNING_CONFIG_FAILED
;
1619 if (oi
->cost
== lcost
)
1623 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1625 ospf6_interface_force_recalculate_cost(oi
);
1630 DEFUN (no_ipv6_ospf6_cost
,
1631 no_ipv6_ospf6_cost_cmd
,
1632 "no ipv6 ospf6 cost [(1-65535)]",
1636 "Calculate interface cost from bandwidth\n"
1637 "Outgoing metric of this interface\n")
1639 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1640 struct ospf6_interface
*oi
;
1643 oi
= (struct ospf6_interface
*)ifp
->info
;
1645 oi
= ospf6_interface_create(ifp
);
1648 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1650 ospf6_interface_recalculate_cost(oi
);
1655 DEFUN (auto_cost_reference_bandwidth
,
1656 auto_cost_reference_bandwidth_cmd
,
1657 "auto-cost reference-bandwidth (1-4294967)",
1658 "Calculate OSPF interface cost according to bandwidth\n"
1659 "Use reference bandwidth method to assign OSPF cost\n"
1660 "The reference bandwidth in terms of Mbits per second\n")
1662 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1664 struct ospf6_area
*oa
;
1665 struct ospf6_interface
*oi
;
1666 struct listnode
*i
, *j
;
1669 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1670 if (refbw
< 1 || refbw
> 4294967) {
1671 vty_out(vty
, "reference-bandwidth value is invalid\n");
1672 return CMD_WARNING_CONFIG_FAILED
;
1675 /* If reference bandwidth is changed. */
1676 if ((refbw
) == o
->ref_bandwidth
)
1679 o
->ref_bandwidth
= refbw
;
1680 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1681 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1682 ospf6_interface_recalculate_cost(oi
);
1687 DEFUN (no_auto_cost_reference_bandwidth
,
1688 no_auto_cost_reference_bandwidth_cmd
,
1689 "no auto-cost reference-bandwidth [(1-4294967)]",
1691 "Calculate OSPF interface cost according to bandwidth\n"
1692 "Use reference bandwidth method to assign OSPF cost\n"
1693 "The reference bandwidth in terms of Mbits per second\n")
1695 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1696 struct ospf6_area
*oa
;
1697 struct ospf6_interface
*oi
;
1698 struct listnode
*i
, *j
;
1700 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
1703 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
1704 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1705 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1706 ospf6_interface_recalculate_cost(oi
);
1712 DEFUN (ipv6_ospf6_hellointerval
,
1713 ipv6_ospf6_hellointerval_cmd
,
1714 "ipv6 ospf6 hello-interval (1-65535)",
1717 "Time between HELLO packets\n"
1720 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1722 struct ospf6_interface
*oi
;
1725 oi
= (struct ospf6_interface
*)ifp
->info
;
1727 oi
= ospf6_interface_create(ifp
);
1730 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
1731 ? OSPF_HELLO_INTERVAL_DEFAULT
1732 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1736 ALIAS (ipv6_ospf6_hellointerval
,
1737 no_ipv6_ospf6_hellointerval_cmd
,
1738 "no ipv6 ospf6 hello-interval [(1-65535)]",
1742 "Time between HELLO packets\n"
1745 /* interface variable set command */
1746 DEFUN (ipv6_ospf6_deadinterval
,
1747 ipv6_ospf6_deadinterval_cmd
,
1748 "ipv6 ospf6 dead-interval (1-65535)",
1751 "Interval time after which a neighbor is declared down\n"
1754 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1756 struct ospf6_interface
*oi
;
1759 oi
= (struct ospf6_interface
*)ifp
->info
;
1761 oi
= ospf6_interface_create(ifp
);
1764 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
1765 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1766 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1770 ALIAS (ipv6_ospf6_deadinterval
,
1771 no_ipv6_ospf6_deadinterval_cmd
,
1772 "no ipv6 ospf6 dead-interval [(1-65535)]",
1776 "Interval time after which a neighbor is declared down\n"
1779 /* interface variable set command */
1780 DEFUN (ipv6_ospf6_transmitdelay
,
1781 ipv6_ospf6_transmitdelay_cmd
,
1782 "ipv6 ospf6 transmit-delay (1-3600)",
1785 "Link state transmit delay\n"
1788 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1790 struct ospf6_interface
*oi
;
1793 oi
= (struct ospf6_interface
*)ifp
->info
;
1795 oi
= ospf6_interface_create(ifp
);
1798 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
1799 ? OSPF6_INTERFACE_TRANSDELAY
1800 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1804 ALIAS (ipv6_ospf6_transmitdelay
,
1805 no_ipv6_ospf6_transmitdelay_cmd
,
1806 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1810 "Link state transmit delay\n"
1813 /* interface variable set command */
1814 DEFUN (ipv6_ospf6_retransmitinterval
,
1815 ipv6_ospf6_retransmitinterval_cmd
,
1816 "ipv6 ospf6 retransmit-interval (1-65535)",
1819 "Time between retransmitting lost link state advertisements\n"
1822 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1824 struct ospf6_interface
*oi
;
1827 oi
= (struct ospf6_interface
*)ifp
->info
;
1829 oi
= ospf6_interface_create(ifp
);
1832 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
1833 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1834 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1838 ALIAS (ipv6_ospf6_retransmitinterval
,
1839 no_ipv6_ospf6_retransmitinterval_cmd
,
1840 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1844 "Time between retransmitting lost link state advertisements\n"
1847 /* interface variable set command */
1848 DEFUN (ipv6_ospf6_priority
,
1849 ipv6_ospf6_priority_cmd
,
1850 "ipv6 ospf6 priority (0-255)",
1856 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1858 struct ospf6_interface
*oi
;
1861 oi
= (struct ospf6_interface
*)ifp
->info
;
1863 oi
= ospf6_interface_create(ifp
);
1866 oi
->priority
= strmatch(argv
[0]->text
, "no")
1867 ? OSPF6_INTERFACE_PRIORITY
1868 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1870 if (oi
->area
&& (oi
->state
== OSPF6_INTERFACE_DROTHER
1871 || oi
->state
== OSPF6_INTERFACE_BDR
1872 || oi
->state
== OSPF6_INTERFACE_DR
))
1873 ospf6_interface_state_change(dr_election(oi
), oi
);
1878 ALIAS (ipv6_ospf6_priority
,
1879 no_ipv6_ospf6_priority_cmd
,
1880 "no ipv6 ospf6 priority [(0-255)]",
1887 DEFUN (ipv6_ospf6_instance
,
1888 ipv6_ospf6_instance_cmd
,
1889 "ipv6 ospf6 instance-id (0-255)",
1892 "Instance ID for this interface\n"
1893 "Instance ID value\n")
1895 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1897 struct ospf6_interface
*oi
;
1900 oi
= (struct ospf6_interface
*)ifp
->info
;
1902 oi
= ospf6_interface_create(ifp
);
1905 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
1906 ? OSPF6_INTERFACE_INSTANCE_ID
1907 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1911 ALIAS (ipv6_ospf6_instance
,
1912 no_ipv6_ospf6_instance_cmd
,
1913 "no ipv6 ospf6 instance-id [(0-255)]",
1917 "Instance ID for this interface\n"
1918 "Instance ID value\n")
1920 DEFUN (ipv6_ospf6_passive
,
1921 ipv6_ospf6_passive_cmd
,
1922 "ipv6 ospf6 passive",
1925 "Passive interface; no adjacency will be formed on this interface\n"
1928 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1929 struct ospf6_interface
*oi
;
1930 struct listnode
*node
, *nnode
;
1931 struct ospf6_neighbor
*on
;
1935 oi
= (struct ospf6_interface
*)ifp
->info
;
1937 oi
= ospf6_interface_create(ifp
);
1940 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1941 THREAD_OFF(oi
->thread_send_hello
);
1942 THREAD_OFF(oi
->thread_sso
);
1944 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1945 THREAD_OFF(on
->inactivity_timer
);
1946 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1952 DEFUN (no_ipv6_ospf6_passive
,
1953 no_ipv6_ospf6_passive_cmd
,
1954 "no ipv6 ospf6 passive",
1958 "passive interface: No Adjacency will be formed on this I/F\n"
1961 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1962 struct ospf6_interface
*oi
;
1965 oi
= (struct ospf6_interface
*)ifp
->info
;
1967 oi
= ospf6_interface_create(ifp
);
1970 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1971 THREAD_OFF(oi
->thread_send_hello
);
1972 THREAD_OFF(oi
->thread_sso
);
1973 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
1974 &oi
->thread_send_hello
);
1979 DEFUN (ipv6_ospf6_mtu_ignore
,
1980 ipv6_ospf6_mtu_ignore_cmd
,
1981 "ipv6 ospf6 mtu-ignore",
1984 "Disable MTU mismatch detection on this interface\n"
1987 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1988 struct ospf6_interface
*oi
;
1991 oi
= (struct ospf6_interface
*)ifp
->info
;
1993 oi
= ospf6_interface_create(ifp
);
2001 DEFUN (no_ipv6_ospf6_mtu_ignore
,
2002 no_ipv6_ospf6_mtu_ignore_cmd
,
2003 "no ipv6 ospf6 mtu-ignore",
2007 "Disable MTU mismatch detection on this interface\n"
2010 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2011 struct ospf6_interface
*oi
;
2014 oi
= (struct ospf6_interface
*)ifp
->info
;
2016 oi
= ospf6_interface_create(ifp
);
2024 DEFUN (ipv6_ospf6_advertise_prefix_list
,
2025 ipv6_ospf6_advertise_prefix_list_cmd
,
2026 "ipv6 ospf6 advertise prefix-list WORD",
2029 "Advertising options\n"
2030 "Filter prefix using prefix-list\n"
2031 "Prefix list name\n"
2034 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2036 struct ospf6_interface
*oi
;
2039 oi
= (struct ospf6_interface
*)ifp
->info
;
2041 oi
= ospf6_interface_create(ifp
);
2045 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2046 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
2048 ospf6_interface_connected_route_update(oi
->interface
);
2051 OSPF6_LINK_LSA_SCHEDULE(oi
);
2052 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2053 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2054 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2056 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2062 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
2063 no_ipv6_ospf6_advertise_prefix_list_cmd
,
2064 "no ipv6 ospf6 advertise prefix-list [WORD]",
2068 "Advertising options\n"
2069 "Filter prefix using prefix-list\n"
2070 "Prefix list name\n")
2072 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2073 struct ospf6_interface
*oi
;
2076 oi
= (struct ospf6_interface
*)ifp
->info
;
2078 oi
= ospf6_interface_create(ifp
);
2082 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2084 ospf6_interface_connected_route_update(oi
->interface
);
2087 OSPF6_LINK_LSA_SCHEDULE(oi
);
2088 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2089 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2090 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2092 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2098 DEFUN (ipv6_ospf6_network
,
2099 ipv6_ospf6_network_cmd
,
2100 "ipv6 ospf6 network <broadcast|point-to-point>",
2104 "Specify OSPF6 broadcast network\n"
2105 "Specify OSPF6 point-to-point network\n"
2108 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2109 int idx_network
= 3;
2110 struct ospf6_interface
*oi
;
2113 oi
= (struct ospf6_interface
*)ifp
->info
;
2115 oi
= ospf6_interface_create(ifp
);
2119 oi
->type_cfg
= true;
2121 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
2122 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
2125 oi
->type
= OSPF_IFTYPE_BROADCAST
;
2126 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
2127 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
2130 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
2133 /* Reset the interface */
2134 thread_execute(master
, interface_down
, oi
, 0);
2135 thread_execute(master
, interface_up
, oi
, 0);
2140 DEFUN (no_ipv6_ospf6_network
,
2141 no_ipv6_ospf6_network_cmd
,
2142 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2146 "Set default network type\n"
2147 "Specify OSPF6 broadcast network\n"
2148 "Specify OSPF6 point-to-point network\n")
2150 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2151 struct ospf6_interface
*oi
;
2156 oi
= (struct ospf6_interface
*)ifp
->info
;
2161 oi
->type_cfg
= false;
2163 type
= ospf6_default_iftype(ifp
);
2164 if (oi
->type
== type
) {
2169 /* Reset the interface */
2170 thread_execute(master
, interface_down
, oi
, 0);
2171 thread_execute(master
, interface_up
, oi
, 0);
2176 static int config_write_ospf6_interface(struct vty
*vty
)
2178 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2179 struct ospf6_interface
*oi
;
2180 struct interface
*ifp
;
2182 FOR_ALL_INTERFACES (vrf
, ifp
) {
2183 oi
= (struct ospf6_interface
*)ifp
->info
;
2187 vty_frame(vty
, "interface %s\n", oi
->interface
->name
);
2190 vty_out(vty
, " description %s\n", ifp
->desc
);
2192 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
2194 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
2195 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
2197 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
2198 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
2199 oi
->hello_interval
);
2201 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
2202 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
2205 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
2206 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
2209 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
2210 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
2212 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
2213 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
2216 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
2217 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
2221 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
2224 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
2225 vty_out(vty
, " ipv6 ospf6 passive\n");
2228 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
2230 if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
2231 vty_out(vty
, " ipv6 ospf6 network point-to-point\n");
2232 else if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_BROADCAST
)
2233 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
2235 ospf6_bfd_write_config(vty
, oi
);
2237 vty_endframe(vty
, "!\n");
2242 static int config_write_ospf6_interface(struct vty
*vty
);
2243 static struct cmd_node interface_node
= {
2244 .name
= "interface",
2245 .node
= INTERFACE_NODE
,
2246 .parent_node
= CONFIG_NODE
,
2247 .prompt
= "%s(config-if)# ",
2248 .config_write
= config_write_ospf6_interface
,
2251 static int ospf6_ifp_create(struct interface
*ifp
)
2253 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2254 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp
->name
,
2255 ifp
->ifindex
, ifp
->mtu6
);
2256 ospf6_interface_if_add(ifp
);
2261 static int ospf6_ifp_up(struct interface
*ifp
)
2263 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2265 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2266 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2267 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2269 ospf6_interface_state_update(ifp
);
2274 static int ospf6_ifp_down(struct interface
*ifp
)
2276 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2278 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2279 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2280 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2282 ospf6_interface_state_update(ifp
);
2287 static int ospf6_ifp_destroy(struct interface
*ifp
)
2290 zlog_warn("Zebra: got delete of %s, but interface is still up",
2293 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2294 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2295 ifp
->name
, ifp
->ifindex
, ifp
->mtu6
);
2300 void ospf6_interface_init(void)
2302 /* Install interface node. */
2303 install_node(&interface_node
);
2305 if_zapi_callbacks(ospf6_ifp_create
, ospf6_ifp_up
,
2306 ospf6_ifp_down
, ospf6_ifp_destroy
);
2308 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
2309 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
2310 install_element(VIEW_NODE
,
2311 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
2312 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
2314 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
2315 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
2316 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
2317 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
2319 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
2320 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
2321 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
2322 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
2323 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
2324 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
2325 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
2326 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
2327 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
2328 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
2329 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
2330 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
2332 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
2333 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
2335 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
2336 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
2338 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
2339 install_element(INTERFACE_NODE
,
2340 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
2342 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
2343 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
2345 /* reference bandwidth commands */
2346 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
2347 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
2350 /* Clear the specified interface structure */
2351 static void ospf6_interface_clear(struct vty
*vty
, struct interface
*ifp
)
2353 struct ospf6_interface
*oi
;
2355 if (!if_is_operative(ifp
))
2358 if (ifp
->info
== NULL
)
2361 oi
= (struct ospf6_interface
*)ifp
->info
;
2363 if (IS_OSPF6_DEBUG_INTERFACE
)
2364 zlog_debug("Interface %s: clear by reset", ifp
->name
);
2366 /* Reset the interface */
2367 thread_execute(master
, interface_down
, oi
, 0);
2368 thread_execute(master
, interface_up
, oi
, 0);
2371 /* Clear interface */
2372 DEFUN (clear_ipv6_ospf6_interface
,
2373 clear_ipv6_ospf6_interface_cmd
,
2374 "clear ipv6 ospf6 interface [IFNAME]",
2382 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2384 struct interface
*ifp
;
2386 if (argc
== 4) /* Clear all the ospfv3 interfaces. */
2388 FOR_ALL_INTERFACES (vrf
, ifp
)
2389 ospf6_interface_clear(vty
, ifp
);
2390 } else /* Interface name is specified. */
2392 if ((ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
2395 vty_out(vty
, "No such Interface: %s\n",
2396 argv
[idx_ifname
]->arg
);
2399 ospf6_interface_clear(vty
, ifp
);
2405 void install_element_ospf6_clear_interface(void)
2407 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2410 DEFUN (debug_ospf6_interface
,
2411 debug_ospf6_interface_cmd
,
2412 "debug ospf6 interface",
2415 "Debug OSPFv3 Interface\n"
2418 OSPF6_DEBUG_INTERFACE_ON();
2422 DEFUN (no_debug_ospf6_interface
,
2423 no_debug_ospf6_interface_cmd
,
2424 "no debug ospf6 interface",
2428 "Debug OSPFv3 Interface\n"
2431 OSPF6_DEBUG_INTERFACE_OFF();
2435 int config_write_ospf6_debug_interface(struct vty
*vty
)
2437 if (IS_OSPF6_DEBUG_INTERFACE
)
2438 vty_out(vty
, "debug ospf6 interface\n");
2442 void install_element_ospf6_debug_interface(void)
2444 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2445 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2446 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2447 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);