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