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
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
33 #include "ospf6_lsa.h"
34 #include "ospf6_lsdb.h"
35 #include "ospf6_network.h"
36 #include "ospf6_message.h"
37 #include "ospf6_route.h"
38 #include "ospf6_top.h"
39 #include "ospf6_area.h"
40 #include "ospf6_interface.h"
41 #include "ospf6_neighbor.h"
42 #include "ospf6_intra.h"
43 #include "ospf6_spf.h"
45 #include "ospf6_bfd.h"
47 DEFINE_MTYPE_STATIC(OSPF6D
, CFG_PLIST_NAME
, "configured prefix list names")
48 DEFINE_QOBJ_TYPE(ospf6_interface
)
49 DEFINE_HOOK(ospf6_interface_change
,
50 (struct ospf6_interface
* oi
, int state
, int old_state
),
51 (oi
, state
, old_state
))
53 unsigned char conf_debug_ospf6_interface
= 0;
55 const char *ospf6_interface_state_str
[] = {
56 "None", "Down", "Loopback", "Waiting", "PointToPoint",
57 "DROther", "BDR", "DR", NULL
};
59 struct ospf6_interface
*ospf6_interface_lookup_by_ifindex(ifindex_t ifindex
)
61 struct ospf6_interface
*oi
;
62 struct interface
*ifp
;
64 ifp
= if_lookup_by_index(ifindex
, VRF_DEFAULT
);
66 return (struct ospf6_interface
*)NULL
;
68 oi
= (struct ospf6_interface
*)ifp
->info
;
72 /* schedule routing table recalculation */
73 static void ospf6_interface_lsdb_hook(struct ospf6_lsa
*lsa
,
76 struct ospf6_interface
*oi
;
82 switch (ntohs(lsa
->header
->type
)) {
83 case OSPF6_LSTYPE_LINK
:
84 if (oi
->state
== OSPF6_INTERFACE_DR
)
85 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
87 ospf6_spf_schedule(oi
->area
->ospf6
, reason
);
95 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa
*lsa
)
97 ospf6_interface_lsdb_hook(lsa
, ospf6_lsadd_to_spf_reason(lsa
));
100 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
102 ospf6_interface_lsdb_hook(lsa
, ospf6_lsremove_to_spf_reason(lsa
));
105 static u_char
ospf6_default_iftype(struct interface
*ifp
)
107 if (if_is_pointopoint(ifp
))
108 return OSPF_IFTYPE_POINTOPOINT
;
109 else if (if_is_loopback(ifp
))
110 return OSPF_IFTYPE_LOOPBACK
;
112 return OSPF_IFTYPE_BROADCAST
;
115 static u_int32_t
ospf6_interface_get_cost(struct ospf6_interface
*oi
)
117 /* If all else fails, use default OSPF cost */
121 bw
= oi
->interface
->bandwidth
? oi
->interface
->bandwidth
122 : OSPF6_INTERFACE_BANDWIDTH
;
123 refbw
= ospf6
? ospf6
->ref_bandwidth
: OSPF6_REFERENCE_BANDWIDTH
;
125 /* A specifed ip ospf cost overrides a calculated one. */
126 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
129 cost
= (u_int32_t
)((double)refbw
/ (double)bw
+ (double)0.5);
132 else if (cost
> UINT32_MAX
)
139 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
143 newcost
= ospf6_interface_get_cost(oi
);
144 if (newcost
== oi
->cost
)
148 /* update cost held in route_connected list in ospf6_interface */
149 ospf6_interface_connected_route_update(oi
->interface
);
151 /* execute LSA hooks */
153 OSPF6_LINK_LSA_SCHEDULE(oi
);
154 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
155 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
156 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
157 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
161 /* Create new ospf6 interface structure */
162 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
164 struct ospf6_interface
*oi
;
165 unsigned int iobuflen
;
167 oi
= (struct ospf6_interface
*)XCALLOC(MTYPE_OSPF6_IF
,
168 sizeof(struct ospf6_interface
));
171 zlog_err("Can't malloc ospf6_interface for ifindex %d",
173 return (struct ospf6_interface
*)NULL
;
176 oi
->area
= (struct ospf6_area
*)NULL
;
177 oi
->neighbor_list
= list_new();
178 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
179 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
180 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
181 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
182 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
184 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
185 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
186 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
187 oi
->type
= ospf6_default_iftype(ifp
);
188 oi
->state
= OSPF6_INTERFACE_DOWN
;
192 /* Try to adjust I/O buffer size with IfMtu */
193 oi
->ifmtu
= ifp
->mtu6
;
194 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
195 if (oi
->ifmtu
> iobuflen
) {
196 if (IS_OSPF6_DEBUG_INTERFACE
)
198 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
199 ifp
->name
, iobuflen
);
200 oi
->ifmtu
= iobuflen
;
203 QOBJ_REG(oi
, ospf6_interface
);
205 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
206 oi
->lsack_list
= ospf6_lsdb_create(oi
);
207 oi
->lsdb
= ospf6_lsdb_create(oi
);
208 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
209 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
210 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
212 oi
->route_connected
=
213 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
214 oi
->route_connected
->scope
= oi
;
221 oi
->cost
= ospf6_interface_get_cost(oi
);
226 void ospf6_interface_delete(struct ospf6_interface
*oi
)
228 struct listnode
*node
, *nnode
;
229 struct ospf6_neighbor
*on
;
233 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
234 ospf6_neighbor_delete(on
);
236 list_delete(oi
->neighbor_list
);
238 THREAD_OFF(oi
->thread_send_hello
);
239 THREAD_OFF(oi
->thread_send_lsupdate
);
240 THREAD_OFF(oi
->thread_send_lsack
);
242 ospf6_lsdb_remove_all(oi
->lsdb
);
243 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
244 ospf6_lsdb_remove_all(oi
->lsack_list
);
246 ospf6_lsdb_delete(oi
->lsdb
);
247 ospf6_lsdb_delete(oi
->lsdb_self
);
249 ospf6_lsdb_delete(oi
->lsupdate_list
);
250 ospf6_lsdb_delete(oi
->lsack_list
);
252 ospf6_route_table_delete(oi
->route_connected
);
255 oi
->interface
->info
= NULL
;
259 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
261 ospf6_bfd_info_free(&(oi
->bfd_info
));
263 XFREE(MTYPE_OSPF6_IF
, oi
);
266 void ospf6_interface_enable(struct ospf6_interface
*oi
)
268 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
269 ospf6_interface_state_update(oi
->interface
);
272 void ospf6_interface_disable(struct ospf6_interface
*oi
)
274 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
276 thread_execute(master
, interface_down
, oi
, 0);
278 ospf6_lsdb_remove_all(oi
->lsdb
);
279 ospf6_lsdb_remove_all(oi
->lsdb_self
);
280 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
281 ospf6_lsdb_remove_all(oi
->lsack_list
);
283 THREAD_OFF(oi
->thread_send_hello
);
284 THREAD_OFF(oi
->thread_send_lsupdate
);
285 THREAD_OFF(oi
->thread_send_lsack
);
287 THREAD_OFF(oi
->thread_network_lsa
);
288 THREAD_OFF(oi
->thread_link_lsa
);
289 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
292 static struct in6_addr
*
293 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
297 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
299 /* for each connected address */
300 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
301 /* if family not AF_INET6, ignore */
302 if (c
->address
->family
!= AF_INET6
)
305 /* linklocal scope check */
306 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
307 l
= &c
->address
->u
.prefix6
;
312 void ospf6_interface_if_add(struct interface
*ifp
)
314 struct ospf6_interface
*oi
;
315 unsigned int iobuflen
;
317 oi
= (struct ospf6_interface
*)ifp
->info
;
321 /* Try to adjust I/O buffer size with IfMtu */
323 oi
->ifmtu
= ifp
->mtu6
;
324 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
325 if (oi
->ifmtu
> iobuflen
) {
326 if (IS_OSPF6_DEBUG_INTERFACE
)
328 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
329 ifp
->name
, iobuflen
);
330 oi
->ifmtu
= iobuflen
;
333 /* interface start */
334 ospf6_interface_state_update(oi
->interface
);
337 void ospf6_interface_if_del(struct interface
*ifp
)
339 struct ospf6_interface
*oi
;
341 oi
= (struct ospf6_interface
*)ifp
->info
;
347 thread_execute(master
, interface_down
, oi
, 0);
349 listnode_delete(oi
->area
->if_list
, oi
);
350 oi
->area
= (struct ospf6_area
*)NULL
;
353 oi
->interface
= NULL
;
356 ospf6_interface_delete(oi
);
359 void ospf6_interface_state_update(struct interface
*ifp
)
361 struct ospf6_interface
*oi
;
363 oi
= (struct ospf6_interface
*)ifp
->info
;
366 if (oi
->area
== NULL
)
368 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
371 if (if_is_operative(ifp
)
372 && (ospf6_interface_get_linklocal_address(oi
->interface
)
373 || if_is_loopback(oi
->interface
)))
374 thread_add_event(master
, interface_up
, oi
, 0);
376 thread_add_event(master
, interface_down
, oi
, 0);
381 void ospf6_interface_connected_route_update(struct interface
*ifp
)
383 struct ospf6_interface
*oi
;
384 struct ospf6_route
*route
;
386 struct listnode
*node
, *nnode
;
387 struct in6_addr nh_addr
;
389 oi
= (struct ospf6_interface
*)ifp
->info
;
393 /* reset linklocal pointer */
394 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
396 /* if area is null, do not make connected-route list */
397 if (oi
->area
== NULL
)
400 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
403 /* update "route to advertise" interface route table */
404 ospf6_route_remove_all(oi
->route_connected
);
406 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
407 if (c
->address
->family
!= AF_INET6
)
410 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
412 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
414 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
416 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
418 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
422 if (oi
->plist_name
) {
423 struct prefix_list
*plist
;
424 enum prefix_list_type ret
;
425 char buf
[PREFIX2STR_BUFFER
];
427 prefix2str(c
->address
, buf
, sizeof(buf
));
428 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
429 ret
= prefix_list_apply(plist
, (void *)c
->address
);
430 if (ret
== PREFIX_DENY
) {
431 if (IS_OSPF6_DEBUG_INTERFACE
)
433 "%s on %s filtered by prefix-list %s ",
434 buf
, oi
->interface
->name
,
440 route
= ospf6_route_create();
441 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
442 apply_mask(&route
->prefix
);
443 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
444 route
->path
.area_id
= oi
->area
->area_id
;
445 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
446 route
->path
.cost
= oi
->cost
;
447 inet_pton(AF_INET6
, "::1", &nh_addr
);
448 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
450 ospf6_route_add(route
, oi
->route_connected
);
453 /* create new Link-LSA */
454 OSPF6_LINK_LSA_SCHEDULE(oi
);
455 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
456 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
459 static void ospf6_interface_state_change(u_char next_state
,
460 struct ospf6_interface
*oi
)
464 prev_state
= oi
->state
;
465 oi
->state
= next_state
;
467 if (prev_state
== next_state
)
471 if (IS_OSPF6_DEBUG_INTERFACE
) {
472 zlog_debug("Interface state change %s: %s -> %s",
474 ospf6_interface_state_str
[prev_state
],
475 ospf6_interface_state_str
[next_state
]);
479 if ((prev_state
== OSPF6_INTERFACE_DR
480 || prev_state
== OSPF6_INTERFACE_BDR
)
481 && (next_state
!= OSPF6_INTERFACE_DR
482 && next_state
!= OSPF6_INTERFACE_BDR
))
483 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
486 if ((prev_state
!= OSPF6_INTERFACE_DR
487 && prev_state
!= OSPF6_INTERFACE_BDR
)
488 && (next_state
== OSPF6_INTERFACE_DR
489 || next_state
== OSPF6_INTERFACE_BDR
))
490 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
493 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
494 if (next_state
== OSPF6_INTERFACE_DOWN
) {
495 OSPF6_NETWORK_LSA_EXECUTE(oi
);
496 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
497 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
498 } else if (prev_state
== OSPF6_INTERFACE_DR
499 || next_state
== OSPF6_INTERFACE_DR
) {
500 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
501 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
502 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
505 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
509 /* DR Election, RFC2328 section 9.4 */
511 #define IS_ELIGIBLE(n) \
512 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
514 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
515 struct ospf6_neighbor
*b
)
517 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
518 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
520 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
522 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
525 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
527 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
530 if (a
->priority
> b
->priority
)
532 if (a
->priority
< b
->priority
)
535 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
537 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
540 zlog_warn("Router-ID duplicate ?");
544 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
545 struct ospf6_neighbor
*b
)
547 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
548 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
550 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
552 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
555 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
557 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
560 if (a
->priority
> b
->priority
)
562 if (a
->priority
< b
->priority
)
565 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
567 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
570 zlog_warn("Router-ID duplicate ?");
574 static u_char
dr_election(struct ospf6_interface
*oi
)
576 struct listnode
*node
, *nnode
;
577 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
578 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
579 u_char next_state
= 0;
581 drouter
= bdrouter
= NULL
;
582 best_drouter
= best_bdrouter
= NULL
;
584 /* pseudo neighbor myself, including noting current DR/BDR (1) */
585 memset(&myself
, 0, sizeof(myself
));
586 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
587 sizeof(myself
.name
));
588 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
589 myself
.drouter
= oi
->drouter
;
590 myself
.bdrouter
= oi
->bdrouter
;
591 myself
.priority
= oi
->priority
;
592 myself
.router_id
= oi
->area
->ospf6
->router_id
;
594 /* Electing BDR (2) */
595 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
596 bdrouter
= better_bdrouter(bdrouter
, on
);
598 best_bdrouter
= bdrouter
;
599 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
601 /* Electing DR (3) */
602 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
603 drouter
= better_drouter(drouter
, on
);
605 best_drouter
= drouter
;
606 drouter
= better_drouter(best_drouter
, &myself
);
610 /* the router itself is newly/no longer DR/BDR (4) */
611 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
612 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
613 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
614 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
615 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
616 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
618 /* compatible to Electing BDR (2) */
619 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
621 /* compatible to Electing DR (3) */
622 drouter
= better_drouter(best_drouter
, &myself
);
627 /* Set interface state accordingly (5) */
628 if (drouter
&& drouter
== &myself
)
629 next_state
= OSPF6_INTERFACE_DR
;
630 else if (bdrouter
&& bdrouter
== &myself
)
631 next_state
= OSPF6_INTERFACE_BDR
;
633 next_state
= OSPF6_INTERFACE_DROTHER
;
635 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
638 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
639 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
640 accordingly after AdjOK */
641 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
642 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
643 if (IS_OSPF6_DEBUG_INTERFACE
)
644 zlog_debug("DR Election on %s: DR: %s BDR: %s",
646 (drouter
? drouter
->name
: "0.0.0.0"),
647 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
649 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
650 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
652 /* Schedule AdjOK. */
653 thread_add_event(master
, adj_ok
, on
, 0);
657 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
658 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
663 /* Interface State Machine */
664 int interface_up(struct thread
*thread
)
666 struct ospf6_interface
*oi
;
668 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
669 assert(oi
&& oi
->interface
);
671 if (IS_OSPF6_DEBUG_INTERFACE
)
672 zlog_debug("Interface Event %s: [InterfaceUp]",
673 oi
->interface
->name
);
675 /* check physical interface is up */
676 if (!if_is_operative(oi
->interface
)) {
677 if (IS_OSPF6_DEBUG_INTERFACE
)
679 "Interface %s is down, can't execute [InterfaceUp]",
680 oi
->interface
->name
);
684 /* check interface has a link-local address */
685 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
686 || if_is_loopback(oi
->interface
))) {
687 if (IS_OSPF6_DEBUG_INTERFACE
)
689 "Interface %s has no link local address, can't execute [InterfaceUp]",
690 oi
->interface
->name
);
695 ospf6_interface_recalculate_cost(oi
);
697 /* if already enabled, do nothing */
698 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
699 if (IS_OSPF6_DEBUG_INTERFACE
)
700 zlog_debug("Interface %s already enabled",
701 oi
->interface
->name
);
705 /* If no area assigned, return */
706 if (oi
->area
== NULL
) {
708 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
709 __func__
, oi
->interface
->name
);
713 /* Join AllSPFRouters */
714 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
)
716 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
718 "Scheduling %s for sso retry, trial count: %d",
719 oi
->interface
->name
, oi
->sso_try_cnt
);
720 thread_add_timer(master
, interface_up
, oi
,
721 OSPF6_INTERFACE_SSO_RETRY_INT
);
725 oi
->sso_try_cnt
= 0; /* Reset on success */
727 /* Update interface route */
728 ospf6_interface_connected_route_update(oi
->interface
);
731 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
732 && !if_is_loopback(oi
->interface
))
733 oi
->thread_send_hello
=
734 thread_add_event(master
, ospf6_hello_send
, oi
, 0);
736 /* decide next interface state */
737 if ((if_is_pointopoint(oi
->interface
))
738 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
739 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
740 } else if (oi
->priority
== 0)
741 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
743 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
744 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
);
750 int wait_timer(struct thread
*thread
)
752 struct ospf6_interface
*oi
;
754 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
755 assert(oi
&& oi
->interface
);
757 if (IS_OSPF6_DEBUG_INTERFACE
)
758 zlog_debug("Interface Event %s: [WaitTimer]",
759 oi
->interface
->name
);
761 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
762 ospf6_interface_state_change(dr_election(oi
), oi
);
767 int backup_seen(struct thread
*thread
)
769 struct ospf6_interface
*oi
;
771 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
772 assert(oi
&& oi
->interface
);
774 if (IS_OSPF6_DEBUG_INTERFACE
)
775 zlog_debug("Interface Event %s: [BackupSeen]",
776 oi
->interface
->name
);
778 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
779 ospf6_interface_state_change(dr_election(oi
), oi
);
784 int neighbor_change(struct thread
*thread
)
786 struct ospf6_interface
*oi
;
788 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
789 assert(oi
&& oi
->interface
);
791 if (IS_OSPF6_DEBUG_INTERFACE
)
792 zlog_debug("Interface Event %s: [NeighborChange]",
793 oi
->interface
->name
);
795 if (oi
->state
== OSPF6_INTERFACE_DROTHER
796 || oi
->state
== OSPF6_INTERFACE_BDR
797 || oi
->state
== OSPF6_INTERFACE_DR
)
798 ospf6_interface_state_change(dr_election(oi
), oi
);
803 int interface_down(struct thread
*thread
)
805 struct ospf6_interface
*oi
;
806 struct listnode
*node
, *nnode
;
807 struct ospf6_neighbor
*on
;
809 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
810 assert(oi
&& oi
->interface
);
812 if (IS_OSPF6_DEBUG_INTERFACE
)
813 zlog_debug("Interface Event %s: [InterfaceDown]",
814 oi
->interface
->name
);
817 THREAD_OFF(oi
->thread_send_hello
);
819 /* Leave AllSPFRouters */
820 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
821 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
824 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
826 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
827 ospf6_neighbor_delete(on
);
829 list_delete_all_node(oi
->neighbor_list
);
831 /* When interface state is reset, also reset information about
832 * DR election, as it is no longer valid. */
833 oi
->drouter
= oi
->prev_drouter
= htonl(0);
834 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
839 /* show specified interface structure */
840 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
)
842 struct ospf6_interface
*oi
;
846 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
847 const char *updown
[3] = {"down", "up", NULL
};
849 struct timeval res
, now
;
851 struct ospf6_lsa
*lsa
;
853 /* check physical interface type */
854 if (if_is_loopback(ifp
))
856 else if (if_is_broadcast(ifp
))
858 else if (if_is_pointopoint(ifp
))
859 type
= "POINTOPOINT";
863 vty_out(vty
, "%s is %s, type %s%s", ifp
->name
,
864 updown
[if_is_operative(ifp
)], type
, VNL
);
865 vty_out(vty
, " Interface ID: %d%s", ifp
->ifindex
, VNL
);
867 if (ifp
->info
== NULL
) {
868 vty_out(vty
, " OSPF not enabled on this interface%s", VNL
);
871 oi
= (struct ospf6_interface
*)ifp
->info
;
873 vty_out(vty
, " Internet Address:%s", VNL
);
875 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
877 prefix2str(p
, strbuf
, sizeof(strbuf
));
880 vty_out(vty
, " inet : %s%s", strbuf
, VNL
);
883 vty_out(vty
, " inet6: %s%s", strbuf
, VNL
);
886 vty_out(vty
, " ??? : %s%s", strbuf
, VNL
);
893 " Instance ID %d, Interface MTU %d (autodetect: %d)%s",
894 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
, VNL
);
895 vty_out(vty
, " MTU mismatch detection: %s%s",
896 oi
->mtu_ignore
? "disabled" : "enabled", VNL
);
897 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
, sizeof(strbuf
));
898 vty_out(vty
, " Area ID %s, Cost %u%s", strbuf
, oi
->cost
, VNL
);
900 vty_out(vty
, " Not Attached to Area%s", VNL
);
902 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d%s",
903 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
905 vty_out(vty
, " Timer intervals configured:%s", VNL
);
906 vty_out(vty
, " Hello %d, Dead %d, Retransmit %d%s",
907 oi
->hello_interval
, oi
->dead_interval
, oi
->rxmt_interval
, VNL
);
909 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
910 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
911 vty_out(vty
, " DR: %s BDR: %s%s", drouter
, bdrouter
, VNL
);
913 vty_out(vty
, " Number of I/F scoped LSAs is %u%s", oi
->lsdb
->count
,
919 if (oi
->thread_send_lsupdate
)
920 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
, &res
);
921 timerstring(&res
, duration
, sizeof(duration
));
923 " %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
924 oi
->lsupdate_list
->count
, duration
,
925 (oi
->thread_send_lsupdate
? "on" : "off"), VNL
);
926 for (lsa
= ospf6_lsdb_head(oi
->lsupdate_list
); lsa
;
927 lsa
= ospf6_lsdb_next(lsa
))
928 vty_out(vty
, " %s%s", lsa
->name
, VNL
);
931 if (oi
->thread_send_lsack
)
932 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
933 timerstring(&res
, duration
, sizeof(duration
));
934 vty_out(vty
, " %d Pending LSAs for LSAck in Time %s [thread %s]%s",
935 oi
->lsack_list
->count
, duration
,
936 (oi
->thread_send_lsack
? "on" : "off"), VNL
);
937 for (lsa
= ospf6_lsdb_head(oi
->lsack_list
); lsa
;
938 lsa
= ospf6_lsdb_next(lsa
))
939 vty_out(vty
, " %s%s", lsa
->name
, VNL
);
940 ospf6_bfd_show_info(vty
, oi
->bfd_info
, 1);
945 DEFUN (show_ipv6_ospf6_interface
,
946 show_ipv6_ospf6_interface_ifname_cmd
,
947 "show ipv6 ospf6 interface [IFNAME]",
955 struct interface
*ifp
;
959 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
961 vty_out(vty
, "No such Interface: %s%s",
962 argv
[idx_ifname
]->arg
, VNL
);
965 ospf6_interface_show(vty
, ifp
);
967 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), i
, ifp
))
968 ospf6_interface_show(vty
, ifp
);
974 DEFUN (show_ipv6_ospf6_interface_ifname_prefix
,
975 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
976 "show ipv6 ospf6 interface IFNAME prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
982 "Display connected prefixes to advertise\n"
983 OSPF6_ROUTE_ADDRESS_STR
984 OSPF6_ROUTE_PREFIX_STR
985 OSPF6_ROUTE_MATCH_STR
986 "Display details of the prefixes\n")
990 struct interface
*ifp
;
991 struct ospf6_interface
*oi
;
993 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
995 vty_out(vty
, "No such Interface: %s%s", argv
[idx_ifname
]->arg
,
1002 vty_out(vty
, "OSPFv3 is not enabled on %s%s",
1003 argv
[idx_ifname
]->arg
, VNL
);
1007 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1008 oi
->route_connected
);
1013 DEFUN (show_ipv6_ospf6_interface_prefix
,
1014 show_ipv6_ospf6_interface_prefix_cmd
,
1015 "show ipv6 ospf6 interface prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
1020 "Display connected prefixes to advertise\n"
1021 OSPF6_ROUTE_ADDRESS_STR
1022 OSPF6_ROUTE_PREFIX_STR
1023 OSPF6_ROUTE_MATCH_STR
1024 "Display details of the prefixes\n")
1028 struct ospf6_interface
*oi
;
1029 struct interface
*ifp
;
1031 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), i
, ifp
)) {
1032 oi
= (struct ospf6_interface
*)ifp
->info
;
1036 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1037 oi
->route_connected
);
1043 /* interface variable set command */
1044 DEFUN (ipv6_ospf6_ifmtu
,
1045 ipv6_ospf6_ifmtu_cmd
,
1046 "ipv6 ospf6 ifmtu (1-65535)",
1050 "OSPFv3 Interface MTU\n"
1053 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1055 struct ospf6_interface
*oi
;
1056 unsigned int ifmtu
, iobuflen
;
1057 struct listnode
*node
, *nnode
;
1058 struct ospf6_neighbor
*on
;
1062 oi
= (struct ospf6_interface
*)ifp
->info
;
1064 oi
= ospf6_interface_create(ifp
);
1067 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1069 if (oi
->ifmtu
== ifmtu
)
1072 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1074 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s",
1075 ifp
->name
, ifp
->mtu6
, VNL
);
1079 if (oi
->ifmtu
< ifmtu
) {
1080 iobuflen
= ospf6_iobuf_size(ifmtu
);
1081 if (iobuflen
< ifmtu
) {
1083 "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
1084 ifp
->name
, iobuflen
, VNL
);
1085 oi
->ifmtu
= iobuflen
;
1091 /* re-establish adjacencies */
1092 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1093 THREAD_OFF(on
->inactivity_timer
);
1094 thread_add_event(master
, inactivity_timer
, on
, 0);
1100 DEFUN (no_ipv6_ospf6_ifmtu
,
1101 no_ipv6_ospf6_ifmtu_cmd
,
1102 "no ipv6 ospf6 ifmtu",
1109 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1110 struct ospf6_interface
*oi
;
1111 unsigned int iobuflen
;
1112 struct listnode
*node
, *nnode
;
1113 struct ospf6_neighbor
*on
;
1117 oi
= (struct ospf6_interface
*)ifp
->info
;
1119 oi
= ospf6_interface_create(ifp
);
1122 if (oi
->ifmtu
< ifp
->mtu
) {
1123 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1124 if (iobuflen
< ifp
->mtu
) {
1126 "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
1127 ifp
->name
, iobuflen
, VNL
);
1128 oi
->ifmtu
= iobuflen
;
1130 oi
->ifmtu
= ifp
->mtu
;
1132 oi
->ifmtu
= ifp
->mtu
;
1134 /* re-establish adjacencies */
1135 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1136 THREAD_OFF(on
->inactivity_timer
);
1137 thread_add_event(master
, inactivity_timer
, on
, 0);
1143 DEFUN (ipv6_ospf6_cost
,
1144 ipv6_ospf6_cost_cmd
,
1145 "ipv6 ospf6 cost (1-65535)",
1149 "Outgoing metric of this interface\n"
1152 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1154 struct ospf6_interface
*oi
;
1155 unsigned long int lcost
;
1159 oi
= (struct ospf6_interface
*)ifp
->info
;
1161 oi
= ospf6_interface_create(ifp
);
1164 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1166 if (lcost
> UINT32_MAX
) {
1167 vty_out(vty
, "Cost %ld is out of range%s", lcost
, VNL
);
1171 if (oi
->cost
== lcost
)
1175 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1177 ospf6_interface_recalculate_cost(oi
);
1182 DEFUN (no_ipv6_ospf6_cost
,
1183 no_ipv6_ospf6_cost_cmd
,
1184 "no ipv6 ospf6 cost",
1188 "Calculate interface cost from bandwidth\n"
1191 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1192 struct ospf6_interface
*oi
;
1195 oi
= (struct ospf6_interface
*)ifp
->info
;
1197 oi
= ospf6_interface_create(ifp
);
1200 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1202 ospf6_interface_recalculate_cost(oi
);
1207 DEFUN (auto_cost_reference_bandwidth
,
1208 auto_cost_reference_bandwidth_cmd
,
1209 "auto-cost reference-bandwidth (1-4294967)",
1210 "Calculate OSPF interface cost according to bandwidth\n"
1211 "Use reference bandwidth method to assign OSPF cost\n"
1212 "The reference bandwidth in terms of Mbits per second\n")
1214 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1216 struct ospf6_area
*oa
;
1217 struct ospf6_interface
*oi
;
1218 struct listnode
*i
, *j
;
1221 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1222 if (refbw
< 1 || refbw
> 4294967) {
1223 vty_out(vty
, "reference-bandwidth value is invalid%s",
1228 /* If reference bandwidth is changed. */
1229 if ((refbw
) == o
->ref_bandwidth
)
1232 o
->ref_bandwidth
= refbw
;
1233 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1234 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1235 ospf6_interface_recalculate_cost(oi
);
1240 DEFUN (no_auto_cost_reference_bandwidth
,
1241 no_auto_cost_reference_bandwidth_cmd
,
1242 "no auto-cost reference-bandwidth [(1-4294967)]",
1244 "Calculate OSPF interface cost according to bandwidth\n"
1245 "Use reference bandwidth method to assign OSPF cost\n"
1246 "The reference bandwidth in terms of Mbits per second\n")
1248 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1249 struct ospf6_area
*oa
;
1250 struct ospf6_interface
*oi
;
1251 struct listnode
*i
, *j
;
1253 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
1256 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
1257 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1258 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1259 ospf6_interface_recalculate_cost(oi
);
1265 DEFUN (ipv6_ospf6_hellointerval
,
1266 ipv6_ospf6_hellointerval_cmd
,
1267 "ipv6 ospf6 hello-interval (1-65535)",
1270 "Time between HELLO packets\n"
1274 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1276 struct ospf6_interface
*oi
;
1279 oi
= (struct ospf6_interface
*)ifp
->info
;
1281 oi
= ospf6_interface_create(ifp
);
1284 oi
->hello_interval
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1288 /* interface variable set command */
1289 DEFUN (ipv6_ospf6_deadinterval
,
1290 ipv6_ospf6_deadinterval_cmd
,
1291 "ipv6 ospf6 dead-interval (1-65535)",
1294 "Interval time after which a neighbor is declared down\n"
1298 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1300 struct ospf6_interface
*oi
;
1303 oi
= (struct ospf6_interface
*)ifp
->info
;
1305 oi
= ospf6_interface_create(ifp
);
1308 oi
->dead_interval
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1312 /* interface variable set command */
1313 DEFUN (ipv6_ospf6_transmitdelay
,
1314 ipv6_ospf6_transmitdelay_cmd
,
1315 "ipv6 ospf6 transmit-delay (1-3600)",
1318 "Link state transmit delay\n"
1321 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1323 struct ospf6_interface
*oi
;
1326 oi
= (struct ospf6_interface
*)ifp
->info
;
1328 oi
= ospf6_interface_create(ifp
);
1331 oi
->transdelay
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1335 /* interface variable set command */
1336 DEFUN (ipv6_ospf6_retransmitinterval
,
1337 ipv6_ospf6_retransmitinterval_cmd
,
1338 "ipv6 ospf6 retransmit-interval (1-65535)",
1341 "Time between retransmitting lost link state advertisements\n"
1345 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1347 struct ospf6_interface
*oi
;
1350 oi
= (struct ospf6_interface
*)ifp
->info
;
1352 oi
= ospf6_interface_create(ifp
);
1355 oi
->rxmt_interval
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1359 /* interface variable set command */
1360 DEFUN (ipv6_ospf6_priority
,
1361 ipv6_ospf6_priority_cmd
,
1362 "ipv6 ospf6 priority (0-255)",
1369 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1371 struct ospf6_interface
*oi
;
1374 oi
= (struct ospf6_interface
*)ifp
->info
;
1376 oi
= ospf6_interface_create(ifp
);
1379 oi
->priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1381 if (oi
->area
&& (oi
->state
== OSPF6_INTERFACE_DROTHER
1382 || oi
->state
== OSPF6_INTERFACE_BDR
1383 || oi
->state
== OSPF6_INTERFACE_DR
))
1384 ospf6_interface_state_change(dr_election(oi
), oi
);
1389 DEFUN (ipv6_ospf6_instance
,
1390 ipv6_ospf6_instance_cmd
,
1391 "ipv6 ospf6 instance-id (0-255)",
1394 "Instance ID for this interface\n"
1395 "Instance ID value\n"
1398 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1400 struct ospf6_interface
*oi
;
1403 oi
= (struct ospf6_interface
*)ifp
->info
;
1405 oi
= ospf6_interface_create(ifp
);
1408 oi
->instance_id
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1412 DEFUN (ipv6_ospf6_passive
,
1413 ipv6_ospf6_passive_cmd
,
1414 "ipv6 ospf6 passive",
1417 "Passive interface; no adjacency will be formed on this interface\n"
1420 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1421 struct ospf6_interface
*oi
;
1422 struct listnode
*node
, *nnode
;
1423 struct ospf6_neighbor
*on
;
1427 oi
= (struct ospf6_interface
*)ifp
->info
;
1429 oi
= ospf6_interface_create(ifp
);
1432 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1433 THREAD_OFF(oi
->thread_send_hello
);
1435 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1436 THREAD_OFF(on
->inactivity_timer
);
1437 thread_add_event(master
, inactivity_timer
, on
, 0);
1443 DEFUN (no_ipv6_ospf6_passive
,
1444 no_ipv6_ospf6_passive_cmd
,
1445 "no ipv6 ospf6 passive",
1449 "passive interface: No Adjacency will be formed on this I/F\n"
1452 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1453 struct ospf6_interface
*oi
;
1456 oi
= (struct ospf6_interface
*)ifp
->info
;
1458 oi
= ospf6_interface_create(ifp
);
1461 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1462 THREAD_OFF(oi
->thread_send_hello
);
1463 oi
->thread_send_hello
=
1464 thread_add_event(master
, ospf6_hello_send
, oi
, 0);
1469 DEFUN (ipv6_ospf6_mtu_ignore
,
1470 ipv6_ospf6_mtu_ignore_cmd
,
1471 "ipv6 ospf6 mtu-ignore",
1474 "Disable MTU mismatch detection on this interface\n"
1477 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1478 struct ospf6_interface
*oi
;
1481 oi
= (struct ospf6_interface
*)ifp
->info
;
1483 oi
= ospf6_interface_create(ifp
);
1491 DEFUN (no_ipv6_ospf6_mtu_ignore
,
1492 no_ipv6_ospf6_mtu_ignore_cmd
,
1493 "no ipv6 ospf6 mtu-ignore",
1497 "Disable MTU mismatch detection on this interface\n"
1500 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1501 struct ospf6_interface
*oi
;
1504 oi
= (struct ospf6_interface
*)ifp
->info
;
1506 oi
= ospf6_interface_create(ifp
);
1514 DEFUN (ipv6_ospf6_advertise_prefix_list
,
1515 ipv6_ospf6_advertise_prefix_list_cmd
,
1516 "ipv6 ospf6 advertise prefix-list WORD",
1519 "Advertising options\n"
1520 "Filter prefix using prefix-list\n"
1521 "Prefix list name\n"
1524 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1526 struct ospf6_interface
*oi
;
1529 oi
= (struct ospf6_interface
*)ifp
->info
;
1531 oi
= ospf6_interface_create(ifp
);
1535 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
1536 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
1538 ospf6_interface_connected_route_update(oi
->interface
);
1541 OSPF6_LINK_LSA_SCHEDULE(oi
);
1542 if (oi
->state
== OSPF6_INTERFACE_DR
) {
1543 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
1544 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
1546 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
1552 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
1553 no_ipv6_ospf6_advertise_prefix_list_cmd
,
1554 "no ipv6 ospf6 advertise prefix-list",
1558 "Advertising options\n"
1559 "Filter prefix using prefix-list\n"
1562 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1563 struct ospf6_interface
*oi
;
1566 oi
= (struct ospf6_interface
*)ifp
->info
;
1568 oi
= ospf6_interface_create(ifp
);
1571 if (oi
->plist_name
) {
1572 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
1573 oi
->plist_name
= NULL
;
1576 ospf6_interface_connected_route_update(oi
->interface
);
1579 OSPF6_LINK_LSA_SCHEDULE(oi
);
1580 if (oi
->state
== OSPF6_INTERFACE_DR
) {
1581 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
1582 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
1584 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
1590 DEFUN (ipv6_ospf6_network
,
1591 ipv6_ospf6_network_cmd
,
1592 "ipv6 ospf6 network <broadcast|point-to-point>",
1596 "Specify OSPF6 broadcast network\n"
1597 "Specify OSPF6 point-to-point network\n"
1600 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1601 int idx_network
= 3;
1602 struct ospf6_interface
*oi
;
1605 oi
= (struct ospf6_interface
*)ifp
->info
;
1607 oi
= ospf6_interface_create(ifp
);
1611 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
1612 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1615 oi
->type
= OSPF_IFTYPE_BROADCAST
;
1616 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
1617 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
1620 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
1623 /* Reset the interface */
1624 thread_add_event(master
, interface_down
, oi
, 0);
1625 thread_add_event(master
, interface_up
, oi
, 0);
1630 DEFUN (no_ipv6_ospf6_network
,
1631 no_ipv6_ospf6_network_cmd
,
1632 "no ipv6 ospf6 network",
1637 "Default to whatever interface type system specifies"
1640 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1641 struct ospf6_interface
*oi
;
1646 oi
= (struct ospf6_interface
*)ifp
->info
;
1651 type
= ospf6_default_iftype(ifp
);
1652 if (oi
->type
== type
) {
1657 /* Reset the interface */
1658 thread_add_event(master
, interface_down
, oi
, 0);
1659 thread_add_event(master
, interface_up
, oi
, 0);
1664 static int config_write_ospf6_interface(struct vty
*vty
)
1667 struct ospf6_interface
*oi
;
1668 struct interface
*ifp
;
1670 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), i
, ifp
)) {
1671 oi
= (struct ospf6_interface
*)ifp
->info
;
1675 vty_out(vty
, "interface %s%s", oi
->interface
->name
, VNL
);
1678 vty_out(vty
, " description %s%s", ifp
->desc
, VNL
);
1679 if (ifp
->mtu6
!= oi
->ifmtu
)
1680 vty_out(vty
, " ipv6 ospf6 ifmtu %d%s", oi
->ifmtu
, VNL
);
1682 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
1683 vty_out(vty
, " ipv6 ospf6 cost %d%s", oi
->cost
, VNL
);
1685 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
1686 vty_out(vty
, " ipv6 ospf6 hello-interval %d%s",
1687 oi
->hello_interval
, VNL
);
1689 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
1690 vty_out(vty
, " ipv6 ospf6 dead-interval %d%s",
1691 oi
->dead_interval
, VNL
);
1693 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
1694 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d%s",
1695 oi
->rxmt_interval
, VNL
);
1697 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
1698 vty_out(vty
, " ipv6 ospf6 priority %d%s", oi
->priority
,
1701 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
1702 vty_out(vty
, " ipv6 ospf6 transmit-delay %d%s",
1703 oi
->transdelay
, VNL
);
1705 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
1706 vty_out(vty
, " ipv6 ospf6 instance-id %d%s",
1707 oi
->instance_id
, VNL
);
1710 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s%s",
1711 oi
->plist_name
, VNL
);
1713 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
1714 vty_out(vty
, " ipv6 ospf6 passive%s", VNL
);
1717 vty_out(vty
, " ipv6 ospf6 mtu-ignore%s", VNL
);
1719 if (oi
->type
!= ospf6_default_iftype(ifp
)) {
1720 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
1722 " ipv6 ospf6 network point-to-point%s",
1724 else if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1725 vty_out(vty
, " ipv6 ospf6 network broadcast%s",
1729 ospf6_bfd_write_config(vty
, oi
);
1731 vty_out(vty
, "!%s", VNL
);
1736 static struct cmd_node interface_node
= {
1737 INTERFACE_NODE
, "%s(config-if)# ", 1 /* VTYSH */
1740 void ospf6_interface_init(void)
1742 /* Install interface node. */
1743 install_node(&interface_node
, config_write_ospf6_interface
);
1746 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
1747 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
1748 install_element(VIEW_NODE
,
1749 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
1751 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
1752 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
1753 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
1754 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
1755 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
1756 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
1757 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
1758 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
1759 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
1760 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
1762 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
1763 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
1765 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
1766 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
1768 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
1769 install_element(INTERFACE_NODE
,
1770 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
1772 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
1773 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
1775 /* reference bandwidth commands */
1776 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
1777 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
1780 /* Clear the specified interface structure */
1781 static void ospf6_interface_clear(struct vty
*vty
, struct interface
*ifp
)
1783 struct ospf6_interface
*oi
;
1785 if (!if_is_operative(ifp
))
1788 if (ifp
->info
== NULL
)
1791 oi
= (struct ospf6_interface
*)ifp
->info
;
1793 if (IS_OSPF6_DEBUG_INTERFACE
)
1794 zlog_debug("Interface %s: clear by reset", ifp
->name
);
1796 /* Reset the interface */
1797 thread_add_event(master
, interface_down
, oi
, 0);
1798 thread_add_event(master
, interface_up
, oi
, 0);
1801 /* Clear interface */
1802 DEFUN (clear_ipv6_ospf6_interface
,
1803 clear_ipv6_ospf6_interface_cmd
,
1804 "clear ipv6 ospf6 interface [IFNAME]",
1813 struct interface
*ifp
;
1814 struct listnode
*node
;
1816 if (argc
== 4) /* Clear all the ospfv3 interfaces. */
1818 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
))
1819 ospf6_interface_clear(vty
, ifp
);
1820 } else /* Interface name is specified. */
1822 if ((ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
1825 vty_out(vty
, "No such Interface: %s%s",
1826 argv
[idx_ifname
]->arg
, VNL
);
1829 ospf6_interface_clear(vty
, ifp
);
1835 void install_element_ospf6_clear_interface(void)
1837 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
1840 DEFUN (debug_ospf6_interface
,
1841 debug_ospf6_interface_cmd
,
1842 "debug ospf6 interface",
1845 "Debug OSPFv3 Interface\n"
1848 OSPF6_DEBUG_INTERFACE_ON();
1852 DEFUN (no_debug_ospf6_interface
,
1853 no_debug_ospf6_interface_cmd
,
1854 "no debug ospf6 interface",
1858 "Debug OSPFv3 Interface\n"
1861 OSPF6_DEBUG_INTERFACE_OFF();
1865 int config_write_ospf6_debug_interface(struct vty
*vty
)
1867 if (IS_OSPF6_DEBUG_INTERFACE
)
1868 vty_out(vty
, "debug ospf6 interface%s", VNL
);
1872 void install_element_ospf6_debug_interface(void)
1874 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
1875 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
1876 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
1877 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);