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