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_network.h"
35 #include "ospf6_message.h"
36 #include "ospf6_route.h"
37 #include "ospf6_top.h"
38 #include "ospf6_area.h"
39 #include "ospf6_interface.h"
40 #include "ospf6_neighbor.h"
41 #include "ospf6_intra.h"
42 #include "ospf6_spf.h"
44 #include "ospf6_bfd.h"
46 DEFINE_MTYPE_STATIC(OSPF6D
, CFG_PLIST_NAME
, "configured prefix list names")
47 DEFINE_QOBJ_TYPE(ospf6_interface
)
48 DEFINE_HOOK(ospf6_interface_change
,
49 (struct ospf6_interface
* oi
, int state
, int old_state
),
50 (oi
, state
, old_state
))
52 unsigned char conf_debug_ospf6_interface
= 0;
54 const char *ospf6_interface_state_str
[] = {
55 "None", "Down", "Loopback", "Waiting", "PointToPoint",
56 "DROther", "BDR", "DR", NULL
};
58 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
)
60 struct ospf6_interface
*oi
;
61 struct interface
*ifp
;
63 ifp
= if_lookup_by_index(ifindex
, VRF_DEFAULT
);
65 return (struct ospf6_interface
*)NULL
;
67 oi
= (struct ospf6_interface
*)ifp
->info
;
71 /* schedule routing table recalculation */
72 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
75 struct ospf6_interface
*oi
;
81 switch (ntohs(lsa
->header
->type
)) {
82 case OSPF6_LSTYPE_LINK
:
83 if (oi
->state
== OSPF6_INTERFACE_DR
)
84 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
86 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
94 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
96 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
99 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
101 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
104 static u_char
ospf6_default_iftype(struct interface
*ifp
)
106 if (if_is_pointopoint(ifp
))
107 return OSPF_IFTYPE_POINTOPOINT
;
108 else if (if_is_loopback(ifp
))
109 return OSPF_IFTYPE_LOOPBACK
;
111 return OSPF_IFTYPE_BROADCAST
;
114 static u_int32_t
ospf6_interface_get_cost(struct ospf6_interface
*oi
)
116 /* If all else fails, use default OSPF cost */
120 /* interface speed and bw can be 0 in some platforms,
121 * use ospf default bw. If bw is configured then it would
124 if (!oi
->interface
->bandwidth
&& oi
->interface
->speed
) {
125 bw
= oi
->interface
->speed
;
127 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
128 : OSPF6_INTERFACE_BANDWIDTH
;
131 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
133 /* A specifed ip ospf cost overrides a calculated one. */
134 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
137 cost
= (u_int32_t
)((double)refbw
/ (double)bw
+ (double)0.5);
140 else if (cost
> UINT32_MAX
)
147 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
151 newcost
= ospf6_interface_get_cost(oi
);
152 if (newcost
== oi
->cost
)
156 /* update cost held in route_connected list in ospf6_interface */
157 ospf6_interface_connected_route_update(oi
->interface
);
159 /* execute LSA hooks */
161 OSPF6_LINK_LSA_SCHEDULE(oi
);
162 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
163 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
164 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
165 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
169 /* Create new ospf6 interface structure */
170 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
172 struct ospf6_interface
*oi
;
173 unsigned int iobuflen
;
175 oi
= (struct ospf6_interface
*)XCALLOC(MTYPE_OSPF6_IF
,
176 sizeof(struct ospf6_interface
));
179 zlog_err("Can't malloc ospf6_interface for ifindex %d",
181 return (struct ospf6_interface
*)NULL
;
184 oi
->area
= (struct ospf6_area
*)NULL
;
185 oi
->neighbor_list
= list_new();
186 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
187 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
188 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
189 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
190 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
192 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
193 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
194 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
195 oi
->type
= ospf6_default_iftype(ifp
);
196 oi
->state
= OSPF6_INTERFACE_DOWN
;
201 /* Try to adjust I/O buffer size with IfMtu */
202 oi
->ifmtu
= ifp
->mtu6
;
203 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
204 if (oi
->ifmtu
> iobuflen
) {
205 if (IS_OSPF6_DEBUG_INTERFACE
)
207 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
208 ifp
->name
, iobuflen
);
209 oi
->ifmtu
= iobuflen
;
212 QOBJ_REG(oi
, ospf6_interface
);
214 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
215 oi
->lsack_list
= ospf6_lsdb_create(oi
);
216 oi
->lsdb
= ospf6_lsdb_create(oi
);
217 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
218 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
219 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
221 oi
->route_connected
=
222 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
223 oi
->route_connected
->scope
= oi
;
230 oi
->cost
= ospf6_interface_get_cost(oi
);
235 void ospf6_interface_delete(struct ospf6_interface
*oi
)
237 struct listnode
*node
, *nnode
;
238 struct ospf6_neighbor
*on
;
242 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
243 ospf6_neighbor_delete(on
);
245 list_delete_and_null(&oi
->neighbor_list
);
247 THREAD_OFF(oi
->thread_send_hello
);
248 THREAD_OFF(oi
->thread_send_lsupdate
);
249 THREAD_OFF(oi
->thread_send_lsack
);
251 ospf6_lsdb_remove_all(oi
->lsdb
);
252 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
253 ospf6_lsdb_remove_all(oi
->lsack_list
);
255 ospf6_lsdb_delete(oi
->lsdb
);
256 ospf6_lsdb_delete(oi
->lsdb_self
);
258 ospf6_lsdb_delete(oi
->lsupdate_list
);
259 ospf6_lsdb_delete(oi
->lsack_list
);
261 ospf6_route_table_delete(oi
->route_connected
);
264 oi
->interface
->info
= NULL
;
268 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
270 ospf6_bfd_info_free(&(oi
->bfd_info
));
272 XFREE(MTYPE_OSPF6_IF
, oi
);
275 void ospf6_interface_enable(struct ospf6_interface
*oi
)
277 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
278 ospf6_interface_state_update(oi
->interface
);
281 void ospf6_interface_disable(struct ospf6_interface
*oi
)
283 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
285 thread_execute(master
, interface_down
, oi
, 0);
287 ospf6_lsdb_remove_all(oi
->lsdb
);
288 ospf6_lsdb_remove_all(oi
->lsdb_self
);
289 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
290 ospf6_lsdb_remove_all(oi
->lsack_list
);
292 THREAD_OFF(oi
->thread_send_hello
);
293 THREAD_OFF(oi
->thread_send_lsupdate
);
294 THREAD_OFF(oi
->thread_send_lsack
);
296 THREAD_OFF(oi
->thread_network_lsa
);
297 THREAD_OFF(oi
->thread_link_lsa
);
298 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
301 static struct in6_addr
*
302 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
306 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
308 /* for each connected address */
309 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
310 /* if family not AF_INET6, ignore */
311 if (c
->address
->family
!= AF_INET6
)
314 /* linklocal scope check */
315 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
316 l
= &c
->address
->u
.prefix6
;
321 void ospf6_interface_if_add(struct interface
*ifp
)
323 struct ospf6_interface
*oi
;
324 unsigned int iobuflen
;
326 oi
= (struct ospf6_interface
*)ifp
->info
;
330 /* Try to adjust I/O buffer size with IfMtu */
332 oi
->ifmtu
= ifp
->mtu6
;
333 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
334 if (oi
->ifmtu
> iobuflen
) {
335 if (IS_OSPF6_DEBUG_INTERFACE
)
337 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
338 ifp
->name
, iobuflen
);
339 oi
->ifmtu
= iobuflen
;
342 /* interface start */
343 ospf6_interface_state_update(oi
->interface
);
346 void ospf6_interface_if_del(struct interface
*ifp
)
348 struct ospf6_interface
*oi
;
350 oi
= (struct ospf6_interface
*)ifp
->info
;
356 thread_execute(master
, interface_down
, oi
, 0);
358 listnode_delete(oi
->area
->if_list
, oi
);
359 oi
->area
= (struct ospf6_area
*)NULL
;
362 oi
->interface
= NULL
;
365 ospf6_interface_delete(oi
);
368 void ospf6_interface_state_update(struct interface
*ifp
)
370 struct ospf6_interface
*oi
;
371 unsigned int iobuflen
;
373 oi
= (struct ospf6_interface
*)ifp
->info
;
376 if (oi
->area
== NULL
)
378 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
381 /* Adjust the mtu values if the kernel told us something new */
382 if (ifp
->mtu6
!= oi
->ifmtu
) {
383 /* If nothing configured, accept it and check for buffer size */
385 oi
->ifmtu
= ifp
->mtu6
;
386 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
387 if (oi
->ifmtu
> iobuflen
) {
388 if (IS_OSPF6_DEBUG_INTERFACE
)
390 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
391 ifp
->name
, iobuflen
);
392 oi
->ifmtu
= iobuflen
;
394 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
395 oi
->ifmtu
= ifp
->mtu6
;
397 "Configured mtu %u on %s overridden by kernel %u",
398 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
400 oi
->ifmtu
= oi
->c_ifmtu
;
403 if (if_is_operative(ifp
)
404 && (ospf6_interface_get_linklocal_address(oi
->interface
)
405 || if_is_loopback(oi
->interface
)))
406 thread_add_event(master
, interface_up
, oi
, 0, NULL
);
408 thread_add_event(master
, interface_down
, oi
, 0, NULL
);
413 void ospf6_interface_connected_route_update(struct interface
*ifp
)
415 struct ospf6_interface
*oi
;
416 struct ospf6_route
*route
;
418 struct listnode
*node
, *nnode
;
419 struct in6_addr nh_addr
;
421 oi
= (struct ospf6_interface
*)ifp
->info
;
425 /* reset linklocal pointer */
426 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
428 /* if area is null, do not make connected-route list */
429 if (oi
->area
== NULL
)
432 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
435 /* update "route to advertise" interface route table */
436 ospf6_route_remove_all(oi
->route_connected
);
438 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
439 if (c
->address
->family
!= AF_INET6
)
442 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
444 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
446 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
448 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
450 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
454 if (oi
->plist_name
) {
455 struct prefix_list
*plist
;
456 enum prefix_list_type ret
;
457 char buf
[PREFIX2STR_BUFFER
];
459 prefix2str(c
->address
, buf
, sizeof(buf
));
460 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
461 ret
= prefix_list_apply(plist
, (void *)c
->address
);
462 if (ret
== PREFIX_DENY
) {
463 if (IS_OSPF6_DEBUG_INTERFACE
)
465 "%s on %s filtered by prefix-list %s ",
466 buf
, oi
->interface
->name
,
472 route
= ospf6_route_create();
473 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
474 apply_mask(&route
->prefix
);
475 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
476 route
->path
.area_id
= oi
->area
->area_id
;
477 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
478 route
->path
.cost
= oi
->cost
;
479 inet_pton(AF_INET6
, "::1", &nh_addr
);
480 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
482 ospf6_route_add(route
, oi
->route_connected
);
485 /* create new Link-LSA */
486 OSPF6_LINK_LSA_SCHEDULE(oi
);
487 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
488 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
491 static void ospf6_interface_state_change(u_char next_state
,
492 struct ospf6_interface
*oi
)
496 prev_state
= oi
->state
;
497 oi
->state
= next_state
;
499 if (prev_state
== next_state
)
503 if (IS_OSPF6_DEBUG_INTERFACE
) {
504 zlog_debug("Interface state change %s: %s -> %s",
506 ospf6_interface_state_str
[prev_state
],
507 ospf6_interface_state_str
[next_state
]);
511 if ((prev_state
== OSPF6_INTERFACE_DR
512 || prev_state
== OSPF6_INTERFACE_BDR
)
513 && (next_state
!= OSPF6_INTERFACE_DR
514 && next_state
!= OSPF6_INTERFACE_BDR
))
515 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
518 if ((prev_state
!= OSPF6_INTERFACE_DR
519 && prev_state
!= OSPF6_INTERFACE_BDR
)
520 && (next_state
== OSPF6_INTERFACE_DR
521 || next_state
== OSPF6_INTERFACE_BDR
))
522 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
525 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
526 if (next_state
== OSPF6_INTERFACE_DOWN
) {
527 OSPF6_NETWORK_LSA_EXECUTE(oi
);
528 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
529 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
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
);
541 /* DR Election, RFC2328 section 9.4 */
543 #define IS_ELIGIBLE(n) \
544 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
546 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
547 struct ospf6_neighbor
*b
)
549 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
550 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
552 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
554 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
557 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
559 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
562 if (a
->priority
> b
->priority
)
564 if (a
->priority
< b
->priority
)
567 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
569 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
572 zlog_warn("Router-ID duplicate ?");
576 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
577 struct ospf6_neighbor
*b
)
579 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
580 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
582 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
584 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
587 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
589 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
592 if (a
->priority
> b
->priority
)
594 if (a
->priority
< b
->priority
)
597 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
599 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
602 zlog_warn("Router-ID duplicate ?");
606 static u_char
dr_election(struct ospf6_interface
*oi
)
608 struct listnode
*node
, *nnode
;
609 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
610 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
611 u_char next_state
= 0;
613 drouter
= bdrouter
= NULL
;
614 best_drouter
= best_bdrouter
= NULL
;
616 /* pseudo neighbor myself, including noting current DR/BDR (1) */
617 memset(&myself
, 0, sizeof(myself
));
618 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
619 sizeof(myself
.name
));
620 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
621 myself
.drouter
= oi
->drouter
;
622 myself
.bdrouter
= oi
->bdrouter
;
623 myself
.priority
= oi
->priority
;
624 myself
.router_id
= oi
->area
->ospf6
->router_id
;
626 /* Electing BDR (2) */
627 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
628 bdrouter
= better_bdrouter(bdrouter
, on
);
630 best_bdrouter
= bdrouter
;
631 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
633 /* Electing DR (3) */
634 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
635 drouter
= better_drouter(drouter
, on
);
637 best_drouter
= drouter
;
638 drouter
= better_drouter(best_drouter
, &myself
);
642 /* the router itself is newly/no longer DR/BDR (4) */
643 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
644 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
645 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
646 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
647 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
648 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
650 /* compatible to Electing BDR (2) */
651 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
653 /* compatible to Electing DR (3) */
654 drouter
= better_drouter(best_drouter
, &myself
);
659 /* Set interface state accordingly (5) */
660 if (drouter
&& drouter
== &myself
)
661 next_state
= OSPF6_INTERFACE_DR
;
662 else if (bdrouter
&& bdrouter
== &myself
)
663 next_state
= OSPF6_INTERFACE_BDR
;
665 next_state
= OSPF6_INTERFACE_DROTHER
;
667 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
670 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
671 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
672 accordingly after AdjOK */
673 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
674 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
675 if (IS_OSPF6_DEBUG_INTERFACE
)
676 zlog_debug("DR Election on %s: DR: %s BDR: %s",
678 (drouter
? drouter
->name
: "0.0.0.0"),
679 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
681 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
682 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
684 /* Schedule AdjOK. */
685 thread_add_event(master
, adj_ok
, on
, 0, NULL
);
689 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
690 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
695 /* Interface State Machine */
696 int interface_up(struct thread
*thread
)
698 struct ospf6_interface
*oi
;
700 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
701 assert(oi
&& oi
->interface
);
703 if (IS_OSPF6_DEBUG_INTERFACE
)
704 zlog_debug("Interface Event %s: [InterfaceUp]",
705 oi
->interface
->name
);
707 /* check physical interface is up */
708 if (!if_is_operative(oi
->interface
)) {
709 if (IS_OSPF6_DEBUG_INTERFACE
)
711 "Interface %s is down, can't execute [InterfaceUp]",
712 oi
->interface
->name
);
716 /* check interface has a link-local address */
717 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
718 || if_is_loopback(oi
->interface
))) {
719 if (IS_OSPF6_DEBUG_INTERFACE
)
721 "Interface %s has no link local address, can't execute [InterfaceUp]",
722 oi
->interface
->name
);
727 ospf6_interface_recalculate_cost(oi
);
729 /* if already enabled, do nothing */
730 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
731 if (IS_OSPF6_DEBUG_INTERFACE
)
732 zlog_debug("Interface %s already enabled",
733 oi
->interface
->name
);
737 /* If no area assigned, return */
738 if (oi
->area
== NULL
) {
740 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
741 __func__
, oi
->interface
->name
);
745 /* Join AllSPFRouters */
746 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
)
748 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
750 "Scheduling %s for sso retry, trial count: %d",
751 oi
->interface
->name
, oi
->sso_try_cnt
);
752 thread_add_timer(master
, interface_up
, oi
,
753 OSPF6_INTERFACE_SSO_RETRY_INT
, NULL
);
757 oi
->sso_try_cnt
= 0; /* Reset on success */
759 /* Update interface route */
760 ospf6_interface_connected_route_update(oi
->interface
);
763 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
764 && !if_is_loopback(oi
->interface
)) {
765 oi
->thread_send_hello
= NULL
;
766 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
767 &oi
->thread_send_hello
);
770 /* decide next interface state */
771 if ((if_is_pointopoint(oi
->interface
))
772 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
773 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
774 } else if (oi
->priority
== 0)
775 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
777 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
778 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
785 int wait_timer(struct thread
*thread
)
787 struct ospf6_interface
*oi
;
789 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
790 assert(oi
&& oi
->interface
);
792 if (IS_OSPF6_DEBUG_INTERFACE
)
793 zlog_debug("Interface Event %s: [WaitTimer]",
794 oi
->interface
->name
);
796 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
797 ospf6_interface_state_change(dr_election(oi
), oi
);
802 int backup_seen(struct thread
*thread
)
804 struct ospf6_interface
*oi
;
806 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
807 assert(oi
&& oi
->interface
);
809 if (IS_OSPF6_DEBUG_INTERFACE
)
810 zlog_debug("Interface Event %s: [BackupSeen]",
811 oi
->interface
->name
);
813 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
814 ospf6_interface_state_change(dr_election(oi
), oi
);
819 int neighbor_change(struct thread
*thread
)
821 struct ospf6_interface
*oi
;
823 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
824 assert(oi
&& oi
->interface
);
826 if (IS_OSPF6_DEBUG_INTERFACE
)
827 zlog_debug("Interface Event %s: [NeighborChange]",
828 oi
->interface
->name
);
830 if (oi
->state
== OSPF6_INTERFACE_DROTHER
831 || oi
->state
== OSPF6_INTERFACE_BDR
832 || oi
->state
== OSPF6_INTERFACE_DR
)
833 ospf6_interface_state_change(dr_election(oi
), oi
);
838 int interface_down(struct thread
*thread
)
840 struct ospf6_interface
*oi
;
841 struct listnode
*node
, *nnode
;
842 struct ospf6_neighbor
*on
;
844 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
845 assert(oi
&& oi
->interface
);
847 if (IS_OSPF6_DEBUG_INTERFACE
)
848 zlog_debug("Interface Event %s: [InterfaceDown]",
849 oi
->interface
->name
);
852 THREAD_OFF(oi
->thread_send_hello
);
854 /* Leave AllSPFRouters */
855 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
856 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
859 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
861 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
862 ospf6_neighbor_delete(on
);
864 list_delete_all_node(oi
->neighbor_list
);
866 /* When interface state is reset, also reset information about
867 * DR election, as it is no longer valid. */
868 oi
->drouter
= oi
->prev_drouter
= htonl(0);
869 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
874 /* show specified interface structure */
875 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
)
877 struct ospf6_interface
*oi
;
881 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
882 const char *updown
[3] = {"down", "up", NULL
};
884 struct timeval res
, now
;
886 struct ospf6_lsa
*lsa
;
888 /* check physical interface type */
889 if (if_is_loopback(ifp
))
891 else if (if_is_broadcast(ifp
))
893 else if (if_is_pointopoint(ifp
))
894 type
= "POINTOPOINT";
898 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
899 updown
[if_is_operative(ifp
)], type
);
900 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
902 if (ifp
->info
== NULL
) {
903 vty_out(vty
, " OSPF not enabled on this interface\n");
906 oi
= (struct ospf6_interface
*)ifp
->info
;
908 vty_out(vty
, " Internet Address:\n");
910 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
912 prefix2str(p
, strbuf
, sizeof(strbuf
));
915 vty_out(vty
, " inet : %s\n", strbuf
);
918 vty_out(vty
, " inet6: %s\n", strbuf
);
921 vty_out(vty
, " ??? : %s\n", strbuf
);
928 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
929 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
930 vty_out(vty
, " MTU mismatch detection: %s\n",
931 oi
->mtu_ignore
? "disabled" : "enabled");
932 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
, sizeof(strbuf
));
933 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
, oi
->cost
);
935 vty_out(vty
, " Not Attached to Area\n");
937 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
938 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
940 vty_out(vty
, " Timer intervals configured:\n");
941 vty_out(vty
, " Hello %d, Dead %d, Retransmit %d\n",
942 oi
->hello_interval
, oi
->dead_interval
, oi
->rxmt_interval
);
944 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
945 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
946 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
948 vty_out(vty
, " Number of I/F scoped LSAs is %u\n", oi
->lsdb
->count
);
953 if (oi
->thread_send_lsupdate
)
954 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
, &res
);
955 timerstring(&res
, duration
, sizeof(duration
));
957 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
958 oi
->lsupdate_list
->count
, duration
,
959 (oi
->thread_send_lsupdate
? "on" : "off"));
960 for (ALL_LSDB(oi
->lsupdate_list
, lsa
))
961 vty_out(vty
, " %s\n", lsa
->name
);
964 if (oi
->thread_send_lsack
)
965 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
966 timerstring(&res
, duration
, sizeof(duration
));
967 vty_out(vty
, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
968 oi
->lsack_list
->count
, duration
,
969 (oi
->thread_send_lsack
? "on" : "off"));
970 for (ALL_LSDB(oi
->lsack_list
, lsa
))
971 vty_out(vty
, " %s\n", lsa
->name
);
972 ospf6_bfd_show_info(vty
, oi
->bfd_info
, 1);
977 DEFUN (show_ipv6_ospf6_interface
,
978 show_ipv6_ospf6_interface_ifname_cmd
,
979 "show ipv6 ospf6 interface [IFNAME]",
986 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
988 struct interface
*ifp
;
991 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
993 vty_out(vty
, "No such Interface: %s\n",
994 argv
[idx_ifname
]->arg
);
997 ospf6_interface_show(vty
, ifp
);
999 FOR_ALL_INTERFACES (vrf
, ifp
)
1000 ospf6_interface_show(vty
, ifp
);
1006 DEFUN (show_ipv6_ospf6_interface_ifname_prefix
,
1007 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1008 "show ipv6 ospf6 interface IFNAME prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
1014 "Display connected prefixes to advertise\n"
1015 OSPF6_ROUTE_ADDRESS_STR
1016 OSPF6_ROUTE_PREFIX_STR
1017 OSPF6_ROUTE_MATCH_STR
1018 "Display details of the prefixes\n")
1022 struct interface
*ifp
;
1023 struct ospf6_interface
*oi
;
1025 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
1027 vty_out(vty
, "No such Interface: %s\n", argv
[idx_ifname
]->arg
);
1033 vty_out(vty
, "OSPFv3 is not enabled on %s\n",
1034 argv
[idx_ifname
]->arg
);
1038 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1039 oi
->route_connected
);
1044 DEFUN (show_ipv6_ospf6_interface_prefix
,
1045 show_ipv6_ospf6_interface_prefix_cmd
,
1046 "show ipv6 ospf6 interface prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
1051 "Display connected prefixes to advertise\n"
1052 OSPF6_ROUTE_ADDRESS_STR
1053 OSPF6_ROUTE_PREFIX_STR
1054 OSPF6_ROUTE_MATCH_STR
1055 "Display details of the prefixes\n")
1057 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1059 struct ospf6_interface
*oi
;
1060 struct interface
*ifp
;
1062 FOR_ALL_INTERFACES (vrf
, ifp
) {
1063 oi
= (struct ospf6_interface
*)ifp
->info
;
1067 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1068 oi
->route_connected
);
1074 /* interface variable set command */
1075 DEFUN (ipv6_ospf6_ifmtu
,
1076 ipv6_ospf6_ifmtu_cmd
,
1077 "ipv6 ospf6 ifmtu (1-65535)",
1081 "OSPFv3 Interface MTU\n"
1084 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1086 struct ospf6_interface
*oi
;
1087 unsigned int ifmtu
, iobuflen
;
1088 struct listnode
*node
, *nnode
;
1089 struct ospf6_neighbor
*on
;
1093 oi
= (struct ospf6_interface
*)ifp
->info
;
1095 oi
= ospf6_interface_create(ifp
);
1098 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1100 if (oi
->c_ifmtu
== ifmtu
)
1103 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1105 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1106 ifp
->name
, ifp
->mtu6
);
1107 return CMD_WARNING_CONFIG_FAILED
;
1110 if (oi
->ifmtu
< ifmtu
) {
1111 iobuflen
= ospf6_iobuf_size(ifmtu
);
1112 if (iobuflen
< ifmtu
) {
1114 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1115 ifp
->name
, iobuflen
);
1116 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1118 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1120 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1122 /* re-establish adjacencies */
1123 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1124 THREAD_OFF(on
->inactivity_timer
);
1125 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1131 DEFUN (no_ipv6_ospf6_ifmtu
,
1132 no_ipv6_ospf6_ifmtu_cmd
,
1133 "no ipv6 ospf6 ifmtu [(1-65535)]",
1138 "OSPFv3 Interface MTU\n"
1141 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1142 struct ospf6_interface
*oi
;
1143 unsigned int iobuflen
;
1144 struct listnode
*node
, *nnode
;
1145 struct ospf6_neighbor
*on
;
1149 oi
= (struct ospf6_interface
*)ifp
->info
;
1151 oi
= ospf6_interface_create(ifp
);
1154 if (oi
->ifmtu
< ifp
->mtu
) {
1155 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1156 if (iobuflen
< ifp
->mtu
) {
1158 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1159 ifp
->name
, iobuflen
);
1160 oi
->ifmtu
= iobuflen
;
1162 oi
->ifmtu
= ifp
->mtu
;
1164 oi
->ifmtu
= ifp
->mtu
;
1168 /* re-establish adjacencies */
1169 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1170 THREAD_OFF(on
->inactivity_timer
);
1171 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1177 DEFUN (ipv6_ospf6_cost
,
1178 ipv6_ospf6_cost_cmd
,
1179 "ipv6 ospf6 cost (1-65535)",
1183 "Outgoing metric of this interface\n")
1185 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1187 struct ospf6_interface
*oi
;
1188 unsigned long int lcost
;
1192 oi
= (struct ospf6_interface
*)ifp
->info
;
1194 oi
= ospf6_interface_create(ifp
);
1197 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1199 if (lcost
> UINT32_MAX
) {
1200 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1201 return CMD_WARNING_CONFIG_FAILED
;
1204 if (oi
->cost
== lcost
)
1208 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1210 ospf6_interface_recalculate_cost(oi
);
1215 DEFUN (no_ipv6_ospf6_cost
,
1216 no_ipv6_ospf6_cost_cmd
,
1217 "no ipv6 ospf6 cost [(1-65535)]",
1221 "Calculate interface cost from bandwidth\n"
1222 "Outgoing metric of this interface\n")
1224 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1225 struct ospf6_interface
*oi
;
1228 oi
= (struct ospf6_interface
*)ifp
->info
;
1230 oi
= ospf6_interface_create(ifp
);
1233 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1235 ospf6_interface_recalculate_cost(oi
);
1240 DEFUN (auto_cost_reference_bandwidth
,
1241 auto_cost_reference_bandwidth_cmd
,
1242 "auto-cost reference-bandwidth (1-4294967)",
1243 "Calculate OSPF interface cost according to bandwidth\n"
1244 "Use reference bandwidth method to assign OSPF cost\n"
1245 "The reference bandwidth in terms of Mbits per second\n")
1247 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1249 struct ospf6_area
*oa
;
1250 struct ospf6_interface
*oi
;
1251 struct listnode
*i
, *j
;
1254 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1255 if (refbw
< 1 || refbw
> 4294967) {
1256 vty_out(vty
, "reference-bandwidth value is invalid\n");
1257 return CMD_WARNING_CONFIG_FAILED
;
1260 /* If reference bandwidth is changed. */
1261 if ((refbw
) == o
->ref_bandwidth
)
1264 o
->ref_bandwidth
= refbw
;
1265 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1266 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1267 ospf6_interface_recalculate_cost(oi
);
1272 DEFUN (no_auto_cost_reference_bandwidth
,
1273 no_auto_cost_reference_bandwidth_cmd
,
1274 "no auto-cost reference-bandwidth [(1-4294967)]",
1276 "Calculate OSPF interface cost according to bandwidth\n"
1277 "Use reference bandwidth method to assign OSPF cost\n"
1278 "The reference bandwidth in terms of Mbits per second\n")
1280 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1281 struct ospf6_area
*oa
;
1282 struct ospf6_interface
*oi
;
1283 struct listnode
*i
, *j
;
1285 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
1288 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
1289 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1290 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1291 ospf6_interface_recalculate_cost(oi
);
1297 DEFUN (ipv6_ospf6_hellointerval
,
1298 ipv6_ospf6_hellointerval_cmd
,
1299 "ipv6 ospf6 hello-interval (1-65535)",
1302 "Time between HELLO packets\n"
1305 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1307 struct ospf6_interface
*oi
;
1310 oi
= (struct ospf6_interface
*)ifp
->info
;
1312 oi
= ospf6_interface_create(ifp
);
1315 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
1316 ? OSPF_HELLO_INTERVAL_DEFAULT
1317 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1321 ALIAS (ipv6_ospf6_hellointerval
,
1322 no_ipv6_ospf6_hellointerval_cmd
,
1323 "no ipv6 ospf6 hello-interval [(1-65535)]",
1327 "Time between HELLO packets\n"
1330 /* interface variable set command */
1331 DEFUN (ipv6_ospf6_deadinterval
,
1332 ipv6_ospf6_deadinterval_cmd
,
1333 "ipv6 ospf6 dead-interval (1-65535)",
1336 "Interval time after which a neighbor is declared down\n"
1339 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1341 struct ospf6_interface
*oi
;
1344 oi
= (struct ospf6_interface
*)ifp
->info
;
1346 oi
= ospf6_interface_create(ifp
);
1349 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
1350 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1351 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1355 ALIAS (ipv6_ospf6_deadinterval
,
1356 no_ipv6_ospf6_deadinterval_cmd
,
1357 "no ipv6 ospf6 dead-interval [(1-65535)]",
1361 "Interval time after which a neighbor is declared down\n"
1364 /* interface variable set command */
1365 DEFUN (ipv6_ospf6_transmitdelay
,
1366 ipv6_ospf6_transmitdelay_cmd
,
1367 "ipv6 ospf6 transmit-delay (1-3600)",
1370 "Link state transmit delay\n"
1373 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1375 struct ospf6_interface
*oi
;
1378 oi
= (struct ospf6_interface
*)ifp
->info
;
1380 oi
= ospf6_interface_create(ifp
);
1383 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
1384 ? OSPF6_INTERFACE_TRANSDELAY
1385 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1389 ALIAS (ipv6_ospf6_transmitdelay
,
1390 no_ipv6_ospf6_transmitdelay_cmd
,
1391 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1395 "Link state transmit delay\n"
1398 /* interface variable set command */
1399 DEFUN (ipv6_ospf6_retransmitinterval
,
1400 ipv6_ospf6_retransmitinterval_cmd
,
1401 "ipv6 ospf6 retransmit-interval (1-65535)",
1404 "Time between retransmitting lost link state advertisements\n"
1407 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1409 struct ospf6_interface
*oi
;
1412 oi
= (struct ospf6_interface
*)ifp
->info
;
1414 oi
= ospf6_interface_create(ifp
);
1417 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
1418 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1419 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1423 ALIAS (ipv6_ospf6_retransmitinterval
,
1424 no_ipv6_ospf6_retransmitinterval_cmd
,
1425 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1429 "Time between retransmitting lost link state advertisements\n"
1432 /* interface variable set command */
1433 DEFUN (ipv6_ospf6_priority
,
1434 ipv6_ospf6_priority_cmd
,
1435 "ipv6 ospf6 priority (0-255)",
1441 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1443 struct ospf6_interface
*oi
;
1446 oi
= (struct ospf6_interface
*)ifp
->info
;
1448 oi
= ospf6_interface_create(ifp
);
1451 oi
->priority
= strmatch(argv
[0]->text
, "no")
1452 ? OSPF6_INTERFACE_PRIORITY
1453 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1455 if (oi
->area
&& (oi
->state
== OSPF6_INTERFACE_DROTHER
1456 || oi
->state
== OSPF6_INTERFACE_BDR
1457 || oi
->state
== OSPF6_INTERFACE_DR
))
1458 ospf6_interface_state_change(dr_election(oi
), oi
);
1463 ALIAS (ipv6_ospf6_priority
,
1464 no_ipv6_ospf6_priority_cmd
,
1465 "no ipv6 ospf6 priority [(0-255)]",
1472 DEFUN (ipv6_ospf6_instance
,
1473 ipv6_ospf6_instance_cmd
,
1474 "ipv6 ospf6 instance-id (0-255)",
1477 "Instance ID for this interface\n"
1478 "Instance ID value\n")
1480 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1482 struct ospf6_interface
*oi
;
1485 oi
= (struct ospf6_interface
*)ifp
->info
;
1487 oi
= ospf6_interface_create(ifp
);
1490 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
1491 ? OSPF6_INTERFACE_INSTANCE_ID
1492 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1496 ALIAS (ipv6_ospf6_instance
,
1497 no_ipv6_ospf6_instance_cmd
,
1498 "no ipv6 ospf6 instance-id [(0-255)]",
1502 "Instance ID for this interface\n"
1503 "Instance ID value\n")
1505 DEFUN (ipv6_ospf6_passive
,
1506 ipv6_ospf6_passive_cmd
,
1507 "ipv6 ospf6 passive",
1510 "Passive interface; no adjacency will be formed on this interface\n"
1513 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1514 struct ospf6_interface
*oi
;
1515 struct listnode
*node
, *nnode
;
1516 struct ospf6_neighbor
*on
;
1520 oi
= (struct ospf6_interface
*)ifp
->info
;
1522 oi
= ospf6_interface_create(ifp
);
1525 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1526 THREAD_OFF(oi
->thread_send_hello
);
1528 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1529 THREAD_OFF(on
->inactivity_timer
);
1530 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1536 DEFUN (no_ipv6_ospf6_passive
,
1537 no_ipv6_ospf6_passive_cmd
,
1538 "no ipv6 ospf6 passive",
1542 "passive interface: No Adjacency will be formed on this I/F\n"
1545 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1546 struct ospf6_interface
*oi
;
1549 oi
= (struct ospf6_interface
*)ifp
->info
;
1551 oi
= ospf6_interface_create(ifp
);
1554 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1555 THREAD_OFF(oi
->thread_send_hello
);
1556 oi
->thread_send_hello
= NULL
;
1557 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
1558 &oi
->thread_send_hello
);
1563 DEFUN (ipv6_ospf6_mtu_ignore
,
1564 ipv6_ospf6_mtu_ignore_cmd
,
1565 "ipv6 ospf6 mtu-ignore",
1568 "Disable MTU mismatch detection on this interface\n"
1571 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1572 struct ospf6_interface
*oi
;
1575 oi
= (struct ospf6_interface
*)ifp
->info
;
1577 oi
= ospf6_interface_create(ifp
);
1585 DEFUN (no_ipv6_ospf6_mtu_ignore
,
1586 no_ipv6_ospf6_mtu_ignore_cmd
,
1587 "no ipv6 ospf6 mtu-ignore",
1591 "Disable MTU mismatch detection on this interface\n"
1594 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1595 struct ospf6_interface
*oi
;
1598 oi
= (struct ospf6_interface
*)ifp
->info
;
1600 oi
= ospf6_interface_create(ifp
);
1608 DEFUN (ipv6_ospf6_advertise_prefix_list
,
1609 ipv6_ospf6_advertise_prefix_list_cmd
,
1610 "ipv6 ospf6 advertise prefix-list WORD",
1613 "Advertising options\n"
1614 "Filter prefix using prefix-list\n"
1615 "Prefix list name\n"
1618 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1620 struct ospf6_interface
*oi
;
1623 oi
= (struct ospf6_interface
*)ifp
->info
;
1625 oi
= ospf6_interface_create(ifp
);
1629 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
1630 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
1632 ospf6_interface_connected_route_update(oi
->interface
);
1635 OSPF6_LINK_LSA_SCHEDULE(oi
);
1636 if (oi
->state
== OSPF6_INTERFACE_DR
) {
1637 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
1638 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
1640 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
1646 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
1647 no_ipv6_ospf6_advertise_prefix_list_cmd
,
1648 "no ipv6 ospf6 advertise prefix-list [WORD]",
1652 "Advertising options\n"
1653 "Filter prefix using prefix-list\n"
1654 "Prefix list name\n")
1656 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1657 struct ospf6_interface
*oi
;
1660 oi
= (struct ospf6_interface
*)ifp
->info
;
1662 oi
= ospf6_interface_create(ifp
);
1666 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
1668 ospf6_interface_connected_route_update(oi
->interface
);
1671 OSPF6_LINK_LSA_SCHEDULE(oi
);
1672 if (oi
->state
== OSPF6_INTERFACE_DR
) {
1673 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
1674 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
1676 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
1682 DEFUN (ipv6_ospf6_network
,
1683 ipv6_ospf6_network_cmd
,
1684 "ipv6 ospf6 network <broadcast|point-to-point>",
1688 "Specify OSPF6 broadcast network\n"
1689 "Specify OSPF6 point-to-point network\n"
1692 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1693 int idx_network
= 3;
1694 struct ospf6_interface
*oi
;
1697 oi
= (struct ospf6_interface
*)ifp
->info
;
1699 oi
= ospf6_interface_create(ifp
);
1703 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
1704 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1707 oi
->type
= OSPF_IFTYPE_BROADCAST
;
1708 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
1709 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
1712 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
1715 /* Reset the interface */
1716 thread_add_event(master
, interface_down
, oi
, 0, NULL
);
1717 thread_add_event(master
, interface_up
, oi
, 0, NULL
);
1722 DEFUN (no_ipv6_ospf6_network
,
1723 no_ipv6_ospf6_network_cmd
,
1724 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
1728 "Set default network type\n"
1729 "Specify OSPF6 broadcast network\n"
1730 "Specify OSPF6 point-to-point network\n")
1732 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1733 struct ospf6_interface
*oi
;
1738 oi
= (struct ospf6_interface
*)ifp
->info
;
1743 type
= ospf6_default_iftype(ifp
);
1744 if (oi
->type
== type
) {
1749 /* Reset the interface */
1750 thread_add_event(master
, interface_down
, oi
, 0, NULL
);
1751 thread_add_event(master
, interface_up
, oi
, 0, NULL
);
1756 static int config_write_ospf6_interface(struct vty
*vty
)
1758 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1759 struct ospf6_interface
*oi
;
1760 struct interface
*ifp
;
1762 FOR_ALL_INTERFACES (vrf
, ifp
) {
1763 oi
= (struct ospf6_interface
*)ifp
->info
;
1767 vty_frame(vty
, "interface %s\n", oi
->interface
->name
);
1770 vty_out(vty
, " description %s\n", ifp
->desc
);
1772 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
1774 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
1775 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
1777 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
1778 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
1779 oi
->hello_interval
);
1781 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
1782 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
1785 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
1786 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
1789 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
1790 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
1792 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
1793 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
1796 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
1797 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
1801 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
1804 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
1805 vty_out(vty
, " ipv6 ospf6 passive\n");
1808 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
1810 if (oi
->type
!= ospf6_default_iftype(ifp
)) {
1811 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
1813 " ipv6 ospf6 network point-to-point\n");
1814 else if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1815 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
1818 ospf6_bfd_write_config(vty
, oi
);
1820 vty_endframe(vty
, "!\n");
1825 static struct cmd_node interface_node
= {
1826 INTERFACE_NODE
, "%s(config-if)# ", 1 /* VTYSH */
1829 void ospf6_interface_init(void)
1831 /* Install interface node. */
1832 install_node(&interface_node
, config_write_ospf6_interface
);
1835 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
1836 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
1837 install_element(VIEW_NODE
,
1838 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
1840 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
1841 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
1842 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
1843 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
1845 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
1846 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
1847 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
1848 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
1849 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
1850 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
1851 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
1852 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
1853 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
1854 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
1855 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
1856 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
1858 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
1859 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
1861 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
1862 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
1864 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
1865 install_element(INTERFACE_NODE
,
1866 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
1868 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
1869 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
1871 /* reference bandwidth commands */
1872 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
1873 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
1876 /* Clear the specified interface structure */
1877 static void ospf6_interface_clear(struct vty
*vty
, struct interface
*ifp
)
1879 struct ospf6_interface
*oi
;
1881 if (!if_is_operative(ifp
))
1884 if (ifp
->info
== NULL
)
1887 oi
= (struct ospf6_interface
*)ifp
->info
;
1889 if (IS_OSPF6_DEBUG_INTERFACE
)
1890 zlog_debug("Interface %s: clear by reset", ifp
->name
);
1892 /* Reset the interface */
1893 thread_add_event(master
, interface_down
, oi
, 0, NULL
);
1894 thread_add_event(master
, interface_up
, oi
, 0, NULL
);
1897 /* Clear interface */
1898 DEFUN (clear_ipv6_ospf6_interface
,
1899 clear_ipv6_ospf6_interface_cmd
,
1900 "clear ipv6 ospf6 interface [IFNAME]",
1908 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1910 struct interface
*ifp
;
1912 if (argc
== 4) /* Clear all the ospfv3 interfaces. */
1914 FOR_ALL_INTERFACES (vrf
, ifp
)
1915 ospf6_interface_clear(vty
, ifp
);
1916 } else /* Interface name is specified. */
1918 if ((ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1921 vty_out(vty
, "No such Interface: %s\n",
1922 argv
[idx_ifname
]->arg
);
1925 ospf6_interface_clear(vty
, ifp
);
1931 void install_element_ospf6_clear_interface(void)
1933 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
1936 DEFUN (debug_ospf6_interface
,
1937 debug_ospf6_interface_cmd
,
1938 "debug ospf6 interface",
1941 "Debug OSPFv3 Interface\n"
1944 OSPF6_DEBUG_INTERFACE_ON();
1948 DEFUN (no_debug_ospf6_interface
,
1949 no_debug_ospf6_interface_cmd
,
1950 "no debug ospf6 interface",
1954 "Debug OSPFv3 Interface\n"
1957 OSPF6_DEBUG_INTERFACE_OFF();
1961 int config_write_ospf6_debug_interface(struct vty
*vty
)
1963 if (IS_OSPF6_DEBUG_INTERFACE
)
1964 vty_out(vty
, "debug ospf6 interface\n");
1968 void install_element_ospf6_debug_interface(void)
1970 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
1971 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
1972 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
1973 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);