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_nssa.h"
41 #include "ospf6_interface.h"
42 #include "ospf6_neighbor.h"
43 #include "ospf6_intra.h"
44 #include "ospf6_spf.h"
46 #include "ospf6_bfd.h"
47 #include "ospf6_zebra.h"
50 #include "ospf6_proto.h"
51 #include "lib/keychain.h"
52 #include "ospf6_auth_trailer.h"
54 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_IF
, "OSPF6 interface");
55 DEFINE_MTYPE(OSPF6D
, OSPF6_AUTH_KEYCHAIN
, "OSPF6 auth keychain");
56 DEFINE_MTYPE(OSPF6D
, OSPF6_AUTH_MANUAL_KEY
, "OSPF6 auth key");
57 DEFINE_MTYPE_STATIC(OSPF6D
, CFG_PLIST_NAME
, "configured prefix list names");
58 DEFINE_QOBJ_TYPE(ospf6_interface
);
59 DEFINE_HOOK(ospf6_interface_change
,
60 (struct ospf6_interface
* oi
, int state
, int old_state
),
61 (oi
, state
, old_state
));
63 unsigned char conf_debug_ospf6_interface
= 0;
65 const char *const ospf6_interface_state_str
[] = {
66 "None", "Down", "Loopback", "Waiting", "PointToPoint",
67 "DROther", "BDR", "DR", NULL
};
69 int ospf6_interface_neighbor_count(struct ospf6_interface
*oi
)
72 struct ospf6_neighbor
*nbr
= NULL
;
73 struct listnode
*node
;
75 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, nbr
)) {
76 /* Down state is not shown. */
77 if (nbr
->state
== OSPF6_NEIGHBOR_DOWN
)
85 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
,
88 struct ospf6_interface
*oi
;
89 struct interface
*ifp
;
91 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
93 return (struct ospf6_interface
*)NULL
;
95 oi
= (struct ospf6_interface
*)ifp
->info
;
99 /* schedule routing table recalculation */
100 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
103 struct ospf6_interface
*oi
;
108 oi
= lsa
->lsdb
->data
;
109 switch (ntohs(lsa
->header
->type
)) {
110 case OSPF6_LSTYPE_LINK
:
111 if (oi
->state
== OSPF6_INTERFACE_DR
)
112 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
114 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
122 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
124 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
127 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
129 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
132 static uint8_t ospf6_default_iftype(struct interface
*ifp
)
134 if (if_is_pointopoint(ifp
))
135 return OSPF_IFTYPE_POINTOPOINT
;
136 else if (if_is_loopback(ifp
))
137 return OSPF_IFTYPE_LOOPBACK
;
139 return OSPF_IFTYPE_BROADCAST
;
142 static uint32_t ospf6_interface_get_cost(struct ospf6_interface
*oi
)
144 /* If all else fails, use default OSPF cost */
148 /* interface speed and bw can be 0 in some platforms,
149 * use ospf default bw. If bw is configured then it would
152 if (!oi
->interface
->bandwidth
&& oi
->interface
->speed
) {
153 bw
= oi
->interface
->speed
;
155 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
156 : OSPF6_INTERFACE_BANDWIDTH
;
159 ospf6
= oi
->interface
->vrf
->info
;
160 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
162 /* A specified ip ospf cost overrides a calculated one. */
163 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
166 cost
= (uint32_t)((double)refbw
/ (double)bw
+ (double)0.5);
174 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface
*oi
)
176 /* update cost held in route_connected list in ospf6_interface */
177 ospf6_interface_connected_route_update(oi
->interface
);
179 /* execute LSA hooks */
181 OSPF6_LINK_LSA_SCHEDULE(oi
);
182 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
183 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
184 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
185 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
189 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
193 newcost
= ospf6_interface_get_cost(oi
);
194 if (newcost
== oi
->cost
)
198 ospf6_interface_force_recalculate_cost(oi
);
201 /* Create new ospf6 interface structure */
202 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
204 struct ospf6_interface
*oi
;
205 unsigned int iobuflen
;
207 oi
= XCALLOC(MTYPE_OSPF6_IF
, sizeof(struct ospf6_interface
));
209 oi
->obuf
= ospf6_fifo_new();
211 oi
->area
= (struct ospf6_area
*)NULL
;
212 oi
->neighbor_list
= list_new();
213 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
214 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
215 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
216 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
217 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
219 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
220 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
221 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
222 oi
->type
= ospf6_default_iftype(ifp
);
223 oi
->state
= OSPF6_INTERFACE_DOWN
;
228 /* Try to adjust I/O buffer size with IfMtu */
229 oi
->ifmtu
= ifp
->mtu6
;
230 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
231 if (oi
->ifmtu
> iobuflen
) {
232 if (IS_OSPF6_DEBUG_INTERFACE
)
234 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
235 ifp
->name
, iobuflen
);
236 oi
->ifmtu
= iobuflen
;
239 QOBJ_REG(oi
, ospf6_interface
);
241 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
242 oi
->lsack_list
= ospf6_lsdb_create(oi
);
243 oi
->lsdb
= ospf6_lsdb_create(oi
);
244 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
245 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
246 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
248 oi
->route_connected
=
249 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
250 oi
->route_connected
->scope
= oi
;
257 oi
->cost
= ospf6_interface_get_cost(oi
);
259 oi
->at_data
.flags
= 0;
264 void ospf6_interface_delete(struct ospf6_interface
*oi
)
266 struct listnode
*node
, *nnode
;
267 struct ospf6_neighbor
*on
;
271 ospf6_fifo_free(oi
->obuf
);
273 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
274 ospf6_neighbor_delete(on
);
276 list_delete(&oi
->neighbor_list
);
278 THREAD_OFF(oi
->thread_send_hello
);
279 THREAD_OFF(oi
->thread_send_lsupdate
);
280 THREAD_OFF(oi
->thread_send_lsack
);
281 THREAD_OFF(oi
->thread_sso
);
282 THREAD_OFF(oi
->thread_wait_timer
);
284 ospf6_lsdb_remove_all(oi
->lsdb
);
285 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
286 ospf6_lsdb_remove_all(oi
->lsack_list
);
288 ospf6_lsdb_delete(oi
->lsdb
);
289 ospf6_lsdb_delete(oi
->lsdb_self
);
291 ospf6_lsdb_delete(oi
->lsupdate_list
);
292 ospf6_lsdb_delete(oi
->lsack_list
);
294 ospf6_route_table_delete(oi
->route_connected
);
297 oi
->interface
->info
= NULL
;
301 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
303 /* disable from area list if possible */
304 ospf6_area_interface_delete(oi
);
306 if (oi
->at_data
.auth_key
)
307 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY
, oi
->at_data
.auth_key
);
309 /* Free BFD allocated data. */
310 XFREE(MTYPE_TMP
, oi
->bfd_config
.profile
);
312 XFREE(MTYPE_OSPF6_IF
, oi
);
315 void ospf6_interface_enable(struct ospf6_interface
*oi
)
317 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
318 ospf6_interface_state_update(oi
->interface
);
321 void ospf6_interface_disable(struct ospf6_interface
*oi
)
323 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
325 thread_execute(master
, interface_down
, oi
, 0);
327 ospf6_lsdb_remove_all(oi
->lsdb
);
328 ospf6_lsdb_remove_all(oi
->lsdb_self
);
329 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
330 ospf6_lsdb_remove_all(oi
->lsack_list
);
332 THREAD_OFF(oi
->thread_send_hello
);
333 THREAD_OFF(oi
->thread_send_lsupdate
);
334 THREAD_OFF(oi
->thread_send_lsack
);
335 THREAD_OFF(oi
->thread_sso
);
337 THREAD_OFF(oi
->thread_network_lsa
);
338 THREAD_OFF(oi
->thread_link_lsa
);
339 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
340 THREAD_OFF(oi
->thread_as_extern_lsa
);
341 THREAD_OFF(oi
->thread_wait_timer
);
344 static struct in6_addr
*
345 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
349 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
351 /* for each connected address */
352 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
353 /* if family not AF_INET6, ignore */
354 if (c
->address
->family
!= AF_INET6
)
357 /* linklocal scope check */
358 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
359 l
= &c
->address
->u
.prefix6
;
364 void ospf6_interface_state_update(struct interface
*ifp
)
366 struct ospf6_interface
*oi
;
367 unsigned int iobuflen
;
369 oi
= (struct ospf6_interface
*)ifp
->info
;
372 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
375 /* Adjust the mtu values if the kernel told us something new */
376 if (ifp
->mtu6
!= oi
->ifmtu
) {
377 /* If nothing configured, accept it and check for buffer size */
379 oi
->ifmtu
= ifp
->mtu6
;
380 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
381 if (oi
->ifmtu
> iobuflen
) {
382 if (IS_OSPF6_DEBUG_INTERFACE
)
384 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
385 ifp
->name
, iobuflen
);
386 oi
->ifmtu
= iobuflen
;
388 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
389 oi
->ifmtu
= ifp
->mtu6
;
391 "Configured mtu %u on %s overridden by kernel %u",
392 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
394 oi
->ifmtu
= oi
->c_ifmtu
;
397 if (if_is_operative(ifp
)
398 && (ospf6_interface_get_linklocal_address(oi
->interface
)
399 || if_is_loopback(oi
->interface
)))
400 thread_execute(master
, interface_up
, oi
, 0);
402 thread_execute(master
, interface_down
, oi
, 0);
407 void ospf6_interface_connected_route_update(struct interface
*ifp
)
409 struct ospf6_interface
*oi
;
410 struct ospf6_route
*route
;
412 struct listnode
*node
, *nnode
;
413 struct in6_addr nh_addr
;
415 oi
= (struct ospf6_interface
*)ifp
->info
;
419 /* reset linklocal pointer */
420 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
422 /* if area is null, do not make connected-route list */
423 if (oi
->area
== NULL
)
426 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
429 /* update "route to advertise" interface route table */
430 ospf6_route_remove_all(oi
->route_connected
);
432 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
433 if (c
->address
->family
!= AF_INET6
)
436 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
438 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
440 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
442 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
444 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
448 if (oi
->plist_name
) {
449 struct prefix_list
*plist
;
450 enum prefix_list_type ret
;
452 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
453 ret
= prefix_list_apply(plist
, (void *)c
->address
);
454 if (ret
== PREFIX_DENY
) {
455 if (IS_OSPF6_DEBUG_INTERFACE
)
457 "%pFX on %s filtered by prefix-list %s ",
458 c
->address
, oi
->interface
->name
,
464 route
= ospf6_route_create(oi
->area
->ospf6
);
465 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
466 apply_mask(&route
->prefix
);
467 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
468 route
->path
.area_id
= oi
->area
->area_id
;
469 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
470 route
->path
.cost
= oi
->cost
;
471 inet_pton(AF_INET6
, "::1", &nh_addr
);
472 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
474 ospf6_route_add(route
, oi
->route_connected
);
477 /* create new Link-LSA */
478 OSPF6_LINK_LSA_SCHEDULE(oi
);
479 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
480 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
483 static int ospf6_interface_state_change(uint8_t next_state
,
484 struct ospf6_interface
*oi
)
489 prev_state
= oi
->state
;
490 oi
->state
= next_state
;
492 if (prev_state
== next_state
)
499 if (IS_OSPF6_DEBUG_INTERFACE
) {
500 zlog_debug("Interface state change %s: %s -> %s",
502 ospf6_interface_state_str
[prev_state
],
503 ospf6_interface_state_str
[next_state
]);
507 ospf6
= oi
->area
->ospf6
;
509 if ((prev_state
== OSPF6_INTERFACE_DR
510 || prev_state
== OSPF6_INTERFACE_BDR
)
511 && (next_state
!= OSPF6_INTERFACE_DR
512 && next_state
!= OSPF6_INTERFACE_BDR
))
513 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
514 IPV6_LEAVE_GROUP
, ospf6
->fd
);
516 if ((prev_state
!= OSPF6_INTERFACE_DR
517 && prev_state
!= OSPF6_INTERFACE_BDR
)
518 && (next_state
== OSPF6_INTERFACE_DR
519 || next_state
== OSPF6_INTERFACE_BDR
))
520 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
521 IPV6_JOIN_GROUP
, ospf6
->fd
);
523 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
524 OSPF6_LINK_LSA_SCHEDULE(oi
);
525 if (next_state
== OSPF6_INTERFACE_DOWN
) {
526 OSPF6_NETWORK_LSA_EXECUTE(oi
);
527 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
528 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
529 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
530 } else if (prev_state
== OSPF6_INTERFACE_DR
531 || next_state
== OSPF6_INTERFACE_DR
) {
532 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
533 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
534 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
537 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
543 /* DR Election, RFC2328 section 9.4 */
545 #define IS_ELIGIBLE(n) \
546 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
548 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
549 struct ospf6_neighbor
*b
)
551 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
552 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
554 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
556 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
559 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
561 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
564 if (a
->priority
> b
->priority
)
566 if (a
->priority
< b
->priority
)
569 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
571 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
574 zlog_warn("Router-ID duplicate ?");
578 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
579 struct ospf6_neighbor
*b
)
581 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
582 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
584 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
586 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
589 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
591 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
594 if (a
->priority
> b
->priority
)
596 if (a
->priority
< b
->priority
)
599 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
601 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
604 zlog_warn("Router-ID duplicate ?");
608 uint8_t dr_election(struct ospf6_interface
*oi
)
610 struct listnode
*node
, *nnode
;
611 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
612 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
613 uint8_t next_state
= 0;
615 drouter
= bdrouter
= NULL
;
616 best_drouter
= best_bdrouter
= NULL
;
618 /* pseudo neighbor myself, including noting current DR/BDR (1) */
619 memset(&myself
, 0, sizeof(myself
));
620 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
621 sizeof(myself
.name
));
622 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
623 myself
.drouter
= oi
->drouter
;
624 myself
.bdrouter
= oi
->bdrouter
;
625 myself
.priority
= oi
->priority
;
626 myself
.router_id
= oi
->area
->ospf6
->router_id
;
628 /* Electing BDR (2) */
629 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
630 bdrouter
= better_bdrouter(bdrouter
, on
);
632 best_bdrouter
= bdrouter
;
633 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
635 /* Electing DR (3) */
636 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
637 drouter
= better_drouter(drouter
, on
);
639 best_drouter
= drouter
;
640 drouter
= better_drouter(best_drouter
, &myself
);
644 /* the router itself is newly/no longer DR/BDR (4) */
645 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
646 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
647 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
648 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
649 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
650 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
652 /* compatible to Electing BDR (2) */
653 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
655 /* compatible to Electing DR (3) */
656 drouter
= better_drouter(best_drouter
, &myself
);
661 /* Set interface state accordingly (5) */
662 if (drouter
&& drouter
== &myself
)
663 next_state
= OSPF6_INTERFACE_DR
;
664 else if (bdrouter
&& bdrouter
== &myself
)
665 next_state
= OSPF6_INTERFACE_BDR
;
667 next_state
= OSPF6_INTERFACE_DROTHER
;
669 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
672 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
673 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
674 accordingly after AdjOK */
675 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
676 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
677 if (IS_OSPF6_DEBUG_INTERFACE
)
678 zlog_debug("DR Election on %s: DR: %s BDR: %s",
680 (drouter
? drouter
->name
: "0.0.0.0"),
681 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
683 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
684 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
686 /* Schedule AdjOK. */
687 thread_add_event(master
, adj_ok
, on
, 0,
692 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
693 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
701 static bool ifmaddr_check(ifindex_t ifindex
, struct in6_addr
*addr
)
703 struct ifmaddrs
*ifmap
, *ifma
;
704 struct sockaddr_dl
*sdl
;
705 struct sockaddr_in6
*sin6
;
708 if (getifmaddrs(&ifmap
) != 0)
711 for (ifma
= ifmap
; ifma
; ifma
= ifma
->ifma_next
) {
712 if (ifma
->ifma_name
== NULL
|| ifma
->ifma_addr
== NULL
)
714 if (ifma
->ifma_name
->sa_family
!= AF_LINK
)
716 if (ifma
->ifma_addr
->sa_family
!= AF_INET6
)
718 sdl
= (struct sockaddr_dl
*)ifma
->ifma_name
;
719 sin6
= (struct sockaddr_in6
*)ifma
->ifma_addr
;
720 if (sdl
->sdl_index
== ifindex
721 && memcmp(&sin6
->sin6_addr
, addr
, IPV6_MAX_BYTELEN
) == 0) {
733 #endif /* __FreeBSD__ */
735 /* Interface State Machine */
736 void interface_up(struct thread
*thread
)
738 struct ospf6_interface
*oi
;
741 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
742 assert(oi
&& oi
->interface
);
745 oi
->type
= ospf6_default_iftype(oi
->interface
);
747 thread_cancel(&oi
->thread_sso
);
749 if (IS_OSPF6_DEBUG_INTERFACE
)
750 zlog_debug("Interface Event %s: [InterfaceUp]",
751 oi
->interface
->name
);
753 /* check physical interface is up */
754 if (!if_is_operative(oi
->interface
)) {
755 zlog_warn("Interface %s is down, can't execute [InterfaceUp]",
756 oi
->interface
->name
);
760 /* check interface has a link-local address */
761 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
762 || if_is_loopback(oi
->interface
))) {
764 "Interface %s has no link local address, can't execute [InterfaceUp]",
765 oi
->interface
->name
);
770 ospf6_interface_recalculate_cost(oi
);
772 /* if already enabled, do nothing */
773 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
774 if (IS_OSPF6_DEBUG_INTERFACE
)
775 zlog_debug("Interface %s already enabled",
776 oi
->interface
->name
);
780 /* If no area assigned, return */
781 if (oi
->area
== NULL
) {
783 "%s: Not scheduling Hello for %s as there is no area assigned yet",
784 __func__
, oi
->interface
->name
);
790 * There's a delay in FreeBSD between issuing a command to leave a
791 * multicast group and an actual leave. If we execute "no router ospf6"
792 * and "router ospf6" fast enough, we can end up in a situation when OS
793 * performs the leave later than it performs the join and the interface
794 * remains without a multicast group. We have to do the join only after
795 * the interface actually left the group.
797 if (ifmaddr_check(oi
->interface
->ifindex
, &allspfrouters6
)) {
799 "Interface %s is still in all routers group, rescheduling for SSO",
800 oi
->interface
->name
);
801 thread_add_timer(master
, interface_up
, oi
,
802 OSPF6_INTERFACE_SSO_RETRY_INT
,
806 #endif /* __FreeBSD__ */
808 ospf6
= oi
->area
->ospf6
;
810 /* Join AllSPFRouters */
811 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
,
814 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
816 "Scheduling %s for sso retry, trial count: %d",
817 oi
->interface
->name
, oi
->sso_try_cnt
);
818 thread_add_timer(master
, interface_up
, oi
,
819 OSPF6_INTERFACE_SSO_RETRY_INT
,
824 oi
->sso_try_cnt
= 0; /* Reset on success */
826 /* Update interface route */
827 ospf6_interface_connected_route_update(oi
->interface
);
830 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
831 && !if_is_loopback(oi
->interface
)) {
832 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
833 &oi
->thread_send_hello
);
836 /* decide next interface state */
837 if (oi
->type
== OSPF_IFTYPE_LOOPBACK
) {
838 ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK
, oi
);
839 } else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
840 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
841 } else if (oi
->priority
== 0)
842 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
844 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
845 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
846 &oi
->thread_wait_timer
);
850 void wait_timer(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: [WaitTimer]",
859 oi
->interface
->name
);
861 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
862 ospf6_interface_state_change(dr_election(oi
), oi
);
865 void backup_seen(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: [BackupSeen]",
874 oi
->interface
->name
);
876 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
877 ospf6_interface_state_change(dr_election(oi
), oi
);
880 void neighbor_change(struct thread
*thread
)
882 struct ospf6_interface
*oi
;
884 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
885 assert(oi
&& oi
->interface
);
887 if (IS_OSPF6_DEBUG_INTERFACE
)
888 zlog_debug("Interface Event %s: [NeighborChange]",
889 oi
->interface
->name
);
891 if (oi
->state
== OSPF6_INTERFACE_DROTHER
892 || oi
->state
== OSPF6_INTERFACE_BDR
893 || oi
->state
== OSPF6_INTERFACE_DR
)
894 ospf6_interface_state_change(dr_election(oi
), oi
);
897 void interface_down(struct thread
*thread
)
899 struct ospf6_interface
*oi
;
900 struct listnode
*node
, *nnode
;
901 struct ospf6_neighbor
*on
;
904 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
905 assert(oi
&& oi
->interface
);
907 if (IS_OSPF6_DEBUG_INTERFACE
)
908 zlog_debug("Interface Event %s: [InterfaceDown]",
909 oi
->interface
->name
);
912 THREAD_OFF(oi
->thread_send_hello
);
914 /* Stop trying to set socket options. */
915 THREAD_OFF(oi
->thread_sso
);
917 /* Cease the HELPER role for all the neighbours
920 if (ospf6_interface_neighbor_count(oi
)) {
922 struct ospf6_neighbor
*nbr
= NULL
;
924 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, ln
, nbr
))
925 ospf6_gr_helper_exit(nbr
, OSPF6_GR_HELPER_TOPO_CHG
);
928 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
929 ospf6_neighbor_delete(on
);
931 list_delete_all_node(oi
->neighbor_list
);
933 /* When interface state is reset, also reset information about
934 * DR election, as it is no longer valid. */
935 oi
->drouter
= oi
->prev_drouter
= htonl(0);
936 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
938 if (oi
->area
== NULL
)
941 ospf6
= oi
->area
->ospf6
;
942 /* Leave AllSPFRouters */
943 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
944 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
945 IPV6_LEAVE_GROUP
, ospf6
->fd
);
947 /* deal with write fifo */
948 ospf6_fifo_flush(oi
->obuf
);
949 if (oi
->on_write_q
) {
950 listnode_delete(ospf6
->oi_write_q
, oi
);
951 if (list_isempty(ospf6
->oi_write_q
))
952 thread_cancel(&ospf6
->t_write
);
956 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
960 static const char *ospf6_iftype_str(uint8_t iftype
)
963 case OSPF_IFTYPE_LOOPBACK
:
965 case OSPF_IFTYPE_BROADCAST
:
967 case OSPF_IFTYPE_POINTOPOINT
:
968 return "POINTOPOINT";
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
)
1002 oi
= (struct ospf6_interface
*)ifp
->info
;
1004 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
1005 json_object_string_add(json_obj
, "operatingAsType",
1006 ospf6_iftype_str(oi
->type
));
1009 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
1010 (if_is_operative(ifp
) ? "up" : "down"),
1011 ospf6_iftype_str(default_iftype
));
1012 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
1014 if (ifp
->info
== NULL
) {
1015 vty_out(vty
, " OSPF not enabled on this interface\n");
1018 oi
= (struct ospf6_interface
*)ifp
->info
;
1020 if (if_is_operative(ifp
) && oi
->type
!= default_iftype
)
1021 vty_out(vty
, " Operating as type %s\n",
1022 ospf6_iftype_str(oi
->type
));
1026 json_arr
= json_object_new_array();
1027 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1028 json_addr
= json_object_new_object();
1030 prefix2str(p
, strbuf
, sizeof(strbuf
));
1031 switch (p
->family
) {
1033 json_object_string_add(json_addr
, "type",
1035 json_object_string_add(json_addr
, "address",
1037 json_object_array_add(json_arr
, json_addr
);
1040 json_object_string_add(json_addr
, "type",
1042 json_object_string_add(json_addr
, "address",
1044 json_object_array_add(json_arr
, json_addr
);
1047 json_object_string_add(json_addr
, "type",
1049 json_object_string_add(json_addr
, "address",
1051 json_object_array_add(json_arr
, json_addr
);
1055 json_object_object_add(json_obj
, "internetAddress", json_arr
);
1057 vty_out(vty
, " Internet Address:\n");
1059 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
1061 prefix2str(p
, strbuf
, sizeof(strbuf
));
1062 switch (p
->family
) {
1064 vty_out(vty
, " inet : %pFX\n", p
);
1067 vty_out(vty
, " inet6: %pFX\n", p
);
1070 vty_out(vty
, " ??? : %pFX\n", p
);
1078 json_object_boolean_true_add(json_obj
,
1080 json_object_int_add(json_obj
, "instanceId",
1082 json_object_int_add(json_obj
, "interfaceMtu",
1084 json_object_int_add(json_obj
, "autoDetect", ifp
->mtu6
);
1085 json_object_string_add(json_obj
, "mtuMismatchDetection",
1086 oi
->mtu_ignore
? "disabled"
1088 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1090 json_object_string_add(json_obj
, "areaId", strbuf
);
1091 json_object_int_add(json_obj
, "cost", oi
->cost
);
1093 json_object_boolean_false_add(json_obj
,
1099 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1100 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
1101 vty_out(vty
, " MTU mismatch detection: %s\n",
1102 oi
->mtu_ignore
? "disabled" : "enabled");
1103 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
,
1105 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
,
1108 vty_out(vty
, " Not Attached to Area\n");
1112 json_object_string_add(json_obj
, "ospf6InterfaceState",
1113 ospf6_interface_state_str
[oi
->state
]);
1114 json_object_int_add(json_obj
, "transmitDelaySec",
1116 json_object_int_add(json_obj
, "priority", oi
->priority
);
1117 json_object_int_add(json_obj
, "timerIntervalsConfigHello",
1118 oi
->hello_interval
);
1119 json_object_int_add(json_obj
, "timerIntervalsConfigDead",
1121 json_object_int_add(json_obj
, "timerIntervalsConfigRetransmit",
1123 json_object_boolean_add(
1124 json_obj
, "timerPassiveIface",
1125 !!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
));
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 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
1133 " Hello %d(%pTHd), Dead %d, Retransmit %d\n",
1134 oi
->hello_interval
, oi
->thread_send_hello
,
1135 oi
->dead_interval
, oi
->rxmt_interval
);
1137 vty_out(vty
, " No Hellos (Passive interface)\n");
1140 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
1141 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
1143 json_object_string_add(json_obj
, "dr", drouter
);
1144 json_object_string_add(json_obj
, "bdr", bdrouter
);
1145 json_object_int_add(json_obj
, "numberOfInterfaceScopedLsa",
1148 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
1149 vty_out(vty
, " Number of I/F scoped LSAs is %u\n",
1157 if (thread_is_scheduled(oi
->thread_send_lsupdate
))
1158 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1160 timerstring(&res
, duration
, sizeof(duration
));
1161 json_object_int_add(json_obj
, "pendingLsaLsUpdateCount",
1162 oi
->lsupdate_list
->count
);
1163 json_object_string_add(json_obj
, "pendingLsaLsUpdateTime",
1165 json_object_string_add(
1166 json_obj
, "lsUpdateSendThread",
1167 (thread_is_scheduled(oi
->thread_send_lsupdate
)
1171 json_arr
= json_object_new_array();
1172 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1173 json_object_array_add(
1174 json_arr
, json_object_new_string(lsa
->name
));
1175 json_object_object_add(json_obj
, "pendingLsaLsUpdate",
1179 if (thread_is_scheduled(oi
->thread_send_lsack
))
1180 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1181 timerstring(&res
, duration
, sizeof(duration
));
1183 json_object_int_add(json_obj
, "pendingLsaLsAckCount",
1184 oi
->lsack_list
->count
);
1185 json_object_string_add(json_obj
, "pendingLsaLsAckTime",
1187 json_object_string_add(
1188 json_obj
, "lsAckSendThread",
1189 (thread_is_scheduled(oi
->thread_send_lsack
) ? "on"
1192 json_arr
= json_object_new_array();
1193 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1194 json_object_array_add(
1195 json_arr
, json_object_new_string(lsa
->name
));
1196 json_object_object_add(json_obj
, "pendingLsaLsAck", json_arr
);
1200 if (thread_is_scheduled(oi
->thread_send_lsupdate
))
1201 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
,
1203 timerstring(&res
, duration
, sizeof(duration
));
1205 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1206 oi
->lsupdate_list
->count
, duration
,
1207 (thread_is_scheduled(oi
->thread_send_lsupdate
)
1210 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
))
1211 vty_out(vty
, " %s\n", lsa
->name
);
1214 if (thread_is_scheduled(oi
->thread_send_lsack
))
1215 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
1216 timerstring(&res
, duration
, sizeof(duration
));
1218 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1219 oi
->lsack_list
->count
, duration
,
1220 (thread_is_scheduled(oi
->thread_send_lsack
) ? "on"
1222 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
))
1223 vty_out(vty
, " %s\n", lsa
->name
);
1227 if (oi
->bfd_config
.enabled
) {
1229 struct json_object
*json_bfd
= json_object_new_object();
1231 json_object_int_add(
1232 json_bfd
, "detectMultiplier",
1233 oi
->bfd_config
.detection_multiplier
);
1234 json_object_int_add(json_bfd
, "rxMinInterval",
1235 oi
->bfd_config
.min_rx
);
1236 json_object_int_add(json_bfd
, "txMinInterval",
1237 oi
->bfd_config
.min_tx
);
1238 json_object_object_add(json_obj
, "peerBfdInfo",
1242 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1243 oi
->bfd_config
.detection_multiplier
,
1244 oi
->bfd_config
.min_rx
, oi
->bfd_config
.min_tx
);
1249 json_auth
= json_object_new_object();
1250 if (oi
->at_data
.flags
!= 0) {
1252 if (CHECK_FLAG(oi
->at_data
.flags
,
1253 OSPF6_AUTH_TRAILER_KEYCHAIN
)) {
1254 json_object_string_add(json_auth
, "authType",
1256 json_object_string_add(json_auth
,
1258 oi
->at_data
.keychain
);
1259 } else if (CHECK_FLAG(oi
->at_data
.flags
,
1260 OSPF6_AUTH_TRAILER_MANUAL_KEY
))
1261 json_object_string_add(json_auth
, "authType",
1263 json_object_int_add(json_auth
, "txPktDrop",
1264 oi
->at_data
.tx_drop
);
1265 json_object_int_add(json_auth
, "rxPktDrop",
1266 oi
->at_data
.rx_drop
);
1268 if (CHECK_FLAG(oi
->at_data
.flags
,
1269 OSPF6_AUTH_TRAILER_KEYCHAIN
))
1271 " Authentication Trailer is enabled with key-chain %s\n",
1272 oi
->at_data
.keychain
);
1273 else if (CHECK_FLAG(oi
->at_data
.flags
,
1274 OSPF6_AUTH_TRAILER_MANUAL_KEY
))
1276 " Authentication trailer is enabled with manual key\n");
1278 " Packet drop Tx %u, Packet drop Rx %u\n",
1279 oi
->at_data
.tx_drop
, oi
->at_data
.rx_drop
);
1283 json_object_string_add(json_auth
, "authType", "NULL");
1285 vty_out(vty
, " Authentication Trailer is disabled\n");
1289 json_object_object_add(json_obj
, "authInfo", json_auth
);
1294 /* Find the global address to be used as a forwarding address in NSSA LSA.*/
1295 struct in6_addr
*ospf6_interface_get_global_address(struct interface
*ifp
)
1298 struct connected
*c
;
1300 /* for each connected address */
1301 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
1302 /* if family not AF_INET6, ignore */
1303 if (c
->address
->family
!= AF_INET6
)
1306 if (!IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
1307 return &c
->address
->u
.prefix6
;
1314 static int show_ospf6_interface_common(struct vty
*vty
, vrf_id_t vrf_id
,
1315 int argc
, struct cmd_token
**argv
,
1316 int idx_ifname
, int intf_idx
,
1317 int json_idx
, bool uj
)
1320 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
1321 struct interface
*ifp
;
1323 json_object
*json_int
;
1326 json
= json_object_new_object();
1327 if (argc
== json_idx
) {
1328 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1329 json_int
= json_object_new_object();
1331 json_object_string_add(json
, "noSuchInterface",
1332 argv
[idx_ifname
]->arg
);
1333 vty_json(vty
, json
);
1334 json_object_free(json_int
);
1337 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1338 json_object_object_add(json
, ifp
->name
, json_int
);
1340 FOR_ALL_INTERFACES (vrf
, ifp
) {
1341 json_int
= json_object_new_object();
1342 ospf6_interface_show(vty
, ifp
, json_int
, uj
);
1343 json_object_object_add(json
, ifp
->name
,
1347 vty_json(vty
, json
);
1349 if (argc
== intf_idx
) {
1350 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1352 vty_out(vty
, "No such Interface: %s\n",
1353 argv
[idx_ifname
]->arg
);
1356 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1358 FOR_ALL_INTERFACES (vrf
, ifp
)
1359 ospf6_interface_show(vty
, ifp
, NULL
, uj
);
1365 /* show interface */
1366 DEFUN(show_ipv6_ospf6_interface
, show_ipv6_ospf6_interface_ifname_cmd
,
1367 "show ipv6 ospf6 [vrf <NAME|all>] interface [IFNAME] [json]",
1368 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1369 "All VRFs\n" INTERFACE_STR IFNAME_STR JSON_STR
)
1374 struct listnode
*node
;
1375 struct ospf6
*ospf6
;
1376 const char *vrf_name
= NULL
;
1377 bool all_vrf
= false;
1379 bool uj
= use_json(argc
, argv
);
1381 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1388 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1389 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1390 show_ospf6_interface_common(vty
, ospf6
->vrf_id
, argc
,
1391 argv
, idx_ifname
, intf_idx
,
1399 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1404 static int ospf6_interface_show_traffic(struct vty
*vty
,
1405 struct interface
*intf_ifp
,
1406 int display_once
, json_object
*json
,
1407 bool use_json
, vrf_id_t vrf_id
)
1409 struct interface
*ifp
;
1410 struct vrf
*vrf
= NULL
;
1411 struct ospf6_interface
*oi
= NULL
;
1412 json_object
*json_interface
;
1414 if (!display_once
&& !use_json
) {
1416 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1417 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1419 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1420 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1423 "--------------------------------------------------------------------------------------------\n");
1426 if (intf_ifp
== NULL
) {
1427 vrf
= vrf_lookup_by_id(vrf_id
);
1428 FOR_ALL_INTERFACES (vrf
, ifp
) {
1430 oi
= (struct ospf6_interface
*)ifp
->info
;
1435 json_interface
= json_object_new_object();
1436 json_object_int_add(json_interface
, "helloRx",
1438 json_object_int_add(json_interface
, "helloTx",
1440 json_object_int_add(json_interface
, "dbDescRx",
1442 json_object_int_add(json_interface
, "dbDescTx",
1444 json_object_int_add(json_interface
, "lsReqRx",
1446 json_object_int_add(json_interface
, "lsReqTx",
1448 json_object_int_add(json_interface
,
1451 json_object_int_add(json_interface
,
1454 json_object_int_add(json_interface
, "lsAckRx",
1456 json_object_int_add(json_interface
, "lsAckTx",
1459 json_object_object_add(json
,
1460 oi
->interface
->name
,
1464 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1465 oi
->interface
->name
, oi
->hello_in
,
1466 oi
->hello_out
, oi
->db_desc_in
,
1467 oi
->db_desc_out
, oi
->ls_req_in
,
1468 oi
->ls_req_out
, oi
->ls_upd_in
,
1469 oi
->ls_upd_out
, oi
->ls_ack_in
,
1473 oi
= intf_ifp
->info
;
1478 json_interface
= json_object_new_object();
1479 json_object_int_add(json_interface
, "helloRx",
1481 json_object_int_add(json_interface
, "helloTx",
1483 json_object_int_add(json_interface
, "dbDescRx",
1485 json_object_int_add(json_interface
, "dbDescTx",
1487 json_object_int_add(json_interface
, "lsReqRx",
1489 json_object_int_add(json_interface
, "lsReqTx",
1491 json_object_int_add(json_interface
, "lsUpdateRx",
1493 json_object_int_add(json_interface
, "lsUpdateTx",
1495 json_object_int_add(json_interface
, "lsAckRx",
1497 json_object_int_add(json_interface
, "lsAckTx",
1500 json_object_object_add(json
, oi
->interface
->name
,
1504 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1505 oi
->interface
->name
, oi
->hello_in
,
1506 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1507 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1508 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1514 static int ospf6_interface_show_traffic_common(struct vty
*vty
, int argc
,
1515 struct cmd_token
**argv
,
1516 vrf_id_t vrf_id
, bool uj
)
1519 int display_once
= 0;
1520 char *intf_name
= NULL
;
1521 struct interface
*ifp
= NULL
;
1522 json_object
*json
= NULL
;
1525 json
= json_object_new_object();
1527 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1528 intf_name
= argv
[idx_ifname
]->arg
;
1529 ifp
= if_lookup_by_name(intf_name
, vrf_id
);
1532 json_object_string_add(json
, "status",
1533 "No Such Interface");
1534 json_object_string_add(json
, "interface",
1536 vty_json(vty
, json
);
1539 if (ifp
->info
== NULL
) {
1540 json_object_string_add(
1542 "OSPF not enabled on this interface");
1543 json_object_string_add(json
, "interface",
1545 vty_json(vty
, json
);
1550 vty_out(vty
, "No such Interface: %s\n",
1554 if (ifp
->info
== NULL
) {
1556 " OSPF not enabled on this interface %s\n",
1563 ospf6_interface_show_traffic(vty
, ifp
, display_once
, json
, uj
, vrf_id
);
1566 vty_json(vty
, json
);
1571 /* show interface */
1572 DEFUN(show_ipv6_ospf6_interface_traffic
, show_ipv6_ospf6_interface_traffic_cmd
,
1573 "show ipv6 ospf6 [vrf <NAME|all>] interface traffic [IFNAME] [json]",
1574 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1575 "All VRFs\n" INTERFACE_STR
1576 "Protocol Packet counters\n" IFNAME_STR JSON_STR
)
1578 struct ospf6
*ospf6
;
1579 struct listnode
*node
;
1580 const char *vrf_name
= NULL
;
1581 bool all_vrf
= false;
1583 bool uj
= use_json(argc
, argv
);
1585 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1587 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1588 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1589 ospf6_interface_show_traffic_common(vty
, argc
, argv
,
1597 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1603 DEFUN(show_ipv6_ospf6_interface_ifname_prefix
,
1604 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1605 "show ipv6 ospf6 [vrf <NAME|all>] interface IFNAME prefix\
1608 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1610 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1611 "All VRFs\n" INTERFACE_STR IFNAME_STR
1612 "Display connected prefixes to advertise\n"
1613 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1614 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1615 "Display details of the prefixes\n" JSON_STR
)
1619 struct ospf6_interface
*oi
;
1620 bool uj
= use_json(argc
, argv
);
1622 struct ospf6
*ospf6
;
1623 struct listnode
*node
;
1624 struct interface
*ifp
;
1625 const char *vrf_name
= NULL
;
1626 bool all_vrf
= false;
1629 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1635 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1636 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1637 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1640 vty_out(vty
, "No such Interface: %s\n",
1641 argv
[idx_ifname
]->arg
);
1647 || CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
1649 "Interface %s not attached to area\n",
1650 argv
[idx_ifname
]->arg
);
1654 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1655 oi
->route_connected
, uj
);
1662 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1667 DEFUN(show_ipv6_ospf6_interface_prefix
, show_ipv6_ospf6_interface_prefix_cmd
,
1668 "show ipv6 ospf6 [vrf <NAME|all>] interface prefix\
1671 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1673 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1674 "All VRFs\n" INTERFACE_STR
1675 "Display connected prefixes to advertise\n"
1676 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1677 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1678 "Display details of the prefixes\n" JSON_STR
)
1680 struct vrf
*vrf
= NULL
;
1682 struct ospf6_interface
*oi
;
1683 struct interface
*ifp
;
1684 bool uj
= use_json(argc
, argv
);
1685 struct listnode
*node
;
1686 struct ospf6
*ospf6
;
1687 const char *vrf_name
= NULL
;
1688 bool all_vrf
= false;
1691 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1695 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1696 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1697 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
1698 FOR_ALL_INTERFACES (vrf
, ifp
) {
1699 oi
= (struct ospf6_interface
*)ifp
->info
;
1701 || CHECK_FLAG(oi
->flag
,
1702 OSPF6_INTERFACE_DISABLE
))
1705 ospf6_route_table_show(vty
, idx_prefix
, argc
,
1707 oi
->route_connected
, uj
);
1714 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1719 void ospf6_interface_start(struct ospf6_interface
*oi
)
1721 struct ospf6
*ospf6
;
1722 struct ospf6_area
*oa
;
1724 if (oi
->area_id_format
== OSPF6_AREA_FMT_UNSET
)
1728 /* Recompute cost */
1729 ospf6_interface_recalculate_cost(oi
);
1733 ospf6
= oi
->interface
->vrf
->info
;
1737 oa
= ospf6_area_lookup(oi
->area_id
, ospf6
);
1739 oa
= ospf6_area_create(oi
->area_id
, ospf6
, oi
->area_id_format
);
1741 /* attach interface to area */
1742 listnode_add(oa
->if_list
, oi
);
1745 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1748 ospf6_interface_enable(oi
);
1750 /* If the router is ABR, originate summary routes */
1751 if (ospf6_check_and_set_router_abr(ospf6
)) {
1752 ospf6_abr_enable_area(oa
);
1753 ospf6_schedule_abr_task(ospf6
);
1757 void ospf6_interface_stop(struct ospf6_interface
*oi
)
1759 struct ospf6_area
*oa
;
1765 ospf6_interface_disable(oi
);
1767 listnode_delete(oa
->if_list
, oi
);
1770 if (oa
->if_list
->count
== 0) {
1771 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1772 ospf6_abr_disable_area(oa
);
1776 /* interface variable set command */
1777 DEFUN (ipv6_ospf6_area
,
1778 ipv6_ospf6_area_cmd
,
1779 "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
1782 "Specify the OSPF6 area ID\n"
1783 "OSPF6 area ID in IPv4 address notation\n"
1784 "OSPF6 area ID in decimal notation\n")
1786 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1787 struct ospf6_interface
*oi
;
1794 oi
= (struct ospf6_interface
*)ifp
->info
;
1796 oi
= ospf6_interface_create(ifp
);
1800 vty_out(vty
, "%s already attached to Area %s\n",
1801 oi
->interface
->name
, oi
->area
->name
);
1805 if (str2area_id(argv
[idx_ipv4
]->arg
, &area_id
, &format
)) {
1806 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1807 return CMD_WARNING_CONFIG_FAILED
;
1810 oi
->area_id
= area_id
;
1811 oi
->area_id_format
= format
;
1813 ospf6_interface_start(oi
);
1818 DEFUN (no_ipv6_ospf6_area
,
1819 no_ipv6_ospf6_area_cmd
,
1820 "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
1824 "Specify the OSPF6 area ID\n"
1825 "OSPF6 area ID in IPv4 address notation\n"
1826 "OSPF6 area ID in decimal notation\n")
1828 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1829 struct ospf6_interface
*oi
;
1833 oi
= (struct ospf6_interface
*)ifp
->info
;
1835 oi
= ospf6_interface_create(ifp
);
1838 ospf6_interface_stop(oi
);
1841 oi
->area_id_format
= OSPF6_AREA_FMT_UNSET
;
1846 DEFUN (ipv6_ospf6_ifmtu
,
1847 ipv6_ospf6_ifmtu_cmd
,
1848 "ipv6 ospf6 ifmtu (1-65535)",
1852 "OSPFv3 Interface MTU\n"
1855 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1857 struct ospf6_interface
*oi
;
1858 unsigned int ifmtu
, iobuflen
;
1859 struct listnode
*node
, *nnode
;
1860 struct ospf6_neighbor
*on
;
1864 oi
= (struct ospf6_interface
*)ifp
->info
;
1866 oi
= ospf6_interface_create(ifp
);
1869 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1871 if (oi
->c_ifmtu
== ifmtu
)
1874 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1876 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1877 ifp
->name
, ifp
->mtu6
);
1878 return CMD_WARNING_CONFIG_FAILED
;
1881 if (oi
->ifmtu
< ifmtu
) {
1882 iobuflen
= ospf6_iobuf_size(ifmtu
);
1883 if (iobuflen
< ifmtu
) {
1885 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1886 ifp
->name
, iobuflen
);
1887 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1889 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1891 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1893 /* re-establish adjacencies */
1894 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1895 THREAD_OFF(on
->inactivity_timer
);
1896 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1902 DEFUN (no_ipv6_ospf6_ifmtu
,
1903 no_ipv6_ospf6_ifmtu_cmd
,
1904 "no ipv6 ospf6 ifmtu [(1-65535)]",
1909 "OSPFv3 Interface MTU\n"
1912 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1913 struct ospf6_interface
*oi
;
1914 unsigned int iobuflen
;
1915 struct listnode
*node
, *nnode
;
1916 struct ospf6_neighbor
*on
;
1920 oi
= (struct ospf6_interface
*)ifp
->info
;
1922 oi
= ospf6_interface_create(ifp
);
1925 if (oi
->ifmtu
< ifp
->mtu
) {
1926 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1927 if (iobuflen
< ifp
->mtu
) {
1929 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1930 ifp
->name
, iobuflen
);
1931 oi
->ifmtu
= iobuflen
;
1933 oi
->ifmtu
= ifp
->mtu
;
1935 oi
->ifmtu
= ifp
->mtu
;
1939 /* re-establish adjacencies */
1940 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1941 THREAD_OFF(on
->inactivity_timer
);
1942 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1948 DEFUN (ipv6_ospf6_cost
,
1949 ipv6_ospf6_cost_cmd
,
1950 "ipv6 ospf6 cost (1-65535)",
1954 "Outgoing metric of this interface\n")
1956 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1958 struct ospf6_interface
*oi
;
1959 unsigned long int lcost
;
1963 oi
= (struct ospf6_interface
*)ifp
->info
;
1965 oi
= ospf6_interface_create(ifp
);
1968 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1970 if (lcost
> UINT32_MAX
) {
1971 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1972 return CMD_WARNING_CONFIG_FAILED
;
1975 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1976 if (oi
->cost
== lcost
)
1980 ospf6_interface_force_recalculate_cost(oi
);
1985 DEFUN (no_ipv6_ospf6_cost
,
1986 no_ipv6_ospf6_cost_cmd
,
1987 "no ipv6 ospf6 cost [(1-65535)]",
1991 "Calculate interface cost from bandwidth\n"
1992 "Outgoing metric of this interface\n")
1994 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1995 struct ospf6_interface
*oi
;
1998 oi
= (struct ospf6_interface
*)ifp
->info
;
2000 oi
= ospf6_interface_create(ifp
);
2003 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
2005 ospf6_interface_recalculate_cost(oi
);
2010 DEFUN (auto_cost_reference_bandwidth
,
2011 auto_cost_reference_bandwidth_cmd
,
2012 "auto-cost reference-bandwidth (1-4294967)",
2013 "Calculate OSPF interface cost according to bandwidth\n"
2014 "Use reference bandwidth method to assign OSPF cost\n"
2015 "The reference bandwidth in terms of Mbits per second\n")
2017 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2019 struct ospf6_area
*oa
;
2020 struct ospf6_interface
*oi
;
2021 struct listnode
*i
, *j
;
2024 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
2025 if (refbw
< 1 || refbw
> 4294967) {
2026 vty_out(vty
, "reference-bandwidth value is invalid\n");
2027 return CMD_WARNING_CONFIG_FAILED
;
2030 /* If reference bandwidth is changed. */
2031 if ((refbw
) == o
->ref_bandwidth
)
2034 o
->ref_bandwidth
= refbw
;
2035 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
2036 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
2037 ospf6_interface_recalculate_cost(oi
);
2042 DEFUN (no_auto_cost_reference_bandwidth
,
2043 no_auto_cost_reference_bandwidth_cmd
,
2044 "no auto-cost reference-bandwidth [(1-4294967)]",
2046 "Calculate OSPF interface cost according to bandwidth\n"
2047 "Use reference bandwidth method to assign OSPF cost\n"
2048 "The reference bandwidth in terms of Mbits per second\n")
2050 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2051 struct ospf6_area
*oa
;
2052 struct ospf6_interface
*oi
;
2053 struct listnode
*i
, *j
;
2055 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
2058 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
2059 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
2060 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
2061 ospf6_interface_recalculate_cost(oi
);
2067 DEFUN (ospf6_write_multiplier
,
2068 ospf6_write_multiplier_cmd
,
2069 "write-multiplier (1-100)",
2070 "Write multiplier\n"
2071 "Maximum number of interface serviced per write\n")
2073 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2074 uint32_t write_oi_count
;
2076 write_oi_count
= strtol(argv
[1]->arg
, NULL
, 10);
2077 if (write_oi_count
< 1 || write_oi_count
> 100) {
2078 vty_out(vty
, "write-multiplier value is invalid\n");
2079 return CMD_WARNING_CONFIG_FAILED
;
2082 o
->write_oi_count
= write_oi_count
;
2086 DEFUN (no_ospf6_write_multiplier
,
2087 no_ospf6_write_multiplier_cmd
,
2088 "no write-multiplier (1-100)",
2090 "Write multiplier\n"
2091 "Maximum number of interface serviced per write\n")
2093 VTY_DECLVAR_CONTEXT(ospf6
, o
);
2095 o
->write_oi_count
= OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
;
2099 DEFUN (ipv6_ospf6_hellointerval
,
2100 ipv6_ospf6_hellointerval_cmd
,
2101 "ipv6 ospf6 hello-interval (1-65535)",
2104 "Time between HELLO packets\n"
2107 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2109 struct ospf6_interface
*oi
;
2112 oi
= (struct ospf6_interface
*)ifp
->info
;
2114 oi
= ospf6_interface_create(ifp
);
2117 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
2118 ? OSPF_HELLO_INTERVAL_DEFAULT
2119 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2122 * If the thread is scheduled, send the new hello now.
2124 if (thread_is_scheduled(oi
->thread_send_hello
)) {
2125 THREAD_OFF(oi
->thread_send_hello
);
2127 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
2128 &oi
->thread_send_hello
);
2133 ALIAS (ipv6_ospf6_hellointerval
,
2134 no_ipv6_ospf6_hellointerval_cmd
,
2135 "no ipv6 ospf6 hello-interval [(1-65535)]",
2139 "Time between HELLO packets\n"
2142 /* interface variable set command */
2143 DEFUN (ipv6_ospf6_deadinterval
,
2144 ipv6_ospf6_deadinterval_cmd
,
2145 "ipv6 ospf6 dead-interval (1-65535)",
2148 "Interval time after which a neighbor is declared down\n"
2151 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2153 struct ospf6_interface
*oi
;
2156 oi
= (struct ospf6_interface
*)ifp
->info
;
2158 oi
= ospf6_interface_create(ifp
);
2161 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
2162 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
2163 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2167 ALIAS (ipv6_ospf6_deadinterval
,
2168 no_ipv6_ospf6_deadinterval_cmd
,
2169 "no ipv6 ospf6 dead-interval [(1-65535)]",
2173 "Interval time after which a neighbor is declared down\n"
2176 /* interface variable set command */
2177 DEFUN (ipv6_ospf6_transmitdelay
,
2178 ipv6_ospf6_transmitdelay_cmd
,
2179 "ipv6 ospf6 transmit-delay (1-3600)",
2182 "Link state transmit delay\n"
2185 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2187 struct ospf6_interface
*oi
;
2190 oi
= (struct ospf6_interface
*)ifp
->info
;
2192 oi
= ospf6_interface_create(ifp
);
2195 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
2196 ? OSPF6_INTERFACE_TRANSDELAY
2197 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2201 ALIAS (ipv6_ospf6_transmitdelay
,
2202 no_ipv6_ospf6_transmitdelay_cmd
,
2203 "no ipv6 ospf6 transmit-delay [(1-3600)]",
2207 "Link state transmit delay\n"
2210 /* interface variable set command */
2211 DEFUN (ipv6_ospf6_retransmitinterval
,
2212 ipv6_ospf6_retransmitinterval_cmd
,
2213 "ipv6 ospf6 retransmit-interval (1-65535)",
2216 "Time between retransmitting lost link state advertisements\n"
2219 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2221 struct ospf6_interface
*oi
;
2224 oi
= (struct ospf6_interface
*)ifp
->info
;
2226 oi
= ospf6_interface_create(ifp
);
2229 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
2230 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
2231 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2235 ALIAS (ipv6_ospf6_retransmitinterval
,
2236 no_ipv6_ospf6_retransmitinterval_cmd
,
2237 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
2241 "Time between retransmitting lost link state advertisements\n"
2244 /* interface variable set command */
2245 DEFUN (ipv6_ospf6_priority
,
2246 ipv6_ospf6_priority_cmd
,
2247 "ipv6 ospf6 priority (0-255)",
2253 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2255 struct ospf6_interface
*oi
;
2258 oi
= (struct ospf6_interface
*)ifp
->info
;
2260 oi
= ospf6_interface_create(ifp
);
2263 oi
->priority
= strmatch(argv
[0]->text
, "no")
2264 ? OSPF6_INTERFACE_PRIORITY
2265 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2268 && (oi
->state
== OSPF6_INTERFACE_DROTHER
2269 || oi
->state
== OSPF6_INTERFACE_BDR
2270 || oi
->state
== OSPF6_INTERFACE_DR
)) {
2271 if (ospf6_interface_state_change(dr_election(oi
), oi
) == -1)
2272 OSPF6_LINK_LSA_SCHEDULE(oi
);
2278 ALIAS (ipv6_ospf6_priority
,
2279 no_ipv6_ospf6_priority_cmd
,
2280 "no ipv6 ospf6 priority [(0-255)]",
2287 DEFUN (ipv6_ospf6_instance
,
2288 ipv6_ospf6_instance_cmd
,
2289 "ipv6 ospf6 instance-id (0-255)",
2292 "Instance ID for this interface\n"
2293 "Instance ID value\n")
2295 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2297 struct ospf6_interface
*oi
;
2300 oi
= (struct ospf6_interface
*)ifp
->info
;
2302 oi
= ospf6_interface_create(ifp
);
2305 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
2306 ? OSPF6_INTERFACE_INSTANCE_ID
2307 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2311 ALIAS (ipv6_ospf6_instance
,
2312 no_ipv6_ospf6_instance_cmd
,
2313 "no ipv6 ospf6 instance-id [(0-255)]",
2317 "Instance ID for this interface\n"
2318 "Instance ID value\n")
2320 DEFUN (ipv6_ospf6_passive
,
2321 ipv6_ospf6_passive_cmd
,
2322 "ipv6 ospf6 passive",
2325 "Passive interface; no adjacency will be formed on this interface\n"
2328 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2329 struct ospf6_interface
*oi
;
2330 struct listnode
*node
, *nnode
;
2331 struct ospf6_neighbor
*on
;
2335 oi
= (struct ospf6_interface
*)ifp
->info
;
2337 oi
= ospf6_interface_create(ifp
);
2340 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2341 THREAD_OFF(oi
->thread_send_hello
);
2342 THREAD_OFF(oi
->thread_sso
);
2344 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
2345 THREAD_OFF(on
->inactivity_timer
);
2346 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
2352 DEFUN (no_ipv6_ospf6_passive
,
2353 no_ipv6_ospf6_passive_cmd
,
2354 "no ipv6 ospf6 passive",
2358 "passive interface: No Adjacency will be formed on this I/F\n"
2361 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2362 struct ospf6_interface
*oi
;
2365 oi
= (struct ospf6_interface
*)ifp
->info
;
2367 oi
= ospf6_interface_create(ifp
);
2370 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
2371 THREAD_OFF(oi
->thread_send_hello
);
2372 THREAD_OFF(oi
->thread_sso
);
2374 /* don't send hellos over loopback interface */
2375 if (!if_is_loopback(oi
->interface
))
2376 thread_add_timer(master
, ospf6_hello_send
, oi
, 0,
2377 &oi
->thread_send_hello
);
2382 DEFUN (ipv6_ospf6_mtu_ignore
,
2383 ipv6_ospf6_mtu_ignore_cmd
,
2384 "ipv6 ospf6 mtu-ignore",
2387 "Disable MTU mismatch detection on this interface\n"
2390 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2391 struct ospf6_interface
*oi
;
2394 oi
= (struct ospf6_interface
*)ifp
->info
;
2396 oi
= ospf6_interface_create(ifp
);
2404 DEFUN (no_ipv6_ospf6_mtu_ignore
,
2405 no_ipv6_ospf6_mtu_ignore_cmd
,
2406 "no ipv6 ospf6 mtu-ignore",
2410 "Disable MTU mismatch detection on this interface\n"
2413 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2414 struct ospf6_interface
*oi
;
2417 oi
= (struct ospf6_interface
*)ifp
->info
;
2419 oi
= ospf6_interface_create(ifp
);
2427 DEFUN (ipv6_ospf6_advertise_prefix_list
,
2428 ipv6_ospf6_advertise_prefix_list_cmd
,
2429 "ipv6 ospf6 advertise prefix-list WORD",
2432 "Advertising options\n"
2433 "Filter prefix using prefix-list\n"
2434 "Prefix list name\n"
2437 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2439 struct ospf6_interface
*oi
;
2442 oi
= (struct ospf6_interface
*)ifp
->info
;
2444 oi
= ospf6_interface_create(ifp
);
2448 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2449 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
2451 ospf6_interface_connected_route_update(oi
->interface
);
2454 OSPF6_LINK_LSA_SCHEDULE(oi
);
2455 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2456 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2457 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2459 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2465 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
2466 no_ipv6_ospf6_advertise_prefix_list_cmd
,
2467 "no ipv6 ospf6 advertise prefix-list [WORD]",
2471 "Advertising options\n"
2472 "Filter prefix using prefix-list\n"
2473 "Prefix list name\n")
2475 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2476 struct ospf6_interface
*oi
;
2479 oi
= (struct ospf6_interface
*)ifp
->info
;
2481 oi
= ospf6_interface_create(ifp
);
2485 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
2487 ospf6_interface_connected_route_update(oi
->interface
);
2490 OSPF6_LINK_LSA_SCHEDULE(oi
);
2491 if (oi
->state
== OSPF6_INTERFACE_DR
) {
2492 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
2493 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
2495 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
2501 DEFUN (ipv6_ospf6_network
,
2502 ipv6_ospf6_network_cmd
,
2503 "ipv6 ospf6 network <broadcast|point-to-point>",
2507 "Specify OSPF6 broadcast network\n"
2508 "Specify OSPF6 point-to-point network\n"
2511 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2512 int idx_network
= 3;
2513 struct ospf6_interface
*oi
;
2516 oi
= (struct ospf6_interface
*)ifp
->info
;
2518 oi
= ospf6_interface_create(ifp
);
2522 oi
->type_cfg
= true;
2524 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
2525 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
2528 oi
->type
= OSPF_IFTYPE_BROADCAST
;
2529 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
2530 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
2533 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
2536 /* Reset the interface */
2537 thread_execute(master
, interface_down
, oi
, 0);
2538 thread_execute(master
, interface_up
, oi
, 0);
2543 DEFUN (no_ipv6_ospf6_network
,
2544 no_ipv6_ospf6_network_cmd
,
2545 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2549 "Set default network type\n"
2550 "Specify OSPF6 broadcast network\n"
2551 "Specify OSPF6 point-to-point network\n")
2553 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2554 struct ospf6_interface
*oi
;
2559 oi
= (struct ospf6_interface
*)ifp
->info
;
2564 oi
->type_cfg
= false;
2566 type
= ospf6_default_iftype(ifp
);
2567 if (oi
->type
== type
) {
2572 /* Reset the interface */
2573 thread_execute(master
, interface_down
, oi
, 0);
2574 thread_execute(master
, interface_up
, oi
, 0);
2579 static int config_write_ospf6_interface(struct vty
*vty
, struct vrf
*vrf
)
2581 struct ospf6_interface
*oi
;
2582 struct interface
*ifp
;
2583 char buf
[INET_ADDRSTRLEN
];
2585 FOR_ALL_INTERFACES (vrf
, ifp
) {
2586 oi
= (struct ospf6_interface
*)ifp
->info
;
2590 if_vty_config_start(vty
, ifp
);
2593 vty_out(vty
, " description %s\n", ifp
->desc
);
2594 if (oi
->area_id_format
!= OSPF6_AREA_FMT_UNSET
) {
2595 area_id2str(buf
, sizeof(buf
), oi
->area_id
,
2596 oi
->area_id_format
);
2597 vty_out(vty
, " ipv6 ospf6 area %s\n", buf
);
2600 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
2602 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
2603 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
2605 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
2606 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
2607 oi
->hello_interval
);
2609 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
2610 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
2613 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
2614 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
2617 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
2618 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
2620 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
2621 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
2624 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
2625 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
2629 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
2632 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
2633 vty_out(vty
, " ipv6 ospf6 passive\n");
2636 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
2638 if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
2639 vty_out(vty
, " ipv6 ospf6 network point-to-point\n");
2640 else if (oi
->type_cfg
&& oi
->type
== OSPF_IFTYPE_BROADCAST
)
2641 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
2643 ospf6_bfd_write_config(vty
, oi
);
2645 ospf6_auth_write_config(vty
, &oi
->at_data
);
2646 if_vty_config_end(vty
);
2651 /* Configuration write function for ospfd. */
2652 static int config_write_interface(struct vty
*vty
)
2655 struct vrf
*vrf
= NULL
;
2657 /* Display all VRF aware OSPF interface configuration */
2658 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2659 write
+= config_write_ospf6_interface(vty
, vrf
);
2665 static int ospf6_ifp_create(struct interface
*ifp
)
2667 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2668 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp
->name
,
2669 ifp
->ifindex
, ifp
->mtu6
);
2672 ospf6_interface_start(ifp
->info
);
2677 static int ospf6_ifp_up(struct interface
*ifp
)
2679 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2681 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2682 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2683 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2685 ospf6_interface_state_update(ifp
);
2690 static int ospf6_ifp_down(struct interface
*ifp
)
2692 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2694 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2695 ifp
->name
, ifp
->ifindex
, (unsigned long long)ifp
->flags
,
2696 ifp
->metric
, ifp
->mtu6
, ifp
->bandwidth
);
2698 ospf6_interface_state_update(ifp
);
2703 static int ospf6_ifp_destroy(struct interface
*ifp
)
2706 zlog_warn("Zebra: got delete of %s, but interface is still up",
2709 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
2710 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2711 ifp
->name
, ifp
->ifindex
, ifp
->mtu6
);
2714 ospf6_interface_stop(ifp
->info
);
2719 void ospf6_interface_init(void)
2721 /* Install interface node. */
2722 if_cmd_init(config_write_interface
);
2723 if_zapi_callbacks(ospf6_ifp_create
, ospf6_ifp_up
,
2724 ospf6_ifp_down
, ospf6_ifp_destroy
);
2726 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
2727 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
2728 install_element(VIEW_NODE
,
2729 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
2730 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
2732 install_element(INTERFACE_NODE
, &ipv6_ospf6_area_cmd
);
2733 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_area_cmd
);
2734 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
2735 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
2736 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
2737 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
2739 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
2740 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
2741 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
2742 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
2743 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
2744 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
2745 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
2746 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
2747 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
2748 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
2749 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
2750 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
2752 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
2753 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
2755 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
2756 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
2758 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
2759 install_element(INTERFACE_NODE
,
2760 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
2762 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
2763 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
2765 /* reference bandwidth commands */
2766 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
2767 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
2768 /* write-multiplier commands */
2769 install_element(OSPF6_NODE
, &ospf6_write_multiplier_cmd
);
2770 install_element(OSPF6_NODE
, &no_ospf6_write_multiplier_cmd
);
2773 /* Clear the specified interface structure */
2774 void ospf6_interface_clear(struct interface
*ifp
)
2776 struct ospf6_interface
*oi
;
2778 if (!if_is_operative(ifp
))
2781 if (ifp
->info
== NULL
)
2784 oi
= (struct ospf6_interface
*)ifp
->info
;
2786 if (IS_OSPF6_DEBUG_INTERFACE
)
2787 zlog_debug("Interface %s: clear by reset", ifp
->name
);
2789 /* Reset the interface */
2790 thread_execute(master
, interface_down
, oi
, 0);
2791 thread_execute(master
, interface_up
, oi
, 0);
2794 /* Clear interface */
2795 DEFUN (clear_ipv6_ospf6_interface
,
2796 clear_ipv6_ospf6_interface_cmd
,
2797 "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
2809 struct interface
*ifp
;
2810 const char *vrf_name
;
2812 if (argv_find(argv
, argc
, "vrf", &idx_vrf
))
2813 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
2815 vrf_name
= VRF_DEFAULT_NAME
;
2816 vrf
= vrf_lookup_by_name(vrf_name
);
2818 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2822 if (!argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
2823 /* Clear all the ospfv3 interfaces. */
2824 FOR_ALL_INTERFACES (vrf
, ifp
)
2825 ospf6_interface_clear(ifp
);
2827 /* Interface name is specified. */
2828 ifp
= if_lookup_by_name_vrf(argv
[idx_ifname
]->arg
, vrf
);
2830 vty_out(vty
, "No such Interface: %s\n",
2831 argv
[idx_ifname
]->arg
);
2834 ospf6_interface_clear(ifp
);
2840 void install_element_ospf6_clear_interface(void)
2842 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2845 DEFUN (debug_ospf6_interface
,
2846 debug_ospf6_interface_cmd
,
2847 "debug ospf6 interface",
2850 "Debug OSPFv3 Interface\n"
2853 OSPF6_DEBUG_INTERFACE_ON();
2857 DEFUN (no_debug_ospf6_interface
,
2858 no_debug_ospf6_interface_cmd
,
2859 "no debug ospf6 interface",
2863 "Debug OSPFv3 Interface\n"
2866 OSPF6_DEBUG_INTERFACE_OFF();
2870 int config_write_ospf6_debug_interface(struct vty
*vty
)
2872 if (IS_OSPF6_DEBUG_INTERFACE
)
2873 vty_out(vty
, "debug ospf6 interface\n");
2877 void install_element_ospf6_debug_interface(void)
2879 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2880 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2881 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2882 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);
2885 void ospf6_auth_write_config(struct vty
*vty
, struct ospf6_auth_data
*at_data
)
2887 if (CHECK_FLAG(at_data
->flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
))
2888 vty_out(vty
, " ipv6 ospf6 authentication keychain %s\n",
2890 else if (CHECK_FLAG(at_data
->flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
))
2892 " ipv6 ospf6 authentication key-id %d hash-algo %s key %s\n",
2894 keychain_get_algo_name_by_id(at_data
->hash_algo
),
2898 DEFUN(ipv6_ospf6_intf_auth_trailer_keychain
,
2899 ipv6_ospf6_intf_auth_trailer_keychain_cmd
,
2900 "ipv6 ospf6 authentication keychain KEYCHAIN_NAME",
2902 "Enable authentication on this interface\n"
2906 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2907 int keychain_idx
= 4;
2908 struct ospf6_interface
*oi
;
2910 oi
= (struct ospf6_interface
*)ifp
->info
;
2912 oi
= ospf6_interface_create(ifp
);
2915 if (CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
)) {
2917 "Manual key configured, unconfigure it before configuring key chain\n");
2918 return CMD_WARNING_CONFIG_FAILED
;
2921 SET_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
);
2922 if (oi
->at_data
.keychain
)
2923 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN
, oi
->at_data
.keychain
);
2925 oi
->at_data
.keychain
=
2926 XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN
, argv
[keychain_idx
]->arg
);
2931 DEFUN(no_ipv6_ospf6_intf_auth_trailer_keychain
,
2932 no_ipv6_ospf6_intf_auth_trailer_keychain_cmd
,
2933 "no ipv6 ospf6 authentication keychain [KEYCHAIN_NAME]",
2934 NO_STR IP6_STR OSPF6_STR
2935 "Enable authentication on this interface\n"
2939 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2940 struct ospf6_interface
*oi
;
2942 oi
= (struct ospf6_interface
*)ifp
->info
;
2944 oi
= ospf6_interface_create(ifp
);
2947 if (!CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
))
2950 if (oi
->at_data
.keychain
) {
2951 oi
->at_data
.flags
= 0;
2952 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN
, oi
->at_data
.keychain
);
2953 oi
->at_data
.keychain
= NULL
;
2959 DEFUN(ipv6_ospf6_intf_auth_trailer_key
, ipv6_ospf6_intf_auth_trailer_key_cmd
,
2960 "ipv6 ospf6 authentication key-id (1-65535) hash-algo "
2961 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
2967 "Cryptographic-algorithm\n"
2968 "Use MD5 algorithm\n"
2969 "Use HMAC-SHA-1 algorithm\n"
2970 "Use HMAC-SHA-256 algorithm\n"
2971 "Use HMAC-SHA-384 algorithm\n"
2972 "Use HMAC-SHA-512 algorithm\n"
2974 "Password string (key)\n")
2976 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2978 int hash_algo_idx
= 6;
2979 int password_idx
= 8;
2980 struct ospf6_interface
*oi
;
2981 uint8_t hash_algo
= KEYCHAIN_ALGO_NULL
;
2983 oi
= (struct ospf6_interface
*)ifp
->info
;
2985 oi
= ospf6_interface_create(ifp
);
2988 if (CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_KEYCHAIN
)) {
2990 "key chain configured, unconfigure it before configuring manual key\n");
2991 return CMD_WARNING_CONFIG_FAILED
;
2994 hash_algo
= keychain_get_algo_id_by_name(argv
[hash_algo_idx
]->arg
);
2995 #ifndef CRYPTO_OPENSSL
2996 if (hash_algo
== KEYCHAIN_ALGO_NULL
) {
2998 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
2999 return CMD_WARNING_CONFIG_FAILED
;
3001 #endif /* CRYPTO_OPENSSL */
3003 SET_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
);
3004 oi
->at_data
.hash_algo
= hash_algo
;
3005 oi
->at_data
.key_id
= (uint16_t)strtol(argv
[key_id_idx
]->arg
, NULL
, 10);
3006 if (oi
->at_data
.auth_key
)
3007 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY
, oi
->at_data
.auth_key
);
3008 oi
->at_data
.auth_key
=
3009 XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY
, argv
[password_idx
]->arg
);
3014 DEFUN(no_ipv6_ospf6_intf_auth_trailer_key
,
3015 no_ipv6_ospf6_intf_auth_trailer_key_cmd
,
3016 "no ipv6 ospf6 authentication key-id [(1-65535) hash-algo "
3017 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
3019 NO_STR IP6_STR OSPF6_STR
3023 "Cryptographic-algorithm\n"
3024 "Use MD5 algorithm\n"
3025 "Use HMAC-SHA-1 algorithm\n"
3026 "Use HMAC-SHA-256 algorithm\n"
3027 "Use HMAC-SHA-384 algorithm\n"
3028 "Use HMAC-SHA-512 algorithm\n"
3030 "Password string (key)\n")
3032 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3033 struct ospf6_interface
*oi
;
3034 #ifndef CRYPTO_OPENSSL
3035 int hash_algo_idx
= 7;
3036 uint8_t hash_algo
= KEYCHAIN_ALGO_NULL
;
3037 #endif /* CRYPTO_OPENSSL */
3039 oi
= (struct ospf6_interface
*)ifp
->info
;
3041 oi
= ospf6_interface_create(ifp
);
3044 if (!CHECK_FLAG(oi
->at_data
.flags
, OSPF6_AUTH_TRAILER_MANUAL_KEY
))
3047 #ifndef CRYPTO_OPENSSL
3048 hash_algo
= keychain_get_algo_id_by_name(argv
[hash_algo_idx
]->arg
);
3049 if (hash_algo
== KEYCHAIN_ALGO_NULL
) {
3051 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
3052 return CMD_WARNING_CONFIG_FAILED
;
3054 #endif /* CRYPTO_OPENSSL */
3056 if (oi
->at_data
.auth_key
) {
3057 oi
->at_data
.flags
= 0;
3058 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY
, oi
->at_data
.auth_key
);
3059 oi
->at_data
.auth_key
= NULL
;
3065 void ospf6_interface_auth_trailer_cmd_init(void)
3067 /*Install OSPF6 auth trailer commands at interface level */
3068 install_element(INTERFACE_NODE
,
3069 &ipv6_ospf6_intf_auth_trailer_keychain_cmd
);
3070 install_element(INTERFACE_NODE
,
3071 &no_ipv6_ospf6_intf_auth_trailer_keychain_cmd
);
3072 install_element(INTERFACE_NODE
, &ipv6_ospf6_intf_auth_trailer_key_cmd
);
3073 install_element(INTERFACE_NODE
,
3074 &no_ipv6_ospf6_intf_auth_trailer_key_cmd
);