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