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 uint8_t 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 uint32_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
= (uint32_t)((double)refbw
/ (double)bw
+ (double)0.5);
140 else if (cost
> UINT32_MAX
)
147 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface
*oi
)
149 /* update cost held in route_connected list in ospf6_interface */
150 ospf6_interface_connected_route_update(oi
->interface
);
152 /* execute LSA hooks */
154 OSPF6_LINK_LSA_SCHEDULE(oi
);
155 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
156 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
157 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
158 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
162 static void ospf6_interface_recalculate_cost(struct ospf6_interface
*oi
)
166 newcost
= ospf6_interface_get_cost(oi
);
167 if (newcost
== oi
->cost
)
171 ospf6_interface_force_recalculate_cost(oi
);
174 /* Create new ospf6 interface structure */
175 struct ospf6_interface
*ospf6_interface_create(struct interface
*ifp
)
177 struct ospf6_interface
*oi
;
178 unsigned int iobuflen
;
180 oi
= (struct ospf6_interface
*)XCALLOC(MTYPE_OSPF6_IF
,
181 sizeof(struct ospf6_interface
));
184 zlog_err("Can't malloc ospf6_interface for ifindex %d",
186 return (struct ospf6_interface
*)NULL
;
189 oi
->area
= (struct ospf6_area
*)NULL
;
190 oi
->neighbor_list
= list_new();
191 oi
->neighbor_list
->cmp
= ospf6_neighbor_cmp
;
192 oi
->linklocal_addr
= (struct in6_addr
*)NULL
;
193 oi
->instance_id
= OSPF6_INTERFACE_INSTANCE_ID
;
194 oi
->transdelay
= OSPF6_INTERFACE_TRANSDELAY
;
195 oi
->priority
= OSPF6_INTERFACE_PRIORITY
;
197 oi
->hello_interval
= OSPF_HELLO_INTERVAL_DEFAULT
;
198 oi
->dead_interval
= OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
;
199 oi
->rxmt_interval
= OSPF_RETRANSMIT_INTERVAL_DEFAULT
;
200 oi
->type
= ospf6_default_iftype(ifp
);
201 oi
->state
= OSPF6_INTERFACE_DOWN
;
206 /* Try to adjust I/O buffer size with IfMtu */
207 oi
->ifmtu
= ifp
->mtu6
;
208 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
209 if (oi
->ifmtu
> iobuflen
) {
210 if (IS_OSPF6_DEBUG_INTERFACE
)
212 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
213 ifp
->name
, iobuflen
);
214 oi
->ifmtu
= iobuflen
;
217 QOBJ_REG(oi
, ospf6_interface
);
219 oi
->lsupdate_list
= ospf6_lsdb_create(oi
);
220 oi
->lsack_list
= ospf6_lsdb_create(oi
);
221 oi
->lsdb
= ospf6_lsdb_create(oi
);
222 oi
->lsdb
->hook_add
= ospf6_interface_lsdb_hook_add
;
223 oi
->lsdb
->hook_remove
= ospf6_interface_lsdb_hook_remove
;
224 oi
->lsdb_self
= ospf6_lsdb_create(oi
);
226 oi
->route_connected
=
227 OSPF6_ROUTE_TABLE_CREATE(INTERFACE
, CONNECTED_ROUTES
);
228 oi
->route_connected
->scope
= oi
;
235 oi
->cost
= ospf6_interface_get_cost(oi
);
240 void ospf6_interface_delete(struct ospf6_interface
*oi
)
242 struct listnode
*node
, *nnode
;
243 struct ospf6_neighbor
*on
;
247 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
248 ospf6_neighbor_delete(on
);
250 list_delete_and_null(&oi
->neighbor_list
);
252 THREAD_OFF(oi
->thread_send_hello
);
253 THREAD_OFF(oi
->thread_send_lsupdate
);
254 THREAD_OFF(oi
->thread_send_lsack
);
256 ospf6_lsdb_remove_all(oi
->lsdb
);
257 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
258 ospf6_lsdb_remove_all(oi
->lsack_list
);
260 ospf6_lsdb_delete(oi
->lsdb
);
261 ospf6_lsdb_delete(oi
->lsdb_self
);
263 ospf6_lsdb_delete(oi
->lsupdate_list
);
264 ospf6_lsdb_delete(oi
->lsack_list
);
266 ospf6_route_table_delete(oi
->route_connected
);
269 oi
->interface
->info
= NULL
;
273 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
275 ospf6_bfd_info_free(&(oi
->bfd_info
));
277 XFREE(MTYPE_OSPF6_IF
, oi
);
280 void ospf6_interface_enable(struct ospf6_interface
*oi
)
282 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
283 ospf6_interface_state_update(oi
->interface
);
286 void ospf6_interface_disable(struct ospf6_interface
*oi
)
288 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
);
290 thread_execute(master
, interface_down
, oi
, 0);
292 ospf6_lsdb_remove_all(oi
->lsdb
);
293 ospf6_lsdb_remove_all(oi
->lsdb_self
);
294 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
295 ospf6_lsdb_remove_all(oi
->lsack_list
);
297 THREAD_OFF(oi
->thread_send_hello
);
298 THREAD_OFF(oi
->thread_send_lsupdate
);
299 THREAD_OFF(oi
->thread_send_lsack
);
301 THREAD_OFF(oi
->thread_network_lsa
);
302 THREAD_OFF(oi
->thread_link_lsa
);
303 THREAD_OFF(oi
->thread_intra_prefix_lsa
);
304 THREAD_OFF(oi
->thread_as_extern_lsa
);
307 static struct in6_addr
*
308 ospf6_interface_get_linklocal_address(struct interface
*ifp
)
312 struct in6_addr
*l
= (struct in6_addr
*)NULL
;
314 /* for each connected address */
315 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, n
, c
)) {
316 /* if family not AF_INET6, ignore */
317 if (c
->address
->family
!= AF_INET6
)
320 /* linklocal scope check */
321 if (IN6_IS_ADDR_LINKLOCAL(&c
->address
->u
.prefix6
))
322 l
= &c
->address
->u
.prefix6
;
327 void ospf6_interface_if_add(struct interface
*ifp
)
329 struct ospf6_interface
*oi
;
330 unsigned int iobuflen
;
332 oi
= (struct ospf6_interface
*)ifp
->info
;
336 /* Try to adjust I/O buffer size with IfMtu */
338 oi
->ifmtu
= ifp
->mtu6
;
339 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
340 if (oi
->ifmtu
> iobuflen
) {
341 if (IS_OSPF6_DEBUG_INTERFACE
)
343 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
344 ifp
->name
, iobuflen
);
345 oi
->ifmtu
= iobuflen
;
348 /* interface start */
349 ospf6_interface_state_update(oi
->interface
);
352 void ospf6_interface_if_del(struct interface
*ifp
)
354 struct ospf6_interface
*oi
;
356 oi
= (struct ospf6_interface
*)ifp
->info
;
362 thread_execute(master
, interface_down
, oi
, 0);
364 listnode_delete(oi
->area
->if_list
, oi
);
365 oi
->area
= (struct ospf6_area
*)NULL
;
368 oi
->interface
= NULL
;
371 ospf6_interface_delete(oi
);
374 void ospf6_interface_state_update(struct interface
*ifp
)
376 struct ospf6_interface
*oi
;
377 unsigned int iobuflen
;
379 oi
= (struct ospf6_interface
*)ifp
->info
;
382 if (oi
->area
== NULL
)
384 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
387 /* Adjust the mtu values if the kernel told us something new */
388 if (ifp
->mtu6
!= oi
->ifmtu
) {
389 /* If nothing configured, accept it and check for buffer size */
391 oi
->ifmtu
= ifp
->mtu6
;
392 iobuflen
= ospf6_iobuf_size(ifp
->mtu6
);
393 if (oi
->ifmtu
> iobuflen
) {
394 if (IS_OSPF6_DEBUG_INTERFACE
)
396 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
397 ifp
->name
, iobuflen
);
398 oi
->ifmtu
= iobuflen
;
400 } else if (oi
->c_ifmtu
> ifp
->mtu6
) {
401 oi
->ifmtu
= ifp
->mtu6
;
403 "Configured mtu %u on %s overridden by kernel %u",
404 oi
->c_ifmtu
, ifp
->name
, ifp
->mtu6
);
406 oi
->ifmtu
= oi
->c_ifmtu
;
409 if (if_is_operative(ifp
)
410 && (ospf6_interface_get_linklocal_address(oi
->interface
)
411 || if_is_loopback(oi
->interface
)))
412 thread_add_event(master
, interface_up
, oi
, 0, NULL
);
414 thread_add_event(master
, interface_down
, oi
, 0, NULL
);
419 void ospf6_interface_connected_route_update(struct interface
*ifp
)
421 struct ospf6_interface
*oi
;
422 struct ospf6_route
*route
;
424 struct listnode
*node
, *nnode
;
425 struct in6_addr nh_addr
;
427 oi
= (struct ospf6_interface
*)ifp
->info
;
431 /* reset linklocal pointer */
432 oi
->linklocal_addr
= ospf6_interface_get_linklocal_address(ifp
);
434 /* if area is null, do not make connected-route list */
435 if (oi
->area
== NULL
)
438 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
441 /* update "route to advertise" interface route table */
442 ospf6_route_remove_all(oi
->route_connected
);
444 for (ALL_LIST_ELEMENTS(oi
->interface
->connected
, node
, nnode
, c
)) {
445 if (c
->address
->family
!= AF_INET6
)
448 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE
,
450 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE
,
452 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE
,
454 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE
,
456 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE
,
460 if (oi
->plist_name
) {
461 struct prefix_list
*plist
;
462 enum prefix_list_type ret
;
463 char buf
[PREFIX2STR_BUFFER
];
465 prefix2str(c
->address
, buf
, sizeof(buf
));
466 plist
= prefix_list_lookup(AFI_IP6
, oi
->plist_name
);
467 ret
= prefix_list_apply(plist
, (void *)c
->address
);
468 if (ret
== PREFIX_DENY
) {
469 if (IS_OSPF6_DEBUG_INTERFACE
)
471 "%s on %s filtered by prefix-list %s ",
472 buf
, oi
->interface
->name
,
478 route
= ospf6_route_create();
479 memcpy(&route
->prefix
, c
->address
, sizeof(struct prefix
));
480 apply_mask(&route
->prefix
);
481 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
482 route
->path
.area_id
= oi
->area
->area_id
;
483 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
484 route
->path
.cost
= oi
->cost
;
485 inet_pton(AF_INET6
, "::1", &nh_addr
);
486 ospf6_route_add_nexthop(route
, oi
->interface
->ifindex
,
488 ospf6_route_add(route
, oi
->route_connected
);
491 /* create new Link-LSA */
492 OSPF6_LINK_LSA_SCHEDULE(oi
);
493 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
494 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
497 static void ospf6_interface_state_change(uint8_t next_state
,
498 struct ospf6_interface
*oi
)
502 prev_state
= oi
->state
;
503 oi
->state
= next_state
;
505 if (prev_state
== next_state
)
509 if (IS_OSPF6_DEBUG_INTERFACE
) {
510 zlog_debug("Interface state change %s: %s -> %s",
512 ospf6_interface_state_str
[prev_state
],
513 ospf6_interface_state_str
[next_state
]);
517 if ((prev_state
== OSPF6_INTERFACE_DR
518 || prev_state
== OSPF6_INTERFACE_BDR
)
519 && (next_state
!= OSPF6_INTERFACE_DR
520 && next_state
!= OSPF6_INTERFACE_BDR
))
521 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
524 if ((prev_state
!= OSPF6_INTERFACE_DR
525 && prev_state
!= OSPF6_INTERFACE_BDR
)
526 && (next_state
== OSPF6_INTERFACE_DR
527 || next_state
== OSPF6_INTERFACE_BDR
))
528 ospf6_sso(oi
->interface
->ifindex
, &alldrouters6
,
531 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
532 if (next_state
== OSPF6_INTERFACE_DOWN
) {
533 OSPF6_NETWORK_LSA_EXECUTE(oi
);
534 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
535 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
536 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi
);
537 } else if (prev_state
== OSPF6_INTERFACE_DR
538 || next_state
== OSPF6_INTERFACE_DR
) {
539 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
540 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
541 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
544 hook_call(ospf6_interface_change
, oi
, next_state
, prev_state
);
548 /* DR Election, RFC2328 section 9.4 */
550 #define IS_ELIGIBLE(n) \
551 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
553 static struct ospf6_neighbor
*better_bdrouter(struct ospf6_neighbor
*a
,
554 struct ospf6_neighbor
*b
)
556 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
557 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
))
559 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
== a
->router_id
)
561 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
== b
->router_id
)
564 if (a
->bdrouter
== a
->router_id
&& b
->bdrouter
!= b
->router_id
)
566 if (a
->bdrouter
!= a
->router_id
&& b
->bdrouter
== b
->router_id
)
569 if (a
->priority
> b
->priority
)
571 if (a
->priority
< b
->priority
)
574 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
576 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
579 zlog_warn("Router-ID duplicate ?");
583 static struct ospf6_neighbor
*better_drouter(struct ospf6_neighbor
*a
,
584 struct ospf6_neighbor
*b
)
586 if ((a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
587 && (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
))
589 else if (a
== NULL
|| !IS_ELIGIBLE(a
) || a
->drouter
!= a
->router_id
)
591 else if (b
== NULL
|| !IS_ELIGIBLE(b
) || b
->drouter
!= b
->router_id
)
594 if (a
->drouter
== a
->router_id
&& b
->drouter
!= b
->router_id
)
596 if (a
->drouter
!= a
->router_id
&& b
->drouter
== b
->router_id
)
599 if (a
->priority
> b
->priority
)
601 if (a
->priority
< b
->priority
)
604 if (ntohl(a
->router_id
) > ntohl(b
->router_id
))
606 if (ntohl(a
->router_id
) < ntohl(b
->router_id
))
609 zlog_warn("Router-ID duplicate ?");
613 static uint8_t dr_election(struct ospf6_interface
*oi
)
615 struct listnode
*node
, *nnode
;
616 struct ospf6_neighbor
*on
, *drouter
, *bdrouter
, myself
;
617 struct ospf6_neighbor
*best_drouter
, *best_bdrouter
;
618 uint8_t next_state
= 0;
620 drouter
= bdrouter
= NULL
;
621 best_drouter
= best_bdrouter
= NULL
;
623 /* pseudo neighbor myself, including noting current DR/BDR (1) */
624 memset(&myself
, 0, sizeof(myself
));
625 inet_ntop(AF_INET
, &oi
->area
->ospf6
->router_id
, myself
.name
,
626 sizeof(myself
.name
));
627 myself
.state
= OSPF6_NEIGHBOR_TWOWAY
;
628 myself
.drouter
= oi
->drouter
;
629 myself
.bdrouter
= oi
->bdrouter
;
630 myself
.priority
= oi
->priority
;
631 myself
.router_id
= oi
->area
->ospf6
->router_id
;
633 /* Electing BDR (2) */
634 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
635 bdrouter
= better_bdrouter(bdrouter
, on
);
637 best_bdrouter
= bdrouter
;
638 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
640 /* Electing DR (3) */
641 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
642 drouter
= better_drouter(drouter
, on
);
644 best_drouter
= drouter
;
645 drouter
= better_drouter(best_drouter
, &myself
);
649 /* the router itself is newly/no longer DR/BDR (4) */
650 if ((drouter
== &myself
&& myself
.drouter
!= myself
.router_id
)
651 || (drouter
!= &myself
&& myself
.drouter
== myself
.router_id
)
652 || (bdrouter
== &myself
&& myself
.bdrouter
!= myself
.router_id
)
653 || (bdrouter
!= &myself
&& myself
.bdrouter
== myself
.router_id
)) {
654 myself
.drouter
= (drouter
? drouter
->router_id
: htonl(0));
655 myself
.bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
657 /* compatible to Electing BDR (2) */
658 bdrouter
= better_bdrouter(best_bdrouter
, &myself
);
660 /* compatible to Electing DR (3) */
661 drouter
= better_drouter(best_drouter
, &myself
);
666 /* Set interface state accordingly (5) */
667 if (drouter
&& drouter
== &myself
)
668 next_state
= OSPF6_INTERFACE_DR
;
669 else if (bdrouter
&& bdrouter
== &myself
)
670 next_state
= OSPF6_INTERFACE_BDR
;
672 next_state
= OSPF6_INTERFACE_DROTHER
;
674 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
677 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
678 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
679 accordingly after AdjOK */
680 if (oi
->drouter
!= (drouter
? drouter
->router_id
: htonl(0))
681 || oi
->bdrouter
!= (bdrouter
? bdrouter
->router_id
: htonl(0))) {
682 if (IS_OSPF6_DEBUG_INTERFACE
)
683 zlog_debug("DR Election on %s: DR: %s BDR: %s",
685 (drouter
? drouter
->name
: "0.0.0.0"),
686 (bdrouter
? bdrouter
->name
: "0.0.0.0"));
688 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, node
, on
)) {
689 if (on
->state
< OSPF6_NEIGHBOR_TWOWAY
)
691 /* Schedule AdjOK. */
692 thread_add_event(master
, adj_ok
, on
, 0, NULL
);
696 oi
->drouter
= (drouter
? drouter
->router_id
: htonl(0));
697 oi
->bdrouter
= (bdrouter
? bdrouter
->router_id
: htonl(0));
702 /* Interface State Machine */
703 int interface_up(struct thread
*thread
)
705 struct ospf6_interface
*oi
;
707 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
708 assert(oi
&& oi
->interface
);
710 if (IS_OSPF6_DEBUG_INTERFACE
)
711 zlog_debug("Interface Event %s: [InterfaceUp]",
712 oi
->interface
->name
);
714 /* check physical interface is up */
715 if (!if_is_operative(oi
->interface
)) {
716 if (IS_OSPF6_DEBUG_INTERFACE
)
718 "Interface %s is down, can't execute [InterfaceUp]",
719 oi
->interface
->name
);
723 /* check interface has a link-local address */
724 if (!(ospf6_interface_get_linklocal_address(oi
->interface
)
725 || if_is_loopback(oi
->interface
))) {
726 if (IS_OSPF6_DEBUG_INTERFACE
)
728 "Interface %s has no link local address, can't execute [InterfaceUp]",
729 oi
->interface
->name
);
734 ospf6_interface_recalculate_cost(oi
);
736 /* if already enabled, do nothing */
737 if (oi
->state
> OSPF6_INTERFACE_DOWN
) {
738 if (IS_OSPF6_DEBUG_INTERFACE
)
739 zlog_debug("Interface %s already enabled",
740 oi
->interface
->name
);
744 /* If no area assigned, return */
745 if (oi
->area
== NULL
) {
747 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
748 __func__
, oi
->interface
->name
);
752 /* Join AllSPFRouters */
753 if (ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
, IPV6_JOIN_GROUP
)
755 if (oi
->sso_try_cnt
++ < OSPF6_INTERFACE_SSO_RETRY_MAX
) {
757 "Scheduling %s for sso retry, trial count: %d",
758 oi
->interface
->name
, oi
->sso_try_cnt
);
759 thread_add_timer(master
, interface_up
, oi
,
760 OSPF6_INTERFACE_SSO_RETRY_INT
, NULL
);
764 oi
->sso_try_cnt
= 0; /* Reset on success */
766 /* Update interface route */
767 ospf6_interface_connected_route_update(oi
->interface
);
770 if (!CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)
771 && !if_is_loopback(oi
->interface
)) {
772 oi
->thread_send_hello
= NULL
;
773 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
774 &oi
->thread_send_hello
);
777 /* decide next interface state */
778 if ((if_is_pointopoint(oi
->interface
))
779 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
780 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT
, oi
);
781 } else if (oi
->priority
== 0)
782 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER
, oi
);
784 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING
, oi
);
785 thread_add_timer(master
, wait_timer
, oi
, oi
->dead_interval
,
792 int wait_timer(struct thread
*thread
)
794 struct ospf6_interface
*oi
;
796 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
797 assert(oi
&& oi
->interface
);
799 if (IS_OSPF6_DEBUG_INTERFACE
)
800 zlog_debug("Interface Event %s: [WaitTimer]",
801 oi
->interface
->name
);
803 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
804 ospf6_interface_state_change(dr_election(oi
), oi
);
809 int backup_seen(struct thread
*thread
)
811 struct ospf6_interface
*oi
;
813 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
814 assert(oi
&& oi
->interface
);
816 if (IS_OSPF6_DEBUG_INTERFACE
)
817 zlog_debug("Interface Event %s: [BackupSeen]",
818 oi
->interface
->name
);
820 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
821 ospf6_interface_state_change(dr_election(oi
), oi
);
826 int neighbor_change(struct thread
*thread
)
828 struct ospf6_interface
*oi
;
830 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
831 assert(oi
&& oi
->interface
);
833 if (IS_OSPF6_DEBUG_INTERFACE
)
834 zlog_debug("Interface Event %s: [NeighborChange]",
835 oi
->interface
->name
);
837 if (oi
->state
== OSPF6_INTERFACE_DROTHER
838 || oi
->state
== OSPF6_INTERFACE_BDR
839 || oi
->state
== OSPF6_INTERFACE_DR
)
840 ospf6_interface_state_change(dr_election(oi
), oi
);
845 int interface_down(struct thread
*thread
)
847 struct ospf6_interface
*oi
;
848 struct listnode
*node
, *nnode
;
849 struct ospf6_neighbor
*on
;
851 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
852 assert(oi
&& oi
->interface
);
854 if (IS_OSPF6_DEBUG_INTERFACE
)
855 zlog_debug("Interface Event %s: [InterfaceDown]",
856 oi
->interface
->name
);
859 THREAD_OFF(oi
->thread_send_hello
);
861 /* Leave AllSPFRouters */
862 if (oi
->state
> OSPF6_INTERFACE_DOWN
)
863 ospf6_sso(oi
->interface
->ifindex
, &allspfrouters6
,
866 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN
, oi
);
868 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
869 ospf6_neighbor_delete(on
);
871 list_delete_all_node(oi
->neighbor_list
);
873 /* When interface state is reset, also reset information about
874 * DR election, as it is no longer valid. */
875 oi
->drouter
= oi
->prev_drouter
= htonl(0);
876 oi
->bdrouter
= oi
->prev_bdrouter
= htonl(0);
881 /* show specified interface structure */
882 static int ospf6_interface_show(struct vty
*vty
, struct interface
*ifp
)
884 struct ospf6_interface
*oi
;
888 char strbuf
[PREFIX2STR_BUFFER
], drouter
[32], bdrouter
[32];
889 const char *updown
[3] = {"down", "up", NULL
};
891 struct timeval res
, now
;
893 struct ospf6_lsa
*lsa
;
895 /* check physical interface type */
896 if (if_is_loopback(ifp
))
898 else if (if_is_broadcast(ifp
))
900 else if (if_is_pointopoint(ifp
))
901 type
= "POINTOPOINT";
905 vty_out(vty
, "%s is %s, type %s\n", ifp
->name
,
906 updown
[if_is_operative(ifp
)], type
);
907 vty_out(vty
, " Interface ID: %d\n", ifp
->ifindex
);
909 if (ifp
->info
== NULL
) {
910 vty_out(vty
, " OSPF not enabled on this interface\n");
913 oi
= (struct ospf6_interface
*)ifp
->info
;
915 vty_out(vty
, " Internet Address:\n");
917 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, i
, c
)) {
919 prefix2str(p
, strbuf
, sizeof(strbuf
));
922 vty_out(vty
, " inet : %s\n", strbuf
);
925 vty_out(vty
, " inet6: %s\n", strbuf
);
928 vty_out(vty
, " ??? : %s\n", strbuf
);
935 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
936 oi
->instance_id
, oi
->ifmtu
, ifp
->mtu6
);
937 vty_out(vty
, " MTU mismatch detection: %s\n",
938 oi
->mtu_ignore
? "disabled" : "enabled");
939 inet_ntop(AF_INET
, &oi
->area
->area_id
, strbuf
, sizeof(strbuf
));
940 vty_out(vty
, " Area ID %s, Cost %u\n", strbuf
, oi
->cost
);
942 vty_out(vty
, " Not Attached to Area\n");
944 vty_out(vty
, " State %s, Transmit Delay %d sec, Priority %d\n",
945 ospf6_interface_state_str
[oi
->state
], oi
->transdelay
,
947 vty_out(vty
, " Timer intervals configured:\n");
948 vty_out(vty
, " Hello %d, Dead %d, Retransmit %d\n",
949 oi
->hello_interval
, oi
->dead_interval
, oi
->rxmt_interval
);
951 inet_ntop(AF_INET
, &oi
->drouter
, drouter
, sizeof(drouter
));
952 inet_ntop(AF_INET
, &oi
->bdrouter
, bdrouter
, sizeof(bdrouter
));
953 vty_out(vty
, " DR: %s BDR: %s\n", drouter
, bdrouter
);
955 vty_out(vty
, " Number of I/F scoped LSAs is %u\n", oi
->lsdb
->count
);
960 if (oi
->thread_send_lsupdate
)
961 timersub(&oi
->thread_send_lsupdate
->u
.sands
, &now
, &res
);
962 timerstring(&res
, duration
, sizeof(duration
));
964 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
965 oi
->lsupdate_list
->count
, duration
,
966 (oi
->thread_send_lsupdate
? "on" : "off"));
967 for (ALL_LSDB(oi
->lsupdate_list
, lsa
))
968 vty_out(vty
, " %s\n", lsa
->name
);
971 if (oi
->thread_send_lsack
)
972 timersub(&oi
->thread_send_lsack
->u
.sands
, &now
, &res
);
973 timerstring(&res
, duration
, sizeof(duration
));
974 vty_out(vty
, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
975 oi
->lsack_list
->count
, duration
,
976 (oi
->thread_send_lsack
? "on" : "off"));
977 for (ALL_LSDB(oi
->lsack_list
, lsa
))
978 vty_out(vty
, " %s\n", lsa
->name
);
979 ospf6_bfd_show_info(vty
, oi
->bfd_info
, 1);
984 DEFUN (show_ipv6_ospf6_interface
,
985 show_ipv6_ospf6_interface_ifname_cmd
,
986 "show ipv6 ospf6 interface [IFNAME]",
993 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
995 struct interface
*ifp
;
998 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
1000 vty_out(vty
, "No such Interface: %s\n",
1001 argv
[idx_ifname
]->arg
);
1004 ospf6_interface_show(vty
, ifp
);
1006 FOR_ALL_INTERFACES (vrf
, ifp
)
1007 ospf6_interface_show(vty
, ifp
);
1013 static int ospf6_interface_show_traffic(struct vty
*vty
, uint32_t vrf_id
,
1014 struct interface
*intf_ifp
,
1017 struct interface
*ifp
;
1018 struct vrf
*vrf
= NULL
;
1019 struct ospf6_interface
*oi
= NULL
;
1021 vrf
= vrf_lookup_by_id(vrf_id
);
1023 if (!display_once
) {
1025 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1026 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1028 vty_out(vty
, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1029 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1032 "--------------------------------------------------------------------------------------------\n");
1035 if (intf_ifp
== NULL
) {
1036 FOR_ALL_INTERFACES (vrf
, ifp
) {
1038 oi
= (struct ospf6_interface
*)ifp
->info
;
1043 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1044 oi
->interface
->name
, oi
->hello_in
,
1045 oi
->hello_out
, oi
->db_desc_in
, oi
->db_desc_out
,
1046 oi
->ls_req_in
, oi
->ls_req_out
, oi
->ls_upd_in
,
1047 oi
->ls_upd_out
, oi
->ls_ack_in
, oi
->ls_ack_out
);
1050 oi
= intf_ifp
->info
;
1055 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1056 oi
->interface
->name
, oi
->hello_in
, oi
->hello_out
,
1057 oi
->db_desc_in
, oi
->db_desc_out
, oi
->ls_req_in
,
1058 oi
->ls_req_out
, oi
->ls_upd_in
, oi
->ls_upd_out
,
1059 oi
->ls_ack_in
, oi
->ls_ack_out
);
1065 /* show interface */
1066 DEFUN (show_ipv6_ospf6_interface_traffic
,
1067 show_ipv6_ospf6_interface_traffic_cmd
,
1068 "show ipv6 ospf6 interface traffic [IFNAME]",
1073 "Protocol Packet counters\n"
1077 int display_once
= 0;
1078 char *intf_name
= NULL
;
1079 struct interface
*ifp
= NULL
;
1081 if (argv_find(argv
, argc
, "IFNAME", &idx_ifname
)) {
1082 intf_name
= argv
[idx_ifname
]->arg
;
1083 ifp
= if_lookup_by_name(intf_name
, VRF_DEFAULT
);
1085 vty_out(vty
, "No such Interface: %s\n", intf_name
);
1088 if (ifp
->info
== NULL
) {
1090 " OSPF not enabled on this interface %s\n",
1096 ospf6_interface_show_traffic(vty
, VRF_DEFAULT
, ifp
, display_once
);
1103 DEFUN (show_ipv6_ospf6_interface_ifname_prefix
,
1104 show_ipv6_ospf6_interface_ifname_prefix_cmd
,
1105 "show ipv6 ospf6 interface IFNAME prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
1111 "Display connected prefixes to advertise\n"
1112 OSPF6_ROUTE_ADDRESS_STR
1113 OSPF6_ROUTE_PREFIX_STR
1114 OSPF6_ROUTE_MATCH_STR
1115 "Display details of the prefixes\n")
1119 struct interface
*ifp
;
1120 struct ospf6_interface
*oi
;
1122 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
1124 vty_out(vty
, "No such Interface: %s\n", argv
[idx_ifname
]->arg
);
1130 vty_out(vty
, "OSPFv3 is not enabled on %s\n",
1131 argv
[idx_ifname
]->arg
);
1135 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1136 oi
->route_connected
);
1141 DEFUN (show_ipv6_ospf6_interface_prefix
,
1142 show_ipv6_ospf6_interface_prefix_cmd
,
1143 "show ipv6 ospf6 interface prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
1148 "Display connected prefixes to advertise\n"
1149 OSPF6_ROUTE_ADDRESS_STR
1150 OSPF6_ROUTE_PREFIX_STR
1151 OSPF6_ROUTE_MATCH_STR
1152 "Display details of the prefixes\n")
1154 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1156 struct ospf6_interface
*oi
;
1157 struct interface
*ifp
;
1159 FOR_ALL_INTERFACES (vrf
, ifp
) {
1160 oi
= (struct ospf6_interface
*)ifp
->info
;
1164 ospf6_route_table_show(vty
, idx_prefix
, argc
, argv
,
1165 oi
->route_connected
);
1171 /* interface variable set command */
1172 DEFUN (ipv6_ospf6_ifmtu
,
1173 ipv6_ospf6_ifmtu_cmd
,
1174 "ipv6 ospf6 ifmtu (1-65535)",
1178 "OSPFv3 Interface MTU\n"
1181 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1183 struct ospf6_interface
*oi
;
1184 unsigned int ifmtu
, iobuflen
;
1185 struct listnode
*node
, *nnode
;
1186 struct ospf6_neighbor
*on
;
1190 oi
= (struct ospf6_interface
*)ifp
->info
;
1192 oi
= ospf6_interface_create(ifp
);
1195 ifmtu
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1197 if (oi
->c_ifmtu
== ifmtu
)
1200 if (ifp
->mtu6
!= 0 && ifp
->mtu6
< ifmtu
) {
1202 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1203 ifp
->name
, ifp
->mtu6
);
1204 return CMD_WARNING_CONFIG_FAILED
;
1207 if (oi
->ifmtu
< ifmtu
) {
1208 iobuflen
= ospf6_iobuf_size(ifmtu
);
1209 if (iobuflen
< ifmtu
) {
1211 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1212 ifp
->name
, iobuflen
);
1213 oi
->ifmtu
= oi
->c_ifmtu
= iobuflen
;
1215 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1217 oi
->ifmtu
= oi
->c_ifmtu
= ifmtu
;
1219 /* re-establish adjacencies */
1220 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1221 THREAD_OFF(on
->inactivity_timer
);
1222 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1228 DEFUN (no_ipv6_ospf6_ifmtu
,
1229 no_ipv6_ospf6_ifmtu_cmd
,
1230 "no ipv6 ospf6 ifmtu [(1-65535)]",
1235 "OSPFv3 Interface MTU\n"
1238 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1239 struct ospf6_interface
*oi
;
1240 unsigned int iobuflen
;
1241 struct listnode
*node
, *nnode
;
1242 struct ospf6_neighbor
*on
;
1246 oi
= (struct ospf6_interface
*)ifp
->info
;
1248 oi
= ospf6_interface_create(ifp
);
1251 if (oi
->ifmtu
< ifp
->mtu
) {
1252 iobuflen
= ospf6_iobuf_size(ifp
->mtu
);
1253 if (iobuflen
< ifp
->mtu
) {
1255 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1256 ifp
->name
, iobuflen
);
1257 oi
->ifmtu
= iobuflen
;
1259 oi
->ifmtu
= ifp
->mtu
;
1261 oi
->ifmtu
= ifp
->mtu
;
1265 /* re-establish adjacencies */
1266 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1267 THREAD_OFF(on
->inactivity_timer
);
1268 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1274 DEFUN (ipv6_ospf6_cost
,
1275 ipv6_ospf6_cost_cmd
,
1276 "ipv6 ospf6 cost (1-65535)",
1280 "Outgoing metric of this interface\n")
1282 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1284 struct ospf6_interface
*oi
;
1285 unsigned long int lcost
;
1289 oi
= (struct ospf6_interface
*)ifp
->info
;
1291 oi
= ospf6_interface_create(ifp
);
1294 lcost
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1296 if (lcost
> UINT32_MAX
) {
1297 vty_out(vty
, "Cost %ld is out of range\n", lcost
);
1298 return CMD_WARNING_CONFIG_FAILED
;
1301 if (oi
->cost
== lcost
)
1305 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1307 ospf6_interface_force_recalculate_cost(oi
);
1312 DEFUN (no_ipv6_ospf6_cost
,
1313 no_ipv6_ospf6_cost_cmd
,
1314 "no ipv6 ospf6 cost [(1-65535)]",
1318 "Calculate interface cost from bandwidth\n"
1319 "Outgoing metric of this interface\n")
1321 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1322 struct ospf6_interface
*oi
;
1325 oi
= (struct ospf6_interface
*)ifp
->info
;
1327 oi
= ospf6_interface_create(ifp
);
1330 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
);
1332 ospf6_interface_recalculate_cost(oi
);
1337 DEFUN (auto_cost_reference_bandwidth
,
1338 auto_cost_reference_bandwidth_cmd
,
1339 "auto-cost reference-bandwidth (1-4294967)",
1340 "Calculate OSPF interface cost according to bandwidth\n"
1341 "Use reference bandwidth method to assign OSPF cost\n"
1342 "The reference bandwidth in terms of Mbits per second\n")
1344 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1346 struct ospf6_area
*oa
;
1347 struct ospf6_interface
*oi
;
1348 struct listnode
*i
, *j
;
1351 refbw
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1352 if (refbw
< 1 || refbw
> 4294967) {
1353 vty_out(vty
, "reference-bandwidth value is invalid\n");
1354 return CMD_WARNING_CONFIG_FAILED
;
1357 /* If reference bandwidth is changed. */
1358 if ((refbw
) == o
->ref_bandwidth
)
1361 o
->ref_bandwidth
= refbw
;
1362 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1363 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1364 ospf6_interface_recalculate_cost(oi
);
1369 DEFUN (no_auto_cost_reference_bandwidth
,
1370 no_auto_cost_reference_bandwidth_cmd
,
1371 "no auto-cost reference-bandwidth [(1-4294967)]",
1373 "Calculate OSPF interface cost according to bandwidth\n"
1374 "Use reference bandwidth method to assign OSPF cost\n"
1375 "The reference bandwidth in terms of Mbits per second\n")
1377 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1378 struct ospf6_area
*oa
;
1379 struct ospf6_interface
*oi
;
1380 struct listnode
*i
, *j
;
1382 if (o
->ref_bandwidth
== OSPF6_REFERENCE_BANDWIDTH
)
1385 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
1386 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
))
1387 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
1388 ospf6_interface_recalculate_cost(oi
);
1394 DEFUN (ipv6_ospf6_hellointerval
,
1395 ipv6_ospf6_hellointerval_cmd
,
1396 "ipv6 ospf6 hello-interval (1-65535)",
1399 "Time between HELLO packets\n"
1402 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1404 struct ospf6_interface
*oi
;
1407 oi
= (struct ospf6_interface
*)ifp
->info
;
1409 oi
= ospf6_interface_create(ifp
);
1412 oi
->hello_interval
= strmatch(argv
[0]->text
, "no")
1413 ? OSPF_HELLO_INTERVAL_DEFAULT
1414 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1418 ALIAS (ipv6_ospf6_hellointerval
,
1419 no_ipv6_ospf6_hellointerval_cmd
,
1420 "no ipv6 ospf6 hello-interval [(1-65535)]",
1424 "Time between HELLO packets\n"
1427 /* interface variable set command */
1428 DEFUN (ipv6_ospf6_deadinterval
,
1429 ipv6_ospf6_deadinterval_cmd
,
1430 "ipv6 ospf6 dead-interval (1-65535)",
1433 "Interval time after which a neighbor is declared down\n"
1436 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1438 struct ospf6_interface
*oi
;
1441 oi
= (struct ospf6_interface
*)ifp
->info
;
1443 oi
= ospf6_interface_create(ifp
);
1446 oi
->dead_interval
= strmatch(argv
[0]->arg
, "no")
1447 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1448 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1452 ALIAS (ipv6_ospf6_deadinterval
,
1453 no_ipv6_ospf6_deadinterval_cmd
,
1454 "no ipv6 ospf6 dead-interval [(1-65535)]",
1458 "Interval time after which a neighbor is declared down\n"
1461 /* interface variable set command */
1462 DEFUN (ipv6_ospf6_transmitdelay
,
1463 ipv6_ospf6_transmitdelay_cmd
,
1464 "ipv6 ospf6 transmit-delay (1-3600)",
1467 "Link state transmit delay\n"
1470 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1472 struct ospf6_interface
*oi
;
1475 oi
= (struct ospf6_interface
*)ifp
->info
;
1477 oi
= ospf6_interface_create(ifp
);
1480 oi
->transdelay
= strmatch(argv
[0]->text
, "no")
1481 ? OSPF6_INTERFACE_TRANSDELAY
1482 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1486 ALIAS (ipv6_ospf6_transmitdelay
,
1487 no_ipv6_ospf6_transmitdelay_cmd
,
1488 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1492 "Link state transmit delay\n"
1495 /* interface variable set command */
1496 DEFUN (ipv6_ospf6_retransmitinterval
,
1497 ipv6_ospf6_retransmitinterval_cmd
,
1498 "ipv6 ospf6 retransmit-interval (1-65535)",
1501 "Time between retransmitting lost link state advertisements\n"
1504 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1506 struct ospf6_interface
*oi
;
1509 oi
= (struct ospf6_interface
*)ifp
->info
;
1511 oi
= ospf6_interface_create(ifp
);
1514 oi
->rxmt_interval
= strmatch(argv
[0]->text
, "no")
1515 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1516 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1520 ALIAS (ipv6_ospf6_retransmitinterval
,
1521 no_ipv6_ospf6_retransmitinterval_cmd
,
1522 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1526 "Time between retransmitting lost link state advertisements\n"
1529 /* interface variable set command */
1530 DEFUN (ipv6_ospf6_priority
,
1531 ipv6_ospf6_priority_cmd
,
1532 "ipv6 ospf6 priority (0-255)",
1538 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1540 struct ospf6_interface
*oi
;
1543 oi
= (struct ospf6_interface
*)ifp
->info
;
1545 oi
= ospf6_interface_create(ifp
);
1548 oi
->priority
= strmatch(argv
[0]->text
, "no")
1549 ? OSPF6_INTERFACE_PRIORITY
1550 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1552 if (oi
->area
&& (oi
->state
== OSPF6_INTERFACE_DROTHER
1553 || oi
->state
== OSPF6_INTERFACE_BDR
1554 || oi
->state
== OSPF6_INTERFACE_DR
))
1555 ospf6_interface_state_change(dr_election(oi
), oi
);
1560 ALIAS (ipv6_ospf6_priority
,
1561 no_ipv6_ospf6_priority_cmd
,
1562 "no ipv6 ospf6 priority [(0-255)]",
1569 DEFUN (ipv6_ospf6_instance
,
1570 ipv6_ospf6_instance_cmd
,
1571 "ipv6 ospf6 instance-id (0-255)",
1574 "Instance ID for this interface\n"
1575 "Instance ID value\n")
1577 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1579 struct ospf6_interface
*oi
;
1582 oi
= (struct ospf6_interface
*)ifp
->info
;
1584 oi
= ospf6_interface_create(ifp
);
1587 oi
->instance_id
= strmatch(argv
[0]->text
, "no")
1588 ? OSPF6_INTERFACE_INSTANCE_ID
1589 : strtoul(argv
[idx_number
]->arg
, NULL
, 10);
1593 ALIAS (ipv6_ospf6_instance
,
1594 no_ipv6_ospf6_instance_cmd
,
1595 "no ipv6 ospf6 instance-id [(0-255)]",
1599 "Instance ID for this interface\n"
1600 "Instance ID value\n")
1602 DEFUN (ipv6_ospf6_passive
,
1603 ipv6_ospf6_passive_cmd
,
1604 "ipv6 ospf6 passive",
1607 "Passive interface; no adjacency will be formed on this interface\n"
1610 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1611 struct ospf6_interface
*oi
;
1612 struct listnode
*node
, *nnode
;
1613 struct ospf6_neighbor
*on
;
1617 oi
= (struct ospf6_interface
*)ifp
->info
;
1619 oi
= ospf6_interface_create(ifp
);
1622 SET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1623 THREAD_OFF(oi
->thread_send_hello
);
1625 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1626 THREAD_OFF(on
->inactivity_timer
);
1627 thread_add_event(master
, inactivity_timer
, on
, 0, NULL
);
1633 DEFUN (no_ipv6_ospf6_passive
,
1634 no_ipv6_ospf6_passive_cmd
,
1635 "no ipv6 ospf6 passive",
1639 "passive interface: No Adjacency will be formed on this I/F\n"
1642 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1643 struct ospf6_interface
*oi
;
1646 oi
= (struct ospf6_interface
*)ifp
->info
;
1648 oi
= ospf6_interface_create(ifp
);
1651 UNSET_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
);
1652 THREAD_OFF(oi
->thread_send_hello
);
1653 oi
->thread_send_hello
= NULL
;
1654 thread_add_event(master
, ospf6_hello_send
, oi
, 0,
1655 &oi
->thread_send_hello
);
1660 DEFUN (ipv6_ospf6_mtu_ignore
,
1661 ipv6_ospf6_mtu_ignore_cmd
,
1662 "ipv6 ospf6 mtu-ignore",
1665 "Disable MTU mismatch detection on this interface\n"
1668 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1669 struct ospf6_interface
*oi
;
1672 oi
= (struct ospf6_interface
*)ifp
->info
;
1674 oi
= ospf6_interface_create(ifp
);
1682 DEFUN (no_ipv6_ospf6_mtu_ignore
,
1683 no_ipv6_ospf6_mtu_ignore_cmd
,
1684 "no ipv6 ospf6 mtu-ignore",
1688 "Disable MTU mismatch detection on this interface\n"
1691 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1692 struct ospf6_interface
*oi
;
1695 oi
= (struct ospf6_interface
*)ifp
->info
;
1697 oi
= ospf6_interface_create(ifp
);
1705 DEFUN (ipv6_ospf6_advertise_prefix_list
,
1706 ipv6_ospf6_advertise_prefix_list_cmd
,
1707 "ipv6 ospf6 advertise prefix-list WORD",
1710 "Advertising options\n"
1711 "Filter prefix using prefix-list\n"
1712 "Prefix list name\n"
1715 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1717 struct ospf6_interface
*oi
;
1720 oi
= (struct ospf6_interface
*)ifp
->info
;
1722 oi
= ospf6_interface_create(ifp
);
1726 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
1727 oi
->plist_name
= XSTRDUP(MTYPE_CFG_PLIST_NAME
, argv
[idx_word
]->arg
);
1729 ospf6_interface_connected_route_update(oi
->interface
);
1732 OSPF6_LINK_LSA_SCHEDULE(oi
);
1733 if (oi
->state
== OSPF6_INTERFACE_DR
) {
1734 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
1735 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
1737 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
1743 DEFUN (no_ipv6_ospf6_advertise_prefix_list
,
1744 no_ipv6_ospf6_advertise_prefix_list_cmd
,
1745 "no ipv6 ospf6 advertise prefix-list [WORD]",
1749 "Advertising options\n"
1750 "Filter prefix using prefix-list\n"
1751 "Prefix list name\n")
1753 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1754 struct ospf6_interface
*oi
;
1757 oi
= (struct ospf6_interface
*)ifp
->info
;
1759 oi
= ospf6_interface_create(ifp
);
1763 XFREE(MTYPE_CFG_PLIST_NAME
, oi
->plist_name
);
1765 ospf6_interface_connected_route_update(oi
->interface
);
1768 OSPF6_LINK_LSA_SCHEDULE(oi
);
1769 if (oi
->state
== OSPF6_INTERFACE_DR
) {
1770 OSPF6_NETWORK_LSA_SCHEDULE(oi
);
1771 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi
);
1773 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi
->area
);
1779 DEFUN (ipv6_ospf6_network
,
1780 ipv6_ospf6_network_cmd
,
1781 "ipv6 ospf6 network <broadcast|point-to-point>",
1785 "Specify OSPF6 broadcast network\n"
1786 "Specify OSPF6 point-to-point network\n"
1789 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1790 int idx_network
= 3;
1791 struct ospf6_interface
*oi
;
1794 oi
= (struct ospf6_interface
*)ifp
->info
;
1796 oi
= ospf6_interface_create(ifp
);
1800 if (strncmp(argv
[idx_network
]->arg
, "b", 1) == 0) {
1801 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1804 oi
->type
= OSPF_IFTYPE_BROADCAST
;
1805 } else if (strncmp(argv
[idx_network
]->arg
, "point-to-p", 10) == 0) {
1806 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
1809 oi
->type
= OSPF_IFTYPE_POINTOPOINT
;
1812 /* Reset the interface */
1813 thread_add_event(master
, interface_down
, oi
, 0, NULL
);
1814 thread_add_event(master
, interface_up
, oi
, 0, NULL
);
1819 DEFUN (no_ipv6_ospf6_network
,
1820 no_ipv6_ospf6_network_cmd
,
1821 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
1825 "Set default network type\n"
1826 "Specify OSPF6 broadcast network\n"
1827 "Specify OSPF6 point-to-point network\n")
1829 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1830 struct ospf6_interface
*oi
;
1835 oi
= (struct ospf6_interface
*)ifp
->info
;
1840 type
= ospf6_default_iftype(ifp
);
1841 if (oi
->type
== type
) {
1846 /* Reset the interface */
1847 thread_add_event(master
, interface_down
, oi
, 0, NULL
);
1848 thread_add_event(master
, interface_up
, oi
, 0, NULL
);
1853 static int config_write_ospf6_interface(struct vty
*vty
)
1855 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1856 struct ospf6_interface
*oi
;
1857 struct interface
*ifp
;
1859 FOR_ALL_INTERFACES (vrf
, ifp
) {
1860 oi
= (struct ospf6_interface
*)ifp
->info
;
1864 vty_frame(vty
, "interface %s\n", oi
->interface
->name
);
1867 vty_out(vty
, " description %s\n", ifp
->desc
);
1869 vty_out(vty
, " ipv6 ospf6 ifmtu %d\n", oi
->c_ifmtu
);
1871 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_NOAUTOCOST
))
1872 vty_out(vty
, " ipv6 ospf6 cost %d\n", oi
->cost
);
1874 if (oi
->hello_interval
!= OSPF6_INTERFACE_HELLO_INTERVAL
)
1875 vty_out(vty
, " ipv6 ospf6 hello-interval %d\n",
1876 oi
->hello_interval
);
1878 if (oi
->dead_interval
!= OSPF6_INTERFACE_DEAD_INTERVAL
)
1879 vty_out(vty
, " ipv6 ospf6 dead-interval %d\n",
1882 if (oi
->rxmt_interval
!= OSPF6_INTERFACE_RXMT_INTERVAL
)
1883 vty_out(vty
, " ipv6 ospf6 retransmit-interval %d\n",
1886 if (oi
->priority
!= OSPF6_INTERFACE_PRIORITY
)
1887 vty_out(vty
, " ipv6 ospf6 priority %d\n", oi
->priority
);
1889 if (oi
->transdelay
!= OSPF6_INTERFACE_TRANSDELAY
)
1890 vty_out(vty
, " ipv6 ospf6 transmit-delay %d\n",
1893 if (oi
->instance_id
!= OSPF6_INTERFACE_INSTANCE_ID
)
1894 vty_out(vty
, " ipv6 ospf6 instance-id %d\n",
1898 vty_out(vty
, " ipv6 ospf6 advertise prefix-list %s\n",
1901 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
1902 vty_out(vty
, " ipv6 ospf6 passive\n");
1905 vty_out(vty
, " ipv6 ospf6 mtu-ignore\n");
1907 if (oi
->type
!= ospf6_default_iftype(ifp
)) {
1908 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
1910 " ipv6 ospf6 network point-to-point\n");
1911 else if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1912 vty_out(vty
, " ipv6 ospf6 network broadcast\n");
1915 ospf6_bfd_write_config(vty
, oi
);
1917 vty_endframe(vty
, "!\n");
1922 static struct cmd_node interface_node
= {
1923 INTERFACE_NODE
, "%s(config-if)# ", 1 /* VTYSH */
1926 void ospf6_interface_init(void)
1928 /* Install interface node. */
1929 install_node(&interface_node
, config_write_ospf6_interface
);
1932 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_prefix_cmd
);
1933 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_ifname_cmd
);
1934 install_element(VIEW_NODE
,
1935 &show_ipv6_ospf6_interface_ifname_prefix_cmd
);
1936 install_element(VIEW_NODE
, &show_ipv6_ospf6_interface_traffic_cmd
);
1938 install_element(INTERFACE_NODE
, &ipv6_ospf6_cost_cmd
);
1939 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_cost_cmd
);
1940 install_element(INTERFACE_NODE
, &ipv6_ospf6_ifmtu_cmd
);
1941 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_ifmtu_cmd
);
1943 install_element(INTERFACE_NODE
, &ipv6_ospf6_deadinterval_cmd
);
1944 install_element(INTERFACE_NODE
, &ipv6_ospf6_hellointerval_cmd
);
1945 install_element(INTERFACE_NODE
, &ipv6_ospf6_priority_cmd
);
1946 install_element(INTERFACE_NODE
, &ipv6_ospf6_retransmitinterval_cmd
);
1947 install_element(INTERFACE_NODE
, &ipv6_ospf6_transmitdelay_cmd
);
1948 install_element(INTERFACE_NODE
, &ipv6_ospf6_instance_cmd
);
1949 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_deadinterval_cmd
);
1950 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_hellointerval_cmd
);
1951 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_priority_cmd
);
1952 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_retransmitinterval_cmd
);
1953 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_transmitdelay_cmd
);
1954 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_instance_cmd
);
1956 install_element(INTERFACE_NODE
, &ipv6_ospf6_passive_cmd
);
1957 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_passive_cmd
);
1959 install_element(INTERFACE_NODE
, &ipv6_ospf6_mtu_ignore_cmd
);
1960 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_mtu_ignore_cmd
);
1962 install_element(INTERFACE_NODE
, &ipv6_ospf6_advertise_prefix_list_cmd
);
1963 install_element(INTERFACE_NODE
,
1964 &no_ipv6_ospf6_advertise_prefix_list_cmd
);
1966 install_element(INTERFACE_NODE
, &ipv6_ospf6_network_cmd
);
1967 install_element(INTERFACE_NODE
, &no_ipv6_ospf6_network_cmd
);
1969 /* reference bandwidth commands */
1970 install_element(OSPF6_NODE
, &auto_cost_reference_bandwidth_cmd
);
1971 install_element(OSPF6_NODE
, &no_auto_cost_reference_bandwidth_cmd
);
1974 /* Clear the specified interface structure */
1975 static void ospf6_interface_clear(struct vty
*vty
, struct interface
*ifp
)
1977 struct ospf6_interface
*oi
;
1979 if (!if_is_operative(ifp
))
1982 if (ifp
->info
== NULL
)
1985 oi
= (struct ospf6_interface
*)ifp
->info
;
1987 if (IS_OSPF6_DEBUG_INTERFACE
)
1988 zlog_debug("Interface %s: clear by reset", ifp
->name
);
1990 /* Reset the interface */
1991 thread_add_event(master
, interface_down
, oi
, 0, NULL
);
1992 thread_add_event(master
, interface_up
, oi
, 0, NULL
);
1995 /* Clear interface */
1996 DEFUN (clear_ipv6_ospf6_interface
,
1997 clear_ipv6_ospf6_interface_cmd
,
1998 "clear ipv6 ospf6 interface [IFNAME]",
2006 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2008 struct interface
*ifp
;
2010 if (argc
== 4) /* Clear all the ospfv3 interfaces. */
2012 FOR_ALL_INTERFACES (vrf
, ifp
)
2013 ospf6_interface_clear(vty
, ifp
);
2014 } else /* Interface name is specified. */
2016 if ((ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
,
2019 vty_out(vty
, "No such Interface: %s\n",
2020 argv
[idx_ifname
]->arg
);
2023 ospf6_interface_clear(vty
, ifp
);
2029 void install_element_ospf6_clear_interface(void)
2031 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_interface_cmd
);
2034 DEFUN (debug_ospf6_interface
,
2035 debug_ospf6_interface_cmd
,
2036 "debug ospf6 interface",
2039 "Debug OSPFv3 Interface\n"
2042 OSPF6_DEBUG_INTERFACE_ON();
2046 DEFUN (no_debug_ospf6_interface
,
2047 no_debug_ospf6_interface_cmd
,
2048 "no debug ospf6 interface",
2052 "Debug OSPFv3 Interface\n"
2055 OSPF6_DEBUG_INTERFACE_OFF();
2059 int config_write_ospf6_debug_interface(struct vty
*vty
)
2061 if (IS_OSPF6_DEBUG_INTERFACE
)
2062 vty_out(vty
, "debug ospf6 interface\n");
2066 void install_element_ospf6_debug_interface(void)
2068 install_element(ENABLE_NODE
, &debug_ospf6_interface_cmd
);
2069 install_element(ENABLE_NODE
, &no_debug_ospf6_interface_cmd
);
2070 install_element(CONFIG_NODE
, &debug_ospf6_interface_cmd
);
2071 install_element(CONFIG_NODE
, &no_debug_ospf6_interface_cmd
);