1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2003 Yasuhiro Ohara
17 #include "ospf6_lsa.h"
18 #include "ospf6_lsdb.h"
19 #include "ospf6_top.h"
20 #include "ospf6_network.h"
21 #include "ospf6_message.h"
22 #include "ospf6_route.h"
23 #include "ospf6_area.h"
24 #include "ospf6_abr.h"
25 #include "ospf6_nssa.h"
26 #include "ospf6_interface.h"
27 #include "ospf6_neighbor.h"
28 #include "ospf6_intra.h"
29 #include "ospf6_spf.h"
31 #include "ospf6_bfd.h"
32 #include "ospf6_zebra.h"
35 #include "ospf6_proto.h"
36 #include "lib/keychain.h"
37 #include "ospf6_auth_trailer.h"
39 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_IF
, "OSPF6 interface");
40 DEFINE_MTYPE(OSPF6D
, OSPF6_AUTH_KEYCHAIN
, "OSPF6 auth keychain");
41 DEFINE_MTYPE(OSPF6D
, OSPF6_AUTH_MANUAL_KEY
, "OSPF6 auth key");
42 DEFINE_MTYPE_STATIC(OSPF6D
, CFG_PLIST_NAME
, "configured prefix list names");
43 DEFINE_QOBJ_TYPE(ospf6_interface
);
44 DEFINE_HOOK(ospf6_interface_change
,
45 (struct ospf6_interface
* oi
, int state
, int old_state
),
46 (oi
, state
, old_state
));
48 unsigned char conf_debug_ospf6_interface
= 0;
50 const char *const ospf6_interface_state_str
[] = {
51 "None", "Down", "Loopback", "Waiting", "PointToPoint",
52 "DROther", "BDR", "DR", NULL
};
54 int ospf6_interface_neighbor_count(struct ospf6_interface
*oi
)
57 struct ospf6_neighbor
*nbr
= NULL
;
58 struct listnode
*node
;
60 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, nbr
)) {
61 /* Down state is not shown. */
62 if (nbr
->state
== OSPF6_NEIGHBOR_DOWN
)
70 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
,
73 struct ospf6_interface
*oi
;
74 struct interface
*ifp
;
76 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
78 return (struct ospf6_interface
*)NULL
;
80 oi
= (struct ospf6_interface
*)ifp
->info
;
84 /* schedule routing table recalculation */
85 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
88 struct ospf6_interface
*oi
;
94 switch (ntohs(lsa
->header
->type
)) {
95 case OSPF6_LSTYPE_LINK
:
96 if (oi
->state
== OSPF6_INTERFACE_DR
)
97 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
99 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
107 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
109 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
112 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
114 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
117 static uint8_t ospf6_default_iftype(struct interface
*ifp
)
119 if (if_is_pointopoint(ifp
))
120 return OSPF_IFTYPE_POINTOPOINT
;
121 else if (if_is_loopback(ifp
))
122 return OSPF_IFTYPE_LOOPBACK
;
124 return OSPF_IFTYPE_BROADCAST
;
127 static uint32_t ospf6_interface_get_cost(struct ospf6_interface
*oi
)
129 /* If all else fails, use default OSPF cost */
133 /* interface speed and bw can be 0 in some platforms,
134 * use ospf default bw. If bw is configured then it would
137 if (!oi
->interface
->bandwidth
&& oi
->interface
->speed
) {
138 bw
= oi
->interface
->speed
;
140 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
141 : OSPF6_INTERFACE_BANDWIDTH
;
144 ospf6
= oi
->interface
->vrf
->info
;
145 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
147 /* A specified ip ospf cost overrides a calculated one. */
148 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
151 cost
= (uint32_t)((double)refbw
/ (double)bw
+ (double)0.5);
159 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface
*oi
)
161 /* update cost held in route_connected list in ospf6_interface */
162 ospf6_interface_connected_route_update(oi
->interface
);
164 /* execute LSA hooks */
166 OSPF6_LINK_LSA_SCHEDULE(oi
);
167 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
168 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
169 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
170 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
174 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
178 newcost
= ospf6_interface_get_cost(oi
);
179 if (newcost
== oi
->cost
)
183 ospf6_interface_force_recalculate_cost(oi
);
186 /* Create new ospf6 interface structure */
187 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
189 struct ospf6_interface
*oi
;
190 unsigned int iobuflen
;
192 oi
= XCALLOC(MTYPE_OSPF6_IF
, sizeof(struct ospf6_interface
));
194 oi
->obuf
= ospf6_fifo_new();
196 oi
->area
= (struct ospf6_area
*)NULL
;
197 oi
->neighbor_list
= list_new();
198 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
199 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
200 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
201 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
202 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
204 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
205 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
206 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
207 oi
->type
= ospf6_default_iftype(ifp
);
208 oi
->state
= OSPF6_INTERFACE_DOWN
;
213 /* Try to adjust I/O buffer size with IfMtu */
214 oi
->ifmtu
= ifp
->mtu6
;
215 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
216 if (oi
->ifmtu
> iobuflen
) {
217 if (IS_OSPF6_DEBUG_INTERFACE
)
219 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
220 ifp
->name
, iobuflen
);
221 oi
->ifmtu
= iobuflen
;
224 QOBJ_REG(oi
, ospf6_interface
);
226 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
227 oi
->lsack_list
= ospf6_lsdb_create(oi
);
228 oi
->lsdb
= ospf6_lsdb_create(oi
);
229 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
230 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
231 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
233 oi
->route_connected
=
234 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
235 oi
->route_connected
->scope
= oi
;
242 oi
->cost
= ospf6_interface_get_cost(oi
);
244 oi
->at_data
.flags
= 0;
249 void ospf6_interface_delete(struct ospf6_interface
*oi
)
251 struct listnode
*node
, *nnode
;
252 struct ospf6_neighbor
*on
;
256 ospf6_fifo_free(oi
->obuf
);
258 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
259 ospf6_neighbor_delete(on
);
261 list_delete(&oi
->neighbor_list
);
263 THREAD_OFF(oi
->thread_send_hello
);
264 THREAD_OFF(oi
->thread_send_lsupdate
);
265 THREAD_OFF(oi
->thread_send_lsack
);
266 THREAD_OFF(oi
->thread_sso
);
267 THREAD_OFF(oi
->thread_wait_timer
);
269 ospf6_lsdb_remove_all(oi
->lsdb
);
270 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
271 ospf6_lsdb_remove_all(oi
->lsack_list
);
273 ospf6_lsdb_delete(oi
->lsdb
);
274 ospf6_lsdb_delete(oi
->lsdb_self
);
276 ospf6_lsdb_delete(oi
->lsupdate_list
);
277 ospf6_lsdb_delete(oi
->lsack_list
);
279 ospf6_route_table_delete(oi
->route_connected
);
282 oi
->interface
->info
= NULL
;
286 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
288 /* disable from area list if possible */
289 ospf6_area_interface_delete(oi
);
291 if (oi
->at_data
.auth_key
)
292 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY
, oi
->at_data
.auth_key
);
294 /* Free BFD allocated data. */
295 XFREE(MTYPE_TMP
, oi
->bfd_config
.profile
);
297 XFREE(MTYPE_OSPF6_IF
, oi
);
300 void ospf6_interface_enable(struct ospf6_interface
*oi
)
302 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
303 ospf6_interface_state_update(oi
->interface
);
306 void ospf6_interface_disable(struct ospf6_interface
*oi
)
308 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
310 thread_execute(master
, interface_down
, oi
, 0);
312 ospf6_lsdb_remove_all(oi
->lsdb
);
313 ospf6_lsdb_remove_all(oi
->lsdb_self
);
314 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
315 ospf6_lsdb_remove_all(oi
->lsack_list
);
317 THREAD_OFF(oi
->thread_send_hello
);
318 THREAD_OFF(oi
->thread_send_lsupdate
);
319 THREAD_OFF(oi
->thread_send_lsack
);
320 THREAD_OFF(oi
->thread_sso
);
322 THREAD_OFF(oi
->thread_network_lsa
);
323 THREAD_OFF(oi
->thread_link_lsa
);
324 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
325 THREAD_OFF(oi
->thread_as_extern_lsa
);
326 THREAD_OFF(oi
->thread_wait_timer
);
329 static struct in6_addr
*
330 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
334 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
336 /* for each connected address */
337 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
338 /* if family not AF_INET6, ignore */
339 if (c
->address
->family
!= AF_INET6
)
342 /* linklocal scope check */
343 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
344 l
= &c
->address
->u
.prefix6
;
349 void ospf6_interface_state_update(struct interface
*ifp
)
351 struct ospf6_interface
*oi
;
352 unsigned int iobuflen
;
354 oi
= (struct ospf6_interface
*)ifp
->info
;
357 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
360 /* Adjust the mtu values if the kernel told us something new */
361 if (ifp
->mtu6
!= oi
->ifmtu
) {
362 /* If nothing configured, accept it and check for buffer size */
364 oi
->ifmtu
= ifp
->mtu6
;
365 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
366 if (oi
->ifmtu
> iobuflen
) {
367 if (IS_OSPF6_DEBUG_INTERFACE
)
369 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
370 ifp
->name
, iobuflen
);
371 oi
->ifmtu
= iobuflen
;
373 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
374 oi
->ifmtu
= ifp
->mtu6
;
376 "Configured mtu %u on %s overridden by kernel %u",
377 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
379 oi
->ifmtu
= oi
->c_ifmtu
;
382 if (if_is_operative(ifp
)
383 && (ospf6_interface_get_linklocal_address(oi
->interface
)
384 || if_is_loopback(oi
->interface
)))
385 thread_execute(master
, interface_up
, oi
, 0);
387 thread_execute(master
, interface_down
, oi
, 0);
392 void ospf6_interface_connected_route_update(struct interface
*ifp
)
394 struct ospf6_interface
*oi
;
395 struct ospf6_route
*route
;
397 struct listnode
*node
, *nnode
;
398 struct in6_addr nh_addr
;
400 oi
= (struct ospf6_interface
*)ifp
->info
;
404 /* reset linklocal pointer */
405 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
407 /* if area is null, do not make connected-route list */
408 if (oi
->area
== NULL
)
411 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
414 /* update "route to advertise" interface route table */
415 ospf6_route_remove_all(oi
->route_connected
);
417 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
418 if (c
->address
->family
!= AF_INET6
)
421 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
423 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
425 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
427 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
429 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
433 if (oi
->plist_name
) {
434 struct prefix_list
*plist
;
435 enum prefix_list_type ret
;
437 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
438 ret
= prefix_list_apply(plist
, (void *)c
->address
);
439 if (ret
== PREFIX_DENY
) {
440 if (IS_OSPF6_DEBUG_INTERFACE
)
442 "%pFX on %s filtered by prefix-list %s ",
443 c
->address
, oi
->interface
->name
,
449 route
= ospf6_route_create(oi
->area
->ospf6
);
450 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
451 apply_mask(&route
->prefix
);
452 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
453 route
->path
.area_id
= oi
->area
->area_id
;
454 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
455 route
->path
.cost
= oi
->cost
;
456 inet_pton(AF_INET6
, "::1", &nh_addr
);
457 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
459 ospf6_route_add(route
, oi
->route_connected
);
462 /* create new Link-LSA */
463 OSPF6_LINK_LSA_SCHEDULE(oi
);
464 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
465 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
468 static int ospf6_interface_state_change(uint8_t next_state
,
469 struct ospf6_interface
*oi
)
474 prev_state
= oi
->state
;
475 oi
->state
= next_state
;
477 if (prev_state
== next_state
)
484 if (IS_OSPF6_DEBUG_INTERFACE
) {
485 zlog_debug("Interface state change %s: %s -> %s",
487 ospf6_interface_state_str
[prev_state
],
488 ospf6_interface_state_str
[next_state
]);
492 ospf6
= oi
->area
->ospf6
;
494 if ((prev_state
== OSPF6_INTERFACE_DR
495 || prev_state
== OSPF6_INTERFACE_BDR
)
496 && (next_state
!= OSPF6_INTERFACE_DR
497 && next_state
!= OSPF6_INTERFACE_BDR
))
498 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
499 IPV6_LEAVE_GROUP
, ospf6
->fd
);
501 if ((prev_state
!= OSPF6_INTERFACE_DR
502 && prev_state
!= OSPF6_INTERFACE_BDR
)
503 && (next_state
== OSPF6_INTERFACE_DR
504 || next_state
== OSPF6_INTERFACE_BDR
))
505 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
506 IPV6_JOIN_GROUP
, ospf6
->fd
);
508 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
509 OSPF6_LINK_LSA_SCHEDULE(oi
);
510 if (next_state
== OSPF6_INTERFACE_DOWN
) {
511 OSPF6_NETWORK_LSA_EXECUTE(oi
);
512 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
513 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
514 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
515 } else if (prev_state
== OSPF6_INTERFACE_DR
516 || next_state
== OSPF6_INTERFACE_DR
) {
517 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
518 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
519 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
522 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
528 /* DR Election, RFC2328 section 9.4 */
530 #define IS_ELIGIBLE(n) \
531 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
533 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
534 struct ospf6_neighbor
*b
)
536 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
537 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
539 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
541 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
544 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
546 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
549 if (a
->priority
> b
->priority
)
551 if (a
->priority
< b
->priority
)
554 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
556 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
559 zlog_warn("Router-ID duplicate ?");
563 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
564 struct ospf6_neighbor
*b
)
566 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
567 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
569 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
571 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
574 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
576 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
579 if (a
->priority
> b
->priority
)
581 if (a
->priority
< b
->priority
)
584 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
586 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
589 zlog_warn("Router-ID duplicate ?");
593 uint8_t dr_election(struct ospf6_interface
*oi
)
595 struct listnode
*node
, *nnode
;
596 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
597 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
598 uint8_t next_state
= 0;
600 drouter
= bdrouter
= NULL
;
601 best_drouter
= best_bdrouter
= NULL
;
603 /* pseudo neighbor myself, including noting current DR/BDR (1) */
604 memset(&myself
, 0, sizeof(myself
));
605 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
606 sizeof(myself
.name
));
607 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
608 myself
.drouter
= oi
->drouter
;
609 myself
.bdrouter
= oi
->bdrouter
;
610 myself
.priority
= oi
->priority
;
611 myself
.router_id
= oi
->area
->ospf6
->router_id
;
613 /* Electing BDR (2) */
614 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
615 bdrouter
= better_bdrouter(bdrouter
, on
);
617 best_bdrouter
= bdrouter
;
618 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
620 /* Electing DR (3) */
621 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
622 drouter
= better_drouter(drouter
, on
);
624 best_drouter
= drouter
;
625 drouter
= better_drouter(best_drouter
, &myself
);
629 /* the router itself is newly/no longer DR/BDR (4) */
630 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
631 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
632 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
633 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
634 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
635 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
637 /* compatible to Electing BDR (2) */
638 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
640 /* compatible to Electing DR (3) */
641 drouter
= better_drouter(best_drouter
, &myself
);
646 /* Set interface state accordingly (5) */
647 if (drouter
&& drouter
== &myself
)
648 next_state
= OSPF6_INTERFACE_DR
;
649 else if (bdrouter
&& bdrouter
== &myself
)
650 next_state
= OSPF6_INTERFACE_BDR
;
652 next_state
= OSPF6_INTERFACE_DROTHER
;
654 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
657 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
658 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
659 accordingly after AdjOK */
660 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
661 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
662 if (IS_OSPF6_DEBUG_INTERFACE
)
663 zlog_debug("DR Election on %s: DR: %s BDR: %s",
665 (drouter
? drouter
->name
: "0.0.0.0"),
666 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
668 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
669 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
671 /* Schedule AdjOK. */
672 thread_add_event(master
, adj_ok
, on
, 0,
677 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
678 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
686 static bool ifmaddr_check(ifindex_t ifindex
, struct in6_addr
*addr
)
688 struct ifmaddrs
*ifmap
, *ifma
;
689 struct sockaddr_dl
*sdl
;
690 struct sockaddr_in6
*sin6
;
693 if (getifmaddrs(&ifmap
) != 0)
696 for (ifma
= ifmap
; ifma
; ifma
= ifma
->ifma_next
) {
697 if (ifma
->ifma_name
== NULL
|| ifma
->ifma_addr
== NULL
)
699 if (ifma
->ifma_name
->sa_family
!= AF_LINK
)
701 if (ifma
->ifma_addr
->sa_family
!= AF_INET6
)
703 sdl
= (struct sockaddr_dl
*)ifma
->ifma_name
;
704 sin6
= (struct sockaddr_in6
*)ifma
->ifma_addr
;
705 if (sdl
->sdl_index
== ifindex
706 && memcmp(&sin6
->sin6_addr
, addr
, IPV6_MAX_BYTELEN
) == 0) {
718 #endif /* __FreeBSD__ */
720 /* Interface State Machine */
721 void interface_up(struct thread
*thread
)
723 struct ospf6_interface
*oi
;
726 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
727 assert(oi
&& oi
->interface
);
730 oi
->type
= ospf6_default_iftype(oi
->interface
);
732 thread_cancel(&oi
->thread_sso
);
734 if (IS_OSPF6_DEBUG_INTERFACE
)
735 zlog_debug("Interface Event %s: [InterfaceUp]",
736 oi
->interface
->name
);
738 /* check physical interface is up */
739 if (!if_is_operative(oi
->interface
)) {
740 zlog_warn("Interface %s is down, can't execute [InterfaceUp]",
741 oi
->interface
->name
);
745 /* check interface has a link-local address */
746 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
747 || if_is_loopback(oi
->interface
))) {
749 "Interface %s has no link local address, can't execute [InterfaceUp]",
750 oi
->interface
->name
);
755 ospf6_interface_recalculate_cost(oi
);
757 /* if already enabled, do nothing */
758 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
759 if (IS_OSPF6_DEBUG_INTERFACE
)
760 zlog_debug("Interface %s already enabled",
761 oi
->interface
->name
);
765 /* If no area assigned, return */
766 if (oi
->area
== NULL
) {
768 "%s: Not scheduling Hello for %s as there is no area assigned yet",
769 __func__
, oi
->interface
->name
);
775 * There's a delay in FreeBSD between issuing a command to leave a
776 * multicast group and an actual leave. If we execute "no router ospf6"
777 * and "router ospf6" fast enough, we can end up in a situation when OS
778 * performs the leave later than it performs the join and the interface
779 * remains without a multicast group. We have to do the join only after
780 * the interface actually left the group.
782 if (ifmaddr_check(oi
->interface
->ifindex
, &allspfrouters6
)) {
784 "Interface %s is still in all routers group, rescheduling for SSO",
785 oi
->interface
->name
);
786 thread_add_timer(master
, interface_up
, oi
,
787 OSPF6_INTERFACE_SSO_RETRY_INT
,
791 #endif /* __FreeBSD__ */
793 ospf6
= oi
->area
->ospf6
;
795 /* Join AllSPFRouters */
796 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
,
799 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
801 "Scheduling %s for sso retry, trial count: %d",
802 oi
->interface
->name
, oi
->sso_try_cnt
);
803 thread_add_timer(master
, interface_up
, oi
,
804 OSPF6_INTERFACE_SSO_RETRY_INT
,
809 oi
->sso_try_cnt
= 0; /* Reset on success */
811 /* Update interface route */
812 ospf6_interface_connected_route_update(oi
->interface
);
815 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
816 && !if_is_loopback(oi
->interface
)) {
817 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
818 &oi
->thread_send_hello
);
821 /* decide next interface state */
822 if (oi
->type
== OSPF_IFTYPE_LOOPBACK
) {
823 ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK
, oi
);
824 } else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
825 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
826 } else if (oi
->priority
== 0)
827 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
829 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
830 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
831 &oi
->thread_wait_timer
);
835 void wait_timer(struct thread
*thread
)
837 struct ospf6_interface
*oi
;
839 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
840 assert(oi
&& oi
->interface
);
842 if (IS_OSPF6_DEBUG_INTERFACE
)
843 zlog_debug("Interface Event %s: [WaitTimer]",
844 oi
->interface
->name
);
846 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
847 ospf6_interface_state_change(dr_election(oi
), oi
);
850 void backup_seen(struct thread
*thread
)
852 struct ospf6_interface
*oi
;
854 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
855 assert(oi
&& oi
->interface
);
857 if (IS_OSPF6_DEBUG_INTERFACE
)
858 zlog_debug("Interface Event %s: [BackupSeen]",
859 oi
->interface
->name
);
861 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
862 ospf6_interface_state_change(dr_election(oi
), oi
);
865 void neighbor_change(struct thread
*thread
)
867 struct ospf6_interface
*oi
;
869 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
870 assert(oi
&& oi
->interface
);
872 if (IS_OSPF6_DEBUG_INTERFACE
)
873 zlog_debug("Interface Event %s: [NeighborChange]",
874 oi
->interface
->name
);
876 if (oi
->state
== OSPF6_INTERFACE_DROTHER
877 || oi
->state
== OSPF6_INTERFACE_BDR
878 || oi
->state
== OSPF6_INTERFACE_DR
)
879 ospf6_interface_state_change(dr_election(oi
), oi
);
882 void interface_down(struct thread
*thread
)
884 struct ospf6_interface
*oi
;
885 struct listnode
*node
, *nnode
;
886 struct ospf6_neighbor
*on
;
889 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
890 assert(oi
&& oi
->interface
);
892 if (IS_OSPF6_DEBUG_INTERFACE
)
893 zlog_debug("Interface Event %s: [InterfaceDown]",
894 oi
->interface
->name
);
897 THREAD_OFF(oi
->thread_send_hello
);
899 /* Stop trying to set socket options. */
900 THREAD_OFF(oi
->thread_sso
);
902 /* Cease the HELPER role for all the neighbours
905 if (ospf6_interface_neighbor_count(oi
)) {
907 struct ospf6_neighbor
*nbr
= NULL
;
909 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, ln
, nbr
))
910 ospf6_gr_helper_exit(nbr
, OSPF6_GR_HELPER_TOPO_CHG
);
913 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
914 ospf6_neighbor_delete(on
);
916 list_delete_all_node(oi
->neighbor_list
);
918 /* When interface state is reset, also reset information about
919 * DR election, as it is no longer valid. */
920 oi
->drouter
= oi
->prev_drouter
= htonl(0);
921 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
923 if (oi
->area
== NULL
)
926 ospf6
= oi
->area
->ospf6
;
927 /* Leave AllSPFRouters */
928 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
929 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
930 IPV6_LEAVE_GROUP
, ospf6
->fd
);
932 /* deal with write fifo */
933 ospf6_fifo_flush(oi
->obuf
);
934 if (oi
->on_write_q
) {
935 listnode_delete(ospf6
->oi_write_q
, oi
);
936 if (list_isempty(ospf6
->oi_write_q
))
937 thread_cancel(&ospf6
->t_write
);
941 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
945 static const char *ospf6_iftype_str(uint8_t iftype
)
948 case OSPF_IFTYPE_LOOPBACK
:
950 case OSPF_IFTYPE_BROADCAST
:
952 case OSPF_IFTYPE_POINTOPOINT
:
953 return "POINTOPOINT";
958 /* show specified interface structure */
959 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
,
960 json_object
*json_obj
, bool use_json
)
962 struct ospf6_interface
*oi
;
966 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
967 uint8_t default_iftype
;
968 struct timeval res
, now
;
970 struct ospf6_lsa
*lsa
, *lsanext
;
971 json_object
*json_arr
;
972 json_object
*json_addr
;
973 struct json_object
*json_auth
= NULL
;
975 default_iftype
= ospf6_default_iftype(ifp
);
978 json_object_string_add(json_obj
, "status",
979 (if_is_operative(ifp
) ? "up" : "down"));
980 json_object_string_add(json_obj
, "type",
981 ospf6_iftype_str(default_iftype
));
982 json_object_int_add(json_obj
, "interfaceId", ifp
->ifindex
);
984 if (ifp
->info
== NULL
)
987 oi
= (struct ospf6_interface
*)ifp
->info
;
989 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
990 json_object_string_add(json_obj
, "operatingAsType",
991 ospf6_iftype_str(oi
->type
));
994 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
995 (if_is_operative(ifp
) ? "up" : "down"),
996 ospf6_iftype_str(default_iftype
));
997 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
999 if (ifp
->info
== NULL
) {
1000 vty_out(vty
, " OSPF not enabled on this interface\n");
1003 oi
= (struct ospf6_interface
*)ifp
->info
;
1005 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
1006 vty_out(vty
, " Operating as type %s\n",
1007 ospf6_iftype_str(oi
->type
));
1011 json_arr
= json_object_new_array();
1012 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1013 json_addr
= json_object_new_object();
1015 prefix2str(p
, strbuf
, sizeof(strbuf
));
1016 switch (p
->family
) {
1018 json_object_string_add(json_addr
, "type",
1020 json_object_string_add(json_addr
, "address",
1022 json_object_array_add(json_arr
, json_addr
);
1025 json_object_string_add(json_addr
, "type",
1027 json_object_string_add(json_addr
, "address",
1029 json_object_array_add(json_arr
, json_addr
);
1032 json_object_string_add(json_addr
, "type",
1034 json_object_string_add(json_addr
, "address",
1036 json_object_array_add(json_arr
, json_addr
);
1040 json_object_object_add(json_obj
, "internetAddress", json_arr
);
1042 vty_out(vty
, " Internet Address:\n");
1044 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1046 prefix2str(p
, strbuf
, sizeof(strbuf
));
1047 switch (p
->family
) {
1049 vty_out(vty
, " inet : %pFX\n", p
);
1052 vty_out(vty
, " inet6: %pFX\n", p
);
1055 vty_out(vty
, " ??? : %pFX\n", p
);
1063 json_object_boolean_true_add(json_obj
,
1065 json_object_int_add(json_obj
, "instanceId",
1067 json_object_int_add(json_obj
, "interfaceMtu",
1069 json_object_int_add(json_obj
, "autoDetect", ifp
->mtu6
);
1070 json_object_string_add(json_obj
, "mtuMismatchDetection",
1071 oi
->mtu_ignore
? "disabled"
1073 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1075 json_object_string_add(json_obj
, "areaId", strbuf
);
1076 json_object_int_add(json_obj
, "cost", oi
->cost
);
1078 json_object_boolean_false_add(json_obj
,
1084 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1085 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
1086 vty_out(vty
, " MTU mismatch detection: %s\n",
1087 oi
->mtu_ignore
? "disabled" : "enabled");
1088 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1090 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
,
1093 vty_out(vty
, " Not Attached to Area\n");
1097 json_object_string_add(json_obj
, "ospf6InterfaceState",
1098 ospf6_interface_state_str
[oi
->state
]);
1099 json_object_int_add(json_obj
, "transmitDelaySec",
1101 json_object_int_add(json_obj
, "priority", oi
->priority
);
1102 json_object_int_add(json_obj
, "timerIntervalsConfigHello",
1103 oi
->hello_interval
);
1104 json_object_int_add(json_obj
, "timerIntervalsConfigDead",
1106 json_object_int_add(json_obj
, "timerIntervalsConfigRetransmit",
1108 json_object_boolean_add(
1109 json_obj
, "timerPassiveIface",
1110 !!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
));
1112 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
1113 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
1115 vty_out(vty
, " Timer intervals configured:\n");
1116 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
1118 " Hello %d(%pTHd), Dead %d, Retransmit %d\n",
1119 oi
->hello_interval
, oi
->thread_send_hello
,
1120 oi
->dead_interval
, oi
->rxmt_interval
);
1122 vty_out(vty
, " No Hellos (Passive interface)\n");
1125 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
1126 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
1128 json_object_string_add(json_obj
, "dr", drouter
);
1129 json_object_string_add(json_obj
, "bdr", bdrouter
);
1130 json_object_int_add(json_obj
, "numberOfInterfaceScopedLsa",
1133 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
1134 vty_out(vty
, " Number of I/F scoped LSAs is %u\n",
1142 if (thread_is_scheduled(oi
->thread_send_lsupdate
))
1143 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1145 timerstring(&res
, duration
, sizeof(duration
));
1146 json_object_int_add(json_obj
, "pendingLsaLsUpdateCount",
1147 oi
->lsupdate_list
->count
);
1148 json_object_string_add(json_obj
, "pendingLsaLsUpdateTime",
1150 json_object_string_add(
1151 json_obj
, "lsUpdateSendThread",
1152 (thread_is_scheduled(oi
->thread_send_lsupdate
)
1156 json_arr
= json_object_new_array();
1157 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1158 json_object_array_add(
1159 json_arr
, json_object_new_string(lsa
->name
));
1160 json_object_object_add(json_obj
, "pendingLsaLsUpdate",
1164 if (thread_is_scheduled(oi
->thread_send_lsack
))
1165 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1166 timerstring(&res
, duration
, sizeof(duration
));
1168 json_object_int_add(json_obj
, "pendingLsaLsAckCount",
1169 oi
->lsack_list
->count
);
1170 json_object_string_add(json_obj
, "pendingLsaLsAckTime",
1172 json_object_string_add(
1173 json_obj
, "lsAckSendThread",
1174 (thread_is_scheduled(oi
->thread_send_lsack
) ? "on"
1177 json_arr
= json_object_new_array();
1178 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1179 json_object_array_add(
1180 json_arr
, json_object_new_string(lsa
->name
));
1181 json_object_object_add(json_obj
, "pendingLsaLsAck", json_arr
);
1185 if (thread_is_scheduled(oi
->thread_send_lsupdate
))
1186 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1188 timerstring(&res
, duration
, sizeof(duration
));
1190 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1191 oi
->lsupdate_list
->count
, duration
,
1192 (thread_is_scheduled(oi
->thread_send_lsupdate
)
1195 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1196 vty_out(vty
, " %s\n", lsa
->name
);
1199 if (thread_is_scheduled(oi
->thread_send_lsack
))
1200 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1201 timerstring(&res
, duration
, sizeof(duration
));
1203 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1204 oi
->lsack_list
->count
, duration
,
1205 (thread_is_scheduled(oi
->thread_send_lsack
) ? "on"
1207 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1208 vty_out(vty
, " %s\n", lsa
->name
);
1212 if (oi
->bfd_config
.enabled
) {
1214 struct json_object
*json_bfd
= json_object_new_object();
1216 json_object_int_add(
1217 json_bfd
, "detectMultiplier",
1218 oi
->bfd_config
.detection_multiplier
);
1219 json_object_int_add(json_bfd
, "rxMinInterval",
1220 oi
->bfd_config
.min_rx
);
1221 json_object_int_add(json_bfd
, "txMinInterval",
1222 oi
->bfd_config
.min_tx
);
1223 json_object_object_add(json_obj
, "peerBfdInfo",
1227 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1228 oi
->bfd_config
.detection_multiplier
,
1229 oi
->bfd_config
.min_rx
, oi
->bfd_config
.min_tx
);
1234 json_auth
= json_object_new_object();
1235 if (oi
->at_data
.flags
!= 0) {
1237 if (CHECK_FLAG(oi
->at_data
.flags
,
1238 OSPF6_AUTH_TRAILER_KEYCHAIN
)) {
1239 json_object_string_add(json_auth
, "authType",
1241 json_object_string_add(json_auth
,
1243 oi
->at_data
.keychain
);
1244 } else if (CHECK_FLAG(oi
->at_data
.flags
,
1245 OSPF6_AUTH_TRAILER_MANUAL_KEY
))
1246 json_object_string_add(json_auth
, "authType",
1248 json_object_int_add(json_auth
, "txPktDrop",
1249 oi
->at_data
.tx_drop
);
1250 json_object_int_add(json_auth
, "rxPktDrop",
1251 oi
->at_data
.rx_drop
);
1253 if (CHECK_FLAG(oi
->at_data
.flags
,
1254 OSPF6_AUTH_TRAILER_KEYCHAIN
))
1256 " Authentication Trailer is enabled with key-chain %s\n",
1257 oi
->at_data
.keychain
);
1258 else if (CHECK_FLAG(oi
->at_data
.flags
,
1259 OSPF6_AUTH_TRAILER_MANUAL_KEY
))
1261 " Authentication trailer is enabled with manual key\n");
1263 " Packet drop Tx %u, Packet drop Rx %u\n",
1264 oi
->at_data
.tx_drop
, oi
->at_data
.rx_drop
);
1268 json_object_string_add(json_auth
, "authType", "NULL");
1270 vty_out(vty
, " Authentication Trailer is disabled\n");
1274 json_object_object_add(json_obj
, "authInfo", json_auth
);
1279 /* Find the global address to be used as a forwarding address in NSSA LSA.*/
1280 struct in6_addr
*ospf6_interface_get_global_address(struct interface
*ifp
)
1283 struct connected
*c
;
1285 /* for each connected address */
1286 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
1287 /* if family not AF_INET6, ignore */
1288 if (c
->address
->family
!= AF_INET6
)
1291 if (!IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
1292 return &c
->address
->u
.prefix6
;
1299 static int show_ospf6_interface_common(struct vty
*vty
, vrf_id_t vrf_id
,
1300 int argc
, struct cmd_token
**argv
,
1301 int idx_ifname
, int intf_idx
,
1302 int json_idx
, bool uj
)
1305 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
1306 struct interface
*ifp
;
1308 json_object
*json_int
;
1311 json
= json_object_new_object();
1312 if (argc
== json_idx
) {
1313 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1314 json_int
= json_object_new_object();
1316 json_object_string_add(json
, "noSuchInterface",
1317 argv
[idx_ifname
]->arg
);
1318 vty_json(vty
, json
);
1319 json_object_free(json_int
);
1322 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1323 json_object_object_add(json
, ifp
->name
, json_int
);
1325 FOR_ALL_INTERFACES (vrf
, ifp
) {
1326 json_int
= json_object_new_object();
1327 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1328 json_object_object_add(json
, ifp
->name
,
1332 vty_json(vty
, json
);
1334 if (argc
== intf_idx
) {
1335 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1337 vty_out(vty
, "No such Interface: %s\n",
1338 argv
[idx_ifname
]->arg
);
1341 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1343 FOR_ALL_INTERFACES (vrf
, ifp
)
1344 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1350 /* show interface */
1351 DEFUN(show_ipv6_ospf6_interface
, show_ipv6_ospf6_interface_ifname_cmd
,
1352 "show ipv6 ospf6 [vrf <NAME|all>] interface [IFNAME] [json]",
1353 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1354 "All VRFs\n" INTERFACE_STR IFNAME_STR JSON_STR
)
1359 struct listnode
*node
;
1360 struct ospf6
*ospf6
;
1361 const char *vrf_name
= NULL
;
1362 bool all_vrf
= false;
1364 bool uj
= use_json(argc
, argv
);
1366 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1373 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1374 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1375 show_ospf6_interface_common(vty
, ospf6
->vrf_id
, argc
,
1376 argv
, idx_ifname
, intf_idx
,
1384 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1389 static int ospf6_interface_show_traffic(struct vty
*vty
,
1390 struct interface
*intf_ifp
,
1391 int display_once
, json_object
*json
,
1392 bool use_json
, vrf_id_t vrf_id
)
1394 struct interface
*ifp
;
1395 struct vrf
*vrf
= NULL
;
1396 struct ospf6_interface
*oi
= NULL
;
1397 json_object
*json_interface
;
1399 if (!display_once
&& !use_json
) {
1401 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1402 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1404 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1405 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1408 "--------------------------------------------------------------------------------------------\n");
1411 if (intf_ifp
== NULL
) {
1412 vrf
= vrf_lookup_by_id(vrf_id
);
1413 FOR_ALL_INTERFACES (vrf
, ifp
) {
1415 oi
= (struct ospf6_interface
*)ifp
->info
;
1420 json_interface
= json_object_new_object();
1421 json_object_int_add(json_interface
, "helloRx",
1423 json_object_int_add(json_interface
, "helloTx",
1425 json_object_int_add(json_interface
, "dbDescRx",
1427 json_object_int_add(json_interface
, "dbDescTx",
1429 json_object_int_add(json_interface
, "lsReqRx",
1431 json_object_int_add(json_interface
, "lsReqTx",
1433 json_object_int_add(json_interface
,
1436 json_object_int_add(json_interface
,
1439 json_object_int_add(json_interface
, "lsAckRx",
1441 json_object_int_add(json_interface
, "lsAckTx",
1444 json_object_object_add(json
,
1445 oi
->interface
->name
,
1449 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1450 oi
->interface
->name
, oi
->hello_in
,
1451 oi
->hello_out
, oi
->db_desc_in
,
1452 oi
->db_desc_out
, oi
->ls_req_in
,
1453 oi
->ls_req_out
, oi
->ls_upd_in
,
1454 oi
->ls_upd_out
, oi
->ls_ack_in
,
1458 oi
= intf_ifp
->info
;
1463 json_interface
= json_object_new_object();
1464 json_object_int_add(json_interface
, "helloRx",
1466 json_object_int_add(json_interface
, "helloTx",
1468 json_object_int_add(json_interface
, "dbDescRx",
1470 json_object_int_add(json_interface
, "dbDescTx",
1472 json_object_int_add(json_interface
, "lsReqRx",
1474 json_object_int_add(json_interface
, "lsReqTx",
1476 json_object_int_add(json_interface
, "lsUpdateRx",
1478 json_object_int_add(json_interface
, "lsUpdateTx",
1480 json_object_int_add(json_interface
, "lsAckRx",
1482 json_object_int_add(json_interface
, "lsAckTx",
1485 json_object_object_add(json
, oi
->interface
->name
,
1489 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1490 oi
->interface
->name
, oi
->hello_in
,
1491 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1492 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1493 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1499 static int ospf6_interface_show_traffic_common(struct vty
*vty
, int argc
,
1500 struct cmd_token
**argv
,
1501 vrf_id_t vrf_id
, bool uj
)
1504 int display_once
= 0;
1505 char *intf_name
= NULL
;
1506 struct interface
*ifp
= NULL
;
1507 json_object
*json
= NULL
;
1510 json
= json_object_new_object();
1512 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1513 intf_name
= argv
[idx_ifname
]->arg
;
1514 ifp
= if_lookup_by_name(intf_name
, vrf_id
);
1517 json_object_string_add(json
, "status",
1518 "No Such Interface");
1519 json_object_string_add(json
, "interface",
1521 vty_json(vty
, json
);
1524 if (ifp
->info
== NULL
) {
1525 json_object_string_add(
1527 "OSPF not enabled on this interface");
1528 json_object_string_add(json
, "interface",
1530 vty_json(vty
, json
);
1535 vty_out(vty
, "No such Interface: %s\n",
1539 if (ifp
->info
== NULL
) {
1541 " OSPF not enabled on this interface %s\n",
1548 ospf6_interface_show_traffic(vty
, ifp
, display_once
, json
, uj
, vrf_id
);
1551 vty_json(vty
, json
);
1556 /* show interface */
1557 DEFUN(show_ipv6_ospf6_interface_traffic
, show_ipv6_ospf6_interface_traffic_cmd
,
1558 "show ipv6 ospf6 [vrf <NAME|all>] interface traffic [IFNAME] [json]",
1559 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1560 "All VRFs\n" INTERFACE_STR
1561 "Protocol Packet counters\n" IFNAME_STR JSON_STR
)
1563 struct ospf6
*ospf6
;
1564 struct listnode
*node
;
1565 const char *vrf_name
= NULL
;
1566 bool all_vrf
= false;
1568 bool uj
= use_json(argc
, argv
);
1570 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1572 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1573 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1574 ospf6_interface_show_traffic_common(vty
, argc
, argv
,
1582 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1588 DEFUN(show_ipv6_ospf6_interface_ifname_prefix
,
1589 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1590 "show ipv6 ospf6 [vrf <NAME|all>] interface IFNAME prefix\
1593 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1595 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1596 "All VRFs\n" INTERFACE_STR IFNAME_STR
1597 "Display connected prefixes to advertise\n"
1598 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1599 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1600 "Display details of the prefixes\n" JSON_STR
)
1604 struct ospf6_interface
*oi
;
1605 bool uj
= use_json(argc
, argv
);
1607 struct ospf6
*ospf6
;
1608 struct listnode
*node
;
1609 struct interface
*ifp
;
1610 const char *vrf_name
= NULL
;
1611 bool all_vrf
= false;
1614 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1620 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1621 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1622 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1625 vty_out(vty
, "No such Interface: %s\n",
1626 argv
[idx_ifname
]->arg
);
1632 || CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
1634 "Interface %s not attached to area\n",
1635 argv
[idx_ifname
]->arg
);
1639 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1640 oi
->route_connected
, uj
);
1647 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1652 DEFUN(show_ipv6_ospf6_interface_prefix
, show_ipv6_ospf6_interface_prefix_cmd
,
1653 "show ipv6 ospf6 [vrf <NAME|all>] interface prefix\
1656 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1658 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1659 "All VRFs\n" INTERFACE_STR
1660 "Display connected prefixes to advertise\n"
1661 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1662 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1663 "Display details of the prefixes\n" JSON_STR
)
1665 struct vrf
*vrf
= NULL
;
1667 struct ospf6_interface
*oi
;
1668 struct interface
*ifp
;
1669 bool uj
= use_json(argc
, argv
);
1670 struct listnode
*node
;
1671 struct ospf6
*ospf6
;
1672 const char *vrf_name
= NULL
;
1673 bool all_vrf
= false;
1676 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1680 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1681 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1682 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
1683 FOR_ALL_INTERFACES (vrf
, ifp
) {
1684 oi
= (struct ospf6_interface
*)ifp
->info
;
1686 || CHECK_FLAG(oi
->flag
,
1687 OSPF6_INTERFACE_DISABLE
))
1690 ospf6_route_table_show(vty
, idx_prefix
, argc
,
1692 oi
->route_connected
, uj
);
1699 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1704 void ospf6_interface_start(struct ospf6_interface
*oi
)
1706 struct ospf6
*ospf6
;
1707 struct ospf6_area
*oa
;
1709 if (oi
->area_id_format
== OSPF6_AREA_FMT_UNSET
)
1713 /* Recompute cost */
1714 ospf6_interface_recalculate_cost(oi
);
1718 ospf6
= oi
->interface
->vrf
->info
;
1722 oa
= ospf6_area_lookup(oi
->area_id
, ospf6
);
1724 oa
= ospf6_area_create(oi
->area_id
, ospf6
, oi
->area_id_format
);
1726 /* attach interface to area */
1727 listnode_add(oa
->if_list
, oi
);
1730 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1733 ospf6_interface_enable(oi
);
1735 /* If the router is ABR, originate summary routes */
1736 if (ospf6_check_and_set_router_abr(ospf6
)) {
1737 ospf6_abr_enable_area(oa
);
1738 ospf6_schedule_abr_task(ospf6
);
1742 void ospf6_interface_stop(struct ospf6_interface
*oi
)
1744 struct ospf6_area
*oa
;
1750 ospf6_interface_disable(oi
);
1752 listnode_delete(oa
->if_list
, oi
);
1755 if (oa
->if_list
->count
== 0) {
1756 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1757 ospf6_abr_disable_area(oa
);
1761 /* interface variable set command */
1762 DEFUN (ipv6_ospf6_area
,
1763 ipv6_ospf6_area_cmd
,
1764 "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
1767 "Specify the OSPF6 area ID\n"
1768 "OSPF6 area ID in IPv4 address notation\n"
1769 "OSPF6 area ID in decimal notation\n")
1771 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1772 struct ospf6_interface
*oi
;
1779 oi
= (struct ospf6_interface
*)ifp
->info
;
1781 oi
= ospf6_interface_create(ifp
);
1785 vty_out(vty
, "%s already attached to Area %s\n",
1786 oi
->interface
->name
, oi
->area
->name
);
1790 if (str2area_id(argv
[idx_ipv4
]->arg
, &area_id
, &format
)) {
1791 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1792 return CMD_WARNING_CONFIG_FAILED
;
1795 oi
->area_id
= area_id
;
1796 oi
->area_id_format
= format
;
1798 ospf6_interface_start(oi
);
1803 DEFUN (no_ipv6_ospf6_area
,
1804 no_ipv6_ospf6_area_cmd
,
1805 "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
1809 "Specify the OSPF6 area ID\n"
1810 "OSPF6 area ID in IPv4 address notation\n"
1811 "OSPF6 area ID in decimal notation\n")
1813 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1814 struct ospf6_interface
*oi
;
1818 oi
= (struct ospf6_interface
*)ifp
->info
;
1820 oi
= ospf6_interface_create(ifp
);
1823 ospf6_interface_stop(oi
);
1826 oi
->area_id_format
= OSPF6_AREA_FMT_UNSET
;
1831 DEFUN (ipv6_ospf6_ifmtu
,
1832 ipv6_ospf6_ifmtu_cmd
,
1833 "ipv6 ospf6 ifmtu (1-65535)",
1837 "OSPFv3 Interface MTU\n"
1840 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1842 struct ospf6_interface
*oi
;
1843 unsigned int ifmtu
, iobuflen
;
1844 struct listnode
*node
, *nnode
;
1845 struct ospf6_neighbor
*on
;
1849 oi
= (struct ospf6_interface
*)ifp
->info
;
1851 oi
= ospf6_interface_create(ifp
);
1854 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1856 if (oi
->c_ifmtu
== ifmtu
)
1859 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1861 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1862 ifp
->name
, ifp
->mtu6
);
1863 return CMD_WARNING_CONFIG_FAILED
;
1866 if (oi
->ifmtu
< ifmtu
) {
1867 iobuflen
= ospf6_iobuf_size(ifmtu
);
1868 if (iobuflen
< ifmtu
) {
1870 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1871 ifp
->name
, iobuflen
);
1872 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1874 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1876 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1878 /* re-establish adjacencies */
1879 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1880 THREAD_OFF(on
->inactivity_timer
);
1881 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1887 DEFUN (no_ipv6_ospf6_ifmtu
,
1888 no_ipv6_ospf6_ifmtu_cmd
,
1889 "no ipv6 ospf6 ifmtu [(1-65535)]",
1894 "OSPFv3 Interface MTU\n"
1897 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1898 struct ospf6_interface
*oi
;
1899 unsigned int iobuflen
;
1900 struct listnode
*node
, *nnode
;
1901 struct ospf6_neighbor
*on
;
1905 oi
= (struct ospf6_interface
*)ifp
->info
;
1907 oi
= ospf6_interface_create(ifp
);
1910 if (oi
->ifmtu
< ifp
->mtu
) {
1911 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1912 if (iobuflen
< ifp
->mtu
) {
1914 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1915 ifp
->name
, iobuflen
);
1916 oi
->ifmtu
= iobuflen
;
1918 oi
->ifmtu
= ifp
->mtu
;
1920 oi
->ifmtu
= ifp
->mtu
;
1924 /* re-establish adjacencies */
1925 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1926 THREAD_OFF(on
->inactivity_timer
);
1927 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1933 DEFUN (ipv6_ospf6_cost
,
1934 ipv6_ospf6_cost_cmd
,
1935 "ipv6 ospf6 cost (1-65535)",
1939 "Outgoing metric of this interface\n")
1941 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1943 struct ospf6_interface
*oi
;
1944 unsigned long int lcost
;
1948 oi
= (struct ospf6_interface
*)ifp
->info
;
1950 oi
= ospf6_interface_create(ifp
);
1953 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1955 if (lcost
> UINT32_MAX
) {
1956 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1957 return CMD_WARNING_CONFIG_FAILED
;
1960 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1961 if (oi
->cost
== lcost
)
1965 ospf6_interface_force_recalculate_cost(oi
);
1970 DEFUN (no_ipv6_ospf6_cost
,
1971 no_ipv6_ospf6_cost_cmd
,
1972 "no ipv6 ospf6 cost [(1-65535)]",
1976 "Calculate interface cost from bandwidth\n"
1977 "Outgoing metric of this interface\n")
1979 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1980 struct ospf6_interface
*oi
;
1983 oi
= (struct ospf6_interface
*)ifp
->info
;
1985 oi
= ospf6_interface_create(ifp
);
1988 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1990 ospf6_interface_recalculate_cost(oi
);
1995 DEFUN (auto_cost_reference_bandwidth
,
1996 auto_cost_reference_bandwidth_cmd
,
1997 "auto-cost reference-bandwidth (1-4294967)",
1998 "Calculate OSPF interface cost according to bandwidth\n"
1999 "Use reference bandwidth method to assign OSPF cost\n"
2000 "The reference bandwidth in terms of Mbits per second\n")
2002 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2004 struct ospf6_area
*oa
;
2005 struct ospf6_interface
*oi
;
2006 struct listnode
*i
, *j
;
2009 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
2010 if (refbw
< 1 || refbw
> 4294967) {
2011 vty_out(vty
, "reference-bandwidth value is invalid\n");
2012 return CMD_WARNING_CONFIG_FAILED
;
2015 /* If reference bandwidth is changed. */
2016 if ((refbw
) == o
->ref_bandwidth
)
2019 o
->ref_bandwidth
= refbw
;
2020 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
2021 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
2022 ospf6_interface_recalculate_cost(oi
);
2027 DEFUN (no_auto_cost_reference_bandwidth
,
2028 no_auto_cost_reference_bandwidth_cmd
,
2029 "no auto-cost reference-bandwidth [(1-4294967)]",
2031 "Calculate OSPF interface cost according to bandwidth\n"
2032 "Use reference bandwidth method to assign OSPF cost\n"
2033 "The reference bandwidth in terms of Mbits per second\n")
2035 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2036 struct ospf6_area
*oa
;
2037 struct ospf6_interface
*oi
;
2038 struct listnode
*i
, *j
;
2040 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
2043 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
2044 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
2045 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
2046 ospf6_interface_recalculate_cost(oi
);
2052 DEFUN (ospf6_write_multiplier
,
2053 ospf6_write_multiplier_cmd
,
2054 "write-multiplier (1-100)",
2055 "Write multiplier\n"
2056 "Maximum number of interface serviced per write\n")
2058 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2059 uint32_t write_oi_count
;
2061 write_oi_count
= strtol(argv
[1]->arg
, NULL
, 10);
2062 if (write_oi_count
< 1 || write_oi_count
> 100) {
2063 vty_out(vty
, "write-multiplier value is invalid\n");
2064 return CMD_WARNING_CONFIG_FAILED
;
2067 o
->write_oi_count
= write_oi_count
;
2071 DEFUN (no_ospf6_write_multiplier
,
2072 no_ospf6_write_multiplier_cmd
,
2073 "no write-multiplier (1-100)",
2075 "Write multiplier\n"
2076 "Maximum number of interface serviced per write\n")
2078 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2080 o
->write_oi_count
= OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
;
2084 DEFUN (ipv6_ospf6_hellointerval
,
2085 ipv6_ospf6_hellointerval_cmd
,
2086 "ipv6 ospf6 hello-interval (1-65535)",
2089 "Time between HELLO packets\n"
2092 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2094 struct ospf6_interface
*oi
;
2097 oi
= (struct ospf6_interface
*)ifp
->info
;
2099 oi
= ospf6_interface_create(ifp
);
2102 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
2103 ? OSPF_HELLO_INTERVAL_DEFAULT
2104 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2107 * If the thread is scheduled, send the new hello now.
2109 if (thread_is_scheduled(oi
->thread_send_hello
)) {
2110 THREAD_OFF(oi
->thread_send_hello
);
2112 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
2113 &oi
->thread_send_hello
);
2118 ALIAS (ipv6_ospf6_hellointerval
,
2119 no_ipv6_ospf6_hellointerval_cmd
,
2120 "no ipv6 ospf6 hello-interval [(1-65535)]",
2124 "Time between HELLO packets\n"
2127 /* interface variable set command */
2128 DEFUN (ipv6_ospf6_deadinterval
,
2129 ipv6_ospf6_deadinterval_cmd
,
2130 "ipv6 ospf6 dead-interval (1-65535)",
2133 "Interval time after which a neighbor is declared down\n"
2136 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2138 struct ospf6_interface
*oi
;
2141 oi
= (struct ospf6_interface
*)ifp
->info
;
2143 oi
= ospf6_interface_create(ifp
);
2146 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
2147 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
2148 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2152 ALIAS (ipv6_ospf6_deadinterval
,
2153 no_ipv6_ospf6_deadinterval_cmd
,
2154 "no ipv6 ospf6 dead-interval [(1-65535)]",
2158 "Interval time after which a neighbor is declared down\n"
2161 /* interface variable set command */
2162 DEFUN (ipv6_ospf6_transmitdelay
,
2163 ipv6_ospf6_transmitdelay_cmd
,
2164 "ipv6 ospf6 transmit-delay (1-3600)",
2167 "Link state transmit delay\n"
2170 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2172 struct ospf6_interface
*oi
;
2175 oi
= (struct ospf6_interface
*)ifp
->info
;
2177 oi
= ospf6_interface_create(ifp
);
2180 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
2181 ? OSPF6_INTERFACE_TRANSDELAY
2182 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2186 ALIAS (ipv6_ospf6_transmitdelay
,
2187 no_ipv6_ospf6_transmitdelay_cmd
,
2188 "no ipv6 ospf6 transmit-delay [(1-3600)]",
2192 "Link state transmit delay\n"
2195 /* interface variable set command */
2196 DEFUN (ipv6_ospf6_retransmitinterval
,
2197 ipv6_ospf6_retransmitinterval_cmd
,
2198 "ipv6 ospf6 retransmit-interval (1-65535)",
2201 "Time between retransmitting lost link state advertisements\n"
2204 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2206 struct ospf6_interface
*oi
;
2209 oi
= (struct ospf6_interface
*)ifp
->info
;
2211 oi
= ospf6_interface_create(ifp
);
2214 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
2215 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
2216 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2220 ALIAS (ipv6_ospf6_retransmitinterval
,
2221 no_ipv6_ospf6_retransmitinterval_cmd
,
2222 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
2226 "Time between retransmitting lost link state advertisements\n"
2229 /* interface variable set command */
2230 DEFUN (ipv6_ospf6_priority
,
2231 ipv6_ospf6_priority_cmd
,
2232 "ipv6 ospf6 priority (0-255)",
2238 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2240 struct ospf6_interface
*oi
;
2243 oi
= (struct ospf6_interface
*)ifp
->info
;
2245 oi
= ospf6_interface_create(ifp
);
2248 oi
->priority
= strmatch(argv
[0]->text
, "no")
2249 ? OSPF6_INTERFACE_PRIORITY
2250 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2253 && (oi
->state
== OSPF6_INTERFACE_DROTHER
2254 || oi
->state
== OSPF6_INTERFACE_BDR
2255 || oi
->state
== OSPF6_INTERFACE_DR
)) {
2256 if (ospf6_interface_state_change(dr_election(oi
), oi
) == -1)
2257 OSPF6_LINK_LSA_SCHEDULE(oi
);
2263 ALIAS (ipv6_ospf6_priority
,
2264 no_ipv6_ospf6_priority_cmd
,
2265 "no ipv6 ospf6 priority [(0-255)]",
2272 DEFUN (ipv6_ospf6_instance
,
2273 ipv6_ospf6_instance_cmd
,
2274 "ipv6 ospf6 instance-id (0-255)",
2277 "Instance ID for this interface\n"
2278 "Instance ID value\n")
2280 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2282 struct ospf6_interface
*oi
;
2285 oi
= (struct ospf6_interface
*)ifp
->info
;
2287 oi
= ospf6_interface_create(ifp
);
2290 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
2291 ? OSPF6_INTERFACE_INSTANCE_ID
2292 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2296 ALIAS (ipv6_ospf6_instance
,
2297 no_ipv6_ospf6_instance_cmd
,
2298 "no ipv6 ospf6 instance-id [(0-255)]",
2302 "Instance ID for this interface\n"
2303 "Instance ID value\n")
2305 DEFUN (ipv6_ospf6_passive
,
2306 ipv6_ospf6_passive_cmd
,
2307 "ipv6 ospf6 passive",
2310 "Passive interface; no adjacency will be formed on this interface\n"
2313 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2314 struct ospf6_interface
*oi
;
2315 struct listnode
*node
, *nnode
;
2316 struct ospf6_neighbor
*on
;
2320 oi
= (struct ospf6_interface
*)ifp
->info
;
2322 oi
= ospf6_interface_create(ifp
);
2325 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2326 THREAD_OFF(oi
->thread_send_hello
);
2327 THREAD_OFF(oi
->thread_sso
);
2329 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
2330 THREAD_OFF(on
->inactivity_timer
);
2331 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
2337 DEFUN (no_ipv6_ospf6_passive
,
2338 no_ipv6_ospf6_passive_cmd
,
2339 "no ipv6 ospf6 passive",
2343 "passive interface: No Adjacency will be formed on this I/F\n"
2346 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2347 struct ospf6_interface
*oi
;
2350 oi
= (struct ospf6_interface
*)ifp
->info
;
2352 oi
= ospf6_interface_create(ifp
);
2355 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2356 THREAD_OFF(oi
->thread_send_hello
);
2357 THREAD_OFF(oi
->thread_sso
);
2359 /* don't send hellos over loopback interface */
2360 if (!if_is_loopback(oi
->interface
))
2361 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
2362 &oi
->thread_send_hello
);
2367 DEFUN (ipv6_ospf6_mtu_ignore
,
2368 ipv6_ospf6_mtu_ignore_cmd
,
2369 "ipv6 ospf6 mtu-ignore",
2372 "Disable MTU mismatch detection on this interface\n"
2375 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2376 struct ospf6_interface
*oi
;
2379 oi
= (struct ospf6_interface
*)ifp
->info
;
2381 oi
= ospf6_interface_create(ifp
);
2389 DEFUN (no_ipv6_ospf6_mtu_ignore
,
2390 no_ipv6_ospf6_mtu_ignore_cmd
,
2391 "no ipv6 ospf6 mtu-ignore",
2395 "Disable MTU mismatch detection on this interface\n"
2398 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2399 struct ospf6_interface
*oi
;
2402 oi
= (struct ospf6_interface
*)ifp
->info
;
2404 oi
= ospf6_interface_create(ifp
);
2412 DEFUN (ipv6_ospf6_advertise_prefix_list
,
2413 ipv6_ospf6_advertise_prefix_list_cmd
,
2414 "ipv6 ospf6 advertise prefix-list WORD",
2417 "Advertising options\n"
2418 "Filter prefix using prefix-list\n"
2419 "Prefix list name\n"
2422 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2424 struct ospf6_interface
*oi
;
2427 oi
= (struct ospf6_interface
*)ifp
->info
;
2429 oi
= ospf6_interface_create(ifp
);
2433 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2434 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
2436 ospf6_interface_connected_route_update(oi
->interface
);
2439 OSPF6_LINK_LSA_SCHEDULE(oi
);
2440 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2441 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2442 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2444 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2450 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
2451 no_ipv6_ospf6_advertise_prefix_list_cmd
,
2452 "no ipv6 ospf6 advertise prefix-list [WORD]",
2456 "Advertising options\n"
2457 "Filter prefix using prefix-list\n"
2458 "Prefix list name\n")
2460 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2461 struct ospf6_interface
*oi
;
2464 oi
= (struct ospf6_interface
*)ifp
->info
;
2466 oi
= ospf6_interface_create(ifp
);
2470 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2472 ospf6_interface_connected_route_update(oi
->interface
);
2475 OSPF6_LINK_LSA_SCHEDULE(oi
);
2476 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2477 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2478 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2480 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2486 DEFUN (ipv6_ospf6_network
,
2487 ipv6_ospf6_network_cmd
,
2488 "ipv6 ospf6 network <broadcast|point-to-point>",
2492 "Specify OSPF6 broadcast network\n"
2493 "Specify OSPF6 point-to-point network\n"
2496 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2497 int idx_network
= 3;
2498 struct ospf6_interface
*oi
;
2501 oi
= (struct ospf6_interface
*)ifp
->info
;
2503 oi
= ospf6_interface_create(ifp
);
2507 oi
->type_cfg
= true;
2509 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
2510 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
2513 oi
->type
= OSPF_IFTYPE_BROADCAST
;
2514 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
2515 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
2518 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
2521 /* Reset the interface */
2522 thread_execute(master
, interface_down
, oi
, 0);
2523 thread_execute(master
, interface_up
, oi
, 0);
2528 DEFUN (no_ipv6_ospf6_network
,
2529 no_ipv6_ospf6_network_cmd
,
2530 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2534 "Set default network type\n"
2535 "Specify OSPF6 broadcast network\n"
2536 "Specify OSPF6 point-to-point network\n")
2538 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2539 struct ospf6_interface
*oi
;
2544 oi
= (struct ospf6_interface
*)ifp
->info
;
2549 oi
->type_cfg
= false;
2551 type
= ospf6_default_iftype(ifp
);
2552 if (oi
->type
== type
) {
2557 /* Reset the interface */
2558 thread_execute(master
, interface_down
, oi
, 0);
2559 thread_execute(master
, interface_up
, oi
, 0);
2564 static int config_write_ospf6_interface(struct vty
*vty
, struct vrf
*vrf
)
2566 struct ospf6_interface
*oi
;
2567 struct interface
*ifp
;
2568 char buf
[INET_ADDRSTRLEN
];
2570 FOR_ALL_INTERFACES (vrf
, ifp
) {
2571 oi
= (struct ospf6_interface
*)ifp
->info
;
2575 if_vty_config_start(vty
, ifp
);
2578 vty_out(vty
, " description %s\n", ifp
->desc
);
2579 if (oi
->area_id_format
!= OSPF6_AREA_FMT_UNSET
) {
2580 area_id2str(buf
, sizeof(buf
), oi
->area_id
,
2581 oi
->area_id_format
);
2582 vty_out(vty
, " ipv6 ospf6 area %s\n", buf
);
2585 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
2587 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
2588 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
2590 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
2591 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
2592 oi
->hello_interval
);
2594 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
2595 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
2598 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
2599 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
2602 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
2603 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
2605 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
2606 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
2609 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
2610 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
2614 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
2617 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
2618 vty_out(vty
, " ipv6 ospf6 passive\n");
2621 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
2623 if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
2624 vty_out(vty
, " ipv6 ospf6 network point-to-point\n");
2625 else if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_BROADCAST
)
2626 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
2628 ospf6_bfd_write_config(vty
, oi
);
2630 ospf6_auth_write_config(vty
, &oi
->at_data
);
2631 if_vty_config_end(vty
);
2636 /* Configuration write function for ospfd. */
2637 static int config_write_interface(struct vty
*vty
)
2640 struct vrf
*vrf
= NULL
;
2642 /* Display all VRF aware OSPF interface configuration */
2643 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2644 write
+= config_write_ospf6_interface(vty
, vrf
);
2650 static int ospf6_ifp_create(struct interface
*ifp
)
2652 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2653 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp
->name
,
2654 ifp
->ifindex
, ifp
->mtu6
);
2657 ospf6_interface_start(ifp
->info
);
2662 static int ospf6_ifp_up(struct interface
*ifp
)
2664 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2666 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2667 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2668 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2670 ospf6_interface_state_update(ifp
);
2675 static int ospf6_ifp_down(struct interface
*ifp
)
2677 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2679 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2680 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2681 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2683 ospf6_interface_state_update(ifp
);
2688 static int ospf6_ifp_destroy(struct interface
*ifp
)
2691 zlog_warn("Zebra: got delete of %s, but interface is still up",
2694 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2695 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2696 ifp
->name
, ifp
->ifindex
, ifp
->mtu6
);
2699 ospf6_interface_stop(ifp
->info
);
2704 void ospf6_interface_init(void)
2706 /* Install interface node. */
2707 if_cmd_init(config_write_interface
);
2708 if_zapi_callbacks(ospf6_ifp_create
, ospf6_ifp_up
,
2709 ospf6_ifp_down
, ospf6_ifp_destroy
);
2711 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
2712 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
2713 install_element(VIEW_NODE
,
2714 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
2715 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
2717 install_element(INTERFACE_NODE
, &ipv6_ospf6_area_cmd
);
2718 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_area_cmd
);
2719 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
2720 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
2721 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
2722 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
2724 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
2725 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
2726 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
2727 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
2728 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
2729 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
2730 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
2731 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
2732 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
2733 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
2734 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
2735 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
2737 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
2738 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
2740 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
2741 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
2743 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
2744 install_element(INTERFACE_NODE
,
2745 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
2747 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
2748 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
2750 /* reference bandwidth commands */
2751 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
2752 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
2753 /* write-multiplier commands */
2754 install_element(OSPF6_NODE
, &ospf6_write_multiplier_cmd
);
2755 install_element(OSPF6_NODE
, &no_ospf6_write_multiplier_cmd
);
2758 /* Clear the specified interface structure */
2759 void ospf6_interface_clear(struct interface
*ifp
)
2761 struct ospf6_interface
*oi
;
2763 if (!if_is_operative(ifp
))
2766 if (ifp
->info
== NULL
)
2769 oi
= (struct ospf6_interface
*)ifp
->info
;
2771 if (IS_OSPF6_DEBUG_INTERFACE
)
2772 zlog_debug("Interface %s: clear by reset", ifp
->name
);
2774 /* Reset the interface */
2775 thread_execute(master
, interface_down
, oi
, 0);
2776 thread_execute(master
, interface_up
, oi
, 0);
2779 /* Clear interface */
2780 DEFUN (clear_ipv6_ospf6_interface
,
2781 clear_ipv6_ospf6_interface_cmd
,
2782 "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
2794 struct interface
*ifp
;
2795 const char *vrf_name
;
2797 if (argv_find(argv
, argc
, "vrf", &idx_vrf
))
2798 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
2800 vrf_name
= VRF_DEFAULT_NAME
;
2801 vrf
= vrf_lookup_by_name(vrf_name
);
2803 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2807 if (!argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
2808 /* Clear all the ospfv3 interfaces. */
2809 FOR_ALL_INTERFACES (vrf
, ifp
)
2810 ospf6_interface_clear(ifp
);
2812 /* Interface name is specified. */
2813 ifp
= if_lookup_by_name_vrf(argv
[idx_ifname
]->arg
, vrf
);
2815 vty_out(vty
, "No such Interface: %s\n",
2816 argv
[idx_ifname
]->arg
);
2819 ospf6_interface_clear(ifp
);
2825 void install_element_ospf6_clear_interface(void)
2827 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2830 DEFUN (debug_ospf6_interface
,
2831 debug_ospf6_interface_cmd
,
2832 "debug ospf6 interface",
2835 "Debug OSPFv3 Interface\n"
2838 OSPF6_DEBUG_INTERFACE_ON();
2842 DEFUN (no_debug_ospf6_interface
,
2843 no_debug_ospf6_interface_cmd
,
2844 "no debug ospf6 interface",
2848 "Debug OSPFv3 Interface\n"
2851 OSPF6_DEBUG_INTERFACE_OFF();
2855 int config_write_ospf6_debug_interface(struct vty
*vty
)
2857 if (IS_OSPF6_DEBUG_INTERFACE
)
2858 vty_out(vty
, "debug ospf6 interface\n");
2862 void install_element_ospf6_debug_interface(void)
2864 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2865 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2866 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2867 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);
2870 void ospf6_auth_write_config(struct vty
*vty
, struct ospf6_auth_data
*at_data
)
2872 if (CHECK_FLAG(at_data
->flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
))
2873 vty_out(vty
, " ipv6 ospf6 authentication keychain %s\n",
2875 else if (CHECK_FLAG(at_data
->flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
))
2877 " ipv6 ospf6 authentication key-id %d hash-algo %s key %s\n",
2879 keychain_get_algo_name_by_id(at_data
->hash_algo
),
2883 DEFUN(ipv6_ospf6_intf_auth_trailer_keychain
,
2884 ipv6_ospf6_intf_auth_trailer_keychain_cmd
,
2885 "ipv6 ospf6 authentication keychain KEYCHAIN_NAME",
2887 "Enable authentication on this interface\n"
2891 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2892 int keychain_idx
= 4;
2893 struct ospf6_interface
*oi
;
2895 oi
= (struct ospf6_interface
*)ifp
->info
;
2897 oi
= ospf6_interface_create(ifp
);
2900 if (CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
)) {
2902 "Manual key configured, unconfigure it before configuring key chain\n");
2903 return CMD_WARNING_CONFIG_FAILED
;
2906 SET_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
);
2907 if (oi
->at_data
.keychain
)
2908 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN
, oi
->at_data
.keychain
);
2910 oi
->at_data
.keychain
=
2911 XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN
, argv
[keychain_idx
]->arg
);
2916 DEFUN(no_ipv6_ospf6_intf_auth_trailer_keychain
,
2917 no_ipv6_ospf6_intf_auth_trailer_keychain_cmd
,
2918 "no ipv6 ospf6 authentication keychain [KEYCHAIN_NAME]",
2919 NO_STR IP6_STR OSPF6_STR
2920 "Enable authentication on this interface\n"
2924 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2925 struct ospf6_interface
*oi
;
2927 oi
= (struct ospf6_interface
*)ifp
->info
;
2929 oi
= ospf6_interface_create(ifp
);
2932 if (!CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
))
2935 if (oi
->at_data
.keychain
) {
2936 oi
->at_data
.flags
= 0;
2937 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN
, oi
->at_data
.keychain
);
2938 oi
->at_data
.keychain
= NULL
;
2944 DEFUN(ipv6_ospf6_intf_auth_trailer_key
, ipv6_ospf6_intf_auth_trailer_key_cmd
,
2945 "ipv6 ospf6 authentication key-id (1-65535) hash-algo "
2946 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
2952 "Cryptographic-algorithm\n"
2953 "Use MD5 algorithm\n"
2954 "Use HMAC-SHA-1 algorithm\n"
2955 "Use HMAC-SHA-256 algorithm\n"
2956 "Use HMAC-SHA-384 algorithm\n"
2957 "Use HMAC-SHA-512 algorithm\n"
2959 "Password string (key)\n")
2961 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2963 int hash_algo_idx
= 6;
2964 int password_idx
= 8;
2965 struct ospf6_interface
*oi
;
2966 uint8_t hash_algo
= KEYCHAIN_ALGO_NULL
;
2968 oi
= (struct ospf6_interface
*)ifp
->info
;
2970 oi
= ospf6_interface_create(ifp
);
2973 if (CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
)) {
2975 "key chain configured, unconfigure it before configuring manual key\n");
2976 return CMD_WARNING_CONFIG_FAILED
;
2979 hash_algo
= keychain_get_algo_id_by_name(argv
[hash_algo_idx
]->arg
);
2980 #ifndef CRYPTO_OPENSSL
2981 if (hash_algo
== KEYCHAIN_ALGO_NULL
) {
2983 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
2984 return CMD_WARNING_CONFIG_FAILED
;
2986 #endif /* CRYPTO_OPENSSL */
2988 SET_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
);
2989 oi
->at_data
.hash_algo
= hash_algo
;
2990 oi
->at_data
.key_id
= (uint16_t)strtol(argv
[key_id_idx
]->arg
, NULL
, 10);
2991 if (oi
->at_data
.auth_key
)
2992 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY
, oi
->at_data
.auth_key
);
2993 oi
->at_data
.auth_key
=
2994 XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY
, argv
[password_idx
]->arg
);
2999 DEFUN(no_ipv6_ospf6_intf_auth_trailer_key
,
3000 no_ipv6_ospf6_intf_auth_trailer_key_cmd
,
3001 "no ipv6 ospf6 authentication key-id [(1-65535) hash-algo "
3002 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
3004 NO_STR IP6_STR OSPF6_STR
3008 "Cryptographic-algorithm\n"
3009 "Use MD5 algorithm\n"
3010 "Use HMAC-SHA-1 algorithm\n"
3011 "Use HMAC-SHA-256 algorithm\n"
3012 "Use HMAC-SHA-384 algorithm\n"
3013 "Use HMAC-SHA-512 algorithm\n"
3015 "Password string (key)\n")
3017 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3018 struct ospf6_interface
*oi
;
3019 #ifndef CRYPTO_OPENSSL
3020 int hash_algo_idx
= 7;
3021 uint8_t hash_algo
= KEYCHAIN_ALGO_NULL
;
3022 #endif /* CRYPTO_OPENSSL */
3024 oi
= (struct ospf6_interface
*)ifp
->info
;
3026 oi
= ospf6_interface_create(ifp
);
3029 if (!CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
))
3032 #ifndef CRYPTO_OPENSSL
3033 hash_algo
= keychain_get_algo_id_by_name(argv
[hash_algo_idx
]->arg
);
3034 if (hash_algo
== KEYCHAIN_ALGO_NULL
) {
3036 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
3037 return CMD_WARNING_CONFIG_FAILED
;
3039 #endif /* CRYPTO_OPENSSL */
3041 if (oi
->at_data
.auth_key
) {
3042 oi
->at_data
.flags
= 0;
3043 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY
, oi
->at_data
.auth_key
);
3044 oi
->at_data
.auth_key
= NULL
;
3050 void ospf6_interface_auth_trailer_cmd_init(void)
3052 /*Install OSPF6 auth trailer commands at interface level */
3053 install_element(INTERFACE_NODE
,
3054 &ipv6_ospf6_intf_auth_trailer_keychain_cmd
);
3055 install_element(INTERFACE_NODE
,
3056 &no_ipv6_ospf6_intf_auth_trailer_keychain_cmd
);
3057 install_element(INTERFACE_NODE
, &ipv6_ospf6_intf_auth_trailer_key_cmd
);
3058 install_element(INTERFACE_NODE
,
3059 &no_ipv6_ospf6_intf_auth_trailer_key_cmd
);