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 #include "ospf6_proto.h"
50 #include "lib/keychain.h"
51 #include "ospf6_auth_trailer.h"
53 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_IF
, "OSPF6 interface");
54 DEFINE_MTYPE(OSPF6D
, OSPF6_AUTH_KEYCHAIN
, "OSPF6 auth keychain");
55 DEFINE_MTYPE(OSPF6D
, OSPF6_AUTH_MANUAL_KEY
, "OSPF6 auth key");
56 DEFINE_MTYPE_STATIC(OSPF6D
, CFG_PLIST_NAME
, "configured prefix list names");
57 DEFINE_QOBJ_TYPE(ospf6_interface
);
58 DEFINE_HOOK(ospf6_interface_change
,
59 (struct ospf6_interface
* oi
, int state
, int old_state
),
60 (oi
, state
, old_state
));
62 unsigned char conf_debug_ospf6_interface
= 0;
64 const char *const ospf6_interface_state_str
[] = {
65 "None", "Down", "Loopback", "Waiting", "PointToPoint",
66 "DROther", "BDR", "DR", NULL
};
68 int ospf6_interface_neighbor_count(struct ospf6_interface
*oi
)
71 struct ospf6_neighbor
*nbr
= NULL
;
72 struct listnode
*node
;
74 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, nbr
)) {
75 /* Down state is not shown. */
76 if (nbr
->state
== OSPF6_NEIGHBOR_DOWN
)
84 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
,
87 struct ospf6_interface
*oi
;
88 struct interface
*ifp
;
90 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
92 return (struct ospf6_interface
*)NULL
;
94 oi
= (struct ospf6_interface
*)ifp
->info
;
98 /* schedule routing table recalculation */
99 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
102 struct ospf6_interface
*oi
;
107 oi
= lsa
->lsdb
->data
;
108 switch (ntohs(lsa
->header
->type
)) {
109 case OSPF6_LSTYPE_LINK
:
110 if (oi
->state
== OSPF6_INTERFACE_DR
)
111 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
113 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
121 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
123 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
126 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
128 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
131 static uint8_t ospf6_default_iftype(struct interface
*ifp
)
133 if (if_is_pointopoint(ifp
))
134 return OSPF_IFTYPE_POINTOPOINT
;
135 else if (if_is_loopback(ifp
))
136 return OSPF_IFTYPE_LOOPBACK
;
138 return OSPF_IFTYPE_BROADCAST
;
141 static uint32_t ospf6_interface_get_cost(struct ospf6_interface
*oi
)
143 /* If all else fails, use default OSPF cost */
147 /* interface speed and bw can be 0 in some platforms,
148 * use ospf default bw. If bw is configured then it would
151 if (!oi
->interface
->bandwidth
&& oi
->interface
->speed
) {
152 bw
= oi
->interface
->speed
;
154 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
155 : OSPF6_INTERFACE_BANDWIDTH
;
158 ospf6
= oi
->interface
->vrf
->info
;
159 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
161 /* A specified ip ospf cost overrides a calculated one. */
162 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
165 cost
= (uint32_t)((double)refbw
/ (double)bw
+ (double)0.5);
173 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface
*oi
)
175 /* update cost held in route_connected list in ospf6_interface */
176 ospf6_interface_connected_route_update(oi
->interface
);
178 /* execute LSA hooks */
180 OSPF6_LINK_LSA_SCHEDULE(oi
);
181 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
182 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
183 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
184 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
188 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
192 newcost
= ospf6_interface_get_cost(oi
);
193 if (newcost
== oi
->cost
)
197 ospf6_interface_force_recalculate_cost(oi
);
200 /* Create new ospf6 interface structure */
201 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
203 struct ospf6_interface
*oi
;
204 unsigned int iobuflen
;
206 oi
= XCALLOC(MTYPE_OSPF6_IF
, sizeof(struct ospf6_interface
));
208 oi
->obuf
= ospf6_fifo_new();
210 oi
->area
= (struct ospf6_area
*)NULL
;
211 oi
->neighbor_list
= list_new();
212 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
213 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
214 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
215 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
216 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
218 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
219 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
220 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
221 oi
->type
= ospf6_default_iftype(ifp
);
222 oi
->state
= OSPF6_INTERFACE_DOWN
;
227 /* Try to adjust I/O buffer size with IfMtu */
228 oi
->ifmtu
= ifp
->mtu6
;
229 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
230 if (oi
->ifmtu
> iobuflen
) {
231 if (IS_OSPF6_DEBUG_INTERFACE
)
233 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
234 ifp
->name
, iobuflen
);
235 oi
->ifmtu
= iobuflen
;
238 QOBJ_REG(oi
, ospf6_interface
);
240 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
241 oi
->lsack_list
= ospf6_lsdb_create(oi
);
242 oi
->lsdb
= ospf6_lsdb_create(oi
);
243 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
244 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
245 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
247 oi
->route_connected
=
248 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
249 oi
->route_connected
->scope
= oi
;
256 oi
->cost
= ospf6_interface_get_cost(oi
);
258 oi
->at_data
.flags
= 0;
263 void ospf6_interface_delete(struct ospf6_interface
*oi
)
265 struct listnode
*node
, *nnode
;
266 struct ospf6_neighbor
*on
;
270 ospf6_fifo_free(oi
->obuf
);
272 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
273 ospf6_neighbor_delete(on
);
275 list_delete(&oi
->neighbor_list
);
277 THREAD_OFF(oi
->thread_send_hello
);
278 THREAD_OFF(oi
->thread_send_lsupdate
);
279 THREAD_OFF(oi
->thread_send_lsack
);
280 THREAD_OFF(oi
->thread_sso
);
281 THREAD_OFF(oi
->thread_wait_timer
);
283 ospf6_lsdb_remove_all(oi
->lsdb
);
284 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
285 ospf6_lsdb_remove_all(oi
->lsack_list
);
287 ospf6_lsdb_delete(oi
->lsdb
);
288 ospf6_lsdb_delete(oi
->lsdb_self
);
290 ospf6_lsdb_delete(oi
->lsupdate_list
);
291 ospf6_lsdb_delete(oi
->lsack_list
);
293 ospf6_route_table_delete(oi
->route_connected
);
296 oi
->interface
->info
= NULL
;
300 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
302 /* disable from area list if possible */
303 ospf6_area_interface_delete(oi
);
305 /* Free BFD allocated data. */
306 XFREE(MTYPE_TMP
, oi
->bfd_config
.profile
);
308 XFREE(MTYPE_OSPF6_IF
, oi
);
311 void ospf6_interface_enable(struct ospf6_interface
*oi
)
313 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
314 ospf6_interface_state_update(oi
->interface
);
317 void ospf6_interface_disable(struct ospf6_interface
*oi
)
319 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
321 thread_execute(master
, interface_down
, oi
, 0);
323 ospf6_lsdb_remove_all(oi
->lsdb
);
324 ospf6_lsdb_remove_all(oi
->lsdb_self
);
325 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
326 ospf6_lsdb_remove_all(oi
->lsack_list
);
328 THREAD_OFF(oi
->thread_send_hello
);
329 THREAD_OFF(oi
->thread_send_lsupdate
);
330 THREAD_OFF(oi
->thread_send_lsack
);
331 THREAD_OFF(oi
->thread_sso
);
333 THREAD_OFF(oi
->thread_network_lsa
);
334 THREAD_OFF(oi
->thread_link_lsa
);
335 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
336 THREAD_OFF(oi
->thread_as_extern_lsa
);
337 THREAD_OFF(oi
->thread_wait_timer
);
340 static struct in6_addr
*
341 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
345 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
347 /* for each connected address */
348 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
349 /* if family not AF_INET6, ignore */
350 if (c
->address
->family
!= AF_INET6
)
353 /* linklocal scope check */
354 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
355 l
= &c
->address
->u
.prefix6
;
360 void ospf6_interface_state_update(struct interface
*ifp
)
362 struct ospf6_interface
*oi
;
363 unsigned int iobuflen
;
365 oi
= (struct ospf6_interface
*)ifp
->info
;
368 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
371 /* Adjust the mtu values if the kernel told us something new */
372 if (ifp
->mtu6
!= oi
->ifmtu
) {
373 /* If nothing configured, accept it and check for buffer size */
375 oi
->ifmtu
= ifp
->mtu6
;
376 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
377 if (oi
->ifmtu
> iobuflen
) {
378 if (IS_OSPF6_DEBUG_INTERFACE
)
380 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
381 ifp
->name
, iobuflen
);
382 oi
->ifmtu
= iobuflen
;
384 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
385 oi
->ifmtu
= ifp
->mtu6
;
387 "Configured mtu %u on %s overridden by kernel %u",
388 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
390 oi
->ifmtu
= oi
->c_ifmtu
;
393 if (if_is_operative(ifp
)
394 && (ospf6_interface_get_linklocal_address(oi
->interface
)
395 || if_is_loopback(oi
->interface
)))
396 thread_execute(master
, interface_up
, oi
, 0);
398 thread_execute(master
, interface_down
, oi
, 0);
403 void ospf6_interface_connected_route_update(struct interface
*ifp
)
405 struct ospf6_interface
*oi
;
406 struct ospf6_route
*route
;
408 struct listnode
*node
, *nnode
;
409 struct in6_addr nh_addr
;
411 oi
= (struct ospf6_interface
*)ifp
->info
;
415 /* reset linklocal pointer */
416 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
418 /* if area is null, do not make connected-route list */
419 if (oi
->area
== NULL
)
422 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
425 /* update "route to advertise" interface route table */
426 ospf6_route_remove_all(oi
->route_connected
);
428 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
429 if (c
->address
->family
!= AF_INET6
)
432 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
434 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
436 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
438 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
440 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
444 if (oi
->plist_name
) {
445 struct prefix_list
*plist
;
446 enum prefix_list_type ret
;
448 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
449 ret
= prefix_list_apply(plist
, (void *)c
->address
);
450 if (ret
== PREFIX_DENY
) {
451 if (IS_OSPF6_DEBUG_INTERFACE
)
453 "%pFX on %s filtered by prefix-list %s ",
454 c
->address
, oi
->interface
->name
,
460 route
= ospf6_route_create(oi
->area
->ospf6
);
461 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
462 apply_mask(&route
->prefix
);
463 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
464 route
->path
.area_id
= oi
->area
->area_id
;
465 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
466 route
->path
.cost
= oi
->cost
;
467 inet_pton(AF_INET6
, "::1", &nh_addr
);
468 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
470 ospf6_route_add(route
, oi
->route_connected
);
473 /* create new Link-LSA */
474 OSPF6_LINK_LSA_SCHEDULE(oi
);
475 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
476 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
479 static int ospf6_interface_state_change(uint8_t next_state
,
480 struct ospf6_interface
*oi
)
485 prev_state
= oi
->state
;
486 oi
->state
= next_state
;
488 if (prev_state
== next_state
)
495 if (IS_OSPF6_DEBUG_INTERFACE
) {
496 zlog_debug("Interface state change %s: %s -> %s",
498 ospf6_interface_state_str
[prev_state
],
499 ospf6_interface_state_str
[next_state
]);
503 ospf6
= oi
->area
->ospf6
;
505 if ((prev_state
== OSPF6_INTERFACE_DR
506 || prev_state
== OSPF6_INTERFACE_BDR
)
507 && (next_state
!= OSPF6_INTERFACE_DR
508 && next_state
!= OSPF6_INTERFACE_BDR
))
509 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
510 IPV6_LEAVE_GROUP
, ospf6
->fd
);
512 if ((prev_state
!= OSPF6_INTERFACE_DR
513 && prev_state
!= OSPF6_INTERFACE_BDR
)
514 && (next_state
== OSPF6_INTERFACE_DR
515 || next_state
== OSPF6_INTERFACE_BDR
))
516 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
517 IPV6_JOIN_GROUP
, ospf6
->fd
);
519 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
520 OSPF6_LINK_LSA_SCHEDULE(oi
);
521 if (next_state
== OSPF6_INTERFACE_DOWN
) {
522 OSPF6_NETWORK_LSA_EXECUTE(oi
);
523 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
524 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
525 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
526 } else if (prev_state
== OSPF6_INTERFACE_DR
527 || next_state
== OSPF6_INTERFACE_DR
) {
528 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
529 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
530 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
533 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
539 /* DR Election, RFC2328 section 9.4 */
541 #define IS_ELIGIBLE(n) \
542 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
544 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
545 struct ospf6_neighbor
*b
)
547 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
548 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
550 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
552 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
555 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
557 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
560 if (a
->priority
> b
->priority
)
562 if (a
->priority
< b
->priority
)
565 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
567 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
570 zlog_warn("Router-ID duplicate ?");
574 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
575 struct ospf6_neighbor
*b
)
577 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
578 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
580 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
582 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
585 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
587 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
590 if (a
->priority
> b
->priority
)
592 if (a
->priority
< b
->priority
)
595 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
597 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
600 zlog_warn("Router-ID duplicate ?");
604 uint8_t dr_election(struct ospf6_interface
*oi
)
606 struct listnode
*node
, *nnode
;
607 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
608 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
609 uint8_t next_state
= 0;
611 drouter
= bdrouter
= NULL
;
612 best_drouter
= best_bdrouter
= NULL
;
614 /* pseudo neighbor myself, including noting current DR/BDR (1) */
615 memset(&myself
, 0, sizeof(myself
));
616 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
617 sizeof(myself
.name
));
618 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
619 myself
.drouter
= oi
->drouter
;
620 myself
.bdrouter
= oi
->bdrouter
;
621 myself
.priority
= oi
->priority
;
622 myself
.router_id
= oi
->area
->ospf6
->router_id
;
624 /* Electing BDR (2) */
625 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
626 bdrouter
= better_bdrouter(bdrouter
, on
);
628 best_bdrouter
= bdrouter
;
629 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
631 /* Electing DR (3) */
632 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
633 drouter
= better_drouter(drouter
, on
);
635 best_drouter
= drouter
;
636 drouter
= better_drouter(best_drouter
, &myself
);
640 /* the router itself is newly/no longer DR/BDR (4) */
641 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
642 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
643 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
644 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
645 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
646 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
648 /* compatible to Electing BDR (2) */
649 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
651 /* compatible to Electing DR (3) */
652 drouter
= better_drouter(best_drouter
, &myself
);
657 /* Set interface state accordingly (5) */
658 if (drouter
&& drouter
== &myself
)
659 next_state
= OSPF6_INTERFACE_DR
;
660 else if (bdrouter
&& bdrouter
== &myself
)
661 next_state
= OSPF6_INTERFACE_BDR
;
663 next_state
= OSPF6_INTERFACE_DROTHER
;
665 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
668 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
669 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
670 accordingly after AdjOK */
671 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
672 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
673 if (IS_OSPF6_DEBUG_INTERFACE
)
674 zlog_debug("DR Election on %s: DR: %s BDR: %s",
676 (drouter
? drouter
->name
: "0.0.0.0"),
677 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
679 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
680 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
682 /* Schedule AdjOK. */
683 thread_add_event(master
, adj_ok
, on
, 0,
688 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
689 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
697 static bool ifmaddr_check(ifindex_t ifindex
, struct in6_addr
*addr
)
699 struct ifmaddrs
*ifmap
, *ifma
;
700 struct sockaddr_dl
*sdl
;
701 struct sockaddr_in6
*sin6
;
704 if (getifmaddrs(&ifmap
) != 0)
707 for (ifma
= ifmap
; ifma
; ifma
= ifma
->ifma_next
) {
708 if (ifma
->ifma_name
== NULL
|| ifma
->ifma_addr
== NULL
)
710 if (ifma
->ifma_name
->sa_family
!= AF_LINK
)
712 if (ifma
->ifma_addr
->sa_family
!= AF_INET6
)
714 sdl
= (struct sockaddr_dl
*)ifma
->ifma_name
;
715 sin6
= (struct sockaddr_in6
*)ifma
->ifma_addr
;
716 if (sdl
->sdl_index
== ifindex
717 && memcmp(&sin6
->sin6_addr
, addr
, IPV6_MAX_BYTELEN
) == 0) {
729 #endif /* __FreeBSD__ */
731 /* Interface State Machine */
732 void interface_up(struct thread
*thread
)
734 struct ospf6_interface
*oi
;
737 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
738 assert(oi
&& oi
->interface
);
741 oi
->type
= ospf6_default_iftype(oi
->interface
);
743 thread_cancel(&oi
->thread_sso
);
745 if (IS_OSPF6_DEBUG_INTERFACE
)
746 zlog_debug("Interface Event %s: [InterfaceUp]",
747 oi
->interface
->name
);
749 /* check physical interface is up */
750 if (!if_is_operative(oi
->interface
)) {
751 zlog_warn("Interface %s is down, can't execute [InterfaceUp]",
752 oi
->interface
->name
);
756 /* check interface has a link-local address */
757 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
758 || if_is_loopback(oi
->interface
))) {
760 "Interface %s has no link local address, can't execute [InterfaceUp]",
761 oi
->interface
->name
);
766 ospf6_interface_recalculate_cost(oi
);
768 /* if already enabled, do nothing */
769 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
770 if (IS_OSPF6_DEBUG_INTERFACE
)
771 zlog_debug("Interface %s already enabled",
772 oi
->interface
->name
);
776 /* If no area assigned, return */
777 if (oi
->area
== NULL
) {
779 "%s: Not scheduling Hello for %s as there is no area assigned yet",
780 __func__
, oi
->interface
->name
);
786 * There's a delay in FreeBSD between issuing a command to leave a
787 * multicast group and an actual leave. If we execute "no router ospf6"
788 * and "router ospf6" fast enough, we can end up in a situation when OS
789 * performs the leave later than it performs the join and the interface
790 * remains without a multicast group. We have to do the join only after
791 * the interface actually left the group.
793 if (ifmaddr_check(oi
->interface
->ifindex
, &allspfrouters6
)) {
795 "Interface %s is still in all routers group, rescheduling for SSO",
796 oi
->interface
->name
);
797 thread_add_timer(master
, interface_up
, oi
,
798 OSPF6_INTERFACE_SSO_RETRY_INT
,
802 #endif /* __FreeBSD__ */
804 ospf6
= oi
->area
->ospf6
;
806 /* Join AllSPFRouters */
807 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
,
810 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
812 "Scheduling %s for sso retry, trial count: %d",
813 oi
->interface
->name
, oi
->sso_try_cnt
);
814 thread_add_timer(master
, interface_up
, oi
,
815 OSPF6_INTERFACE_SSO_RETRY_INT
,
820 oi
->sso_try_cnt
= 0; /* Reset on success */
822 /* Update interface route */
823 ospf6_interface_connected_route_update(oi
->interface
);
826 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
827 && !if_is_loopback(oi
->interface
)) {
828 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
829 &oi
->thread_send_hello
);
832 /* decide next interface state */
833 if (oi
->type
== OSPF_IFTYPE_LOOPBACK
) {
834 ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK
, oi
);
835 } else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
836 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
837 } else if (oi
->priority
== 0)
838 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
840 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
841 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
842 &oi
->thread_wait_timer
);
846 void wait_timer(struct thread
*thread
)
848 struct ospf6_interface
*oi
;
850 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
851 assert(oi
&& oi
->interface
);
853 if (IS_OSPF6_DEBUG_INTERFACE
)
854 zlog_debug("Interface Event %s: [WaitTimer]",
855 oi
->interface
->name
);
857 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
858 ospf6_interface_state_change(dr_election(oi
), oi
);
861 void backup_seen(struct thread
*thread
)
863 struct ospf6_interface
*oi
;
865 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
866 assert(oi
&& oi
->interface
);
868 if (IS_OSPF6_DEBUG_INTERFACE
)
869 zlog_debug("Interface Event %s: [BackupSeen]",
870 oi
->interface
->name
);
872 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
873 ospf6_interface_state_change(dr_election(oi
), oi
);
876 void neighbor_change(struct thread
*thread
)
878 struct ospf6_interface
*oi
;
880 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
881 assert(oi
&& oi
->interface
);
883 if (IS_OSPF6_DEBUG_INTERFACE
)
884 zlog_debug("Interface Event %s: [NeighborChange]",
885 oi
->interface
->name
);
887 if (oi
->state
== OSPF6_INTERFACE_DROTHER
888 || oi
->state
== OSPF6_INTERFACE_BDR
889 || oi
->state
== OSPF6_INTERFACE_DR
)
890 ospf6_interface_state_change(dr_election(oi
), oi
);
893 void interface_down(struct thread
*thread
)
895 struct ospf6_interface
*oi
;
896 struct listnode
*node
, *nnode
;
897 struct ospf6_neighbor
*on
;
900 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
901 assert(oi
&& oi
->interface
);
903 if (IS_OSPF6_DEBUG_INTERFACE
)
904 zlog_debug("Interface Event %s: [InterfaceDown]",
905 oi
->interface
->name
);
908 THREAD_OFF(oi
->thread_send_hello
);
910 /* Stop trying to set socket options. */
911 THREAD_OFF(oi
->thread_sso
);
913 /* Cease the HELPER role for all the neighbours
916 if (ospf6_interface_neighbor_count(oi
)) {
918 struct ospf6_neighbor
*nbr
= NULL
;
920 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, ln
, nbr
))
921 ospf6_gr_helper_exit(nbr
, OSPF6_GR_HELPER_TOPO_CHG
);
924 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
925 ospf6_neighbor_delete(on
);
927 list_delete_all_node(oi
->neighbor_list
);
929 /* When interface state is reset, also reset information about
930 * DR election, as it is no longer valid. */
931 oi
->drouter
= oi
->prev_drouter
= htonl(0);
932 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
934 if (oi
->area
== NULL
)
937 ospf6
= oi
->area
->ospf6
;
938 /* Leave AllSPFRouters */
939 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
940 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
941 IPV6_LEAVE_GROUP
, ospf6
->fd
);
943 /* deal with write fifo */
944 ospf6_fifo_flush(oi
->obuf
);
945 if (oi
->on_write_q
) {
946 listnode_delete(ospf6
->oi_write_q
, oi
);
947 if (list_isempty(ospf6
->oi_write_q
))
948 thread_cancel(&ospf6
->t_write
);
952 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
956 static const char *ospf6_iftype_str(uint8_t iftype
)
959 case OSPF_IFTYPE_LOOPBACK
:
961 case OSPF_IFTYPE_BROADCAST
:
963 case OSPF_IFTYPE_POINTOPOINT
:
964 return "POINTOPOINT";
969 #if CONFDATE > 20220709
970 CPP_NOTICE("Time to remove ospf6Enabled from JSON output")
973 /* show specified interface structure */
974 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
,
975 json_object
*json_obj
, bool use_json
)
977 struct ospf6_interface
*oi
;
981 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
982 uint8_t default_iftype
;
983 struct timeval res
, now
;
985 struct ospf6_lsa
*lsa
, *lsanext
;
986 json_object
*json_arr
;
987 json_object
*json_addr
;
988 struct json_object
*json_auth
= NULL
;
990 default_iftype
= ospf6_default_iftype(ifp
);
993 json_object_string_add(json_obj
, "status",
994 (if_is_operative(ifp
) ? "up" : "down"));
995 json_object_string_add(json_obj
, "type",
996 ospf6_iftype_str(default_iftype
));
997 json_object_int_add(json_obj
, "interfaceId", ifp
->ifindex
);
999 if (ifp
->info
== NULL
) {
1000 json_object_boolean_false_add(json_obj
, "ospf6Enabled");
1003 json_object_boolean_true_add(json_obj
, "ospf6Enabled");
1005 oi
= (struct ospf6_interface
*)ifp
->info
;
1007 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
1008 json_object_string_add(json_obj
, "operatingAsType",
1009 ospf6_iftype_str(oi
->type
));
1012 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
1013 (if_is_operative(ifp
) ? "up" : "down"),
1014 ospf6_iftype_str(default_iftype
));
1015 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
1017 if (ifp
->info
== NULL
) {
1018 vty_out(vty
, " OSPF not enabled on this interface\n");
1021 oi
= (struct ospf6_interface
*)ifp
->info
;
1023 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
1024 vty_out(vty
, " Operating as type %s\n",
1025 ospf6_iftype_str(oi
->type
));
1029 json_arr
= json_object_new_array();
1030 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1031 json_addr
= json_object_new_object();
1033 prefix2str(p
, strbuf
, sizeof(strbuf
));
1034 switch (p
->family
) {
1036 json_object_string_add(json_addr
, "type",
1038 json_object_string_add(json_addr
, "address",
1040 json_object_array_add(json_arr
, json_addr
);
1043 json_object_string_add(json_addr
, "type",
1045 json_object_string_add(json_addr
, "address",
1047 json_object_array_add(json_arr
, json_addr
);
1050 json_object_string_add(json_addr
, "type",
1052 json_object_string_add(json_addr
, "address",
1054 json_object_array_add(json_arr
, json_addr
);
1058 json_object_object_add(json_obj
, "internetAddress", json_arr
);
1060 vty_out(vty
, " Internet Address:\n");
1062 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1064 prefix2str(p
, strbuf
, sizeof(strbuf
));
1065 switch (p
->family
) {
1067 vty_out(vty
, " inet : %pFX\n", p
);
1070 vty_out(vty
, " inet6: %pFX\n", p
);
1073 vty_out(vty
, " ??? : %pFX\n", p
);
1081 json_object_boolean_true_add(json_obj
,
1083 json_object_int_add(json_obj
, "instanceId",
1085 json_object_int_add(json_obj
, "interfaceMtu",
1087 json_object_int_add(json_obj
, "autoDetect", ifp
->mtu6
);
1088 json_object_string_add(json_obj
, "mtuMismatchDetection",
1089 oi
->mtu_ignore
? "disabled"
1091 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1093 json_object_string_add(json_obj
, "areaId", strbuf
);
1094 json_object_int_add(json_obj
, "cost", oi
->cost
);
1096 json_object_boolean_false_add(json_obj
,
1102 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1103 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
1104 vty_out(vty
, " MTU mismatch detection: %s\n",
1105 oi
->mtu_ignore
? "disabled" : "enabled");
1106 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1108 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
,
1111 vty_out(vty
, " Not Attached to Area\n");
1115 json_object_string_add(json_obj
, "ospf6InterfaceState",
1116 ospf6_interface_state_str
[oi
->state
]);
1117 json_object_int_add(json_obj
, "transmitDelaySec",
1119 json_object_int_add(json_obj
, "priority", oi
->priority
);
1120 json_object_int_add(json_obj
, "timerIntervalsConfigHello",
1121 oi
->hello_interval
);
1122 json_object_int_add(json_obj
, "timerIntervalsConfigDead",
1124 json_object_int_add(json_obj
, "timerIntervalsConfigRetransmit",
1127 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
1128 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
1130 vty_out(vty
, " Timer intervals configured:\n");
1131 vty_out(vty
, " Hello %d(%pTHd), Dead %d, Retransmit %d\n",
1132 oi
->hello_interval
, oi
->thread_send_hello
,
1133 oi
->dead_interval
, oi
->rxmt_interval
);
1136 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
1137 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
1139 json_object_string_add(json_obj
, "dr", drouter
);
1140 json_object_string_add(json_obj
, "bdr", bdrouter
);
1141 json_object_int_add(json_obj
, "numberOfInterfaceScopedLsa",
1144 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
1145 vty_out(vty
, " Number of I/F scoped LSAs is %u\n",
1153 if (thread_is_scheduled(oi
->thread_send_lsupdate
))
1154 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1156 timerstring(&res
, duration
, sizeof(duration
));
1157 json_object_int_add(json_obj
, "pendingLsaLsUpdateCount",
1158 oi
->lsupdate_list
->count
);
1159 json_object_string_add(json_obj
, "pendingLsaLsUpdateTime",
1161 json_object_string_add(
1162 json_obj
, "lsUpdateSendThread",
1163 (thread_is_scheduled(oi
->thread_send_lsupdate
)
1167 json_arr
= json_object_new_array();
1168 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1169 json_object_array_add(
1170 json_arr
, json_object_new_string(lsa
->name
));
1171 json_object_object_add(json_obj
, "pendingLsaLsUpdate",
1175 if (thread_is_scheduled(oi
->thread_send_lsack
))
1176 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1177 timerstring(&res
, duration
, sizeof(duration
));
1179 json_object_int_add(json_obj
, "pendingLsaLsAckCount",
1180 oi
->lsack_list
->count
);
1181 json_object_string_add(json_obj
, "pendingLsaLsAckTime",
1183 json_object_string_add(
1184 json_obj
, "lsAckSendThread",
1185 (thread_is_scheduled(oi
->thread_send_lsack
) ? "on"
1188 json_arr
= json_object_new_array();
1189 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1190 json_object_array_add(
1191 json_arr
, json_object_new_string(lsa
->name
));
1192 json_object_object_add(json_obj
, "pendingLsaLsAck", json_arr
);
1196 if (thread_is_scheduled(oi
->thread_send_lsupdate
))
1197 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1199 timerstring(&res
, duration
, sizeof(duration
));
1201 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1202 oi
->lsupdate_list
->count
, duration
,
1203 (thread_is_scheduled(oi
->thread_send_lsupdate
)
1206 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1207 vty_out(vty
, " %s\n", lsa
->name
);
1210 if (thread_is_scheduled(oi
->thread_send_lsack
))
1211 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1212 timerstring(&res
, duration
, sizeof(duration
));
1214 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1215 oi
->lsack_list
->count
, duration
,
1216 (thread_is_scheduled(oi
->thread_send_lsack
) ? "on"
1218 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1219 vty_out(vty
, " %s\n", lsa
->name
);
1223 if (oi
->bfd_config
.enabled
) {
1225 struct json_object
*json_bfd
= json_object_new_object();
1227 json_object_int_add(
1228 json_bfd
, "detectMultiplier",
1229 oi
->bfd_config
.detection_multiplier
);
1230 json_object_int_add(json_bfd
, "rxMinInterval",
1231 oi
->bfd_config
.min_rx
);
1232 json_object_int_add(json_bfd
, "txMinInterval",
1233 oi
->bfd_config
.min_tx
);
1234 json_object_object_add(json_obj
, "peerBfdInfo",
1238 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1239 oi
->bfd_config
.detection_multiplier
,
1240 oi
->bfd_config
.min_rx
, oi
->bfd_config
.min_tx
);
1244 json_auth
= json_object_new_object();
1245 if (oi
->at_data
.flags
!= 0) {
1247 if (CHECK_FLAG(oi
->at_data
.flags
,
1248 OSPF6_AUTH_TRAILER_KEYCHAIN
)) {
1249 json_object_string_add(json_auth
, "authType",
1251 json_object_string_add(json_auth
,
1253 oi
->at_data
.keychain
);
1254 } else if (CHECK_FLAG(oi
->at_data
.flags
,
1255 OSPF6_AUTH_TRAILER_MANUAL_KEY
))
1256 json_object_string_add(json_auth
, "authType",
1258 json_object_int_add(json_auth
, "txPktDrop",
1259 oi
->at_data
.tx_drop
);
1260 json_object_int_add(json_auth
, "rxPktDrop",
1261 oi
->at_data
.rx_drop
);
1263 if (CHECK_FLAG(oi
->at_data
.flags
,
1264 OSPF6_AUTH_TRAILER_KEYCHAIN
))
1266 " Authentication Trailer is enabled with key-chain %s\n",
1267 oi
->at_data
.keychain
);
1268 else if (CHECK_FLAG(oi
->at_data
.flags
,
1269 OSPF6_AUTH_TRAILER_MANUAL_KEY
))
1271 " Authentication trailer is enabled with manual key\n");
1273 " Packet drop Tx %u, Packet drop Rx %u\n",
1274 oi
->at_data
.tx_drop
, oi
->at_data
.rx_drop
);
1278 json_object_string_add(json_auth
, "authType", "NULL");
1280 vty_out(vty
, " Authentication Trailer is disabled\n");
1284 json_object_object_add(json_obj
, "authInfo", json_auth
);
1289 /* Find the global address to be used as a forwarding address in NSSA LSA.*/
1290 struct in6_addr
*ospf6_interface_get_global_address(struct interface
*ifp
)
1293 struct connected
*c
;
1295 /* for each connected address */
1296 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
1297 /* if family not AF_INET6, ignore */
1298 if (c
->address
->family
!= AF_INET6
)
1301 if (!IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
1302 return &c
->address
->u
.prefix6
;
1309 static int show_ospf6_interface_common(struct vty
*vty
, vrf_id_t vrf_id
,
1310 int argc
, struct cmd_token
**argv
,
1311 int idx_ifname
, int intf_idx
,
1312 int json_idx
, bool uj
)
1315 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
1316 struct interface
*ifp
;
1318 json_object
*json_int
;
1321 json
= json_object_new_object();
1322 if (argc
== json_idx
) {
1323 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1324 json_int
= json_object_new_object();
1326 json_object_string_add(json
, "noSuchInterface",
1327 argv
[idx_ifname
]->arg
);
1328 vty_json(vty
, json
);
1329 json_object_free(json_int
);
1332 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1333 json_object_object_add(json
, ifp
->name
, json_int
);
1335 FOR_ALL_INTERFACES (vrf
, ifp
) {
1336 json_int
= json_object_new_object();
1337 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1338 json_object_object_add(json
, ifp
->name
,
1342 vty_json(vty
, json
);
1344 if (argc
== intf_idx
) {
1345 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1347 vty_out(vty
, "No such Interface: %s\n",
1348 argv
[idx_ifname
]->arg
);
1351 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1353 FOR_ALL_INTERFACES (vrf
, ifp
)
1354 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1360 /* show interface */
1361 DEFUN(show_ipv6_ospf6_interface
, show_ipv6_ospf6_interface_ifname_cmd
,
1362 "show ipv6 ospf6 [vrf <NAME|all>] interface [IFNAME] [json]",
1363 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1364 "All VRFs\n" INTERFACE_STR IFNAME_STR JSON_STR
)
1369 struct listnode
*node
;
1370 struct ospf6
*ospf6
;
1371 const char *vrf_name
= NULL
;
1372 bool all_vrf
= false;
1374 bool uj
= use_json(argc
, argv
);
1376 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1383 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1384 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1385 show_ospf6_interface_common(vty
, ospf6
->vrf_id
, argc
,
1386 argv
, idx_ifname
, intf_idx
,
1394 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1399 static int ospf6_interface_show_traffic(struct vty
*vty
,
1400 struct interface
*intf_ifp
,
1401 int display_once
, json_object
*json
,
1402 bool use_json
, vrf_id_t vrf_id
)
1404 struct interface
*ifp
;
1405 struct vrf
*vrf
= NULL
;
1406 struct ospf6_interface
*oi
= NULL
;
1407 json_object
*json_interface
;
1409 if (!display_once
&& !use_json
) {
1411 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1412 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1414 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1415 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1418 "--------------------------------------------------------------------------------------------\n");
1421 if (intf_ifp
== NULL
) {
1422 vrf
= vrf_lookup_by_id(vrf_id
);
1423 FOR_ALL_INTERFACES (vrf
, ifp
) {
1425 oi
= (struct ospf6_interface
*)ifp
->info
;
1430 json_interface
= json_object_new_object();
1431 json_object_int_add(json_interface
, "helloRx",
1433 json_object_int_add(json_interface
, "helloTx",
1435 json_object_int_add(json_interface
, "dbDescRx",
1437 json_object_int_add(json_interface
, "dbDescTx",
1439 json_object_int_add(json_interface
, "lsReqRx",
1441 json_object_int_add(json_interface
, "lsReqTx",
1443 json_object_int_add(json_interface
,
1446 json_object_int_add(json_interface
,
1449 json_object_int_add(json_interface
, "lsAckRx",
1451 json_object_int_add(json_interface
, "lsAckTx",
1454 json_object_object_add(json
,
1455 oi
->interface
->name
,
1459 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1460 oi
->interface
->name
, oi
->hello_in
,
1461 oi
->hello_out
, oi
->db_desc_in
,
1462 oi
->db_desc_out
, oi
->ls_req_in
,
1463 oi
->ls_req_out
, oi
->ls_upd_in
,
1464 oi
->ls_upd_out
, oi
->ls_ack_in
,
1468 oi
= intf_ifp
->info
;
1473 json_interface
= json_object_new_object();
1474 json_object_int_add(json_interface
, "helloRx",
1476 json_object_int_add(json_interface
, "helloTx",
1478 json_object_int_add(json_interface
, "dbDescRx",
1480 json_object_int_add(json_interface
, "dbDescTx",
1482 json_object_int_add(json_interface
, "lsReqRx",
1484 json_object_int_add(json_interface
, "lsReqTx",
1486 json_object_int_add(json_interface
, "lsUpdateRx",
1488 json_object_int_add(json_interface
, "lsUpdateTx",
1490 json_object_int_add(json_interface
, "lsAckRx",
1492 json_object_int_add(json_interface
, "lsAckTx",
1495 json_object_object_add(json
, oi
->interface
->name
,
1499 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1500 oi
->interface
->name
, oi
->hello_in
,
1501 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1502 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1503 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1509 static int ospf6_interface_show_traffic_common(struct vty
*vty
, int argc
,
1510 struct cmd_token
**argv
,
1511 vrf_id_t vrf_id
, bool uj
)
1514 int display_once
= 0;
1515 char *intf_name
= NULL
;
1516 struct interface
*ifp
= NULL
;
1517 json_object
*json
= NULL
;
1520 json
= json_object_new_object();
1522 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1523 intf_name
= argv
[idx_ifname
]->arg
;
1524 ifp
= if_lookup_by_name(intf_name
, vrf_id
);
1527 json_object_string_add(json
, "status",
1528 "No Such Interface");
1529 json_object_string_add(json
, "interface",
1531 vty_json(vty
, json
);
1534 if (ifp
->info
== NULL
) {
1535 json_object_string_add(
1537 "OSPF not enabled on this interface");
1538 json_object_string_add(json
, "interface",
1540 vty_json(vty
, json
);
1545 vty_out(vty
, "No such Interface: %s\n",
1549 if (ifp
->info
== NULL
) {
1551 " OSPF not enabled on this interface %s\n",
1558 ospf6_interface_show_traffic(vty
, ifp
, display_once
, json
, uj
, vrf_id
);
1561 vty_json(vty
, json
);
1566 /* show interface */
1567 DEFUN(show_ipv6_ospf6_interface_traffic
, show_ipv6_ospf6_interface_traffic_cmd
,
1568 "show ipv6 ospf6 [vrf <NAME|all>] interface traffic [IFNAME] [json]",
1569 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1570 "All VRFs\n" INTERFACE_STR
1571 "Protocol Packet counters\n" IFNAME_STR JSON_STR
)
1573 struct ospf6
*ospf6
;
1574 struct listnode
*node
;
1575 const char *vrf_name
= NULL
;
1576 bool all_vrf
= false;
1578 bool uj
= use_json(argc
, argv
);
1580 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1582 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1583 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1584 ospf6_interface_show_traffic_common(vty
, argc
, argv
,
1592 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1598 DEFUN(show_ipv6_ospf6_interface_ifname_prefix
,
1599 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1600 "show ipv6 ospf6 [vrf <NAME|all>] interface IFNAME prefix\
1603 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1605 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1606 "All VRFs\n" INTERFACE_STR IFNAME_STR
1607 "Display connected prefixes to advertise\n"
1608 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1609 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1610 "Display details of the prefixes\n" JSON_STR
)
1614 struct ospf6_interface
*oi
;
1615 bool uj
= use_json(argc
, argv
);
1617 struct ospf6
*ospf6
;
1618 struct listnode
*node
;
1619 struct interface
*ifp
;
1620 const char *vrf_name
= NULL
;
1621 bool all_vrf
= false;
1624 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1630 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1631 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1632 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1635 vty_out(vty
, "No such Interface: %s\n",
1636 argv
[idx_ifname
]->arg
);
1642 || CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
1644 "Interface %s not attached to area\n",
1645 argv
[idx_ifname
]->arg
);
1649 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1650 oi
->route_connected
, uj
);
1657 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1662 DEFUN(show_ipv6_ospf6_interface_prefix
, show_ipv6_ospf6_interface_prefix_cmd
,
1663 "show ipv6 ospf6 [vrf <NAME|all>] interface prefix\
1666 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1668 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1669 "All VRFs\n" INTERFACE_STR
1670 "Display connected prefixes to advertise\n"
1671 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1672 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1673 "Display details of the prefixes\n" JSON_STR
)
1675 struct vrf
*vrf
= NULL
;
1677 struct ospf6_interface
*oi
;
1678 struct interface
*ifp
;
1679 bool uj
= use_json(argc
, argv
);
1680 struct listnode
*node
;
1681 struct ospf6
*ospf6
;
1682 const char *vrf_name
= NULL
;
1683 bool all_vrf
= false;
1686 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1690 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1691 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1692 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
1693 FOR_ALL_INTERFACES (vrf
, ifp
) {
1694 oi
= (struct ospf6_interface
*)ifp
->info
;
1696 || CHECK_FLAG(oi
->flag
,
1697 OSPF6_INTERFACE_DISABLE
))
1700 ospf6_route_table_show(vty
, idx_prefix
, argc
,
1702 oi
->route_connected
, uj
);
1709 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1714 void ospf6_interface_start(struct ospf6_interface
*oi
)
1716 struct ospf6
*ospf6
;
1717 struct ospf6_area
*oa
;
1719 if (oi
->area_id_format
== OSPF6_AREA_FMT_UNSET
)
1723 /* Recompute cost */
1724 ospf6_interface_recalculate_cost(oi
);
1728 ospf6
= oi
->interface
->vrf
->info
;
1732 oa
= ospf6_area_lookup(oi
->area_id
, ospf6
);
1734 oa
= ospf6_area_create(oi
->area_id
, ospf6
, oi
->area_id_format
);
1736 /* attach interface to area */
1737 listnode_add(oa
->if_list
, oi
);
1740 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1743 ospf6_interface_enable(oi
);
1745 /* If the router is ABR, originate summary routes */
1746 if (ospf6_check_and_set_router_abr(ospf6
))
1747 ospf6_abr_enable_area(oa
);
1750 void ospf6_interface_stop(struct ospf6_interface
*oi
)
1752 struct ospf6_area
*oa
;
1758 ospf6_interface_disable(oi
);
1760 listnode_delete(oa
->if_list
, oi
);
1763 if (oa
->if_list
->count
== 0) {
1764 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1765 ospf6_abr_disable_area(oa
);
1769 /* interface variable set command */
1770 DEFUN (ipv6_ospf6_area
,
1771 ipv6_ospf6_area_cmd
,
1772 "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
1775 "Specify the OSPF6 area ID\n"
1776 "OSPF6 area ID in IPv4 address notation\n"
1777 "OSPF6 area ID in decimal notation\n")
1779 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1780 struct ospf6_interface
*oi
;
1787 oi
= (struct ospf6_interface
*)ifp
->info
;
1789 oi
= ospf6_interface_create(ifp
);
1793 vty_out(vty
, "%s already attached to Area %s\n",
1794 oi
->interface
->name
, oi
->area
->name
);
1798 if (str2area_id(argv
[idx_ipv4
]->arg
, &area_id
, &format
)) {
1799 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1800 return CMD_WARNING_CONFIG_FAILED
;
1803 oi
->area_id
= area_id
;
1804 oi
->area_id_format
= format
;
1806 ospf6_interface_start(oi
);
1811 DEFUN (no_ipv6_ospf6_area
,
1812 no_ipv6_ospf6_area_cmd
,
1813 "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
1817 "Specify the OSPF6 area ID\n"
1818 "OSPF6 area ID in IPv4 address notation\n"
1819 "OSPF6 area ID in decimal notation\n")
1821 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1822 struct ospf6_interface
*oi
;
1826 oi
= (struct ospf6_interface
*)ifp
->info
;
1828 oi
= ospf6_interface_create(ifp
);
1831 ospf6_interface_stop(oi
);
1834 oi
->area_id_format
= OSPF6_AREA_FMT_UNSET
;
1839 DEFUN (ipv6_ospf6_ifmtu
,
1840 ipv6_ospf6_ifmtu_cmd
,
1841 "ipv6 ospf6 ifmtu (1-65535)",
1845 "OSPFv3 Interface MTU\n"
1848 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1850 struct ospf6_interface
*oi
;
1851 unsigned int ifmtu
, iobuflen
;
1852 struct listnode
*node
, *nnode
;
1853 struct ospf6_neighbor
*on
;
1857 oi
= (struct ospf6_interface
*)ifp
->info
;
1859 oi
= ospf6_interface_create(ifp
);
1862 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1864 if (oi
->c_ifmtu
== ifmtu
)
1867 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1869 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1870 ifp
->name
, ifp
->mtu6
);
1871 return CMD_WARNING_CONFIG_FAILED
;
1874 if (oi
->ifmtu
< ifmtu
) {
1875 iobuflen
= ospf6_iobuf_size(ifmtu
);
1876 if (iobuflen
< ifmtu
) {
1878 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1879 ifp
->name
, iobuflen
);
1880 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1882 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1884 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1886 /* re-establish adjacencies */
1887 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1888 THREAD_OFF(on
->inactivity_timer
);
1889 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1895 DEFUN (no_ipv6_ospf6_ifmtu
,
1896 no_ipv6_ospf6_ifmtu_cmd
,
1897 "no ipv6 ospf6 ifmtu [(1-65535)]",
1902 "OSPFv3 Interface MTU\n"
1905 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1906 struct ospf6_interface
*oi
;
1907 unsigned int iobuflen
;
1908 struct listnode
*node
, *nnode
;
1909 struct ospf6_neighbor
*on
;
1913 oi
= (struct ospf6_interface
*)ifp
->info
;
1915 oi
= ospf6_interface_create(ifp
);
1918 if (oi
->ifmtu
< ifp
->mtu
) {
1919 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1920 if (iobuflen
< ifp
->mtu
) {
1922 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1923 ifp
->name
, iobuflen
);
1924 oi
->ifmtu
= iobuflen
;
1926 oi
->ifmtu
= ifp
->mtu
;
1928 oi
->ifmtu
= ifp
->mtu
;
1932 /* re-establish adjacencies */
1933 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1934 THREAD_OFF(on
->inactivity_timer
);
1935 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1941 DEFUN (ipv6_ospf6_cost
,
1942 ipv6_ospf6_cost_cmd
,
1943 "ipv6 ospf6 cost (1-65535)",
1947 "Outgoing metric of this interface\n")
1949 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1951 struct ospf6_interface
*oi
;
1952 unsigned long int lcost
;
1956 oi
= (struct ospf6_interface
*)ifp
->info
;
1958 oi
= ospf6_interface_create(ifp
);
1961 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1963 if (lcost
> UINT32_MAX
) {
1964 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1965 return CMD_WARNING_CONFIG_FAILED
;
1968 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1969 if (oi
->cost
== lcost
)
1973 ospf6_interface_force_recalculate_cost(oi
);
1978 DEFUN (no_ipv6_ospf6_cost
,
1979 no_ipv6_ospf6_cost_cmd
,
1980 "no ipv6 ospf6 cost [(1-65535)]",
1984 "Calculate interface cost from bandwidth\n"
1985 "Outgoing metric of 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
);
1996 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1998 ospf6_interface_recalculate_cost(oi
);
2003 DEFUN (auto_cost_reference_bandwidth
,
2004 auto_cost_reference_bandwidth_cmd
,
2005 "auto-cost reference-bandwidth (1-4294967)",
2006 "Calculate OSPF interface cost according to bandwidth\n"
2007 "Use reference bandwidth method to assign OSPF cost\n"
2008 "The reference bandwidth in terms of Mbits per second\n")
2010 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2012 struct ospf6_area
*oa
;
2013 struct ospf6_interface
*oi
;
2014 struct listnode
*i
, *j
;
2017 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
2018 if (refbw
< 1 || refbw
> 4294967) {
2019 vty_out(vty
, "reference-bandwidth value is invalid\n");
2020 return CMD_WARNING_CONFIG_FAILED
;
2023 /* If reference bandwidth is changed. */
2024 if ((refbw
) == o
->ref_bandwidth
)
2027 o
->ref_bandwidth
= refbw
;
2028 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
2029 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
2030 ospf6_interface_recalculate_cost(oi
);
2035 DEFUN (no_auto_cost_reference_bandwidth
,
2036 no_auto_cost_reference_bandwidth_cmd
,
2037 "no auto-cost reference-bandwidth [(1-4294967)]",
2039 "Calculate OSPF interface cost according to bandwidth\n"
2040 "Use reference bandwidth method to assign OSPF cost\n"
2041 "The reference bandwidth in terms of Mbits per second\n")
2043 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2044 struct ospf6_area
*oa
;
2045 struct ospf6_interface
*oi
;
2046 struct listnode
*i
, *j
;
2048 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
2051 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
2052 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
2053 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
2054 ospf6_interface_recalculate_cost(oi
);
2060 DEFUN (ospf6_write_multiplier
,
2061 ospf6_write_multiplier_cmd
,
2062 "write-multiplier (1-100)",
2063 "Write multiplier\n"
2064 "Maximum number of interface serviced per write\n")
2066 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2067 uint32_t write_oi_count
;
2069 write_oi_count
= strtol(argv
[1]->arg
, NULL
, 10);
2070 if (write_oi_count
< 1 || write_oi_count
> 100) {
2071 vty_out(vty
, "write-multiplier value is invalid\n");
2072 return CMD_WARNING_CONFIG_FAILED
;
2075 o
->write_oi_count
= write_oi_count
;
2079 DEFUN (no_ospf6_write_multiplier
,
2080 no_ospf6_write_multiplier_cmd
,
2081 "no write-multiplier (1-100)",
2083 "Write multiplier\n"
2084 "Maximum number of interface serviced per write\n")
2086 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2088 o
->write_oi_count
= OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
;
2092 DEFUN (ipv6_ospf6_hellointerval
,
2093 ipv6_ospf6_hellointerval_cmd
,
2094 "ipv6 ospf6 hello-interval (1-65535)",
2097 "Time between HELLO packets\n"
2100 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2102 struct ospf6_interface
*oi
;
2105 oi
= (struct ospf6_interface
*)ifp
->info
;
2107 oi
= ospf6_interface_create(ifp
);
2110 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
2111 ? OSPF_HELLO_INTERVAL_DEFAULT
2112 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2115 * If the thread is scheduled, send the new hello now.
2117 if (thread_is_scheduled(oi
->thread_send_hello
)) {
2118 THREAD_OFF(oi
->thread_send_hello
);
2120 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
2121 &oi
->thread_send_hello
);
2126 ALIAS (ipv6_ospf6_hellointerval
,
2127 no_ipv6_ospf6_hellointerval_cmd
,
2128 "no ipv6 ospf6 hello-interval [(1-65535)]",
2132 "Time between HELLO packets\n"
2135 /* interface variable set command */
2136 DEFUN (ipv6_ospf6_deadinterval
,
2137 ipv6_ospf6_deadinterval_cmd
,
2138 "ipv6 ospf6 dead-interval (1-65535)",
2141 "Interval time after which a neighbor is declared down\n"
2144 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2146 struct ospf6_interface
*oi
;
2149 oi
= (struct ospf6_interface
*)ifp
->info
;
2151 oi
= ospf6_interface_create(ifp
);
2154 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
2155 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
2156 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2160 ALIAS (ipv6_ospf6_deadinterval
,
2161 no_ipv6_ospf6_deadinterval_cmd
,
2162 "no ipv6 ospf6 dead-interval [(1-65535)]",
2166 "Interval time after which a neighbor is declared down\n"
2169 /* interface variable set command */
2170 DEFUN (ipv6_ospf6_transmitdelay
,
2171 ipv6_ospf6_transmitdelay_cmd
,
2172 "ipv6 ospf6 transmit-delay (1-3600)",
2175 "Link state transmit delay\n"
2178 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2180 struct ospf6_interface
*oi
;
2183 oi
= (struct ospf6_interface
*)ifp
->info
;
2185 oi
= ospf6_interface_create(ifp
);
2188 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
2189 ? OSPF6_INTERFACE_TRANSDELAY
2190 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2194 ALIAS (ipv6_ospf6_transmitdelay
,
2195 no_ipv6_ospf6_transmitdelay_cmd
,
2196 "no ipv6 ospf6 transmit-delay [(1-3600)]",
2200 "Link state transmit delay\n"
2203 /* interface variable set command */
2204 DEFUN (ipv6_ospf6_retransmitinterval
,
2205 ipv6_ospf6_retransmitinterval_cmd
,
2206 "ipv6 ospf6 retransmit-interval (1-65535)",
2209 "Time between retransmitting lost link state advertisements\n"
2212 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2214 struct ospf6_interface
*oi
;
2217 oi
= (struct ospf6_interface
*)ifp
->info
;
2219 oi
= ospf6_interface_create(ifp
);
2222 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
2223 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
2224 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2228 ALIAS (ipv6_ospf6_retransmitinterval
,
2229 no_ipv6_ospf6_retransmitinterval_cmd
,
2230 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
2234 "Time between retransmitting lost link state advertisements\n"
2237 /* interface variable set command */
2238 DEFUN (ipv6_ospf6_priority
,
2239 ipv6_ospf6_priority_cmd
,
2240 "ipv6 ospf6 priority (0-255)",
2246 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2248 struct ospf6_interface
*oi
;
2251 oi
= (struct ospf6_interface
*)ifp
->info
;
2253 oi
= ospf6_interface_create(ifp
);
2256 oi
->priority
= strmatch(argv
[0]->text
, "no")
2257 ? OSPF6_INTERFACE_PRIORITY
2258 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2261 && (oi
->state
== OSPF6_INTERFACE_DROTHER
2262 || oi
->state
== OSPF6_INTERFACE_BDR
2263 || oi
->state
== OSPF6_INTERFACE_DR
)) {
2264 if (ospf6_interface_state_change(dr_election(oi
), oi
) == -1)
2265 OSPF6_LINK_LSA_SCHEDULE(oi
);
2271 ALIAS (ipv6_ospf6_priority
,
2272 no_ipv6_ospf6_priority_cmd
,
2273 "no ipv6 ospf6 priority [(0-255)]",
2280 DEFUN (ipv6_ospf6_instance
,
2281 ipv6_ospf6_instance_cmd
,
2282 "ipv6 ospf6 instance-id (0-255)",
2285 "Instance ID for this interface\n"
2286 "Instance ID value\n")
2288 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2290 struct ospf6_interface
*oi
;
2293 oi
= (struct ospf6_interface
*)ifp
->info
;
2295 oi
= ospf6_interface_create(ifp
);
2298 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
2299 ? OSPF6_INTERFACE_INSTANCE_ID
2300 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2304 ALIAS (ipv6_ospf6_instance
,
2305 no_ipv6_ospf6_instance_cmd
,
2306 "no ipv6 ospf6 instance-id [(0-255)]",
2310 "Instance ID for this interface\n"
2311 "Instance ID value\n")
2313 DEFUN (ipv6_ospf6_passive
,
2314 ipv6_ospf6_passive_cmd
,
2315 "ipv6 ospf6 passive",
2318 "Passive interface; no adjacency will be formed on this interface\n"
2321 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2322 struct ospf6_interface
*oi
;
2323 struct listnode
*node
, *nnode
;
2324 struct ospf6_neighbor
*on
;
2328 oi
= (struct ospf6_interface
*)ifp
->info
;
2330 oi
= ospf6_interface_create(ifp
);
2333 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2334 THREAD_OFF(oi
->thread_send_hello
);
2335 THREAD_OFF(oi
->thread_sso
);
2337 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
2338 THREAD_OFF(on
->inactivity_timer
);
2339 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
2345 DEFUN (no_ipv6_ospf6_passive
,
2346 no_ipv6_ospf6_passive_cmd
,
2347 "no ipv6 ospf6 passive",
2351 "passive interface: No Adjacency will be formed on this I/F\n"
2354 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2355 struct ospf6_interface
*oi
;
2358 oi
= (struct ospf6_interface
*)ifp
->info
;
2360 oi
= ospf6_interface_create(ifp
);
2363 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2364 THREAD_OFF(oi
->thread_send_hello
);
2365 THREAD_OFF(oi
->thread_sso
);
2367 /* don't send hellos over loopback interface */
2368 if (!if_is_loopback(oi
->interface
))
2369 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
2370 &oi
->thread_send_hello
);
2375 DEFUN (ipv6_ospf6_mtu_ignore
,
2376 ipv6_ospf6_mtu_ignore_cmd
,
2377 "ipv6 ospf6 mtu-ignore",
2380 "Disable MTU mismatch detection on this interface\n"
2383 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2384 struct ospf6_interface
*oi
;
2387 oi
= (struct ospf6_interface
*)ifp
->info
;
2389 oi
= ospf6_interface_create(ifp
);
2397 DEFUN (no_ipv6_ospf6_mtu_ignore
,
2398 no_ipv6_ospf6_mtu_ignore_cmd
,
2399 "no ipv6 ospf6 mtu-ignore",
2403 "Disable MTU mismatch detection on this interface\n"
2406 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2407 struct ospf6_interface
*oi
;
2410 oi
= (struct ospf6_interface
*)ifp
->info
;
2412 oi
= ospf6_interface_create(ifp
);
2420 DEFUN (ipv6_ospf6_advertise_prefix_list
,
2421 ipv6_ospf6_advertise_prefix_list_cmd
,
2422 "ipv6 ospf6 advertise prefix-list WORD",
2425 "Advertising options\n"
2426 "Filter prefix using prefix-list\n"
2427 "Prefix list name\n"
2430 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2432 struct ospf6_interface
*oi
;
2435 oi
= (struct ospf6_interface
*)ifp
->info
;
2437 oi
= ospf6_interface_create(ifp
);
2441 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2442 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
2444 ospf6_interface_connected_route_update(oi
->interface
);
2447 OSPF6_LINK_LSA_SCHEDULE(oi
);
2448 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2449 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2450 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2452 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2458 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
2459 no_ipv6_ospf6_advertise_prefix_list_cmd
,
2460 "no ipv6 ospf6 advertise prefix-list [WORD]",
2464 "Advertising options\n"
2465 "Filter prefix using prefix-list\n"
2466 "Prefix list name\n")
2468 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2469 struct ospf6_interface
*oi
;
2472 oi
= (struct ospf6_interface
*)ifp
->info
;
2474 oi
= ospf6_interface_create(ifp
);
2478 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2480 ospf6_interface_connected_route_update(oi
->interface
);
2483 OSPF6_LINK_LSA_SCHEDULE(oi
);
2484 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2485 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2486 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2488 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2494 DEFUN (ipv6_ospf6_network
,
2495 ipv6_ospf6_network_cmd
,
2496 "ipv6 ospf6 network <broadcast|point-to-point>",
2500 "Specify OSPF6 broadcast network\n"
2501 "Specify OSPF6 point-to-point network\n"
2504 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2505 int idx_network
= 3;
2506 struct ospf6_interface
*oi
;
2509 oi
= (struct ospf6_interface
*)ifp
->info
;
2511 oi
= ospf6_interface_create(ifp
);
2515 oi
->type_cfg
= true;
2517 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
2518 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
2521 oi
->type
= OSPF_IFTYPE_BROADCAST
;
2522 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
2523 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
2526 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
2529 /* Reset the interface */
2530 thread_execute(master
, interface_down
, oi
, 0);
2531 thread_execute(master
, interface_up
, oi
, 0);
2536 DEFUN (no_ipv6_ospf6_network
,
2537 no_ipv6_ospf6_network_cmd
,
2538 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2542 "Set default network type\n"
2543 "Specify OSPF6 broadcast network\n"
2544 "Specify OSPF6 point-to-point network\n")
2546 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2547 struct ospf6_interface
*oi
;
2552 oi
= (struct ospf6_interface
*)ifp
->info
;
2557 oi
->type_cfg
= false;
2559 type
= ospf6_default_iftype(ifp
);
2560 if (oi
->type
== type
) {
2565 /* Reset the interface */
2566 thread_execute(master
, interface_down
, oi
, 0);
2567 thread_execute(master
, interface_up
, oi
, 0);
2572 static int config_write_ospf6_interface(struct vty
*vty
, struct vrf
*vrf
)
2574 struct ospf6_interface
*oi
;
2575 struct interface
*ifp
;
2576 char buf
[INET_ADDRSTRLEN
];
2578 FOR_ALL_INTERFACES (vrf
, ifp
) {
2579 oi
= (struct ospf6_interface
*)ifp
->info
;
2583 if_vty_config_start(vty
, ifp
);
2586 vty_out(vty
, " description %s\n", ifp
->desc
);
2587 if (oi
->area_id_format
!= OSPF6_AREA_FMT_UNSET
) {
2588 area_id2str(buf
, sizeof(buf
), oi
->area_id
,
2589 oi
->area_id_format
);
2590 vty_out(vty
, " ipv6 ospf6 area %s\n", buf
);
2593 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
2595 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
2596 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
2598 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
2599 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
2600 oi
->hello_interval
);
2602 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
2603 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
2606 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
2607 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
2610 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
2611 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
2613 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
2614 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
2617 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
2618 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
2622 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
2625 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
2626 vty_out(vty
, " ipv6 ospf6 passive\n");
2629 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
2631 if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
2632 vty_out(vty
, " ipv6 ospf6 network point-to-point\n");
2633 else if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_BROADCAST
)
2634 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
2636 ospf6_bfd_write_config(vty
, oi
);
2638 ospf6_auth_write_config(vty
, &oi
->at_data
);
2639 if_vty_config_end(vty
);
2644 /* Configuration write function for ospfd. */
2645 static int config_write_interface(struct vty
*vty
)
2648 struct vrf
*vrf
= NULL
;
2650 /* Display all VRF aware OSPF interface configuration */
2651 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2652 write
+= config_write_ospf6_interface(vty
, vrf
);
2658 static int ospf6_ifp_create(struct interface
*ifp
)
2660 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2661 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp
->name
,
2662 ifp
->ifindex
, ifp
->mtu6
);
2665 ospf6_interface_start(ifp
->info
);
2670 static int ospf6_ifp_up(struct interface
*ifp
)
2672 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2674 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2675 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2676 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2678 ospf6_interface_state_update(ifp
);
2683 static int ospf6_ifp_down(struct interface
*ifp
)
2685 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2687 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2688 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2689 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2691 ospf6_interface_state_update(ifp
);
2696 static int ospf6_ifp_destroy(struct interface
*ifp
)
2699 zlog_warn("Zebra: got delete of %s, but interface is still up",
2702 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2703 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2704 ifp
->name
, ifp
->ifindex
, ifp
->mtu6
);
2707 ospf6_interface_stop(ifp
->info
);
2712 void ospf6_interface_init(void)
2714 /* Install interface node. */
2715 if_cmd_init(config_write_interface
);
2716 if_zapi_callbacks(ospf6_ifp_create
, ospf6_ifp_up
,
2717 ospf6_ifp_down
, ospf6_ifp_destroy
);
2719 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
2720 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
2721 install_element(VIEW_NODE
,
2722 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
2723 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
2725 install_element(INTERFACE_NODE
, &ipv6_ospf6_area_cmd
);
2726 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_area_cmd
);
2727 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
2728 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
2729 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
2730 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
2732 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
2733 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
2734 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
2735 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
2736 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
2737 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
2738 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
2739 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
2740 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
2741 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
2742 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
2743 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
2745 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
2746 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
2748 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
2749 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
2751 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
2752 install_element(INTERFACE_NODE
,
2753 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
2755 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
2756 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
2758 /* reference bandwidth commands */
2759 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
2760 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
2761 /* write-multiplier commands */
2762 install_element(OSPF6_NODE
, &ospf6_write_multiplier_cmd
);
2763 install_element(OSPF6_NODE
, &no_ospf6_write_multiplier_cmd
);
2766 /* Clear the specified interface structure */
2767 void ospf6_interface_clear(struct interface
*ifp
)
2769 struct ospf6_interface
*oi
;
2771 if (!if_is_operative(ifp
))
2774 if (ifp
->info
== NULL
)
2777 oi
= (struct ospf6_interface
*)ifp
->info
;
2779 if (IS_OSPF6_DEBUG_INTERFACE
)
2780 zlog_debug("Interface %s: clear by reset", ifp
->name
);
2782 /* Reset the interface */
2783 thread_execute(master
, interface_down
, oi
, 0);
2784 thread_execute(master
, interface_up
, oi
, 0);
2787 /* Clear interface */
2788 DEFUN (clear_ipv6_ospf6_interface
,
2789 clear_ipv6_ospf6_interface_cmd
,
2790 "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
2802 struct interface
*ifp
;
2803 const char *vrf_name
;
2805 if (argv_find(argv
, argc
, "vrf", &idx_vrf
))
2806 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
2808 vrf_name
= VRF_DEFAULT_NAME
;
2809 vrf
= vrf_lookup_by_name(vrf_name
);
2811 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2815 if (!argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
2816 /* Clear all the ospfv3 interfaces. */
2817 FOR_ALL_INTERFACES (vrf
, ifp
)
2818 ospf6_interface_clear(ifp
);
2820 /* Interface name is specified. */
2821 ifp
= if_lookup_by_name_vrf(argv
[idx_ifname
]->arg
, vrf
);
2823 vty_out(vty
, "No such Interface: %s\n",
2824 argv
[idx_ifname
]->arg
);
2827 ospf6_interface_clear(ifp
);
2833 void install_element_ospf6_clear_interface(void)
2835 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2838 DEFUN (debug_ospf6_interface
,
2839 debug_ospf6_interface_cmd
,
2840 "debug ospf6 interface",
2843 "Debug OSPFv3 Interface\n"
2846 OSPF6_DEBUG_INTERFACE_ON();
2850 DEFUN (no_debug_ospf6_interface
,
2851 no_debug_ospf6_interface_cmd
,
2852 "no debug ospf6 interface",
2856 "Debug OSPFv3 Interface\n"
2859 OSPF6_DEBUG_INTERFACE_OFF();
2863 int config_write_ospf6_debug_interface(struct vty
*vty
)
2865 if (IS_OSPF6_DEBUG_INTERFACE
)
2866 vty_out(vty
, "debug ospf6 interface\n");
2870 void install_element_ospf6_debug_interface(void)
2872 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2873 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2874 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2875 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);
2878 void ospf6_auth_write_config(struct vty
*vty
, struct ospf6_auth_data
*at_data
)
2880 if (CHECK_FLAG(at_data
->flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
))
2881 vty_out(vty
, " ipv6 ospf6 authentication keychain %s\n",
2883 else if (CHECK_FLAG(at_data
->flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
))
2885 " ipv6 ospf6 authentication key-id %d hash-algo %s key %s\n",
2887 keychain_get_algo_name_by_id(at_data
->hash_algo
),
2891 DEFUN(ipv6_ospf6_intf_auth_trailer_keychain
,
2892 ipv6_ospf6_intf_auth_trailer_keychain_cmd
,
2893 "ipv6 ospf6 authentication keychain KEYCHAIN_NAME",
2895 "Enable authentication on this interface\n"
2899 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2900 int keychain_idx
= 4;
2901 struct ospf6_interface
*oi
;
2903 oi
= (struct ospf6_interface
*)ifp
->info
;
2905 oi
= ospf6_interface_create(ifp
);
2908 if (CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
)) {
2910 "Manual key configured, unconfigure it before configuring key chain\n");
2911 return CMD_WARNING_CONFIG_FAILED
;
2914 SET_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
);
2915 if (oi
->at_data
.keychain
)
2916 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN
, oi
->at_data
.keychain
);
2918 oi
->at_data
.keychain
=
2919 XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN
, argv
[keychain_idx
]->arg
);
2924 DEFUN(no_ipv6_ospf6_intf_auth_trailer_keychain
,
2925 no_ipv6_ospf6_intf_auth_trailer_keychain_cmd
,
2926 "no ipv6 ospf6 authentication keychain [KEYCHAIN_NAME]",
2927 NO_STR IP6_STR OSPF6_STR
2928 "Enable authentication on this interface\n"
2932 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2933 struct ospf6_interface
*oi
;
2935 oi
= (struct ospf6_interface
*)ifp
->info
;
2937 oi
= ospf6_interface_create(ifp
);
2940 if (!CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
))
2943 if (oi
->at_data
.keychain
) {
2944 oi
->at_data
.flags
= 0;
2945 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN
, oi
->at_data
.keychain
);
2946 oi
->at_data
.keychain
= NULL
;
2952 DEFUN(ipv6_ospf6_intf_auth_trailer_key
, ipv6_ospf6_intf_auth_trailer_key_cmd
,
2953 "ipv6 ospf6 authentication key-id (1-65535) hash-algo "
2954 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
2960 "Cryptographic-algorithm\n"
2961 "Use MD5 algorithm\n"
2962 "Use HMAC-SHA-1 algorithm\n"
2963 "Use HMAC-SHA-256 algorithm\n"
2964 "Use HMAC-SHA-384 algorithm\n"
2965 "Use HMAC-SHA-512 algorithm\n"
2967 "Password string (key)\n")
2969 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2971 int hash_algo_idx
= 6;
2972 int password_idx
= 8;
2973 struct ospf6_interface
*oi
;
2974 uint8_t hash_algo
= KEYCHAIN_ALGO_NULL
;
2976 oi
= (struct ospf6_interface
*)ifp
->info
;
2978 oi
= ospf6_interface_create(ifp
);
2981 if (CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
)) {
2983 "key chain configured, unconfigure it before configuring manual key\n");
2984 return CMD_WARNING_CONFIG_FAILED
;
2987 hash_algo
= keychain_get_algo_id_by_name(argv
[hash_algo_idx
]->arg
);
2988 #ifndef CRYPTO_OPENSSL
2989 if (hash_algo
== KEYCHAIN_ALGO_NULL
) {
2991 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
2992 return CMD_WARNING_CONFIG_FAILED
;
2994 #endif /* CRYPTO_OPENSSL */
2996 SET_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
);
2997 oi
->at_data
.hash_algo
= hash_algo
;
2998 oi
->at_data
.key_id
= (uint16_t)strtol(argv
[key_id_idx
]->arg
, NULL
, 10);
2999 if (oi
->at_data
.auth_key
)
3000 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY
, oi
->at_data
.auth_key
);
3001 oi
->at_data
.auth_key
=
3002 XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY
, argv
[password_idx
]->arg
);
3007 DEFUN(no_ipv6_ospf6_intf_auth_trailer_key
,
3008 no_ipv6_ospf6_intf_auth_trailer_key_cmd
,
3009 "no ipv6 ospf6 authentication key-id [(1-65535) hash-algo "
3010 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
3012 NO_STR IP6_STR OSPF6_STR
3016 "Cryptographic-algorithm\n"
3017 "Use MD5 algorithm\n"
3018 "Use HMAC-SHA-1 algorithm\n"
3019 "Use HMAC-SHA-256 algorithm\n"
3020 "Use HMAC-SHA-384 algorithm\n"
3021 "Use HMAC-SHA-512 algorithm\n"
3023 "Password string (key)\n")
3025 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3026 struct ospf6_interface
*oi
;
3027 #ifndef CRYPTO_OPENSSL
3028 int hash_algo_idx
= 7;
3029 uint8_t hash_algo
= KEYCHAIN_ALGO_NULL
;
3030 #endif /* CRYPTO_OPENSSL */
3032 oi
= (struct ospf6_interface
*)ifp
->info
;
3034 oi
= ospf6_interface_create(ifp
);
3037 if (!CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
))
3040 #ifndef CRYPTO_OPENSSL
3041 hash_algo
= keychain_get_algo_id_by_name(argv
[hash_algo_idx
]->arg
);
3042 if (hash_algo
== KEYCHAIN_ALGO_NULL
) {
3044 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
3045 return CMD_WARNING_CONFIG_FAILED
;
3047 #endif /* CRYPTO_OPENSSL */
3049 if (oi
->at_data
.auth_key
) {
3050 oi
->at_data
.flags
= 0;
3051 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY
, oi
->at_data
.auth_key
);
3052 oi
->at_data
.auth_key
= NULL
;
3058 void ospf6_interface_auth_trailer_cmd_init(void)
3060 /*Install OSPF6 auth trailer commands at interface level */
3061 install_element(INTERFACE_NODE
,
3062 &ipv6_ospf6_intf_auth_trailer_keychain_cmd
);
3063 install_element(INTERFACE_NODE
,
3064 &no_ipv6_ospf6_intf_auth_trailer_keychain_cmd
);
3065 install_element(INTERFACE_NODE
, &ipv6_ospf6_intf_auth_trailer_key_cmd
);
3066 install_element(INTERFACE_NODE
,
3067 &no_ipv6_ospf6_intf_auth_trailer_key_cmd
);