]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_interface.c
Merge pull request #3792 from donaldsharp/pbr_massacre_at_5
[mirror_frr.git] / ospf6d / ospf6_interface.c
1 /*
2 * Copyright (C) 2003 Yasuhiro Ohara
3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
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
19 */
20
21 #include <zebra.h>
22
23 #include "memory.h"
24 #include "if.h"
25 #include "log.h"
26 #include "command.h"
27 #include "thread.h"
28 #include "prefix.h"
29 #include "plist.h"
30 #include "zclient.h"
31
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"
43 #include "ospf6d.h"
44 #include "ospf6_bfd.h"
45
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))
51
52 unsigned char conf_debug_ospf6_interface = 0;
53
54 const char *ospf6_interface_state_str[] = {
55 "None", "Down", "Loopback", "Waiting", "PointToPoint",
56 "DROther", "BDR", "DR", NULL};
57
58 struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex)
59 {
60 struct ospf6_interface *oi;
61 struct interface *ifp;
62
63 ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
64 if (ifp == NULL)
65 return (struct ospf6_interface *)NULL;
66
67 oi = (struct ospf6_interface *)ifp->info;
68 return oi;
69 }
70
71 /* schedule routing table recalculation */
72 static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa,
73 unsigned int reason)
74 {
75 struct ospf6_interface *oi;
76
77 if (lsa == NULL)
78 return;
79
80 oi = lsa->lsdb->data;
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);
85 if (oi->area)
86 ospf6_spf_schedule(oi->area->ospf6, reason);
87 break;
88
89 default:
90 break;
91 }
92 }
93
94 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa *lsa)
95 {
96 ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa));
97 }
98
99 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa *lsa)
100 {
101 ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa));
102 }
103
104 static uint8_t ospf6_default_iftype(struct interface *ifp)
105 {
106 if (if_is_pointopoint(ifp))
107 return OSPF_IFTYPE_POINTOPOINT;
108 else if (if_is_loopback(ifp))
109 return OSPF_IFTYPE_LOOPBACK;
110 else
111 return OSPF_IFTYPE_BROADCAST;
112 }
113
114 static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
115 {
116 /* If all else fails, use default OSPF cost */
117 uint32_t cost;
118 uint32_t bw, refbw;
119
120 /* interface speed and bw can be 0 in some platforms,
121 * use ospf default bw. If bw is configured then it would
122 * be used.
123 */
124 if (!oi->interface->bandwidth && oi->interface->speed) {
125 bw = oi->interface->speed;
126 } else {
127 bw = oi->interface->bandwidth ? oi->interface->bandwidth
128 : OSPF6_INTERFACE_BANDWIDTH;
129 }
130
131 refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
132
133 /* A specifed ip ospf cost overrides a calculated one. */
134 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
135 cost = oi->cost;
136 else {
137 cost = (uint32_t)((double)refbw / (double)bw + (double)0.5);
138 if (cost < 1)
139 cost = 1;
140 else if (cost > UINT32_MAX)
141 cost = UINT32_MAX;
142 }
143
144 return cost;
145 }
146
147 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface *oi)
148 {
149 /* update cost held in route_connected list in ospf6_interface */
150 ospf6_interface_connected_route_update(oi->interface);
151
152 /* execute LSA hooks */
153 if (oi->area) {
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);
159 }
160 }
161
162 static void ospf6_interface_recalculate_cost(struct ospf6_interface *oi)
163 {
164 uint32_t newcost;
165
166 newcost = ospf6_interface_get_cost(oi);
167 if (newcost == oi->cost)
168 return;
169 oi->cost = newcost;
170
171 ospf6_interface_force_recalculate_cost(oi);
172 }
173
174 /* Create new ospf6 interface structure */
175 struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
176 {
177 struct ospf6_interface *oi;
178 unsigned int iobuflen;
179
180 oi = (struct ospf6_interface *)XCALLOC(MTYPE_OSPF6_IF,
181 sizeof(struct ospf6_interface));
182
183 oi->area = (struct ospf6_area *)NULL;
184 oi->neighbor_list = list_new();
185 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
186 oi->linklocal_addr = (struct in6_addr *)NULL;
187 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
188 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
189 oi->priority = OSPF6_INTERFACE_PRIORITY;
190
191 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
192 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
193 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
194 oi->type = ospf6_default_iftype(ifp);
195 oi->state = OSPF6_INTERFACE_DOWN;
196 oi->flag = 0;
197 oi->mtu_ignore = 0;
198 oi->c_ifmtu = 0;
199
200 /* Try to adjust I/O buffer size with IfMtu */
201 oi->ifmtu = ifp->mtu6;
202 iobuflen = ospf6_iobuf_size(ifp->mtu6);
203 if (oi->ifmtu > iobuflen) {
204 if (IS_OSPF6_DEBUG_INTERFACE)
205 zlog_debug(
206 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
207 ifp->name, iobuflen);
208 oi->ifmtu = iobuflen;
209 }
210
211 QOBJ_REG(oi, ospf6_interface);
212
213 oi->lsupdate_list = ospf6_lsdb_create(oi);
214 oi->lsack_list = ospf6_lsdb_create(oi);
215 oi->lsdb = ospf6_lsdb_create(oi);
216 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
217 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
218 oi->lsdb_self = ospf6_lsdb_create(oi);
219
220 oi->route_connected =
221 OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
222 oi->route_connected->scope = oi;
223
224 /* link both */
225 oi->interface = ifp;
226 ifp->info = oi;
227
228 /* Compute cost. */
229 oi->cost = ospf6_interface_get_cost(oi);
230
231 return oi;
232 }
233
234 void ospf6_interface_delete(struct ospf6_interface *oi)
235 {
236 struct listnode *node, *nnode;
237 struct ospf6_neighbor *on;
238
239 QOBJ_UNREG(oi);
240
241 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
242 ospf6_neighbor_delete(on);
243
244 list_delete(&oi->neighbor_list);
245
246 THREAD_OFF(oi->thread_send_hello);
247 THREAD_OFF(oi->thread_send_lsupdate);
248 THREAD_OFF(oi->thread_send_lsack);
249 THREAD_OFF(oi->thread_sso);
250
251 ospf6_lsdb_remove_all(oi->lsdb);
252 ospf6_lsdb_remove_all(oi->lsupdate_list);
253 ospf6_lsdb_remove_all(oi->lsack_list);
254
255 ospf6_lsdb_delete(oi->lsdb);
256 ospf6_lsdb_delete(oi->lsdb_self);
257
258 ospf6_lsdb_delete(oi->lsupdate_list);
259 ospf6_lsdb_delete(oi->lsack_list);
260
261 ospf6_route_table_delete(oi->route_connected);
262
263 /* cut link */
264 oi->interface->info = NULL;
265
266 /* plist_name */
267 if (oi->plist_name)
268 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
269
270 ospf6_bfd_info_free(&(oi->bfd_info));
271
272 /* disable from area list if possible */
273 ospf6_area_interface_delete(oi);
274
275 XFREE(MTYPE_OSPF6_IF, oi);
276 }
277
278 void ospf6_interface_enable(struct ospf6_interface *oi)
279 {
280 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
281 ospf6_interface_state_update(oi->interface);
282 }
283
284 void ospf6_interface_disable(struct ospf6_interface *oi)
285 {
286 SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
287
288 thread_execute(master, interface_down, oi, 0);
289
290 ospf6_lsdb_remove_all(oi->lsdb);
291 ospf6_lsdb_remove_all(oi->lsdb_self);
292 ospf6_lsdb_remove_all(oi->lsupdate_list);
293 ospf6_lsdb_remove_all(oi->lsack_list);
294
295 THREAD_OFF(oi->thread_send_hello);
296 THREAD_OFF(oi->thread_send_lsupdate);
297 THREAD_OFF(oi->thread_send_lsack);
298 THREAD_OFF(oi->thread_sso);
299
300 THREAD_OFF(oi->thread_network_lsa);
301 THREAD_OFF(oi->thread_link_lsa);
302 THREAD_OFF(oi->thread_intra_prefix_lsa);
303 THREAD_OFF(oi->thread_as_extern_lsa);
304 }
305
306 static struct in6_addr *
307 ospf6_interface_get_linklocal_address(struct interface *ifp)
308 {
309 struct listnode *n;
310 struct connected *c;
311 struct in6_addr *l = (struct in6_addr *)NULL;
312
313 /* for each connected address */
314 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
315 /* if family not AF_INET6, ignore */
316 if (c->address->family != AF_INET6)
317 continue;
318
319 /* linklocal scope check */
320 if (IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
321 l = &c->address->u.prefix6;
322 }
323 return l;
324 }
325
326 void ospf6_interface_if_add(struct interface *ifp)
327 {
328 struct ospf6_interface *oi;
329 unsigned int iobuflen;
330
331 oi = (struct ospf6_interface *)ifp->info;
332 if (oi == NULL)
333 return;
334
335 /* Try to adjust I/O buffer size with IfMtu */
336 if (oi->ifmtu == 0)
337 oi->ifmtu = ifp->mtu6;
338 iobuflen = ospf6_iobuf_size(ifp->mtu6);
339 if (oi->ifmtu > iobuflen) {
340 if (IS_OSPF6_DEBUG_INTERFACE)
341 zlog_debug(
342 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
343 ifp->name, iobuflen);
344 oi->ifmtu = iobuflen;
345 }
346
347 /* interface start */
348 ospf6_interface_state_update(oi->interface);
349 }
350
351 void ospf6_interface_state_update(struct interface *ifp)
352 {
353 struct ospf6_interface *oi;
354 unsigned int iobuflen;
355
356 oi = (struct ospf6_interface *)ifp->info;
357 if (oi == NULL)
358 return;
359 if (oi->area == NULL)
360 return;
361 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
362 return;
363
364 /* Adjust the mtu values if the kernel told us something new */
365 if (ifp->mtu6 != oi->ifmtu) {
366 /* If nothing configured, accept it and check for buffer size */
367 if (!oi->c_ifmtu) {
368 oi->ifmtu = ifp->mtu6;
369 iobuflen = ospf6_iobuf_size(ifp->mtu6);
370 if (oi->ifmtu > iobuflen) {
371 if (IS_OSPF6_DEBUG_INTERFACE)
372 zlog_debug(
373 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
374 ifp->name, iobuflen);
375 oi->ifmtu = iobuflen;
376 }
377 } else if (oi->c_ifmtu > ifp->mtu6) {
378 oi->ifmtu = ifp->mtu6;
379 zlog_warn(
380 "Configured mtu %u on %s overridden by kernel %u",
381 oi->c_ifmtu, ifp->name, ifp->mtu6);
382 } else
383 oi->ifmtu = oi->c_ifmtu;
384 }
385
386 if (if_is_operative(ifp)
387 && (ospf6_interface_get_linklocal_address(oi->interface)
388 || if_is_loopback(oi->interface)))
389 thread_execute(master, interface_up, oi, 0);
390 else
391 thread_execute(master, interface_down, oi, 0);
392
393 return;
394 }
395
396 void ospf6_interface_connected_route_update(struct interface *ifp)
397 {
398 struct ospf6_interface *oi;
399 struct ospf6_route *route;
400 struct connected *c;
401 struct listnode *node, *nnode;
402 struct in6_addr nh_addr;
403
404 oi = (struct ospf6_interface *)ifp->info;
405 if (oi == NULL)
406 return;
407
408 /* reset linklocal pointer */
409 oi->linklocal_addr = ospf6_interface_get_linklocal_address(ifp);
410
411 /* if area is null, do not make connected-route list */
412 if (oi->area == NULL)
413 return;
414
415 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
416 return;
417
418 /* update "route to advertise" interface route table */
419 ospf6_route_remove_all(oi->route_connected);
420
421 for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
422 if (c->address->family != AF_INET6)
423 continue;
424
425 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE,
426 c->address);
427 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE,
428 c->address);
429 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE,
430 c->address);
431 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE,
432 c->address);
433 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE,
434 c->address);
435
436 /* apply filter */
437 if (oi->plist_name) {
438 struct prefix_list *plist;
439 enum prefix_list_type ret;
440 char buf[PREFIX2STR_BUFFER];
441
442 prefix2str(c->address, buf, sizeof(buf));
443 plist = prefix_list_lookup(AFI_IP6, oi->plist_name);
444 ret = prefix_list_apply(plist, (void *)c->address);
445 if (ret == PREFIX_DENY) {
446 if (IS_OSPF6_DEBUG_INTERFACE)
447 zlog_debug(
448 "%s on %s filtered by prefix-list %s ",
449 buf, oi->interface->name,
450 oi->plist_name);
451 continue;
452 }
453 }
454
455 route = ospf6_route_create();
456 memcpy(&route->prefix, c->address, sizeof(struct prefix));
457 apply_mask(&route->prefix);
458 route->type = OSPF6_DEST_TYPE_NETWORK;
459 route->path.area_id = oi->area->area_id;
460 route->path.type = OSPF6_PATH_TYPE_INTRA;
461 route->path.cost = oi->cost;
462 inet_pton(AF_INET6, "::1", &nh_addr);
463 ospf6_route_add_nexthop(route, oi->interface->ifindex,
464 &nh_addr);
465 ospf6_route_add(route, oi->route_connected);
466 }
467
468 /* create new Link-LSA */
469 OSPF6_LINK_LSA_SCHEDULE(oi);
470 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
471 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
472 }
473
474 static void ospf6_interface_state_change(uint8_t next_state,
475 struct ospf6_interface *oi)
476 {
477 uint8_t prev_state;
478
479 prev_state = oi->state;
480 oi->state = next_state;
481
482 if (prev_state == next_state)
483 return;
484
485 /* log */
486 if (IS_OSPF6_DEBUG_INTERFACE) {
487 zlog_debug("Interface state change %s: %s -> %s",
488 oi->interface->name,
489 ospf6_interface_state_str[prev_state],
490 ospf6_interface_state_str[next_state]);
491 }
492 oi->state_change++;
493
494 if ((prev_state == OSPF6_INTERFACE_DR
495 || prev_state == OSPF6_INTERFACE_BDR)
496 && (next_state != OSPF6_INTERFACE_DR
497 && next_state != OSPF6_INTERFACE_BDR))
498 ospf6_sso(oi->interface->ifindex, &alldrouters6,
499 IPV6_LEAVE_GROUP);
500
501 if ((prev_state != OSPF6_INTERFACE_DR
502 && prev_state != OSPF6_INTERFACE_BDR)
503 && (next_state == OSPF6_INTERFACE_DR
504 || next_state == OSPF6_INTERFACE_BDR))
505 ospf6_sso(oi->interface->ifindex, &alldrouters6,
506 IPV6_JOIN_GROUP);
507
508 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
509 if (next_state == OSPF6_INTERFACE_DOWN) {
510 OSPF6_NETWORK_LSA_EXECUTE(oi);
511 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
512 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
513 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
514 } else if (prev_state == OSPF6_INTERFACE_DR
515 || next_state == OSPF6_INTERFACE_DR) {
516 OSPF6_NETWORK_LSA_SCHEDULE(oi);
517 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
518 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
519 }
520
521 hook_call(ospf6_interface_change, oi, next_state, prev_state);
522 }
523
524
525 /* DR Election, RFC2328 section 9.4 */
526
527 #define IS_ELIGIBLE(n) \
528 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
529
530 static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a,
531 struct ospf6_neighbor *b)
532 {
533 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
534 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id))
535 return NULL;
536 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
537 return b;
538 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)
539 return a;
540
541 if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
542 return a;
543 if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
544 return b;
545
546 if (a->priority > b->priority)
547 return a;
548 if (a->priority < b->priority)
549 return b;
550
551 if (ntohl(a->router_id) > ntohl(b->router_id))
552 return a;
553 if (ntohl(a->router_id) < ntohl(b->router_id))
554 return b;
555
556 zlog_warn("Router-ID duplicate ?");
557 return a;
558 }
559
560 static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
561 struct ospf6_neighbor *b)
562 {
563 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
564 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id))
565 return NULL;
566 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
567 return b;
568 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)
569 return a;
570
571 if (a->drouter == a->router_id && b->drouter != b->router_id)
572 return a;
573 if (a->drouter != a->router_id && b->drouter == b->router_id)
574 return b;
575
576 if (a->priority > b->priority)
577 return a;
578 if (a->priority < b->priority)
579 return b;
580
581 if (ntohl(a->router_id) > ntohl(b->router_id))
582 return a;
583 if (ntohl(a->router_id) < ntohl(b->router_id))
584 return b;
585
586 zlog_warn("Router-ID duplicate ?");
587 return a;
588 }
589
590 static uint8_t dr_election(struct ospf6_interface *oi)
591 {
592 struct listnode *node, *nnode;
593 struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
594 struct ospf6_neighbor *best_drouter, *best_bdrouter;
595 uint8_t next_state = 0;
596
597 drouter = bdrouter = NULL;
598 best_drouter = best_bdrouter = NULL;
599
600 /* pseudo neighbor myself, including noting current DR/BDR (1) */
601 memset(&myself, 0, sizeof(myself));
602 inet_ntop(AF_INET, &oi->area->ospf6->router_id, myself.name,
603 sizeof(myself.name));
604 myself.state = OSPF6_NEIGHBOR_TWOWAY;
605 myself.drouter = oi->drouter;
606 myself.bdrouter = oi->bdrouter;
607 myself.priority = oi->priority;
608 myself.router_id = oi->area->ospf6->router_id;
609
610 /* Electing BDR (2) */
611 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
612 bdrouter = better_bdrouter(bdrouter, on);
613
614 best_bdrouter = bdrouter;
615 bdrouter = better_bdrouter(best_bdrouter, &myself);
616
617 /* Electing DR (3) */
618 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
619 drouter = better_drouter(drouter, on);
620
621 best_drouter = drouter;
622 drouter = better_drouter(best_drouter, &myself);
623 if (drouter == NULL)
624 drouter = bdrouter;
625
626 /* the router itself is newly/no longer DR/BDR (4) */
627 if ((drouter == &myself && myself.drouter != myself.router_id)
628 || (drouter != &myself && myself.drouter == myself.router_id)
629 || (bdrouter == &myself && myself.bdrouter != myself.router_id)
630 || (bdrouter != &myself && myself.bdrouter == myself.router_id)) {
631 myself.drouter = (drouter ? drouter->router_id : htonl(0));
632 myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
633
634 /* compatible to Electing BDR (2) */
635 bdrouter = better_bdrouter(best_bdrouter, &myself);
636
637 /* compatible to Electing DR (3) */
638 drouter = better_drouter(best_drouter, &myself);
639 if (drouter == NULL)
640 drouter = bdrouter;
641 }
642
643 /* Set interface state accordingly (5) */
644 if (drouter && drouter == &myself)
645 next_state = OSPF6_INTERFACE_DR;
646 else if (bdrouter && bdrouter == &myself)
647 next_state = OSPF6_INTERFACE_BDR;
648 else
649 next_state = OSPF6_INTERFACE_DROTHER;
650
651 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
652 /* XXX */
653
654 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
655 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
656 accordingly after AdjOK */
657 if (oi->drouter != (drouter ? drouter->router_id : htonl(0))
658 || oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0))) {
659 if (IS_OSPF6_DEBUG_INTERFACE)
660 zlog_debug("DR Election on %s: DR: %s BDR: %s",
661 oi->interface->name,
662 (drouter ? drouter->name : "0.0.0.0"),
663 (bdrouter ? bdrouter->name : "0.0.0.0"));
664
665 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) {
666 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
667 continue;
668 /* Schedule AdjOK. */
669 thread_add_event(master, adj_ok, on, 0, NULL);
670 }
671 }
672
673 oi->drouter = (drouter ? drouter->router_id : htonl(0));
674 oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
675 return next_state;
676 }
677
678
679 /* Interface State Machine */
680 int interface_up(struct thread *thread)
681 {
682 struct ospf6_interface *oi;
683
684 oi = (struct ospf6_interface *)THREAD_ARG(thread);
685 assert(oi && oi->interface);
686
687 /*
688 * Remove old pointer. If this thread wasn't a timer this
689 * operation won't make a difference, because it is already NULL.
690 */
691 oi->thread_sso = NULL;
692
693 if (IS_OSPF6_DEBUG_INTERFACE)
694 zlog_debug("Interface Event %s: [InterfaceUp]",
695 oi->interface->name);
696
697 /* check physical interface is up */
698 if (!if_is_operative(oi->interface)) {
699 if (IS_OSPF6_DEBUG_INTERFACE)
700 zlog_debug(
701 "Interface %s is down, can't execute [InterfaceUp]",
702 oi->interface->name);
703 return 0;
704 }
705
706 /* check interface has a link-local address */
707 if (!(ospf6_interface_get_linklocal_address(oi->interface)
708 || if_is_loopback(oi->interface))) {
709 if (IS_OSPF6_DEBUG_INTERFACE)
710 zlog_debug(
711 "Interface %s has no link local address, can't execute [InterfaceUp]",
712 oi->interface->name);
713 return 0;
714 }
715
716 /* Recompute cost */
717 ospf6_interface_recalculate_cost(oi);
718
719 /* if already enabled, do nothing */
720 if (oi->state > OSPF6_INTERFACE_DOWN) {
721 if (IS_OSPF6_DEBUG_INTERFACE)
722 zlog_debug("Interface %s already enabled",
723 oi->interface->name);
724 return 0;
725 }
726
727 /* If no area assigned, return */
728 if (oi->area == NULL) {
729 zlog_debug(
730 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
731 __func__, oi->interface->name);
732 return 0;
733 }
734
735 #ifdef __FreeBSD__
736 /*
737 * XXX: Schedule IPv6 group join for later, otherwise we might
738 * lose the multicast group registration caused by IPv6 group
739 * leave race.
740 */
741 if (oi->sso_try_cnt == 0) {
742 oi->sso_try_cnt++;
743 zlog_info("Scheduling %s for sso", oi->interface->name);
744 thread_add_timer(master, interface_up, oi,
745 OSPF6_INTERFACE_SSO_RETRY_INT,
746 &oi->thread_sso);
747 return 0;
748 }
749 #endif /* __FreeBSD__ */
750
751 /* Join AllSPFRouters */
752 if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP)
753 < 0) {
754 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
755 zlog_info(
756 "Scheduling %s for sso retry, trial count: %d",
757 oi->interface->name, oi->sso_try_cnt);
758 thread_add_timer(master, interface_up, oi,
759 OSPF6_INTERFACE_SSO_RETRY_INT,
760 &oi->thread_sso);
761 }
762 return 0;
763 }
764 oi->sso_try_cnt = 0; /* Reset on success */
765
766 /* Update interface route */
767 ospf6_interface_connected_route_update(oi->interface);
768
769 /* Schedule Hello */
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);
775 }
776
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);
783 else {
784 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
785 thread_add_timer(master, wait_timer, oi, oi->dead_interval,
786 NULL);
787 }
788
789 return 0;
790 }
791
792 int wait_timer(struct thread *thread)
793 {
794 struct ospf6_interface *oi;
795
796 oi = (struct ospf6_interface *)THREAD_ARG(thread);
797 assert(oi && oi->interface);
798
799 if (IS_OSPF6_DEBUG_INTERFACE)
800 zlog_debug("Interface Event %s: [WaitTimer]",
801 oi->interface->name);
802
803 if (oi->state == OSPF6_INTERFACE_WAITING)
804 ospf6_interface_state_change(dr_election(oi), oi);
805
806 return 0;
807 }
808
809 int backup_seen(struct thread *thread)
810 {
811 struct ospf6_interface *oi;
812
813 oi = (struct ospf6_interface *)THREAD_ARG(thread);
814 assert(oi && oi->interface);
815
816 if (IS_OSPF6_DEBUG_INTERFACE)
817 zlog_debug("Interface Event %s: [BackupSeen]",
818 oi->interface->name);
819
820 if (oi->state == OSPF6_INTERFACE_WAITING)
821 ospf6_interface_state_change(dr_election(oi), oi);
822
823 return 0;
824 }
825
826 int neighbor_change(struct thread *thread)
827 {
828 struct ospf6_interface *oi;
829
830 oi = (struct ospf6_interface *)THREAD_ARG(thread);
831 assert(oi && oi->interface);
832
833 if (IS_OSPF6_DEBUG_INTERFACE)
834 zlog_debug("Interface Event %s: [NeighborChange]",
835 oi->interface->name);
836
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);
841
842 return 0;
843 }
844
845 int interface_down(struct thread *thread)
846 {
847 struct ospf6_interface *oi;
848 struct listnode *node, *nnode;
849 struct ospf6_neighbor *on;
850
851 oi = (struct ospf6_interface *)THREAD_ARG(thread);
852 assert(oi && oi->interface);
853
854 if (IS_OSPF6_DEBUG_INTERFACE)
855 zlog_debug("Interface Event %s: [InterfaceDown]",
856 oi->interface->name);
857
858 /* Stop Hellos */
859 THREAD_OFF(oi->thread_send_hello);
860
861 /* Stop trying to set socket options. */
862 THREAD_OFF(oi->thread_sso);
863
864 /* Leave AllSPFRouters */
865 if (oi->state > OSPF6_INTERFACE_DOWN)
866 ospf6_sso(oi->interface->ifindex, &allspfrouters6,
867 IPV6_LEAVE_GROUP);
868
869 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
870
871 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
872 ospf6_neighbor_delete(on);
873
874 list_delete_all_node(oi->neighbor_list);
875
876 /* When interface state is reset, also reset information about
877 * DR election, as it is no longer valid. */
878 oi->drouter = oi->prev_drouter = htonl(0);
879 oi->bdrouter = oi->prev_bdrouter = htonl(0);
880 return 0;
881 }
882
883
884 /* show specified interface structure */
885 static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
886 {
887 struct ospf6_interface *oi;
888 struct connected *c;
889 struct prefix *p;
890 struct listnode *i;
891 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
892 const char *type;
893 struct timeval res, now;
894 char duration[32];
895 struct ospf6_lsa *lsa;
896
897 /* check physical interface type */
898 if (if_is_loopback(ifp))
899 type = "LOOPBACK";
900 else if (if_is_broadcast(ifp))
901 type = "BROADCAST";
902 else if (if_is_pointopoint(ifp))
903 type = "POINTOPOINT";
904 else
905 type = "UNKNOWN";
906
907 vty_out(vty, "%s is %s, type %s\n", ifp->name,
908 (if_is_operative(ifp) ? "up" : "down"), type);
909 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
910
911 if (ifp->info == NULL) {
912 vty_out(vty, " OSPF not enabled on this interface\n");
913 return 0;
914 } else
915 oi = (struct ospf6_interface *)ifp->info;
916
917 vty_out(vty, " Internet Address:\n");
918
919 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
920 p = c->address;
921 prefix2str(p, strbuf, sizeof(strbuf));
922 switch (p->family) {
923 case AF_INET:
924 vty_out(vty, " inet : %s\n", strbuf);
925 break;
926 case AF_INET6:
927 vty_out(vty, " inet6: %s\n", strbuf);
928 break;
929 default:
930 vty_out(vty, " ??? : %s\n", strbuf);
931 break;
932 }
933 }
934
935 if (oi->area) {
936 vty_out(vty,
937 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
938 oi->instance_id, oi->ifmtu, ifp->mtu6);
939 vty_out(vty, " MTU mismatch detection: %s\n",
940 oi->mtu_ignore ? "disabled" : "enabled");
941 inet_ntop(AF_INET, &oi->area->area_id, strbuf, sizeof(strbuf));
942 vty_out(vty, " Area ID %s, Cost %u\n", strbuf, oi->cost);
943 } else
944 vty_out(vty, " Not Attached to Area\n");
945
946 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
947 ospf6_interface_state_str[oi->state], oi->transdelay,
948 oi->priority);
949 vty_out(vty, " Timer intervals configured:\n");
950 vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
951 oi->hello_interval, oi->dead_interval, oi->rxmt_interval);
952
953 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
954 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
955 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
956
957 vty_out(vty, " Number of I/F scoped LSAs is %u\n", oi->lsdb->count);
958
959 monotime(&now);
960
961 timerclear(&res);
962 if (oi->thread_send_lsupdate)
963 timersub(&oi->thread_send_lsupdate->u.sands, &now, &res);
964 timerstring(&res, duration, sizeof(duration));
965 vty_out(vty,
966 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
967 oi->lsupdate_list->count, duration,
968 (oi->thread_send_lsupdate ? "on" : "off"));
969 for (ALL_LSDB(oi->lsupdate_list, lsa))
970 vty_out(vty, " %s\n", lsa->name);
971
972 timerclear(&res);
973 if (oi->thread_send_lsack)
974 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
975 timerstring(&res, duration, sizeof(duration));
976 vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
977 oi->lsack_list->count, duration,
978 (oi->thread_send_lsack ? "on" : "off"));
979 for (ALL_LSDB(oi->lsack_list, lsa))
980 vty_out(vty, " %s\n", lsa->name);
981 ospf6_bfd_show_info(vty, oi->bfd_info, 1);
982 return 0;
983 }
984
985 /* show interface */
986 DEFUN (show_ipv6_ospf6_interface,
987 show_ipv6_ospf6_interface_ifname_cmd,
988 "show ipv6 ospf6 interface [IFNAME]",
989 SHOW_STR
990 IP6_STR
991 OSPF6_STR
992 INTERFACE_STR
993 IFNAME_STR)
994 {
995 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
996 int idx_ifname = 4;
997 struct interface *ifp;
998
999 if (argc == 5) {
1000 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
1001 if (ifp == NULL) {
1002 vty_out(vty, "No such Interface: %s\n",
1003 argv[idx_ifname]->arg);
1004 return CMD_WARNING;
1005 }
1006 ospf6_interface_show(vty, ifp);
1007 } else {
1008 FOR_ALL_INTERFACES (vrf, ifp)
1009 ospf6_interface_show(vty, ifp);
1010 }
1011
1012 return CMD_SUCCESS;
1013 }
1014
1015 static int ospf6_interface_show_traffic(struct vty *vty, uint32_t vrf_id,
1016 struct interface *intf_ifp,
1017 int display_once)
1018 {
1019 struct interface *ifp;
1020 struct vrf *vrf = NULL;
1021 struct ospf6_interface *oi = NULL;
1022
1023 vrf = vrf_lookup_by_id(vrf_id);
1024
1025 if (!display_once) {
1026 vty_out(vty, "\n");
1027 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1028 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1029 " LS-Ack");
1030 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1031 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1032 " Rx/Tx");
1033 vty_out(vty,
1034 "--------------------------------------------------------------------------------------------\n");
1035 }
1036
1037 if (intf_ifp == NULL) {
1038 FOR_ALL_INTERFACES (vrf, ifp) {
1039 if (ifp->info)
1040 oi = (struct ospf6_interface *)ifp->info;
1041 else
1042 continue;
1043
1044 vty_out(vty,
1045 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1046 oi->interface->name, oi->hello_in,
1047 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1048 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1049 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
1050 }
1051 } else {
1052 oi = intf_ifp->info;
1053 if (oi == NULL)
1054 return CMD_WARNING;
1055
1056 vty_out(vty,
1057 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1058 oi->interface->name, oi->hello_in, oi->hello_out,
1059 oi->db_desc_in, oi->db_desc_out, oi->ls_req_in,
1060 oi->ls_req_out, oi->ls_upd_in, oi->ls_upd_out,
1061 oi->ls_ack_in, oi->ls_ack_out);
1062 }
1063
1064 return CMD_SUCCESS;
1065 }
1066
1067 /* show interface */
1068 DEFUN (show_ipv6_ospf6_interface_traffic,
1069 show_ipv6_ospf6_interface_traffic_cmd,
1070 "show ipv6 ospf6 interface traffic [IFNAME]",
1071 SHOW_STR
1072 IP6_STR
1073 OSPF6_STR
1074 INTERFACE_STR
1075 "Protocol Packet counters\n"
1076 IFNAME_STR)
1077 {
1078 int idx_ifname = 0;
1079 int display_once = 0;
1080 char *intf_name = NULL;
1081 struct interface *ifp = NULL;
1082
1083 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1084 intf_name = argv[idx_ifname]->arg;
1085 ifp = if_lookup_by_name(intf_name, VRF_DEFAULT);
1086 if (ifp == NULL) {
1087 vty_out(vty, "No such Interface: %s\n", intf_name);
1088 return CMD_WARNING;
1089 }
1090 if (ifp->info == NULL) {
1091 vty_out(vty,
1092 " OSPF not enabled on this interface %s\n",
1093 intf_name);
1094 return 0;
1095 }
1096 }
1097
1098 ospf6_interface_show_traffic(vty, VRF_DEFAULT, ifp, display_once);
1099
1100
1101 return CMD_SUCCESS;
1102 }
1103
1104
1105 DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
1106 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1107 "show ipv6 ospf6 interface IFNAME prefix\
1108 [<\
1109 detail\
1110 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1111 >]",
1112 SHOW_STR
1113 IP6_STR
1114 OSPF6_STR
1115 INTERFACE_STR
1116 IFNAME_STR
1117 "Display connected prefixes to advertise\n"
1118 "Display details of the prefixes\n"
1119 OSPF6_ROUTE_ADDRESS_STR
1120 OSPF6_ROUTE_PREFIX_STR
1121 OSPF6_ROUTE_MATCH_STR
1122 "Display details of the prefixes\n")
1123 {
1124 int idx_ifname = 4;
1125 int idx_prefix = 6;
1126 struct interface *ifp;
1127 struct ospf6_interface *oi;
1128
1129 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
1130 if (ifp == NULL) {
1131 vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
1132 return CMD_WARNING;
1133 }
1134
1135 oi = ifp->info;
1136 if (oi == NULL) {
1137 vty_out(vty, "OSPFv3 is not enabled on %s\n",
1138 argv[idx_ifname]->arg);
1139 return CMD_WARNING;
1140 }
1141
1142 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1143 oi->route_connected);
1144
1145 return CMD_SUCCESS;
1146 }
1147
1148 DEFUN (show_ipv6_ospf6_interface_prefix,
1149 show_ipv6_ospf6_interface_prefix_cmd,
1150 "show ipv6 ospf6 interface prefix\
1151 [<\
1152 detail\
1153 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1154 >]",
1155 SHOW_STR
1156 IP6_STR
1157 OSPF6_STR
1158 INTERFACE_STR
1159 "Display connected prefixes to advertise\n"
1160 "Display details of the prefixes\n"
1161 OSPF6_ROUTE_ADDRESS_STR
1162 OSPF6_ROUTE_PREFIX_STR
1163 OSPF6_ROUTE_MATCH_STR
1164 "Display details of the prefixes\n")
1165 {
1166 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1167 int idx_prefix = 5;
1168 struct ospf6_interface *oi;
1169 struct interface *ifp;
1170
1171 FOR_ALL_INTERFACES (vrf, ifp) {
1172 oi = (struct ospf6_interface *)ifp->info;
1173 if (oi == NULL)
1174 continue;
1175
1176 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1177 oi->route_connected);
1178 }
1179
1180 return CMD_SUCCESS;
1181 }
1182
1183 /* interface variable set command */
1184 DEFUN (ipv6_ospf6_ifmtu,
1185 ipv6_ospf6_ifmtu_cmd,
1186 "ipv6 ospf6 ifmtu (1-65535)",
1187 IP6_STR
1188 OSPF6_STR
1189 "Interface MTU\n"
1190 "OSPFv3 Interface MTU\n"
1191 )
1192 {
1193 VTY_DECLVAR_CONTEXT(interface, ifp);
1194 int idx_number = 3;
1195 struct ospf6_interface *oi;
1196 unsigned int ifmtu, iobuflen;
1197 struct listnode *node, *nnode;
1198 struct ospf6_neighbor *on;
1199
1200 assert(ifp);
1201
1202 oi = (struct ospf6_interface *)ifp->info;
1203 if (oi == NULL)
1204 oi = ospf6_interface_create(ifp);
1205 assert(oi);
1206
1207 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1208
1209 if (oi->c_ifmtu == ifmtu)
1210 return CMD_SUCCESS;
1211
1212 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1213 vty_out(vty,
1214 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1215 ifp->name, ifp->mtu6);
1216 return CMD_WARNING_CONFIG_FAILED;
1217 }
1218
1219 if (oi->ifmtu < ifmtu) {
1220 iobuflen = ospf6_iobuf_size(ifmtu);
1221 if (iobuflen < ifmtu) {
1222 vty_out(vty,
1223 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1224 ifp->name, iobuflen);
1225 oi->ifmtu = oi->c_ifmtu = iobuflen;
1226 } else
1227 oi->ifmtu = oi->c_ifmtu = ifmtu;
1228 } else
1229 oi->ifmtu = oi->c_ifmtu = ifmtu;
1230
1231 /* re-establish adjacencies */
1232 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1233 THREAD_OFF(on->inactivity_timer);
1234 thread_add_event(master, inactivity_timer, on, 0, NULL);
1235 }
1236
1237 return CMD_SUCCESS;
1238 }
1239
1240 DEFUN (no_ipv6_ospf6_ifmtu,
1241 no_ipv6_ospf6_ifmtu_cmd,
1242 "no ipv6 ospf6 ifmtu [(1-65535)]",
1243 NO_STR
1244 IP6_STR
1245 OSPF6_STR
1246 "Interface MTU\n"
1247 "OSPFv3 Interface MTU\n"
1248 )
1249 {
1250 VTY_DECLVAR_CONTEXT(interface, ifp);
1251 struct ospf6_interface *oi;
1252 unsigned int iobuflen;
1253 struct listnode *node, *nnode;
1254 struct ospf6_neighbor *on;
1255
1256 assert(ifp);
1257
1258 oi = (struct ospf6_interface *)ifp->info;
1259 if (oi == NULL)
1260 oi = ospf6_interface_create(ifp);
1261 assert(oi);
1262
1263 if (oi->ifmtu < ifp->mtu) {
1264 iobuflen = ospf6_iobuf_size(ifp->mtu);
1265 if (iobuflen < ifp->mtu) {
1266 vty_out(vty,
1267 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1268 ifp->name, iobuflen);
1269 oi->ifmtu = iobuflen;
1270 } else
1271 oi->ifmtu = ifp->mtu;
1272 } else
1273 oi->ifmtu = ifp->mtu;
1274
1275 oi->c_ifmtu = 0;
1276
1277 /* re-establish adjacencies */
1278 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1279 THREAD_OFF(on->inactivity_timer);
1280 thread_add_event(master, inactivity_timer, on, 0, NULL);
1281 }
1282
1283 return CMD_SUCCESS;
1284 }
1285
1286 DEFUN (ipv6_ospf6_cost,
1287 ipv6_ospf6_cost_cmd,
1288 "ipv6 ospf6 cost (1-65535)",
1289 IP6_STR
1290 OSPF6_STR
1291 "Interface cost\n"
1292 "Outgoing metric of this interface\n")
1293 {
1294 VTY_DECLVAR_CONTEXT(interface, ifp);
1295 int idx_number = 3;
1296 struct ospf6_interface *oi;
1297 unsigned long int lcost;
1298
1299 assert(ifp);
1300
1301 oi = (struct ospf6_interface *)ifp->info;
1302 if (oi == NULL)
1303 oi = ospf6_interface_create(ifp);
1304 assert(oi);
1305
1306 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1307
1308 if (lcost > UINT32_MAX) {
1309 vty_out(vty, "Cost %ld is out of range\n", lcost);
1310 return CMD_WARNING_CONFIG_FAILED;
1311 }
1312
1313 if (oi->cost == lcost)
1314 return CMD_SUCCESS;
1315
1316 oi->cost = lcost;
1317 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1318
1319 ospf6_interface_force_recalculate_cost(oi);
1320
1321 return CMD_SUCCESS;
1322 }
1323
1324 DEFUN (no_ipv6_ospf6_cost,
1325 no_ipv6_ospf6_cost_cmd,
1326 "no ipv6 ospf6 cost [(1-65535)]",
1327 NO_STR
1328 IP6_STR
1329 OSPF6_STR
1330 "Calculate interface cost from bandwidth\n"
1331 "Outgoing metric of this interface\n")
1332 {
1333 VTY_DECLVAR_CONTEXT(interface, ifp);
1334 struct ospf6_interface *oi;
1335 assert(ifp);
1336
1337 oi = (struct ospf6_interface *)ifp->info;
1338 if (oi == NULL)
1339 oi = ospf6_interface_create(ifp);
1340 assert(oi);
1341
1342 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1343
1344 ospf6_interface_recalculate_cost(oi);
1345
1346 return CMD_SUCCESS;
1347 }
1348
1349 DEFUN (auto_cost_reference_bandwidth,
1350 auto_cost_reference_bandwidth_cmd,
1351 "auto-cost reference-bandwidth (1-4294967)",
1352 "Calculate OSPF interface cost according to bandwidth\n"
1353 "Use reference bandwidth method to assign OSPF cost\n"
1354 "The reference bandwidth in terms of Mbits per second\n")
1355 {
1356 VTY_DECLVAR_CONTEXT(ospf6, o);
1357 int idx_number = 2;
1358 struct ospf6_area *oa;
1359 struct ospf6_interface *oi;
1360 struct listnode *i, *j;
1361 uint32_t refbw;
1362
1363 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1364 if (refbw < 1 || refbw > 4294967) {
1365 vty_out(vty, "reference-bandwidth value is invalid\n");
1366 return CMD_WARNING_CONFIG_FAILED;
1367 }
1368
1369 /* If reference bandwidth is changed. */
1370 if ((refbw) == o->ref_bandwidth)
1371 return CMD_SUCCESS;
1372
1373 o->ref_bandwidth = refbw;
1374 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1375 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1376 ospf6_interface_recalculate_cost(oi);
1377
1378 return CMD_SUCCESS;
1379 }
1380
1381 DEFUN (no_auto_cost_reference_bandwidth,
1382 no_auto_cost_reference_bandwidth_cmd,
1383 "no auto-cost reference-bandwidth [(1-4294967)]",
1384 NO_STR
1385 "Calculate OSPF interface cost according to bandwidth\n"
1386 "Use reference bandwidth method to assign OSPF cost\n"
1387 "The reference bandwidth in terms of Mbits per second\n")
1388 {
1389 VTY_DECLVAR_CONTEXT(ospf6, o);
1390 struct ospf6_area *oa;
1391 struct ospf6_interface *oi;
1392 struct listnode *i, *j;
1393
1394 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1395 return CMD_SUCCESS;
1396
1397 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1398 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1399 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1400 ospf6_interface_recalculate_cost(oi);
1401
1402 return CMD_SUCCESS;
1403 }
1404
1405
1406 DEFUN (ipv6_ospf6_hellointerval,
1407 ipv6_ospf6_hellointerval_cmd,
1408 "ipv6 ospf6 hello-interval (1-65535)",
1409 IP6_STR
1410 OSPF6_STR
1411 "Time between HELLO packets\n"
1412 SECONDS_STR)
1413 {
1414 VTY_DECLVAR_CONTEXT(interface, ifp);
1415 int idx_number = 3;
1416 struct ospf6_interface *oi;
1417 assert(ifp);
1418
1419 oi = (struct ospf6_interface *)ifp->info;
1420 if (oi == NULL)
1421 oi = ospf6_interface_create(ifp);
1422 assert(oi);
1423
1424 oi->hello_interval = strmatch(argv[0]->text, "no")
1425 ? OSPF_HELLO_INTERVAL_DEFAULT
1426 : strtoul(argv[idx_number]->arg, NULL, 10);
1427 return CMD_SUCCESS;
1428 }
1429
1430 ALIAS (ipv6_ospf6_hellointerval,
1431 no_ipv6_ospf6_hellointerval_cmd,
1432 "no ipv6 ospf6 hello-interval [(1-65535)]",
1433 NO_STR
1434 IP6_STR
1435 OSPF6_STR
1436 "Time between HELLO packets\n"
1437 SECONDS_STR)
1438
1439 /* interface variable set command */
1440 DEFUN (ipv6_ospf6_deadinterval,
1441 ipv6_ospf6_deadinterval_cmd,
1442 "ipv6 ospf6 dead-interval (1-65535)",
1443 IP6_STR
1444 OSPF6_STR
1445 "Interval time after which a neighbor is declared down\n"
1446 SECONDS_STR)
1447 {
1448 VTY_DECLVAR_CONTEXT(interface, ifp);
1449 int idx_number = 3;
1450 struct ospf6_interface *oi;
1451 assert(ifp);
1452
1453 oi = (struct ospf6_interface *)ifp->info;
1454 if (oi == NULL)
1455 oi = ospf6_interface_create(ifp);
1456 assert(oi);
1457
1458 oi->dead_interval = strmatch(argv[0]->arg, "no")
1459 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1460 : strtoul(argv[idx_number]->arg, NULL, 10);
1461 return CMD_SUCCESS;
1462 }
1463
1464 ALIAS (ipv6_ospf6_deadinterval,
1465 no_ipv6_ospf6_deadinterval_cmd,
1466 "no ipv6 ospf6 dead-interval [(1-65535)]",
1467 NO_STR
1468 IP6_STR
1469 OSPF6_STR
1470 "Interval time after which a neighbor is declared down\n"
1471 SECONDS_STR)
1472
1473 /* interface variable set command */
1474 DEFUN (ipv6_ospf6_transmitdelay,
1475 ipv6_ospf6_transmitdelay_cmd,
1476 "ipv6 ospf6 transmit-delay (1-3600)",
1477 IP6_STR
1478 OSPF6_STR
1479 "Link state transmit delay\n"
1480 SECONDS_STR)
1481 {
1482 VTY_DECLVAR_CONTEXT(interface, ifp);
1483 int idx_number = 3;
1484 struct ospf6_interface *oi;
1485 assert(ifp);
1486
1487 oi = (struct ospf6_interface *)ifp->info;
1488 if (oi == NULL)
1489 oi = ospf6_interface_create(ifp);
1490 assert(oi);
1491
1492 oi->transdelay = strmatch(argv[0]->text, "no")
1493 ? OSPF6_INTERFACE_TRANSDELAY
1494 : strtoul(argv[idx_number]->arg, NULL, 10);
1495 return CMD_SUCCESS;
1496 }
1497
1498 ALIAS (ipv6_ospf6_transmitdelay,
1499 no_ipv6_ospf6_transmitdelay_cmd,
1500 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1501 NO_STR
1502 IP6_STR
1503 OSPF6_STR
1504 "Link state transmit delay\n"
1505 SECONDS_STR)
1506
1507 /* interface variable set command */
1508 DEFUN (ipv6_ospf6_retransmitinterval,
1509 ipv6_ospf6_retransmitinterval_cmd,
1510 "ipv6 ospf6 retransmit-interval (1-65535)",
1511 IP6_STR
1512 OSPF6_STR
1513 "Time between retransmitting lost link state advertisements\n"
1514 SECONDS_STR)
1515 {
1516 VTY_DECLVAR_CONTEXT(interface, ifp);
1517 int idx_number = 3;
1518 struct ospf6_interface *oi;
1519 assert(ifp);
1520
1521 oi = (struct ospf6_interface *)ifp->info;
1522 if (oi == NULL)
1523 oi = ospf6_interface_create(ifp);
1524 assert(oi);
1525
1526 oi->rxmt_interval = strmatch(argv[0]->text, "no")
1527 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1528 : strtoul(argv[idx_number]->arg, NULL, 10);
1529 return CMD_SUCCESS;
1530 }
1531
1532 ALIAS (ipv6_ospf6_retransmitinterval,
1533 no_ipv6_ospf6_retransmitinterval_cmd,
1534 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1535 NO_STR
1536 IP6_STR
1537 OSPF6_STR
1538 "Time between retransmitting lost link state advertisements\n"
1539 SECONDS_STR)
1540
1541 /* interface variable set command */
1542 DEFUN (ipv6_ospf6_priority,
1543 ipv6_ospf6_priority_cmd,
1544 "ipv6 ospf6 priority (0-255)",
1545 IP6_STR
1546 OSPF6_STR
1547 "Router priority\n"
1548 "Priority value\n")
1549 {
1550 VTY_DECLVAR_CONTEXT(interface, ifp);
1551 int idx_number = 3;
1552 struct ospf6_interface *oi;
1553 assert(ifp);
1554
1555 oi = (struct ospf6_interface *)ifp->info;
1556 if (oi == NULL)
1557 oi = ospf6_interface_create(ifp);
1558 assert(oi);
1559
1560 oi->priority = strmatch(argv[0]->text, "no")
1561 ? OSPF6_INTERFACE_PRIORITY
1562 : strtoul(argv[idx_number]->arg, NULL, 10);
1563
1564 if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
1565 || oi->state == OSPF6_INTERFACE_BDR
1566 || oi->state == OSPF6_INTERFACE_DR))
1567 ospf6_interface_state_change(dr_election(oi), oi);
1568
1569 return CMD_SUCCESS;
1570 }
1571
1572 ALIAS (ipv6_ospf6_priority,
1573 no_ipv6_ospf6_priority_cmd,
1574 "no ipv6 ospf6 priority [(0-255)]",
1575 NO_STR
1576 IP6_STR
1577 OSPF6_STR
1578 "Router priority\n"
1579 "Priority value\n")
1580
1581 DEFUN (ipv6_ospf6_instance,
1582 ipv6_ospf6_instance_cmd,
1583 "ipv6 ospf6 instance-id (0-255)",
1584 IP6_STR
1585 OSPF6_STR
1586 "Instance ID for this interface\n"
1587 "Instance ID value\n")
1588 {
1589 VTY_DECLVAR_CONTEXT(interface, ifp);
1590 int idx_number = 3;
1591 struct ospf6_interface *oi;
1592 assert(ifp);
1593
1594 oi = (struct ospf6_interface *)ifp->info;
1595 if (oi == NULL)
1596 oi = ospf6_interface_create(ifp);
1597 assert(oi);
1598
1599 oi->instance_id = strmatch(argv[0]->text, "no")
1600 ? OSPF6_INTERFACE_INSTANCE_ID
1601 : strtoul(argv[idx_number]->arg, NULL, 10);
1602 return CMD_SUCCESS;
1603 }
1604
1605 ALIAS (ipv6_ospf6_instance,
1606 no_ipv6_ospf6_instance_cmd,
1607 "no ipv6 ospf6 instance-id [(0-255)]",
1608 NO_STR
1609 IP6_STR
1610 OSPF6_STR
1611 "Instance ID for this interface\n"
1612 "Instance ID value\n")
1613
1614 DEFUN (ipv6_ospf6_passive,
1615 ipv6_ospf6_passive_cmd,
1616 "ipv6 ospf6 passive",
1617 IP6_STR
1618 OSPF6_STR
1619 "Passive interface; no adjacency will be formed on this interface\n"
1620 )
1621 {
1622 VTY_DECLVAR_CONTEXT(interface, ifp);
1623 struct ospf6_interface *oi;
1624 struct listnode *node, *nnode;
1625 struct ospf6_neighbor *on;
1626
1627 assert(ifp);
1628
1629 oi = (struct ospf6_interface *)ifp->info;
1630 if (oi == NULL)
1631 oi = ospf6_interface_create(ifp);
1632 assert(oi);
1633
1634 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1635 THREAD_OFF(oi->thread_send_hello);
1636 THREAD_OFF(oi->thread_sso);
1637
1638 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1639 THREAD_OFF(on->inactivity_timer);
1640 thread_add_event(master, inactivity_timer, on, 0, NULL);
1641 }
1642
1643 return CMD_SUCCESS;
1644 }
1645
1646 DEFUN (no_ipv6_ospf6_passive,
1647 no_ipv6_ospf6_passive_cmd,
1648 "no ipv6 ospf6 passive",
1649 NO_STR
1650 IP6_STR
1651 OSPF6_STR
1652 "passive interface: No Adjacency will be formed on this I/F\n"
1653 )
1654 {
1655 VTY_DECLVAR_CONTEXT(interface, ifp);
1656 struct ospf6_interface *oi;
1657 assert(ifp);
1658
1659 oi = (struct ospf6_interface *)ifp->info;
1660 if (oi == NULL)
1661 oi = ospf6_interface_create(ifp);
1662 assert(oi);
1663
1664 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1665 THREAD_OFF(oi->thread_send_hello);
1666 THREAD_OFF(oi->thread_sso);
1667 thread_add_event(master, ospf6_hello_send, oi, 0,
1668 &oi->thread_send_hello);
1669
1670 return CMD_SUCCESS;
1671 }
1672
1673 DEFUN (ipv6_ospf6_mtu_ignore,
1674 ipv6_ospf6_mtu_ignore_cmd,
1675 "ipv6 ospf6 mtu-ignore",
1676 IP6_STR
1677 OSPF6_STR
1678 "Disable MTU mismatch detection on this interface\n"
1679 )
1680 {
1681 VTY_DECLVAR_CONTEXT(interface, ifp);
1682 struct ospf6_interface *oi;
1683 assert(ifp);
1684
1685 oi = (struct ospf6_interface *)ifp->info;
1686 if (oi == NULL)
1687 oi = ospf6_interface_create(ifp);
1688 assert(oi);
1689
1690 oi->mtu_ignore = 1;
1691
1692 return CMD_SUCCESS;
1693 }
1694
1695 DEFUN (no_ipv6_ospf6_mtu_ignore,
1696 no_ipv6_ospf6_mtu_ignore_cmd,
1697 "no ipv6 ospf6 mtu-ignore",
1698 NO_STR
1699 IP6_STR
1700 OSPF6_STR
1701 "Disable MTU mismatch detection on this interface\n"
1702 )
1703 {
1704 VTY_DECLVAR_CONTEXT(interface, ifp);
1705 struct ospf6_interface *oi;
1706 assert(ifp);
1707
1708 oi = (struct ospf6_interface *)ifp->info;
1709 if (oi == NULL)
1710 oi = ospf6_interface_create(ifp);
1711 assert(oi);
1712
1713 oi->mtu_ignore = 0;
1714
1715 return CMD_SUCCESS;
1716 }
1717
1718 DEFUN (ipv6_ospf6_advertise_prefix_list,
1719 ipv6_ospf6_advertise_prefix_list_cmd,
1720 "ipv6 ospf6 advertise prefix-list WORD",
1721 IP6_STR
1722 OSPF6_STR
1723 "Advertising options\n"
1724 "Filter prefix using prefix-list\n"
1725 "Prefix list name\n"
1726 )
1727 {
1728 VTY_DECLVAR_CONTEXT(interface, ifp);
1729 int idx_word = 4;
1730 struct ospf6_interface *oi;
1731 assert(ifp);
1732
1733 oi = (struct ospf6_interface *)ifp->info;
1734 if (oi == NULL)
1735 oi = ospf6_interface_create(ifp);
1736 assert(oi);
1737
1738 if (oi->plist_name)
1739 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
1740 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
1741
1742 ospf6_interface_connected_route_update(oi->interface);
1743
1744 if (oi->area) {
1745 OSPF6_LINK_LSA_SCHEDULE(oi);
1746 if (oi->state == OSPF6_INTERFACE_DR) {
1747 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1748 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1749 }
1750 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1751 }
1752
1753 return CMD_SUCCESS;
1754 }
1755
1756 DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1757 no_ipv6_ospf6_advertise_prefix_list_cmd,
1758 "no ipv6 ospf6 advertise prefix-list [WORD]",
1759 NO_STR
1760 IP6_STR
1761 OSPF6_STR
1762 "Advertising options\n"
1763 "Filter prefix using prefix-list\n"
1764 "Prefix list name\n")
1765 {
1766 VTY_DECLVAR_CONTEXT(interface, ifp);
1767 struct ospf6_interface *oi;
1768 assert(ifp);
1769
1770 oi = (struct ospf6_interface *)ifp->info;
1771 if (oi == NULL)
1772 oi = ospf6_interface_create(ifp);
1773 assert(oi);
1774
1775 if (oi->plist_name)
1776 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
1777
1778 ospf6_interface_connected_route_update(oi->interface);
1779
1780 if (oi->area) {
1781 OSPF6_LINK_LSA_SCHEDULE(oi);
1782 if (oi->state == OSPF6_INTERFACE_DR) {
1783 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1784 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1785 }
1786 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1787 }
1788
1789 return CMD_SUCCESS;
1790 }
1791
1792 DEFUN (ipv6_ospf6_network,
1793 ipv6_ospf6_network_cmd,
1794 "ipv6 ospf6 network <broadcast|point-to-point>",
1795 IP6_STR
1796 OSPF6_STR
1797 "Network type\n"
1798 "Specify OSPF6 broadcast network\n"
1799 "Specify OSPF6 point-to-point network\n"
1800 )
1801 {
1802 VTY_DECLVAR_CONTEXT(interface, ifp);
1803 int idx_network = 3;
1804 struct ospf6_interface *oi;
1805 assert(ifp);
1806
1807 oi = (struct ospf6_interface *)ifp->info;
1808 if (oi == NULL) {
1809 oi = ospf6_interface_create(ifp);
1810 }
1811 assert(oi);
1812
1813 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
1814 if (oi->type == OSPF_IFTYPE_BROADCAST)
1815 return CMD_SUCCESS;
1816
1817 oi->type = OSPF_IFTYPE_BROADCAST;
1818 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
1819 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
1820 return CMD_SUCCESS;
1821 }
1822 oi->type = OSPF_IFTYPE_POINTOPOINT;
1823 }
1824
1825 /* Reset the interface */
1826 thread_execute(master, interface_down, oi, 0);
1827 thread_execute(master, interface_up, oi, 0);
1828
1829 return CMD_SUCCESS;
1830 }
1831
1832 DEFUN (no_ipv6_ospf6_network,
1833 no_ipv6_ospf6_network_cmd,
1834 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
1835 NO_STR
1836 IP6_STR
1837 OSPF6_STR
1838 "Set default network type\n"
1839 "Specify OSPF6 broadcast network\n"
1840 "Specify OSPF6 point-to-point network\n")
1841 {
1842 VTY_DECLVAR_CONTEXT(interface, ifp);
1843 struct ospf6_interface *oi;
1844 int type;
1845
1846 assert(ifp);
1847
1848 oi = (struct ospf6_interface *)ifp->info;
1849 if (oi == NULL) {
1850 return CMD_SUCCESS;
1851 }
1852
1853 type = ospf6_default_iftype(ifp);
1854 if (oi->type == type) {
1855 return CMD_SUCCESS;
1856 }
1857 oi->type = type;
1858
1859 /* Reset the interface */
1860 thread_execute(master, interface_down, oi, 0);
1861 thread_execute(master, interface_up, oi, 0);
1862
1863 return CMD_SUCCESS;
1864 }
1865
1866 static int config_write_ospf6_interface(struct vty *vty)
1867 {
1868 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1869 struct ospf6_interface *oi;
1870 struct interface *ifp;
1871
1872 FOR_ALL_INTERFACES (vrf, ifp) {
1873 oi = (struct ospf6_interface *)ifp->info;
1874 if (oi == NULL)
1875 continue;
1876
1877 vty_frame(vty, "interface %s\n", oi->interface->name);
1878
1879 if (ifp->desc)
1880 vty_out(vty, " description %s\n", ifp->desc);
1881 if (oi->c_ifmtu)
1882 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
1883
1884 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
1885 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
1886
1887 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1888 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
1889 oi->hello_interval);
1890
1891 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1892 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
1893 oi->dead_interval);
1894
1895 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1896 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
1897 oi->rxmt_interval);
1898
1899 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1900 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
1901
1902 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1903 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
1904 oi->transdelay);
1905
1906 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1907 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
1908 oi->instance_id);
1909
1910 if (oi->plist_name)
1911 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
1912 oi->plist_name);
1913
1914 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
1915 vty_out(vty, " ipv6 ospf6 passive\n");
1916
1917 if (oi->mtu_ignore)
1918 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
1919
1920 if (oi->type != ospf6_default_iftype(ifp)) {
1921 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
1922 vty_out(vty,
1923 " ipv6 ospf6 network point-to-point\n");
1924 else if (oi->type == OSPF_IFTYPE_BROADCAST)
1925 vty_out(vty, " ipv6 ospf6 network broadcast\n");
1926 }
1927
1928 ospf6_bfd_write_config(vty, oi);
1929
1930 vty_endframe(vty, "!\n");
1931 }
1932 return 0;
1933 }
1934
1935 static struct cmd_node interface_node = {
1936 INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */
1937 };
1938
1939 void ospf6_interface_init(void)
1940 {
1941 /* Install interface node. */
1942 install_node(&interface_node, config_write_ospf6_interface);
1943 if_cmd_init();
1944
1945 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
1946 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1947 install_element(VIEW_NODE,
1948 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
1949 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
1950
1951 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
1952 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
1953 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
1954 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
1955
1956 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1957 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1958 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1959 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1960 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1961 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
1962 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
1963 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
1964 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
1965 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
1966 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
1967 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
1968
1969 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1970 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
1971
1972 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
1973 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
1974
1975 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1976 install_element(INTERFACE_NODE,
1977 &no_ipv6_ospf6_advertise_prefix_list_cmd);
1978
1979 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
1980 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
1981
1982 /* reference bandwidth commands */
1983 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
1984 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
1985 }
1986
1987 /* Clear the specified interface structure */
1988 static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
1989 {
1990 struct ospf6_interface *oi;
1991
1992 if (!if_is_operative(ifp))
1993 return;
1994
1995 if (ifp->info == NULL)
1996 return;
1997
1998 oi = (struct ospf6_interface *)ifp->info;
1999
2000 if (IS_OSPF6_DEBUG_INTERFACE)
2001 zlog_debug("Interface %s: clear by reset", ifp->name);
2002
2003 /* Reset the interface */
2004 thread_execute(master, interface_down, oi, 0);
2005 thread_execute(master, interface_up, oi, 0);
2006 }
2007
2008 /* Clear interface */
2009 DEFUN (clear_ipv6_ospf6_interface,
2010 clear_ipv6_ospf6_interface_cmd,
2011 "clear ipv6 ospf6 interface [IFNAME]",
2012 CLEAR_STR
2013 IP6_STR
2014 OSPF6_STR
2015 INTERFACE_STR
2016 IFNAME_STR
2017 )
2018 {
2019 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
2020 int idx_ifname = 4;
2021 struct interface *ifp;
2022
2023 if (argc == 4) /* Clear all the ospfv3 interfaces. */
2024 {
2025 FOR_ALL_INTERFACES (vrf, ifp)
2026 ospf6_interface_clear(vty, ifp);
2027 } else /* Interface name is specified. */
2028 {
2029 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
2030 VRF_DEFAULT))
2031 == NULL) {
2032 vty_out(vty, "No such Interface: %s\n",
2033 argv[idx_ifname]->arg);
2034 return CMD_WARNING;
2035 }
2036 ospf6_interface_clear(vty, ifp);
2037 }
2038
2039 return CMD_SUCCESS;
2040 }
2041
2042 void install_element_ospf6_clear_interface(void)
2043 {
2044 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
2045 }
2046
2047 DEFUN (debug_ospf6_interface,
2048 debug_ospf6_interface_cmd,
2049 "debug ospf6 interface",
2050 DEBUG_STR
2051 OSPF6_STR
2052 "Debug OSPFv3 Interface\n"
2053 )
2054 {
2055 OSPF6_DEBUG_INTERFACE_ON();
2056 return CMD_SUCCESS;
2057 }
2058
2059 DEFUN (no_debug_ospf6_interface,
2060 no_debug_ospf6_interface_cmd,
2061 "no debug ospf6 interface",
2062 NO_STR
2063 DEBUG_STR
2064 OSPF6_STR
2065 "Debug OSPFv3 Interface\n"
2066 )
2067 {
2068 OSPF6_DEBUG_INTERFACE_OFF();
2069 return CMD_SUCCESS;
2070 }
2071
2072 int config_write_ospf6_debug_interface(struct vty *vty)
2073 {
2074 if (IS_OSPF6_DEBUG_INTERFACE)
2075 vty_out(vty, "debug ospf6 interface\n");
2076 return 0;
2077 }
2078
2079 void install_element_ospf6_debug_interface(void)
2080 {
2081 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2082 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2083 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2084 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
2085 }