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