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