]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_interface.c
Merge pull request #5388 from donaldsharp/7.1_cherrys
[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, VRF_DEFAULT);
1000 if (ifp == NULL) {
1001 vty_out(vty, "No such Interface: %s\n",
1002 argv[idx_ifname]->arg);
1003 return CMD_WARNING;
1004 }
1005 ospf6_interface_show(vty, ifp);
1006 } else {
1007 FOR_ALL_INTERFACES (vrf, ifp)
1008 ospf6_interface_show(vty, ifp);
1009 }
1010
1011 return CMD_SUCCESS;
1012 }
1013
1014 static int ospf6_interface_show_traffic(struct vty *vty, uint32_t vrf_id,
1015 struct interface *intf_ifp,
1016 int display_once)
1017 {
1018 struct interface *ifp;
1019 struct vrf *vrf = NULL;
1020 struct ospf6_interface *oi = NULL;
1021
1022 vrf = vrf_lookup_by_id(vrf_id);
1023
1024 if (!display_once) {
1025 vty_out(vty, "\n");
1026 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1027 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1028 " LS-Ack");
1029 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1030 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1031 " Rx/Tx");
1032 vty_out(vty,
1033 "--------------------------------------------------------------------------------------------\n");
1034 }
1035
1036 if (intf_ifp == NULL) {
1037 FOR_ALL_INTERFACES (vrf, ifp) {
1038 if (ifp->info)
1039 oi = (struct ospf6_interface *)ifp->info;
1040 else
1041 continue;
1042
1043 vty_out(vty,
1044 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1045 oi->interface->name, oi->hello_in,
1046 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1047 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1048 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
1049 }
1050 } else {
1051 oi = intf_ifp->info;
1052 if (oi == NULL)
1053 return CMD_WARNING;
1054
1055 vty_out(vty,
1056 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1057 oi->interface->name, oi->hello_in, oi->hello_out,
1058 oi->db_desc_in, oi->db_desc_out, oi->ls_req_in,
1059 oi->ls_req_out, oi->ls_upd_in, oi->ls_upd_out,
1060 oi->ls_ack_in, oi->ls_ack_out);
1061 }
1062
1063 return CMD_SUCCESS;
1064 }
1065
1066 /* show interface */
1067 DEFUN (show_ipv6_ospf6_interface_traffic,
1068 show_ipv6_ospf6_interface_traffic_cmd,
1069 "show ipv6 ospf6 interface traffic [IFNAME]",
1070 SHOW_STR
1071 IP6_STR
1072 OSPF6_STR
1073 INTERFACE_STR
1074 "Protocol Packet counters\n"
1075 IFNAME_STR)
1076 {
1077 int idx_ifname = 0;
1078 int display_once = 0;
1079 char *intf_name = NULL;
1080 struct interface *ifp = NULL;
1081
1082 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1083 intf_name = argv[idx_ifname]->arg;
1084 ifp = if_lookup_by_name(intf_name, VRF_DEFAULT);
1085 if (ifp == NULL) {
1086 vty_out(vty, "No such Interface: %s\n", intf_name);
1087 return CMD_WARNING;
1088 }
1089 if (ifp->info == NULL) {
1090 vty_out(vty,
1091 " OSPF not enabled on this interface %s\n",
1092 intf_name);
1093 return 0;
1094 }
1095 }
1096
1097 ospf6_interface_show_traffic(vty, VRF_DEFAULT, ifp, display_once);
1098
1099
1100 return CMD_SUCCESS;
1101 }
1102
1103
1104 DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
1105 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1106 "show ipv6 ospf6 interface IFNAME prefix\
1107 [<\
1108 detail\
1109 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1110 >]",
1111 SHOW_STR
1112 IP6_STR
1113 OSPF6_STR
1114 INTERFACE_STR
1115 IFNAME_STR
1116 "Display connected prefixes to advertise\n"
1117 "Display details of the prefixes\n"
1118 OSPF6_ROUTE_ADDRESS_STR
1119 OSPF6_ROUTE_PREFIX_STR
1120 OSPF6_ROUTE_MATCH_STR
1121 "Display details of the prefixes\n")
1122 {
1123 int idx_ifname = 4;
1124 int idx_prefix = 6;
1125 struct interface *ifp;
1126 struct ospf6_interface *oi;
1127
1128 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
1129 if (ifp == NULL) {
1130 vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
1131 return CMD_WARNING;
1132 }
1133
1134 oi = ifp->info;
1135 if (oi == NULL) {
1136 vty_out(vty, "OSPFv3 is not enabled on %s\n",
1137 argv[idx_ifname]->arg);
1138 return CMD_WARNING;
1139 }
1140
1141 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1142 oi->route_connected);
1143
1144 return CMD_SUCCESS;
1145 }
1146
1147 DEFUN (show_ipv6_ospf6_interface_prefix,
1148 show_ipv6_ospf6_interface_prefix_cmd,
1149 "show ipv6 ospf6 interface prefix\
1150 [<\
1151 detail\
1152 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1153 >]",
1154 SHOW_STR
1155 IP6_STR
1156 OSPF6_STR
1157 INTERFACE_STR
1158 "Display connected prefixes to advertise\n"
1159 "Display details of the prefixes\n"
1160 OSPF6_ROUTE_ADDRESS_STR
1161 OSPF6_ROUTE_PREFIX_STR
1162 OSPF6_ROUTE_MATCH_STR
1163 "Display details of the prefixes\n")
1164 {
1165 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1166 int idx_prefix = 5;
1167 struct ospf6_interface *oi;
1168 struct interface *ifp;
1169
1170 FOR_ALL_INTERFACES (vrf, ifp) {
1171 oi = (struct ospf6_interface *)ifp->info;
1172 if (oi == NULL)
1173 continue;
1174
1175 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1176 oi->route_connected);
1177 }
1178
1179 return CMD_SUCCESS;
1180 }
1181
1182 /* interface variable set command */
1183 DEFUN (ipv6_ospf6_ifmtu,
1184 ipv6_ospf6_ifmtu_cmd,
1185 "ipv6 ospf6 ifmtu (1-65535)",
1186 IP6_STR
1187 OSPF6_STR
1188 "Interface MTU\n"
1189 "OSPFv3 Interface MTU\n"
1190 )
1191 {
1192 VTY_DECLVAR_CONTEXT(interface, ifp);
1193 int idx_number = 3;
1194 struct ospf6_interface *oi;
1195 unsigned int ifmtu, iobuflen;
1196 struct listnode *node, *nnode;
1197 struct ospf6_neighbor *on;
1198
1199 assert(ifp);
1200
1201 oi = (struct ospf6_interface *)ifp->info;
1202 if (oi == NULL)
1203 oi = ospf6_interface_create(ifp);
1204 assert(oi);
1205
1206 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1207
1208 if (oi->c_ifmtu == ifmtu)
1209 return CMD_SUCCESS;
1210
1211 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1212 vty_out(vty,
1213 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1214 ifp->name, ifp->mtu6);
1215 return CMD_WARNING_CONFIG_FAILED;
1216 }
1217
1218 if (oi->ifmtu < ifmtu) {
1219 iobuflen = ospf6_iobuf_size(ifmtu);
1220 if (iobuflen < ifmtu) {
1221 vty_out(vty,
1222 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1223 ifp->name, iobuflen);
1224 oi->ifmtu = oi->c_ifmtu = iobuflen;
1225 } else
1226 oi->ifmtu = oi->c_ifmtu = ifmtu;
1227 } else
1228 oi->ifmtu = oi->c_ifmtu = ifmtu;
1229
1230 /* re-establish adjacencies */
1231 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1232 THREAD_OFF(on->inactivity_timer);
1233 thread_add_event(master, inactivity_timer, on, 0, NULL);
1234 }
1235
1236 return CMD_SUCCESS;
1237 }
1238
1239 DEFUN (no_ipv6_ospf6_ifmtu,
1240 no_ipv6_ospf6_ifmtu_cmd,
1241 "no ipv6 ospf6 ifmtu [(1-65535)]",
1242 NO_STR
1243 IP6_STR
1244 OSPF6_STR
1245 "Interface MTU\n"
1246 "OSPFv3 Interface MTU\n"
1247 )
1248 {
1249 VTY_DECLVAR_CONTEXT(interface, ifp);
1250 struct ospf6_interface *oi;
1251 unsigned int iobuflen;
1252 struct listnode *node, *nnode;
1253 struct ospf6_neighbor *on;
1254
1255 assert(ifp);
1256
1257 oi = (struct ospf6_interface *)ifp->info;
1258 if (oi == NULL)
1259 oi = ospf6_interface_create(ifp);
1260 assert(oi);
1261
1262 if (oi->ifmtu < ifp->mtu) {
1263 iobuflen = ospf6_iobuf_size(ifp->mtu);
1264 if (iobuflen < ifp->mtu) {
1265 vty_out(vty,
1266 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1267 ifp->name, iobuflen);
1268 oi->ifmtu = iobuflen;
1269 } else
1270 oi->ifmtu = ifp->mtu;
1271 } else
1272 oi->ifmtu = ifp->mtu;
1273
1274 oi->c_ifmtu = 0;
1275
1276 /* re-establish adjacencies */
1277 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1278 THREAD_OFF(on->inactivity_timer);
1279 thread_add_event(master, inactivity_timer, on, 0, NULL);
1280 }
1281
1282 return CMD_SUCCESS;
1283 }
1284
1285 DEFUN (ipv6_ospf6_cost,
1286 ipv6_ospf6_cost_cmd,
1287 "ipv6 ospf6 cost (1-65535)",
1288 IP6_STR
1289 OSPF6_STR
1290 "Interface cost\n"
1291 "Outgoing metric of this interface\n")
1292 {
1293 VTY_DECLVAR_CONTEXT(interface, ifp);
1294 int idx_number = 3;
1295 struct ospf6_interface *oi;
1296 unsigned long int lcost;
1297
1298 assert(ifp);
1299
1300 oi = (struct ospf6_interface *)ifp->info;
1301 if (oi == NULL)
1302 oi = ospf6_interface_create(ifp);
1303 assert(oi);
1304
1305 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1306
1307 if (lcost > UINT32_MAX) {
1308 vty_out(vty, "Cost %ld is out of range\n", lcost);
1309 return CMD_WARNING_CONFIG_FAILED;
1310 }
1311
1312 if (oi->cost == lcost)
1313 return CMD_SUCCESS;
1314
1315 oi->cost = lcost;
1316 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1317
1318 ospf6_interface_force_recalculate_cost(oi);
1319
1320 return CMD_SUCCESS;
1321 }
1322
1323 DEFUN (no_ipv6_ospf6_cost,
1324 no_ipv6_ospf6_cost_cmd,
1325 "no ipv6 ospf6 cost [(1-65535)]",
1326 NO_STR
1327 IP6_STR
1328 OSPF6_STR
1329 "Calculate interface cost from bandwidth\n"
1330 "Outgoing metric of this interface\n")
1331 {
1332 VTY_DECLVAR_CONTEXT(interface, ifp);
1333 struct ospf6_interface *oi;
1334 assert(ifp);
1335
1336 oi = (struct ospf6_interface *)ifp->info;
1337 if (oi == NULL)
1338 oi = ospf6_interface_create(ifp);
1339 assert(oi);
1340
1341 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1342
1343 ospf6_interface_recalculate_cost(oi);
1344
1345 return CMD_SUCCESS;
1346 }
1347
1348 DEFUN (auto_cost_reference_bandwidth,
1349 auto_cost_reference_bandwidth_cmd,
1350 "auto-cost reference-bandwidth (1-4294967)",
1351 "Calculate OSPF interface cost according to bandwidth\n"
1352 "Use reference bandwidth method to assign OSPF cost\n"
1353 "The reference bandwidth in terms of Mbits per second\n")
1354 {
1355 VTY_DECLVAR_CONTEXT(ospf6, o);
1356 int idx_number = 2;
1357 struct ospf6_area *oa;
1358 struct ospf6_interface *oi;
1359 struct listnode *i, *j;
1360 uint32_t refbw;
1361
1362 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1363 if (refbw < 1 || refbw > 4294967) {
1364 vty_out(vty, "reference-bandwidth value is invalid\n");
1365 return CMD_WARNING_CONFIG_FAILED;
1366 }
1367
1368 /* If reference bandwidth is changed. */
1369 if ((refbw) == o->ref_bandwidth)
1370 return CMD_SUCCESS;
1371
1372 o->ref_bandwidth = refbw;
1373 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1374 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1375 ospf6_interface_recalculate_cost(oi);
1376
1377 return CMD_SUCCESS;
1378 }
1379
1380 DEFUN (no_auto_cost_reference_bandwidth,
1381 no_auto_cost_reference_bandwidth_cmd,
1382 "no auto-cost reference-bandwidth [(1-4294967)]",
1383 NO_STR
1384 "Calculate OSPF interface cost according to bandwidth\n"
1385 "Use reference bandwidth method to assign OSPF cost\n"
1386 "The reference bandwidth in terms of Mbits per second\n")
1387 {
1388 VTY_DECLVAR_CONTEXT(ospf6, o);
1389 struct ospf6_area *oa;
1390 struct ospf6_interface *oi;
1391 struct listnode *i, *j;
1392
1393 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1394 return CMD_SUCCESS;
1395
1396 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1397 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1398 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1399 ospf6_interface_recalculate_cost(oi);
1400
1401 return CMD_SUCCESS;
1402 }
1403
1404
1405 DEFUN (ipv6_ospf6_hellointerval,
1406 ipv6_ospf6_hellointerval_cmd,
1407 "ipv6 ospf6 hello-interval (1-65535)",
1408 IP6_STR
1409 OSPF6_STR
1410 "Time between HELLO packets\n"
1411 SECONDS_STR)
1412 {
1413 VTY_DECLVAR_CONTEXT(interface, ifp);
1414 int idx_number = 3;
1415 struct ospf6_interface *oi;
1416 assert(ifp);
1417
1418 oi = (struct ospf6_interface *)ifp->info;
1419 if (oi == NULL)
1420 oi = ospf6_interface_create(ifp);
1421 assert(oi);
1422
1423 oi->hello_interval = strmatch(argv[0]->text, "no")
1424 ? OSPF_HELLO_INTERVAL_DEFAULT
1425 : strtoul(argv[idx_number]->arg, NULL, 10);
1426 return CMD_SUCCESS;
1427 }
1428
1429 ALIAS (ipv6_ospf6_hellointerval,
1430 no_ipv6_ospf6_hellointerval_cmd,
1431 "no ipv6 ospf6 hello-interval [(1-65535)]",
1432 NO_STR
1433 IP6_STR
1434 OSPF6_STR
1435 "Time between HELLO packets\n"
1436 SECONDS_STR)
1437
1438 /* interface variable set command */
1439 DEFUN (ipv6_ospf6_deadinterval,
1440 ipv6_ospf6_deadinterval_cmd,
1441 "ipv6 ospf6 dead-interval (1-65535)",
1442 IP6_STR
1443 OSPF6_STR
1444 "Interval time after which a neighbor is declared down\n"
1445 SECONDS_STR)
1446 {
1447 VTY_DECLVAR_CONTEXT(interface, ifp);
1448 int idx_number = 3;
1449 struct ospf6_interface *oi;
1450 assert(ifp);
1451
1452 oi = (struct ospf6_interface *)ifp->info;
1453 if (oi == NULL)
1454 oi = ospf6_interface_create(ifp);
1455 assert(oi);
1456
1457 oi->dead_interval = strmatch(argv[0]->arg, "no")
1458 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1459 : strtoul(argv[idx_number]->arg, NULL, 10);
1460 return CMD_SUCCESS;
1461 }
1462
1463 ALIAS (ipv6_ospf6_deadinterval,
1464 no_ipv6_ospf6_deadinterval_cmd,
1465 "no ipv6 ospf6 dead-interval [(1-65535)]",
1466 NO_STR
1467 IP6_STR
1468 OSPF6_STR
1469 "Interval time after which a neighbor is declared down\n"
1470 SECONDS_STR)
1471
1472 /* interface variable set command */
1473 DEFUN (ipv6_ospf6_transmitdelay,
1474 ipv6_ospf6_transmitdelay_cmd,
1475 "ipv6 ospf6 transmit-delay (1-3600)",
1476 IP6_STR
1477 OSPF6_STR
1478 "Link state transmit delay\n"
1479 SECONDS_STR)
1480 {
1481 VTY_DECLVAR_CONTEXT(interface, ifp);
1482 int idx_number = 3;
1483 struct ospf6_interface *oi;
1484 assert(ifp);
1485
1486 oi = (struct ospf6_interface *)ifp->info;
1487 if (oi == NULL)
1488 oi = ospf6_interface_create(ifp);
1489 assert(oi);
1490
1491 oi->transdelay = strmatch(argv[0]->text, "no")
1492 ? OSPF6_INTERFACE_TRANSDELAY
1493 : strtoul(argv[idx_number]->arg, NULL, 10);
1494 return CMD_SUCCESS;
1495 }
1496
1497 ALIAS (ipv6_ospf6_transmitdelay,
1498 no_ipv6_ospf6_transmitdelay_cmd,
1499 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1500 NO_STR
1501 IP6_STR
1502 OSPF6_STR
1503 "Link state transmit delay\n"
1504 SECONDS_STR)
1505
1506 /* interface variable set command */
1507 DEFUN (ipv6_ospf6_retransmitinterval,
1508 ipv6_ospf6_retransmitinterval_cmd,
1509 "ipv6 ospf6 retransmit-interval (1-65535)",
1510 IP6_STR
1511 OSPF6_STR
1512 "Time between retransmitting lost link state advertisements\n"
1513 SECONDS_STR)
1514 {
1515 VTY_DECLVAR_CONTEXT(interface, ifp);
1516 int idx_number = 3;
1517 struct ospf6_interface *oi;
1518 assert(ifp);
1519
1520 oi = (struct ospf6_interface *)ifp->info;
1521 if (oi == NULL)
1522 oi = ospf6_interface_create(ifp);
1523 assert(oi);
1524
1525 oi->rxmt_interval = strmatch(argv[0]->text, "no")
1526 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1527 : strtoul(argv[idx_number]->arg, NULL, 10);
1528 return CMD_SUCCESS;
1529 }
1530
1531 ALIAS (ipv6_ospf6_retransmitinterval,
1532 no_ipv6_ospf6_retransmitinterval_cmd,
1533 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1534 NO_STR
1535 IP6_STR
1536 OSPF6_STR
1537 "Time between retransmitting lost link state advertisements\n"
1538 SECONDS_STR)
1539
1540 /* interface variable set command */
1541 DEFUN (ipv6_ospf6_priority,
1542 ipv6_ospf6_priority_cmd,
1543 "ipv6 ospf6 priority (0-255)",
1544 IP6_STR
1545 OSPF6_STR
1546 "Router priority\n"
1547 "Priority value\n")
1548 {
1549 VTY_DECLVAR_CONTEXT(interface, ifp);
1550 int idx_number = 3;
1551 struct ospf6_interface *oi;
1552 assert(ifp);
1553
1554 oi = (struct ospf6_interface *)ifp->info;
1555 if (oi == NULL)
1556 oi = ospf6_interface_create(ifp);
1557 assert(oi);
1558
1559 oi->priority = strmatch(argv[0]->text, "no")
1560 ? OSPF6_INTERFACE_PRIORITY
1561 : strtoul(argv[idx_number]->arg, NULL, 10);
1562
1563 if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
1564 || oi->state == OSPF6_INTERFACE_BDR
1565 || oi->state == OSPF6_INTERFACE_DR))
1566 ospf6_interface_state_change(dr_election(oi), oi);
1567
1568 return CMD_SUCCESS;
1569 }
1570
1571 ALIAS (ipv6_ospf6_priority,
1572 no_ipv6_ospf6_priority_cmd,
1573 "no ipv6 ospf6 priority [(0-255)]",
1574 NO_STR
1575 IP6_STR
1576 OSPF6_STR
1577 "Router priority\n"
1578 "Priority value\n")
1579
1580 DEFUN (ipv6_ospf6_instance,
1581 ipv6_ospf6_instance_cmd,
1582 "ipv6 ospf6 instance-id (0-255)",
1583 IP6_STR
1584 OSPF6_STR
1585 "Instance ID for this interface\n"
1586 "Instance ID value\n")
1587 {
1588 VTY_DECLVAR_CONTEXT(interface, ifp);
1589 int idx_number = 3;
1590 struct ospf6_interface *oi;
1591 assert(ifp);
1592
1593 oi = (struct ospf6_interface *)ifp->info;
1594 if (oi == NULL)
1595 oi = ospf6_interface_create(ifp);
1596 assert(oi);
1597
1598 oi->instance_id = strmatch(argv[0]->text, "no")
1599 ? OSPF6_INTERFACE_INSTANCE_ID
1600 : strtoul(argv[idx_number]->arg, NULL, 10);
1601 return CMD_SUCCESS;
1602 }
1603
1604 ALIAS (ipv6_ospf6_instance,
1605 no_ipv6_ospf6_instance_cmd,
1606 "no ipv6 ospf6 instance-id [(0-255)]",
1607 NO_STR
1608 IP6_STR
1609 OSPF6_STR
1610 "Instance ID for this interface\n"
1611 "Instance ID value\n")
1612
1613 DEFUN (ipv6_ospf6_passive,
1614 ipv6_ospf6_passive_cmd,
1615 "ipv6 ospf6 passive",
1616 IP6_STR
1617 OSPF6_STR
1618 "Passive interface; no adjacency will be formed on this interface\n"
1619 )
1620 {
1621 VTY_DECLVAR_CONTEXT(interface, ifp);
1622 struct ospf6_interface *oi;
1623 struct listnode *node, *nnode;
1624 struct ospf6_neighbor *on;
1625
1626 assert(ifp);
1627
1628 oi = (struct ospf6_interface *)ifp->info;
1629 if (oi == NULL)
1630 oi = ospf6_interface_create(ifp);
1631 assert(oi);
1632
1633 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1634 THREAD_OFF(oi->thread_send_hello);
1635 THREAD_OFF(oi->thread_sso);
1636
1637 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1638 THREAD_OFF(on->inactivity_timer);
1639 thread_add_event(master, inactivity_timer, on, 0, NULL);
1640 }
1641
1642 return CMD_SUCCESS;
1643 }
1644
1645 DEFUN (no_ipv6_ospf6_passive,
1646 no_ipv6_ospf6_passive_cmd,
1647 "no ipv6 ospf6 passive",
1648 NO_STR
1649 IP6_STR
1650 OSPF6_STR
1651 "passive interface: No Adjacency will be formed on this I/F\n"
1652 )
1653 {
1654 VTY_DECLVAR_CONTEXT(interface, ifp);
1655 struct ospf6_interface *oi;
1656 assert(ifp);
1657
1658 oi = (struct ospf6_interface *)ifp->info;
1659 if (oi == NULL)
1660 oi = ospf6_interface_create(ifp);
1661 assert(oi);
1662
1663 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1664 THREAD_OFF(oi->thread_send_hello);
1665 THREAD_OFF(oi->thread_sso);
1666 thread_add_event(master, ospf6_hello_send, oi, 0,
1667 &oi->thread_send_hello);
1668
1669 return CMD_SUCCESS;
1670 }
1671
1672 DEFUN (ipv6_ospf6_mtu_ignore,
1673 ipv6_ospf6_mtu_ignore_cmd,
1674 "ipv6 ospf6 mtu-ignore",
1675 IP6_STR
1676 OSPF6_STR
1677 "Disable MTU mismatch detection on this interface\n"
1678 )
1679 {
1680 VTY_DECLVAR_CONTEXT(interface, ifp);
1681 struct ospf6_interface *oi;
1682 assert(ifp);
1683
1684 oi = (struct ospf6_interface *)ifp->info;
1685 if (oi == NULL)
1686 oi = ospf6_interface_create(ifp);
1687 assert(oi);
1688
1689 oi->mtu_ignore = 1;
1690
1691 return CMD_SUCCESS;
1692 }
1693
1694 DEFUN (no_ipv6_ospf6_mtu_ignore,
1695 no_ipv6_ospf6_mtu_ignore_cmd,
1696 "no ipv6 ospf6 mtu-ignore",
1697 NO_STR
1698 IP6_STR
1699 OSPF6_STR
1700 "Disable MTU mismatch detection on this interface\n"
1701 )
1702 {
1703 VTY_DECLVAR_CONTEXT(interface, ifp);
1704 struct ospf6_interface *oi;
1705 assert(ifp);
1706
1707 oi = (struct ospf6_interface *)ifp->info;
1708 if (oi == NULL)
1709 oi = ospf6_interface_create(ifp);
1710 assert(oi);
1711
1712 oi->mtu_ignore = 0;
1713
1714 return CMD_SUCCESS;
1715 }
1716
1717 DEFUN (ipv6_ospf6_advertise_prefix_list,
1718 ipv6_ospf6_advertise_prefix_list_cmd,
1719 "ipv6 ospf6 advertise prefix-list WORD",
1720 IP6_STR
1721 OSPF6_STR
1722 "Advertising options\n"
1723 "Filter prefix using prefix-list\n"
1724 "Prefix list name\n"
1725 )
1726 {
1727 VTY_DECLVAR_CONTEXT(interface, ifp);
1728 int idx_word = 4;
1729 struct ospf6_interface *oi;
1730 assert(ifp);
1731
1732 oi = (struct ospf6_interface *)ifp->info;
1733 if (oi == NULL)
1734 oi = ospf6_interface_create(ifp);
1735 assert(oi);
1736
1737 if (oi->plist_name)
1738 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
1739 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
1740
1741 ospf6_interface_connected_route_update(oi->interface);
1742
1743 if (oi->area) {
1744 OSPF6_LINK_LSA_SCHEDULE(oi);
1745 if (oi->state == OSPF6_INTERFACE_DR) {
1746 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1747 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1748 }
1749 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1750 }
1751
1752 return CMD_SUCCESS;
1753 }
1754
1755 DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1756 no_ipv6_ospf6_advertise_prefix_list_cmd,
1757 "no ipv6 ospf6 advertise prefix-list [WORD]",
1758 NO_STR
1759 IP6_STR
1760 OSPF6_STR
1761 "Advertising options\n"
1762 "Filter prefix using prefix-list\n"
1763 "Prefix list name\n")
1764 {
1765 VTY_DECLVAR_CONTEXT(interface, ifp);
1766 struct ospf6_interface *oi;
1767 assert(ifp);
1768
1769 oi = (struct ospf6_interface *)ifp->info;
1770 if (oi == NULL)
1771 oi = ospf6_interface_create(ifp);
1772 assert(oi);
1773
1774 if (oi->plist_name)
1775 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
1776
1777 ospf6_interface_connected_route_update(oi->interface);
1778
1779 if (oi->area) {
1780 OSPF6_LINK_LSA_SCHEDULE(oi);
1781 if (oi->state == OSPF6_INTERFACE_DR) {
1782 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1783 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1784 }
1785 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1786 }
1787
1788 return CMD_SUCCESS;
1789 }
1790
1791 DEFUN (ipv6_ospf6_network,
1792 ipv6_ospf6_network_cmd,
1793 "ipv6 ospf6 network <broadcast|point-to-point>",
1794 IP6_STR
1795 OSPF6_STR
1796 "Network type\n"
1797 "Specify OSPF6 broadcast network\n"
1798 "Specify OSPF6 point-to-point network\n"
1799 )
1800 {
1801 VTY_DECLVAR_CONTEXT(interface, ifp);
1802 int idx_network = 3;
1803 struct ospf6_interface *oi;
1804 assert(ifp);
1805
1806 oi = (struct ospf6_interface *)ifp->info;
1807 if (oi == NULL) {
1808 oi = ospf6_interface_create(ifp);
1809 }
1810 assert(oi);
1811
1812 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
1813 if (oi->type == OSPF_IFTYPE_BROADCAST)
1814 return CMD_SUCCESS;
1815
1816 oi->type = OSPF_IFTYPE_BROADCAST;
1817 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
1818 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
1819 return CMD_SUCCESS;
1820 }
1821 oi->type = OSPF_IFTYPE_POINTOPOINT;
1822 }
1823
1824 /* Reset the interface */
1825 thread_execute(master, interface_down, oi, 0);
1826 thread_execute(master, interface_up, oi, 0);
1827
1828 return CMD_SUCCESS;
1829 }
1830
1831 DEFUN (no_ipv6_ospf6_network,
1832 no_ipv6_ospf6_network_cmd,
1833 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
1834 NO_STR
1835 IP6_STR
1836 OSPF6_STR
1837 "Set default network type\n"
1838 "Specify OSPF6 broadcast network\n"
1839 "Specify OSPF6 point-to-point network\n")
1840 {
1841 VTY_DECLVAR_CONTEXT(interface, ifp);
1842 struct ospf6_interface *oi;
1843 int type;
1844
1845 assert(ifp);
1846
1847 oi = (struct ospf6_interface *)ifp->info;
1848 if (oi == NULL) {
1849 return CMD_SUCCESS;
1850 }
1851
1852 type = ospf6_default_iftype(ifp);
1853 if (oi->type == type) {
1854 return CMD_SUCCESS;
1855 }
1856 oi->type = type;
1857
1858 /* Reset the interface */
1859 thread_execute(master, interface_down, oi, 0);
1860 thread_execute(master, interface_up, oi, 0);
1861
1862 return CMD_SUCCESS;
1863 }
1864
1865 static int config_write_ospf6_interface(struct vty *vty)
1866 {
1867 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1868 struct ospf6_interface *oi;
1869 struct interface *ifp;
1870
1871 FOR_ALL_INTERFACES (vrf, ifp) {
1872 oi = (struct ospf6_interface *)ifp->info;
1873 if (oi == NULL)
1874 continue;
1875
1876 vty_frame(vty, "interface %s\n", oi->interface->name);
1877
1878 if (ifp->desc)
1879 vty_out(vty, " description %s\n", ifp->desc);
1880 if (oi->c_ifmtu)
1881 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
1882
1883 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
1884 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
1885
1886 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1887 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
1888 oi->hello_interval);
1889
1890 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1891 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
1892 oi->dead_interval);
1893
1894 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1895 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
1896 oi->rxmt_interval);
1897
1898 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1899 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
1900
1901 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1902 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
1903 oi->transdelay);
1904
1905 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1906 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
1907 oi->instance_id);
1908
1909 if (oi->plist_name)
1910 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
1911 oi->plist_name);
1912
1913 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
1914 vty_out(vty, " ipv6 ospf6 passive\n");
1915
1916 if (oi->mtu_ignore)
1917 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
1918
1919 if (oi->type != ospf6_default_iftype(ifp)) {
1920 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
1921 vty_out(vty,
1922 " ipv6 ospf6 network point-to-point\n");
1923 else if (oi->type == OSPF_IFTYPE_BROADCAST)
1924 vty_out(vty, " ipv6 ospf6 network broadcast\n");
1925 }
1926
1927 ospf6_bfd_write_config(vty, oi);
1928
1929 vty_endframe(vty, "!\n");
1930 }
1931 return 0;
1932 }
1933
1934 static struct cmd_node interface_node = {
1935 INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */
1936 };
1937
1938 void ospf6_interface_init(void)
1939 {
1940 /* Install interface node. */
1941 install_node(&interface_node, config_write_ospf6_interface);
1942 if_cmd_init();
1943
1944 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
1945 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1946 install_element(VIEW_NODE,
1947 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
1948 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
1949
1950 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
1951 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
1952 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
1953 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
1954
1955 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1956 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1957 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1958 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1959 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1960 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
1961 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
1962 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
1963 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
1964 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
1965 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
1966 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
1967
1968 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1969 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
1970
1971 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
1972 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
1973
1974 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1975 install_element(INTERFACE_NODE,
1976 &no_ipv6_ospf6_advertise_prefix_list_cmd);
1977
1978 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
1979 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
1980
1981 /* reference bandwidth commands */
1982 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
1983 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
1984 }
1985
1986 /* Clear the specified interface structure */
1987 static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
1988 {
1989 struct ospf6_interface *oi;
1990
1991 if (!if_is_operative(ifp))
1992 return;
1993
1994 if (ifp->info == NULL)
1995 return;
1996
1997 oi = (struct ospf6_interface *)ifp->info;
1998
1999 if (IS_OSPF6_DEBUG_INTERFACE)
2000 zlog_debug("Interface %s: clear by reset", ifp->name);
2001
2002 /* Reset the interface */
2003 thread_execute(master, interface_down, oi, 0);
2004 thread_execute(master, interface_up, oi, 0);
2005 }
2006
2007 /* Clear interface */
2008 DEFUN (clear_ipv6_ospf6_interface,
2009 clear_ipv6_ospf6_interface_cmd,
2010 "clear ipv6 ospf6 interface [IFNAME]",
2011 CLEAR_STR
2012 IP6_STR
2013 OSPF6_STR
2014 INTERFACE_STR
2015 IFNAME_STR
2016 )
2017 {
2018 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
2019 int idx_ifname = 4;
2020 struct interface *ifp;
2021
2022 if (argc == 4) /* Clear all the ospfv3 interfaces. */
2023 {
2024 FOR_ALL_INTERFACES (vrf, ifp)
2025 ospf6_interface_clear(vty, ifp);
2026 } else /* Interface name is specified. */
2027 {
2028 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
2029 VRF_DEFAULT))
2030 == NULL) {
2031 vty_out(vty, "No such Interface: %s\n",
2032 argv[idx_ifname]->arg);
2033 return CMD_WARNING;
2034 }
2035 ospf6_interface_clear(vty, ifp);
2036 }
2037
2038 return CMD_SUCCESS;
2039 }
2040
2041 void install_element_ospf6_clear_interface(void)
2042 {
2043 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
2044 }
2045
2046 DEFUN (debug_ospf6_interface,
2047 debug_ospf6_interface_cmd,
2048 "debug ospf6 interface",
2049 DEBUG_STR
2050 OSPF6_STR
2051 "Debug OSPFv3 Interface\n"
2052 )
2053 {
2054 OSPF6_DEBUG_INTERFACE_ON();
2055 return CMD_SUCCESS;
2056 }
2057
2058 DEFUN (no_debug_ospf6_interface,
2059 no_debug_ospf6_interface_cmd,
2060 "no debug ospf6 interface",
2061 NO_STR
2062 DEBUG_STR
2063 OSPF6_STR
2064 "Debug OSPFv3 Interface\n"
2065 )
2066 {
2067 OSPF6_DEBUG_INTERFACE_OFF();
2068 return CMD_SUCCESS;
2069 }
2070
2071 int config_write_ospf6_debug_interface(struct vty *vty)
2072 {
2073 if (IS_OSPF6_DEBUG_INTERFACE)
2074 vty_out(vty, "debug ospf6 interface\n");
2075 return 0;
2076 }
2077
2078 void install_element_ospf6_debug_interface(void)
2079 {
2080 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2081 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2082 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2083 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
2084 }