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