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