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