]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_interface.c
tools: improve explanation of 'wrap' options
[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_abr.h"
40 #include "ospf6_interface.h"
41 #include "ospf6_neighbor.h"
42 #include "ospf6_intra.h"
43 #include "ospf6_spf.h"
44 #include "ospf6d.h"
45 #include "ospf6_bfd.h"
46 #include "ospf6_zebra.h"
47 #include "ospf6_gr.h"
48 #include "lib/json.h"
49 #include "ospf6_proto.h"
50 #include "lib/keychain.h"
51 #include "ospf6_auth_trailer.h"
52
53 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_IF, "OSPF6 interface");
54 DEFINE_MTYPE(OSPF6D, OSPF6_AUTH_KEYCHAIN, "OSPF6 auth keychain");
55 DEFINE_MTYPE(OSPF6D, OSPF6_AUTH_MANUAL_KEY, "OSPF6 auth key");
56 DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names");
57 DEFINE_QOBJ_TYPE(ospf6_interface);
58 DEFINE_HOOK(ospf6_interface_change,
59 (struct ospf6_interface * oi, int state, int old_state),
60 (oi, state, old_state));
61
62 unsigned char conf_debug_ospf6_interface = 0;
63
64 const char *const ospf6_interface_state_str[] = {
65 "None", "Down", "Loopback", "Waiting", "PointToPoint",
66 "DROther", "BDR", "DR", NULL};
67
68 int ospf6_interface_neighbor_count(struct ospf6_interface *oi)
69 {
70 int count = 0;
71 struct ospf6_neighbor *nbr = NULL;
72 struct listnode *node;
73
74 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, nbr)) {
75 /* Down state is not shown. */
76 if (nbr->state == OSPF6_NEIGHBOR_DOWN)
77 continue;
78 count++;
79 }
80
81 return count;
82 }
83
84 struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex,
85 vrf_id_t vrf_id)
86 {
87 struct ospf6_interface *oi;
88 struct interface *ifp;
89
90 ifp = if_lookup_by_index(ifindex, vrf_id);
91 if (ifp == NULL)
92 return (struct ospf6_interface *)NULL;
93
94 oi = (struct ospf6_interface *)ifp->info;
95 return oi;
96 }
97
98 /* schedule routing table recalculation */
99 static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa,
100 unsigned int reason)
101 {
102 struct ospf6_interface *oi;
103
104 if (lsa == NULL)
105 return;
106
107 oi = lsa->lsdb->data;
108 switch (ntohs(lsa->header->type)) {
109 case OSPF6_LSTYPE_LINK:
110 if (oi->state == OSPF6_INTERFACE_DR)
111 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
112 if (oi->area)
113 ospf6_spf_schedule(oi->area->ospf6, reason);
114 break;
115
116 default:
117 break;
118 }
119 }
120
121 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa *lsa)
122 {
123 ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa));
124 }
125
126 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa *lsa)
127 {
128 ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa));
129 }
130
131 static uint8_t ospf6_default_iftype(struct interface *ifp)
132 {
133 if (if_is_pointopoint(ifp))
134 return OSPF_IFTYPE_POINTOPOINT;
135 else if (if_is_loopback(ifp))
136 return OSPF_IFTYPE_LOOPBACK;
137 else
138 return OSPF_IFTYPE_BROADCAST;
139 }
140
141 static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
142 {
143 /* If all else fails, use default OSPF cost */
144 uint32_t cost;
145 uint32_t bw, refbw;
146 struct ospf6 *ospf6;
147 /* interface speed and bw can be 0 in some platforms,
148 * use ospf default bw. If bw is configured then it would
149 * be used.
150 */
151 if (!oi->interface->bandwidth && oi->interface->speed) {
152 bw = oi->interface->speed;
153 } else {
154 bw = oi->interface->bandwidth ? oi->interface->bandwidth
155 : OSPF6_INTERFACE_BANDWIDTH;
156 }
157
158 ospf6 = oi->interface->vrf->info;
159 refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
160
161 /* A specified ip ospf cost overrides a calculated one. */
162 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
163 cost = oi->cost;
164 else {
165 cost = (uint32_t)((double)refbw / (double)bw + (double)0.5);
166 if (cost < 1)
167 cost = 1;
168 else if (cost > UINT32_MAX)
169 cost = UINT32_MAX;
170 }
171
172 return cost;
173 }
174
175 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface *oi)
176 {
177 /* update cost held in route_connected list in ospf6_interface */
178 ospf6_interface_connected_route_update(oi->interface);
179
180 /* execute LSA hooks */
181 if (oi->area) {
182 OSPF6_LINK_LSA_SCHEDULE(oi);
183 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
184 OSPF6_NETWORK_LSA_SCHEDULE(oi);
185 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
186 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
187 }
188 }
189
190 static void ospf6_interface_recalculate_cost(struct ospf6_interface *oi)
191 {
192 uint32_t newcost;
193
194 newcost = ospf6_interface_get_cost(oi);
195 if (newcost == oi->cost)
196 return;
197 oi->cost = newcost;
198
199 ospf6_interface_force_recalculate_cost(oi);
200 }
201
202 /* Create new ospf6 interface structure */
203 struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
204 {
205 struct ospf6_interface *oi;
206 unsigned int iobuflen;
207
208 oi = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
209
210 oi->obuf = ospf6_fifo_new();
211
212 oi->area = (struct ospf6_area *)NULL;
213 oi->neighbor_list = list_new();
214 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
215 oi->linklocal_addr = (struct in6_addr *)NULL;
216 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
217 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
218 oi->priority = OSPF6_INTERFACE_PRIORITY;
219
220 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
221 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
222 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
223 oi->type = ospf6_default_iftype(ifp);
224 oi->state = OSPF6_INTERFACE_DOWN;
225 oi->flag = 0;
226 oi->mtu_ignore = 0;
227 oi->c_ifmtu = 0;
228
229 /* Try to adjust I/O buffer size with IfMtu */
230 oi->ifmtu = ifp->mtu6;
231 iobuflen = ospf6_iobuf_size(ifp->mtu6);
232 if (oi->ifmtu > iobuflen) {
233 if (IS_OSPF6_DEBUG_INTERFACE)
234 zlog_debug(
235 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
236 ifp->name, iobuflen);
237 oi->ifmtu = iobuflen;
238 }
239
240 QOBJ_REG(oi, ospf6_interface);
241
242 oi->lsupdate_list = ospf6_lsdb_create(oi);
243 oi->lsack_list = ospf6_lsdb_create(oi);
244 oi->lsdb = ospf6_lsdb_create(oi);
245 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
246 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
247 oi->lsdb_self = ospf6_lsdb_create(oi);
248
249 oi->route_connected =
250 OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
251 oi->route_connected->scope = oi;
252
253 /* link both */
254 oi->interface = ifp;
255 ifp->info = oi;
256
257 /* Compute cost. */
258 oi->cost = ospf6_interface_get_cost(oi);
259
260 oi->at_data.flags = 0;
261
262 return oi;
263 }
264
265 void ospf6_interface_delete(struct ospf6_interface *oi)
266 {
267 struct listnode *node, *nnode;
268 struct ospf6_neighbor *on;
269
270 QOBJ_UNREG(oi);
271
272 ospf6_fifo_free(oi->obuf);
273
274 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
275 ospf6_neighbor_delete(on);
276
277 list_delete(&oi->neighbor_list);
278
279 THREAD_OFF(oi->thread_send_hello);
280 THREAD_OFF(oi->thread_send_lsupdate);
281 THREAD_OFF(oi->thread_send_lsack);
282 THREAD_OFF(oi->thread_sso);
283 THREAD_OFF(oi->thread_wait_timer);
284
285 ospf6_lsdb_remove_all(oi->lsdb);
286 ospf6_lsdb_remove_all(oi->lsupdate_list);
287 ospf6_lsdb_remove_all(oi->lsack_list);
288
289 ospf6_lsdb_delete(oi->lsdb);
290 ospf6_lsdb_delete(oi->lsdb_self);
291
292 ospf6_lsdb_delete(oi->lsupdate_list);
293 ospf6_lsdb_delete(oi->lsack_list);
294
295 ospf6_route_table_delete(oi->route_connected);
296
297 /* cut link */
298 oi->interface->info = NULL;
299
300 /* plist_name */
301 if (oi->plist_name)
302 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
303
304 /* disable from area list if possible */
305 ospf6_area_interface_delete(oi);
306
307 /* Free BFD allocated data. */
308 XFREE(MTYPE_TMP, oi->bfd_config.profile);
309
310 XFREE(MTYPE_OSPF6_IF, oi);
311 }
312
313 void ospf6_interface_enable(struct ospf6_interface *oi)
314 {
315 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
316 ospf6_interface_state_update(oi->interface);
317 }
318
319 void ospf6_interface_disable(struct ospf6_interface *oi)
320 {
321 SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
322
323 thread_execute(master, interface_down, oi, 0);
324
325 ospf6_lsdb_remove_all(oi->lsdb);
326 ospf6_lsdb_remove_all(oi->lsdb_self);
327 ospf6_lsdb_remove_all(oi->lsupdate_list);
328 ospf6_lsdb_remove_all(oi->lsack_list);
329
330 THREAD_OFF(oi->thread_send_hello);
331 THREAD_OFF(oi->thread_send_lsupdate);
332 THREAD_OFF(oi->thread_send_lsack);
333 THREAD_OFF(oi->thread_sso);
334
335 THREAD_OFF(oi->thread_network_lsa);
336 THREAD_OFF(oi->thread_link_lsa);
337 THREAD_OFF(oi->thread_intra_prefix_lsa);
338 THREAD_OFF(oi->thread_as_extern_lsa);
339 THREAD_OFF(oi->thread_wait_timer);
340 }
341
342 static struct in6_addr *
343 ospf6_interface_get_linklocal_address(struct interface *ifp)
344 {
345 struct listnode *n;
346 struct connected *c;
347 struct in6_addr *l = (struct in6_addr *)NULL;
348
349 /* for each connected address */
350 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
351 /* if family not AF_INET6, ignore */
352 if (c->address->family != AF_INET6)
353 continue;
354
355 /* linklocal scope check */
356 if (IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
357 l = &c->address->u.prefix6;
358 }
359 return l;
360 }
361
362 void ospf6_interface_state_update(struct interface *ifp)
363 {
364 struct ospf6_interface *oi;
365 unsigned int iobuflen;
366
367 oi = (struct ospf6_interface *)ifp->info;
368 if (oi == NULL)
369 return;
370 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
371 return;
372
373 /* Adjust the mtu values if the kernel told us something new */
374 if (ifp->mtu6 != oi->ifmtu) {
375 /* If nothing configured, accept it and check for buffer size */
376 if (!oi->c_ifmtu) {
377 oi->ifmtu = ifp->mtu6;
378 iobuflen = ospf6_iobuf_size(ifp->mtu6);
379 if (oi->ifmtu > iobuflen) {
380 if (IS_OSPF6_DEBUG_INTERFACE)
381 zlog_debug(
382 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
383 ifp->name, iobuflen);
384 oi->ifmtu = iobuflen;
385 }
386 } else if (oi->c_ifmtu > ifp->mtu6) {
387 oi->ifmtu = ifp->mtu6;
388 zlog_warn(
389 "Configured mtu %u on %s overridden by kernel %u",
390 oi->c_ifmtu, ifp->name, ifp->mtu6);
391 } else
392 oi->ifmtu = oi->c_ifmtu;
393 }
394
395 if (if_is_operative(ifp)
396 && (ospf6_interface_get_linklocal_address(oi->interface)
397 || if_is_loopback(oi->interface)))
398 thread_execute(master, interface_up, oi, 0);
399 else
400 thread_execute(master, interface_down, oi, 0);
401
402 return;
403 }
404
405 void ospf6_interface_connected_route_update(struct interface *ifp)
406 {
407 struct ospf6_interface *oi;
408 struct ospf6_route *route;
409 struct connected *c;
410 struct listnode *node, *nnode;
411 struct in6_addr nh_addr;
412
413 oi = (struct ospf6_interface *)ifp->info;
414 if (oi == NULL)
415 return;
416
417 /* reset linklocal pointer */
418 oi->linklocal_addr = ospf6_interface_get_linklocal_address(ifp);
419
420 /* if area is null, do not make connected-route list */
421 if (oi->area == NULL)
422 return;
423
424 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
425 return;
426
427 /* update "route to advertise" interface route table */
428 ospf6_route_remove_all(oi->route_connected);
429
430 for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
431 if (c->address->family != AF_INET6)
432 continue;
433
434 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE,
435 c->address);
436 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE,
437 c->address);
438 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE,
439 c->address);
440 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE,
441 c->address);
442 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE,
443 c->address);
444
445 /* apply filter */
446 if (oi->plist_name) {
447 struct prefix_list *plist;
448 enum prefix_list_type ret;
449
450 plist = prefix_list_lookup(AFI_IP6, oi->plist_name);
451 ret = prefix_list_apply(plist, (void *)c->address);
452 if (ret == PREFIX_DENY) {
453 if (IS_OSPF6_DEBUG_INTERFACE)
454 zlog_debug(
455 "%pFX on %s filtered by prefix-list %s ",
456 c->address, oi->interface->name,
457 oi->plist_name);
458 continue;
459 }
460 }
461
462 route = ospf6_route_create(oi->area->ospf6);
463 memcpy(&route->prefix, c->address, sizeof(struct prefix));
464 apply_mask(&route->prefix);
465 route->type = OSPF6_DEST_TYPE_NETWORK;
466 route->path.area_id = oi->area->area_id;
467 route->path.type = OSPF6_PATH_TYPE_INTRA;
468 route->path.cost = oi->cost;
469 inet_pton(AF_INET6, "::1", &nh_addr);
470 ospf6_route_add_nexthop(route, oi->interface->ifindex,
471 &nh_addr);
472 ospf6_route_add(route, oi->route_connected);
473 }
474
475 /* create new Link-LSA */
476 OSPF6_LINK_LSA_SCHEDULE(oi);
477 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
478 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
479 }
480
481 static int ospf6_interface_state_change(uint8_t next_state,
482 struct ospf6_interface *oi)
483 {
484 uint8_t prev_state;
485 struct ospf6 *ospf6;
486
487 prev_state = oi->state;
488 oi->state = next_state;
489
490 if (prev_state == next_state)
491 return -1;
492
493 if (!oi->area)
494 return -1;
495
496 /* log */
497 if (IS_OSPF6_DEBUG_INTERFACE) {
498 zlog_debug("Interface state change %s: %s -> %s",
499 oi->interface->name,
500 ospf6_interface_state_str[prev_state],
501 ospf6_interface_state_str[next_state]);
502 }
503 oi->state_change++;
504
505 ospf6 = oi->area->ospf6;
506
507 if ((prev_state == OSPF6_INTERFACE_DR
508 || prev_state == OSPF6_INTERFACE_BDR)
509 && (next_state != OSPF6_INTERFACE_DR
510 && next_state != OSPF6_INTERFACE_BDR))
511 ospf6_sso(oi->interface->ifindex, &alldrouters6,
512 IPV6_LEAVE_GROUP, ospf6->fd);
513
514 if ((prev_state != OSPF6_INTERFACE_DR
515 && prev_state != OSPF6_INTERFACE_BDR)
516 && (next_state == OSPF6_INTERFACE_DR
517 || next_state == OSPF6_INTERFACE_BDR))
518 ospf6_sso(oi->interface->ifindex, &alldrouters6,
519 IPV6_JOIN_GROUP, ospf6->fd);
520
521 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
522 OSPF6_LINK_LSA_SCHEDULE(oi);
523 if (next_state == OSPF6_INTERFACE_DOWN) {
524 OSPF6_NETWORK_LSA_EXECUTE(oi);
525 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
526 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
527 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
528 } else if (prev_state == OSPF6_INTERFACE_DR
529 || next_state == OSPF6_INTERFACE_DR) {
530 OSPF6_NETWORK_LSA_SCHEDULE(oi);
531 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
532 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
533 }
534
535 hook_call(ospf6_interface_change, oi, next_state, prev_state);
536
537 return 0;
538 }
539
540
541 /* DR Election, RFC2328 section 9.4 */
542
543 #define IS_ELIGIBLE(n) \
544 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
545
546 static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a,
547 struct ospf6_neighbor *b)
548 {
549 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
550 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id))
551 return NULL;
552 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
553 return b;
554 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)
555 return a;
556
557 if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
558 return a;
559 if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
560 return b;
561
562 if (a->priority > b->priority)
563 return a;
564 if (a->priority < b->priority)
565 return b;
566
567 if (ntohl(a->router_id) > ntohl(b->router_id))
568 return a;
569 if (ntohl(a->router_id) < ntohl(b->router_id))
570 return b;
571
572 zlog_warn("Router-ID duplicate ?");
573 return a;
574 }
575
576 static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
577 struct ospf6_neighbor *b)
578 {
579 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
580 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id))
581 return NULL;
582 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
583 return b;
584 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)
585 return a;
586
587 if (a->drouter == a->router_id && b->drouter != b->router_id)
588 return a;
589 if (a->drouter != a->router_id && b->drouter == b->router_id)
590 return b;
591
592 if (a->priority > b->priority)
593 return a;
594 if (a->priority < b->priority)
595 return b;
596
597 if (ntohl(a->router_id) > ntohl(b->router_id))
598 return a;
599 if (ntohl(a->router_id) < ntohl(b->router_id))
600 return b;
601
602 zlog_warn("Router-ID duplicate ?");
603 return a;
604 }
605
606 uint8_t dr_election(struct ospf6_interface *oi)
607 {
608 struct listnode *node, *nnode;
609 struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
610 struct ospf6_neighbor *best_drouter, *best_bdrouter;
611 uint8_t next_state = 0;
612
613 drouter = bdrouter = NULL;
614 best_drouter = best_bdrouter = NULL;
615
616 /* pseudo neighbor myself, including noting current DR/BDR (1) */
617 memset(&myself, 0, sizeof(myself));
618 inet_ntop(AF_INET, &oi->area->ospf6->router_id, myself.name,
619 sizeof(myself.name));
620 myself.state = OSPF6_NEIGHBOR_TWOWAY;
621 myself.drouter = oi->drouter;
622 myself.bdrouter = oi->bdrouter;
623 myself.priority = oi->priority;
624 myself.router_id = oi->area->ospf6->router_id;
625
626 /* Electing BDR (2) */
627 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
628 bdrouter = better_bdrouter(bdrouter, on);
629
630 best_bdrouter = bdrouter;
631 bdrouter = better_bdrouter(best_bdrouter, &myself);
632
633 /* Electing DR (3) */
634 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
635 drouter = better_drouter(drouter, on);
636
637 best_drouter = drouter;
638 drouter = better_drouter(best_drouter, &myself);
639 if (drouter == NULL)
640 drouter = bdrouter;
641
642 /* the router itself is newly/no longer DR/BDR (4) */
643 if ((drouter == &myself && myself.drouter != myself.router_id)
644 || (drouter != &myself && myself.drouter == myself.router_id)
645 || (bdrouter == &myself && myself.bdrouter != myself.router_id)
646 || (bdrouter != &myself && myself.bdrouter == myself.router_id)) {
647 myself.drouter = (drouter ? drouter->router_id : htonl(0));
648 myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
649
650 /* compatible to Electing BDR (2) */
651 bdrouter = better_bdrouter(best_bdrouter, &myself);
652
653 /* compatible to Electing DR (3) */
654 drouter = better_drouter(best_drouter, &myself);
655 if (drouter == NULL)
656 drouter = bdrouter;
657 }
658
659 /* Set interface state accordingly (5) */
660 if (drouter && drouter == &myself)
661 next_state = OSPF6_INTERFACE_DR;
662 else if (bdrouter && bdrouter == &myself)
663 next_state = OSPF6_INTERFACE_BDR;
664 else
665 next_state = OSPF6_INTERFACE_DROTHER;
666
667 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
668 /* XXX */
669
670 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
671 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
672 accordingly after AdjOK */
673 if (oi->drouter != (drouter ? drouter->router_id : htonl(0))
674 || oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0))) {
675 if (IS_OSPF6_DEBUG_INTERFACE)
676 zlog_debug("DR Election on %s: DR: %s BDR: %s",
677 oi->interface->name,
678 (drouter ? drouter->name : "0.0.0.0"),
679 (bdrouter ? bdrouter->name : "0.0.0.0"));
680
681 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) {
682 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
683 continue;
684 /* Schedule AdjOK. */
685 thread_add_event(master, adj_ok, on, 0,
686 &on->thread_adj_ok);
687 }
688 }
689
690 oi->drouter = (drouter ? drouter->router_id : htonl(0));
691 oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
692 return next_state;
693 }
694
695 #ifdef __FreeBSD__
696
697 #include <ifaddrs.h>
698
699 static bool ifmaddr_check(ifindex_t ifindex, struct in6_addr *addr)
700 {
701 struct ifmaddrs *ifmap, *ifma;
702 struct sockaddr_dl *sdl;
703 struct sockaddr_in6 *sin6;
704 bool found = false;
705
706 if (getifmaddrs(&ifmap) != 0)
707 return false;
708
709 for (ifma = ifmap; ifma; ifma = ifma->ifma_next) {
710 if (ifma->ifma_name == NULL || ifma->ifma_addr == NULL)
711 continue;
712 if (ifma->ifma_name->sa_family != AF_LINK)
713 continue;
714 if (ifma->ifma_addr->sa_family != AF_INET6)
715 continue;
716 sdl = (struct sockaddr_dl *)ifma->ifma_name;
717 sin6 = (struct sockaddr_in6 *)ifma->ifma_addr;
718 if (sdl->sdl_index == ifindex
719 && memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) {
720 found = true;
721 break;
722 }
723 }
724
725 if (ifmap)
726 freeifmaddrs(ifmap);
727
728 return found;
729 }
730
731 #endif /* __FreeBSD__ */
732
733 /* Interface State Machine */
734 void interface_up(struct thread *thread)
735 {
736 struct ospf6_interface *oi;
737 struct ospf6 *ospf6;
738
739 oi = (struct ospf6_interface *)THREAD_ARG(thread);
740 assert(oi && oi->interface);
741
742 if (!oi->type_cfg)
743 oi->type = ospf6_default_iftype(oi->interface);
744
745 thread_cancel(&oi->thread_sso);
746
747 if (IS_OSPF6_DEBUG_INTERFACE)
748 zlog_debug("Interface Event %s: [InterfaceUp]",
749 oi->interface->name);
750
751 /* check physical interface is up */
752 if (!if_is_operative(oi->interface)) {
753 zlog_warn("Interface %s is down, can't execute [InterfaceUp]",
754 oi->interface->name);
755 return;
756 }
757
758 /* check interface has a link-local address */
759 if (!(ospf6_interface_get_linklocal_address(oi->interface)
760 || if_is_loopback(oi->interface))) {
761 zlog_warn(
762 "Interface %s has no link local address, can't execute [InterfaceUp]",
763 oi->interface->name);
764 return;
765 }
766
767 /* Recompute cost */
768 ospf6_interface_recalculate_cost(oi);
769
770 /* if already enabled, do nothing */
771 if (oi->state > OSPF6_INTERFACE_DOWN) {
772 if (IS_OSPF6_DEBUG_INTERFACE)
773 zlog_debug("Interface %s already enabled",
774 oi->interface->name);
775 return;
776 }
777
778 /* If no area assigned, return */
779 if (oi->area == NULL) {
780 zlog_warn(
781 "%s: Not scheduling Hello for %s as there is no area assigned yet",
782 __func__, oi->interface->name);
783 return;
784 }
785
786 #ifdef __FreeBSD__
787 /*
788 * There's a delay in FreeBSD between issuing a command to leave a
789 * multicast group and an actual leave. If we execute "no router ospf6"
790 * and "router ospf6" fast enough, we can end up in a situation when OS
791 * performs the leave later than it performs the join and the interface
792 * remains without a multicast group. We have to do the join only after
793 * the interface actually left the group.
794 */
795 if (ifmaddr_check(oi->interface->ifindex, &allspfrouters6)) {
796 zlog_info(
797 "Interface %s is still in all routers group, rescheduling for SSO",
798 oi->interface->name);
799 thread_add_timer(master, interface_up, oi,
800 OSPF6_INTERFACE_SSO_RETRY_INT,
801 &oi->thread_sso);
802 return;
803 }
804 #endif /* __FreeBSD__ */
805
806 ospf6 = oi->area->ospf6;
807
808 /* Join AllSPFRouters */
809 if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP,
810 ospf6->fd)
811 < 0) {
812 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
813 zlog_info(
814 "Scheduling %s for sso retry, trial count: %d",
815 oi->interface->name, oi->sso_try_cnt);
816 thread_add_timer(master, interface_up, oi,
817 OSPF6_INTERFACE_SSO_RETRY_INT,
818 &oi->thread_sso);
819 }
820 return;
821 }
822 oi->sso_try_cnt = 0; /* Reset on success */
823
824 /* Update interface route */
825 ospf6_interface_connected_route_update(oi->interface);
826
827 /* Schedule Hello */
828 if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
829 && !if_is_loopback(oi->interface)) {
830 thread_add_timer(master, ospf6_hello_send, oi, 0,
831 &oi->thread_send_hello);
832 }
833
834 /* decide next interface state */
835 if (oi->type == OSPF_IFTYPE_LOOPBACK) {
836 ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK, oi);
837 } else if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
838 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
839 } else if (oi->priority == 0)
840 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
841 else {
842 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
843 thread_add_timer(master, wait_timer, oi, oi->dead_interval,
844 &oi->thread_wait_timer);
845 }
846 }
847
848 void wait_timer(struct thread *thread)
849 {
850 struct ospf6_interface *oi;
851
852 oi = (struct ospf6_interface *)THREAD_ARG(thread);
853 assert(oi && oi->interface);
854
855 if (IS_OSPF6_DEBUG_INTERFACE)
856 zlog_debug("Interface Event %s: [WaitTimer]",
857 oi->interface->name);
858
859 if (oi->state == OSPF6_INTERFACE_WAITING)
860 ospf6_interface_state_change(dr_election(oi), oi);
861 }
862
863 void backup_seen(struct thread *thread)
864 {
865 struct ospf6_interface *oi;
866
867 oi = (struct ospf6_interface *)THREAD_ARG(thread);
868 assert(oi && oi->interface);
869
870 if (IS_OSPF6_DEBUG_INTERFACE)
871 zlog_debug("Interface Event %s: [BackupSeen]",
872 oi->interface->name);
873
874 if (oi->state == OSPF6_INTERFACE_WAITING)
875 ospf6_interface_state_change(dr_election(oi), oi);
876 }
877
878 void neighbor_change(struct thread *thread)
879 {
880 struct ospf6_interface *oi;
881
882 oi = (struct ospf6_interface *)THREAD_ARG(thread);
883 assert(oi && oi->interface);
884
885 if (IS_OSPF6_DEBUG_INTERFACE)
886 zlog_debug("Interface Event %s: [NeighborChange]",
887 oi->interface->name);
888
889 if (oi->state == OSPF6_INTERFACE_DROTHER
890 || oi->state == OSPF6_INTERFACE_BDR
891 || oi->state == OSPF6_INTERFACE_DR)
892 ospf6_interface_state_change(dr_election(oi), oi);
893 }
894
895 void interface_down(struct thread *thread)
896 {
897 struct ospf6_interface *oi;
898 struct listnode *node, *nnode;
899 struct ospf6_neighbor *on;
900 struct ospf6 *ospf6;
901
902 oi = (struct ospf6_interface *)THREAD_ARG(thread);
903 assert(oi && oi->interface);
904
905 if (IS_OSPF6_DEBUG_INTERFACE)
906 zlog_debug("Interface Event %s: [InterfaceDown]",
907 oi->interface->name);
908
909 /* Stop Hellos */
910 THREAD_OFF(oi->thread_send_hello);
911
912 /* Stop trying to set socket options. */
913 THREAD_OFF(oi->thread_sso);
914
915 /* Cease the HELPER role for all the neighbours
916 * of this interface.
917 */
918 if (ospf6_interface_neighbor_count(oi)) {
919 struct listnode *ln;
920 struct ospf6_neighbor *nbr = NULL;
921
922 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, ln, nbr))
923 ospf6_gr_helper_exit(nbr, OSPF6_GR_HELPER_TOPO_CHG);
924 }
925
926 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
927 ospf6_neighbor_delete(on);
928
929 list_delete_all_node(oi->neighbor_list);
930
931 /* When interface state is reset, also reset information about
932 * DR election, as it is no longer valid. */
933 oi->drouter = oi->prev_drouter = htonl(0);
934 oi->bdrouter = oi->prev_bdrouter = htonl(0);
935
936 if (oi->area == NULL)
937 return;
938
939 ospf6 = oi->area->ospf6;
940 /* Leave AllSPFRouters */
941 if (oi->state > OSPF6_INTERFACE_DOWN)
942 ospf6_sso(oi->interface->ifindex, &allspfrouters6,
943 IPV6_LEAVE_GROUP, ospf6->fd);
944
945 /* deal with write fifo */
946 ospf6_fifo_flush(oi->obuf);
947 if (oi->on_write_q) {
948 listnode_delete(ospf6->oi_write_q, oi);
949 if (list_isempty(ospf6->oi_write_q))
950 thread_cancel(&ospf6->t_write);
951 oi->on_write_q = 0;
952 }
953
954 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
955 }
956
957
958 static const char *ospf6_iftype_str(uint8_t iftype)
959 {
960 switch (iftype) {
961 case OSPF_IFTYPE_LOOPBACK:
962 return "LOOPBACK";
963 case OSPF_IFTYPE_BROADCAST:
964 return "BROADCAST";
965 case OSPF_IFTYPE_POINTOPOINT:
966 return "POINTOPOINT";
967 }
968 return "UNKNOWN";
969 }
970
971 #if CONFDATE > 20220709
972 CPP_NOTICE("Time to remove ospf6Enabled from JSON output")
973 #endif
974
975 /* show specified interface structure */
976 static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
977 json_object *json_obj, bool use_json)
978 {
979 struct ospf6_interface *oi;
980 struct connected *c;
981 struct prefix *p;
982 struct listnode *i;
983 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
984 uint8_t default_iftype;
985 struct timeval res, now;
986 char duration[32];
987 struct ospf6_lsa *lsa, *lsanext;
988 json_object *json_arr;
989 json_object *json_addr;
990 struct json_object *json_auth = NULL;
991
992 default_iftype = ospf6_default_iftype(ifp);
993
994 if (use_json) {
995 json_object_string_add(json_obj, "status",
996 (if_is_operative(ifp) ? "up" : "down"));
997 json_object_string_add(json_obj, "type",
998 ospf6_iftype_str(default_iftype));
999 json_object_int_add(json_obj, "interfaceId", ifp->ifindex);
1000
1001 if (ifp->info == NULL) {
1002 json_object_boolean_false_add(json_obj, "ospf6Enabled");
1003 return 0;
1004 }
1005 json_object_boolean_true_add(json_obj, "ospf6Enabled");
1006
1007 oi = (struct ospf6_interface *)ifp->info;
1008
1009 if (if_is_operative(ifp) && oi->type != default_iftype)
1010 json_object_string_add(json_obj, "operatingAsType",
1011 ospf6_iftype_str(oi->type));
1012
1013 } else {
1014 vty_out(vty, "%s is %s, type %s\n", ifp->name,
1015 (if_is_operative(ifp) ? "up" : "down"),
1016 ospf6_iftype_str(default_iftype));
1017 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
1018
1019 if (ifp->info == NULL) {
1020 vty_out(vty, " OSPF not enabled on this interface\n");
1021 return 0;
1022 }
1023 oi = (struct ospf6_interface *)ifp->info;
1024
1025 if (if_is_operative(ifp) && oi->type != default_iftype)
1026 vty_out(vty, " Operating as type %s\n",
1027 ospf6_iftype_str(oi->type));
1028 }
1029
1030 if (use_json) {
1031 json_arr = json_object_new_array();
1032 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1033 json_addr = json_object_new_object();
1034 p = c->address;
1035 prefix2str(p, strbuf, sizeof(strbuf));
1036 switch (p->family) {
1037 case AF_INET:
1038 json_object_string_add(json_addr, "type",
1039 "inet");
1040 json_object_string_add(json_addr, "address",
1041 strbuf);
1042 json_object_array_add(json_arr, json_addr);
1043 break;
1044 case AF_INET6:
1045 json_object_string_add(json_addr, "type",
1046 "inet6");
1047 json_object_string_add(json_addr, "address",
1048 strbuf);
1049 json_object_array_add(json_arr, json_addr);
1050 break;
1051 default:
1052 json_object_string_add(json_addr, "type",
1053 "unknown");
1054 json_object_string_add(json_addr, "address",
1055 strbuf);
1056 json_object_array_add(json_arr, json_addr);
1057 break;
1058 }
1059 }
1060 json_object_object_add(json_obj, "internetAddress", json_arr);
1061 } else {
1062 vty_out(vty, " Internet Address:\n");
1063
1064 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1065 p = c->address;
1066 prefix2str(p, strbuf, sizeof(strbuf));
1067 switch (p->family) {
1068 case AF_INET:
1069 vty_out(vty, " inet : %pFX\n", p);
1070 break;
1071 case AF_INET6:
1072 vty_out(vty, " inet6: %pFX\n", p);
1073 break;
1074 default:
1075 vty_out(vty, " ??? : %pFX\n", p);
1076 break;
1077 }
1078 }
1079 }
1080
1081 if (use_json) {
1082 if (oi->area) {
1083 json_object_boolean_true_add(json_obj,
1084 "attachedToArea");
1085 json_object_int_add(json_obj, "instanceId",
1086 oi->instance_id);
1087 json_object_int_add(json_obj, "interfaceMtu",
1088 oi->ifmtu);
1089 json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
1090 json_object_string_add(json_obj, "mtuMismatchDetection",
1091 oi->mtu_ignore ? "disabled"
1092 : "enabled");
1093 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1094 sizeof(strbuf));
1095 json_object_string_add(json_obj, "areaId", strbuf);
1096 json_object_int_add(json_obj, "cost", oi->cost);
1097 } else
1098 json_object_boolean_false_add(json_obj,
1099 "attachedToArea");
1100
1101 } else {
1102 if (oi->area) {
1103 vty_out(vty,
1104 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1105 oi->instance_id, oi->ifmtu, ifp->mtu6);
1106 vty_out(vty, " MTU mismatch detection: %s\n",
1107 oi->mtu_ignore ? "disabled" : "enabled");
1108 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1109 sizeof(strbuf));
1110 vty_out(vty, " Area ID %s, Cost %u\n", strbuf,
1111 oi->cost);
1112 } else
1113 vty_out(vty, " Not Attached to Area\n");
1114 }
1115
1116 if (use_json) {
1117 json_object_string_add(json_obj, "ospf6InterfaceState",
1118 ospf6_interface_state_str[oi->state]);
1119 json_object_int_add(json_obj, "transmitDelaySec",
1120 oi->transdelay);
1121 json_object_int_add(json_obj, "priority", oi->priority);
1122 json_object_int_add(json_obj, "timerIntervalsConfigHello",
1123 oi->hello_interval);
1124 json_object_int_add(json_obj, "timerIntervalsConfigDead",
1125 oi->dead_interval);
1126 json_object_int_add(json_obj, "timerIntervalsConfigRetransmit",
1127 oi->rxmt_interval);
1128 } else {
1129 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
1130 ospf6_interface_state_str[oi->state], oi->transdelay,
1131 oi->priority);
1132 vty_out(vty, " Timer intervals configured:\n");
1133 vty_out(vty, " Hello %d(%pTHd), Dead %d, Retransmit %d\n",
1134 oi->hello_interval, oi->thread_send_hello,
1135 oi->dead_interval, oi->rxmt_interval);
1136 }
1137
1138 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
1139 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
1140 if (use_json) {
1141 json_object_string_add(json_obj, "dr", drouter);
1142 json_object_string_add(json_obj, "bdr", bdrouter);
1143 json_object_int_add(json_obj, "numberOfInterfaceScopedLsa",
1144 oi->lsdb->count);
1145 } else {
1146 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
1147 vty_out(vty, " Number of I/F scoped LSAs is %u\n",
1148 oi->lsdb->count);
1149 }
1150
1151 monotime(&now);
1152
1153 if (use_json) {
1154 timerclear(&res);
1155 if (thread_is_scheduled(oi->thread_send_lsupdate))
1156 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1157 &res);
1158 timerstring(&res, duration, sizeof(duration));
1159 json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
1160 oi->lsupdate_list->count);
1161 json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
1162 duration);
1163 json_object_string_add(
1164 json_obj, "lsUpdateSendThread",
1165 (thread_is_scheduled(oi->thread_send_lsupdate)
1166 ? "on"
1167 : "off"));
1168
1169 json_arr = json_object_new_array();
1170 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1171 json_object_array_add(
1172 json_arr, json_object_new_string(lsa->name));
1173 json_object_object_add(json_obj, "pendingLsaLsUpdate",
1174 json_arr);
1175
1176 timerclear(&res);
1177 if (thread_is_scheduled(oi->thread_send_lsack))
1178 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1179 timerstring(&res, duration, sizeof(duration));
1180
1181 json_object_int_add(json_obj, "pendingLsaLsAckCount",
1182 oi->lsack_list->count);
1183 json_object_string_add(json_obj, "pendingLsaLsAckTime",
1184 duration);
1185 json_object_string_add(
1186 json_obj, "lsAckSendThread",
1187 (thread_is_scheduled(oi->thread_send_lsack) ? "on"
1188 : "off"));
1189
1190 json_arr = json_object_new_array();
1191 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1192 json_object_array_add(
1193 json_arr, json_object_new_string(lsa->name));
1194 json_object_object_add(json_obj, "pendingLsaLsAck", json_arr);
1195
1196 } else {
1197 timerclear(&res);
1198 if (thread_is_scheduled(oi->thread_send_lsupdate))
1199 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1200 &res);
1201 timerstring(&res, duration, sizeof(duration));
1202 vty_out(vty,
1203 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1204 oi->lsupdate_list->count, duration,
1205 (thread_is_scheduled(oi->thread_send_lsupdate)
1206 ? "on"
1207 : "off"));
1208 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1209 vty_out(vty, " %s\n", lsa->name);
1210
1211 timerclear(&res);
1212 if (thread_is_scheduled(oi->thread_send_lsack))
1213 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1214 timerstring(&res, duration, sizeof(duration));
1215 vty_out(vty,
1216 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1217 oi->lsack_list->count, duration,
1218 (thread_is_scheduled(oi->thread_send_lsack) ? "on"
1219 : "off"));
1220 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1221 vty_out(vty, " %s\n", lsa->name);
1222 }
1223
1224 /* BFD specific. */
1225 if (oi->bfd_config.enabled) {
1226 if (use_json) {
1227 struct json_object *json_bfd = json_object_new_object();
1228
1229 json_object_int_add(
1230 json_bfd, "detectMultiplier",
1231 oi->bfd_config.detection_multiplier);
1232 json_object_int_add(json_bfd, "rxMinInterval",
1233 oi->bfd_config.min_rx);
1234 json_object_int_add(json_bfd, "txMinInterval",
1235 oi->bfd_config.min_tx);
1236 json_object_object_add(json_obj, "peerBfdInfo",
1237 json_bfd);
1238 } else {
1239 vty_out(vty,
1240 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1241 oi->bfd_config.detection_multiplier,
1242 oi->bfd_config.min_rx, oi->bfd_config.min_tx);
1243 }
1244 }
1245
1246 json_auth = json_object_new_object();
1247 if (oi->at_data.flags != 0) {
1248 if (use_json) {
1249 if (CHECK_FLAG(oi->at_data.flags,
1250 OSPF6_AUTH_TRAILER_KEYCHAIN)) {
1251 json_object_string_add(json_auth, "authType",
1252 "keychain");
1253 json_object_string_add(json_auth,
1254 "keychainName",
1255 oi->at_data.keychain);
1256 } else if (CHECK_FLAG(oi->at_data.flags,
1257 OSPF6_AUTH_TRAILER_MANUAL_KEY))
1258 json_object_string_add(json_auth, "authType",
1259 "manualkey");
1260 json_object_int_add(json_auth, "txPktDrop",
1261 oi->at_data.tx_drop);
1262 json_object_int_add(json_auth, "rxPktDrop",
1263 oi->at_data.rx_drop);
1264 } else {
1265 if (CHECK_FLAG(oi->at_data.flags,
1266 OSPF6_AUTH_TRAILER_KEYCHAIN))
1267 vty_out(vty,
1268 " Authentication Trailer is enabled with key-chain %s\n",
1269 oi->at_data.keychain);
1270 else if (CHECK_FLAG(oi->at_data.flags,
1271 OSPF6_AUTH_TRAILER_MANUAL_KEY))
1272 vty_out(vty,
1273 " Authentication trailer is enabled with manual key\n");
1274 vty_out(vty,
1275 " Packet drop Tx %u, Packet drop Rx %u\n",
1276 oi->at_data.tx_drop, oi->at_data.rx_drop);
1277 }
1278 } else {
1279 if (use_json)
1280 json_object_string_add(json_auth, "authType", "NULL");
1281 else
1282 vty_out(vty, " Authentication Trailer is disabled\n");
1283 }
1284
1285 if (use_json)
1286 json_object_object_add(json_obj, "authInfo", json_auth);
1287
1288 return 0;
1289 }
1290
1291 /* Find the global address to be used as a forwarding address in NSSA LSA.*/
1292 struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
1293 {
1294 struct listnode *n;
1295 struct connected *c;
1296
1297 /* for each connected address */
1298 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
1299 /* if family not AF_INET6, ignore */
1300 if (c->address->family != AF_INET6)
1301 continue;
1302
1303 if (!IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
1304 return &c->address->u.prefix6;
1305 }
1306
1307 return NULL;
1308 }
1309
1310
1311 static int show_ospf6_interface_common(struct vty *vty, vrf_id_t vrf_id,
1312 int argc, struct cmd_token **argv,
1313 int idx_ifname, int intf_idx,
1314 int json_idx, bool uj)
1315 {
1316
1317 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
1318 struct interface *ifp;
1319 json_object *json;
1320 json_object *json_int;
1321
1322 if (uj) {
1323 json = json_object_new_object();
1324 if (argc == json_idx) {
1325 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
1326 json_int = json_object_new_object();
1327 if (ifp == NULL) {
1328 json_object_string_add(json, "noSuchInterface",
1329 argv[idx_ifname]->arg);
1330 vty_json(vty, json);
1331 json_object_free(json_int);
1332 return CMD_WARNING;
1333 }
1334 ospf6_interface_show(vty, ifp, json_int, uj);
1335 json_object_object_add(json, ifp->name, json_int);
1336 } else {
1337 FOR_ALL_INTERFACES (vrf, ifp) {
1338 json_int = json_object_new_object();
1339 ospf6_interface_show(vty, ifp, json_int, uj);
1340 json_object_object_add(json, ifp->name,
1341 json_int);
1342 }
1343 }
1344 vty_json(vty, json);
1345 } else {
1346 if (argc == intf_idx) {
1347 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
1348 if (ifp == NULL) {
1349 vty_out(vty, "No such Interface: %s\n",
1350 argv[idx_ifname]->arg);
1351 return CMD_WARNING;
1352 }
1353 ospf6_interface_show(vty, ifp, NULL, uj);
1354 } else {
1355 FOR_ALL_INTERFACES (vrf, ifp)
1356 ospf6_interface_show(vty, ifp, NULL, uj);
1357 }
1358 }
1359 return CMD_SUCCESS;
1360 }
1361
1362 /* show interface */
1363 DEFUN(show_ipv6_ospf6_interface, show_ipv6_ospf6_interface_ifname_cmd,
1364 "show ipv6 ospf6 [vrf <NAME|all>] interface [IFNAME] [json]",
1365 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1366 "All VRFs\n" INTERFACE_STR IFNAME_STR JSON_STR)
1367 {
1368 int idx_ifname = 4;
1369 int intf_idx = 5;
1370 int json_idx = 6;
1371 struct listnode *node;
1372 struct ospf6 *ospf6;
1373 const char *vrf_name = NULL;
1374 bool all_vrf = false;
1375 int idx_vrf = 0;
1376 bool uj = use_json(argc, argv);
1377
1378 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1379 if (idx_vrf > 0) {
1380 idx_ifname += 2;
1381 intf_idx += 2;
1382 json_idx += 2;
1383 }
1384
1385 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1386 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1387 show_ospf6_interface_common(vty, ospf6->vrf_id, argc,
1388 argv, idx_ifname, intf_idx,
1389 json_idx, uj);
1390
1391 if (!all_vrf)
1392 break;
1393 }
1394 }
1395
1396 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1397
1398 return CMD_SUCCESS;
1399 }
1400
1401 static int ospf6_interface_show_traffic(struct vty *vty,
1402 struct interface *intf_ifp,
1403 int display_once, json_object *json,
1404 bool use_json, vrf_id_t vrf_id)
1405 {
1406 struct interface *ifp;
1407 struct vrf *vrf = NULL;
1408 struct ospf6_interface *oi = NULL;
1409 json_object *json_interface;
1410
1411 if (!display_once && !use_json) {
1412 vty_out(vty, "\n");
1413 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1414 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1415 " LS-Ack");
1416 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1417 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1418 " Rx/Tx");
1419 vty_out(vty,
1420 "--------------------------------------------------------------------------------------------\n");
1421 }
1422
1423 if (intf_ifp == NULL) {
1424 vrf = vrf_lookup_by_id(vrf_id);
1425 FOR_ALL_INTERFACES (vrf, ifp) {
1426 if (ifp->info)
1427 oi = (struct ospf6_interface *)ifp->info;
1428 else
1429 continue;
1430
1431 if (use_json) {
1432 json_interface = json_object_new_object();
1433 json_object_int_add(json_interface, "helloRx",
1434 oi->hello_in);
1435 json_object_int_add(json_interface, "helloTx",
1436 oi->hello_out);
1437 json_object_int_add(json_interface, "dbDescRx",
1438 oi->db_desc_in);
1439 json_object_int_add(json_interface, "dbDescTx",
1440 oi->db_desc_out);
1441 json_object_int_add(json_interface, "lsReqRx",
1442 oi->ls_req_in);
1443 json_object_int_add(json_interface, "lsReqTx",
1444 oi->ls_req_out);
1445 json_object_int_add(json_interface,
1446 "lsUpdateRx",
1447 oi->ls_upd_in);
1448 json_object_int_add(json_interface,
1449 "lsUpdateTx",
1450 oi->ls_upd_out);
1451 json_object_int_add(json_interface, "lsAckRx",
1452 oi->ls_ack_in);
1453 json_object_int_add(json_interface, "lsAckTx",
1454 oi->ls_ack_out);
1455
1456 json_object_object_add(json,
1457 oi->interface->name,
1458 json_interface);
1459 } else
1460 vty_out(vty,
1461 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1462 oi->interface->name, oi->hello_in,
1463 oi->hello_out, oi->db_desc_in,
1464 oi->db_desc_out, oi->ls_req_in,
1465 oi->ls_req_out, oi->ls_upd_in,
1466 oi->ls_upd_out, oi->ls_ack_in,
1467 oi->ls_ack_out);
1468 }
1469 } else {
1470 oi = intf_ifp->info;
1471 if (oi == NULL)
1472 return CMD_WARNING;
1473
1474 if (use_json) {
1475 json_interface = json_object_new_object();
1476 json_object_int_add(json_interface, "helloRx",
1477 oi->hello_in);
1478 json_object_int_add(json_interface, "helloTx",
1479 oi->hello_out);
1480 json_object_int_add(json_interface, "dbDescRx",
1481 oi->db_desc_in);
1482 json_object_int_add(json_interface, "dbDescTx",
1483 oi->db_desc_out);
1484 json_object_int_add(json_interface, "lsReqRx",
1485 oi->ls_req_in);
1486 json_object_int_add(json_interface, "lsReqTx",
1487 oi->ls_req_out);
1488 json_object_int_add(json_interface, "lsUpdateRx",
1489 oi->ls_upd_in);
1490 json_object_int_add(json_interface, "lsUpdateTx",
1491 oi->ls_upd_out);
1492 json_object_int_add(json_interface, "lsAckRx",
1493 oi->ls_ack_in);
1494 json_object_int_add(json_interface, "lsAckTx",
1495 oi->ls_ack_out);
1496
1497 json_object_object_add(json, oi->interface->name,
1498 json_interface);
1499 } else
1500 vty_out(vty,
1501 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1502 oi->interface->name, oi->hello_in,
1503 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1504 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1505 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
1506 }
1507
1508 return CMD_SUCCESS;
1509 }
1510
1511 static int ospf6_interface_show_traffic_common(struct vty *vty, int argc,
1512 struct cmd_token **argv,
1513 vrf_id_t vrf_id, bool uj)
1514 {
1515 int idx_ifname = 0;
1516 int display_once = 0;
1517 char *intf_name = NULL;
1518 struct interface *ifp = NULL;
1519 json_object *json = NULL;
1520
1521 if (uj)
1522 json = json_object_new_object();
1523
1524 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1525 intf_name = argv[idx_ifname]->arg;
1526 ifp = if_lookup_by_name(intf_name, vrf_id);
1527 if (uj) {
1528 if (ifp == NULL) {
1529 json_object_string_add(json, "status",
1530 "No Such Interface");
1531 json_object_string_add(json, "interface",
1532 intf_name);
1533 vty_json(vty, json);
1534 return CMD_WARNING;
1535 }
1536 if (ifp->info == NULL) {
1537 json_object_string_add(
1538 json, "status",
1539 "OSPF not enabled on this interface");
1540 json_object_string_add(json, "interface",
1541 intf_name);
1542 vty_json(vty, json);
1543 return 0;
1544 }
1545 } else {
1546 if (ifp == NULL) {
1547 vty_out(vty, "No such Interface: %s\n",
1548 intf_name);
1549 return CMD_WARNING;
1550 }
1551 if (ifp->info == NULL) {
1552 vty_out(vty,
1553 " OSPF not enabled on this interface %s\n",
1554 intf_name);
1555 return 0;
1556 }
1557 }
1558 }
1559
1560 ospf6_interface_show_traffic(vty, ifp, display_once, json, uj, vrf_id);
1561
1562 if (uj)
1563 vty_json(vty, json);
1564
1565 return CMD_SUCCESS;
1566 }
1567
1568 /* show interface */
1569 DEFUN(show_ipv6_ospf6_interface_traffic, show_ipv6_ospf6_interface_traffic_cmd,
1570 "show ipv6 ospf6 [vrf <NAME|all>] interface traffic [IFNAME] [json]",
1571 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1572 "All VRFs\n" INTERFACE_STR
1573 "Protocol Packet counters\n" IFNAME_STR JSON_STR)
1574 {
1575 struct ospf6 *ospf6;
1576 struct listnode *node;
1577 const char *vrf_name = NULL;
1578 bool all_vrf = false;
1579 int idx_vrf = 0;
1580 bool uj = use_json(argc, argv);
1581
1582 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1583
1584 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1585 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1586 ospf6_interface_show_traffic_common(vty, argc, argv,
1587 ospf6->vrf_id, uj);
1588
1589 if (!all_vrf)
1590 break;
1591 }
1592 }
1593
1594 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1595
1596 return CMD_SUCCESS;
1597 }
1598
1599
1600 DEFUN(show_ipv6_ospf6_interface_ifname_prefix,
1601 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1602 "show ipv6 ospf6 [vrf <NAME|all>] interface IFNAME prefix\
1603 [<\
1604 detail\
1605 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1606 >] [json]",
1607 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1608 "All VRFs\n" INTERFACE_STR IFNAME_STR
1609 "Display connected prefixes to advertise\n"
1610 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1611 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1612 "Display details of the prefixes\n" JSON_STR)
1613 {
1614 int idx_ifname = 4;
1615 int idx_prefix = 6;
1616 struct ospf6_interface *oi;
1617 bool uj = use_json(argc, argv);
1618
1619 struct ospf6 *ospf6;
1620 struct listnode *node;
1621 struct interface *ifp;
1622 const char *vrf_name = NULL;
1623 bool all_vrf = false;
1624 int idx_vrf = 0;
1625
1626 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1627 if (idx_vrf > 0) {
1628 idx_ifname += 2;
1629 idx_prefix += 2;
1630 }
1631
1632 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1633 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1634 ifp = if_lookup_by_name(argv[idx_ifname]->arg,
1635 ospf6->vrf_id);
1636 if (ifp == NULL) {
1637 vty_out(vty, "No such Interface: %s\n",
1638 argv[idx_ifname]->arg);
1639 return CMD_WARNING;
1640 }
1641
1642 oi = ifp->info;
1643 if (oi == NULL
1644 || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
1645 vty_out(vty,
1646 "Interface %s not attached to area\n",
1647 argv[idx_ifname]->arg);
1648 return CMD_WARNING;
1649 }
1650
1651 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1652 oi->route_connected, uj);
1653
1654 if (!all_vrf)
1655 break;
1656 }
1657 }
1658
1659 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1660
1661 return CMD_SUCCESS;
1662 }
1663
1664 DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd,
1665 "show ipv6 ospf6 [vrf <NAME|all>] interface prefix\
1666 [<\
1667 detail\
1668 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1669 >] [json]",
1670 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1671 "All VRFs\n" INTERFACE_STR
1672 "Display connected prefixes to advertise\n"
1673 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1674 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1675 "Display details of the prefixes\n" JSON_STR)
1676 {
1677 struct vrf *vrf = NULL;
1678 int idx_prefix = 5;
1679 struct ospf6_interface *oi;
1680 struct interface *ifp;
1681 bool uj = use_json(argc, argv);
1682 struct listnode *node;
1683 struct ospf6 *ospf6;
1684 const char *vrf_name = NULL;
1685 bool all_vrf = false;
1686 int idx_vrf = 0;
1687
1688 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1689 if (idx_vrf > 0)
1690 idx_prefix += 2;
1691
1692 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1693 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1694 vrf = vrf_lookup_by_id(ospf6->vrf_id);
1695 FOR_ALL_INTERFACES (vrf, ifp) {
1696 oi = (struct ospf6_interface *)ifp->info;
1697 if (oi == NULL
1698 || CHECK_FLAG(oi->flag,
1699 OSPF6_INTERFACE_DISABLE))
1700 continue;
1701
1702 ospf6_route_table_show(vty, idx_prefix, argc,
1703 argv,
1704 oi->route_connected, uj);
1705 }
1706 if (!all_vrf)
1707 break;
1708 }
1709 }
1710
1711 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1712
1713 return CMD_SUCCESS;
1714 }
1715
1716 void ospf6_interface_start(struct ospf6_interface *oi)
1717 {
1718 struct ospf6 *ospf6;
1719 struct ospf6_area *oa;
1720
1721 if (oi->area_id_format == OSPF6_AREA_FMT_UNSET)
1722 return;
1723
1724 if (oi->area)
1725 return;
1726
1727 ospf6 = oi->interface->vrf->info;
1728 if (!ospf6)
1729 return;
1730
1731 oa = ospf6_area_lookup(oi->area_id, ospf6);
1732 if (oa == NULL)
1733 oa = ospf6_area_create(oi->area_id, ospf6, oi->area_id_format);
1734
1735 /* attach interface to area */
1736 listnode_add(oa->if_list, oi);
1737 oi->area = oa;
1738
1739 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1740
1741 /* start up */
1742 ospf6_interface_enable(oi);
1743
1744 /* If the router is ABR, originate summary routes */
1745 if (ospf6_check_and_set_router_abr(ospf6))
1746 ospf6_abr_enable_area(oa);
1747 }
1748
1749 void ospf6_interface_stop(struct ospf6_interface *oi)
1750 {
1751 struct ospf6_area *oa;
1752
1753 oa = oi->area;
1754 if (!oa)
1755 return;
1756
1757 ospf6_interface_disable(oi);
1758
1759 listnode_delete(oa->if_list, oi);
1760 oi->area = NULL;
1761
1762 if (oa->if_list->count == 0) {
1763 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1764 ospf6_abr_disable_area(oa);
1765 }
1766 }
1767
1768 /* interface variable set command */
1769 DEFUN (ipv6_ospf6_area,
1770 ipv6_ospf6_area_cmd,
1771 "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
1772 IP6_STR
1773 OSPF6_STR
1774 "Specify the OSPF6 area ID\n"
1775 "OSPF6 area ID in IPv4 address notation\n"
1776 "OSPF6 area ID in decimal notation\n")
1777 {
1778 VTY_DECLVAR_CONTEXT(interface, ifp);
1779 struct ospf6_interface *oi;
1780 int idx_ipv4 = 3;
1781 uint32_t area_id;
1782 int format;
1783
1784 assert(ifp);
1785
1786 oi = (struct ospf6_interface *)ifp->info;
1787 if (oi == NULL)
1788 oi = ospf6_interface_create(ifp);
1789 assert(oi);
1790
1791 if (oi->area) {
1792 vty_out(vty, "%s already attached to Area %s\n",
1793 oi->interface->name, oi->area->name);
1794 return CMD_SUCCESS;
1795 }
1796
1797 if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) {
1798 vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
1799 return CMD_WARNING_CONFIG_FAILED;
1800 }
1801
1802 oi->area_id = area_id;
1803 oi->area_id_format = format;
1804
1805 ospf6_interface_start(oi);
1806
1807 return CMD_SUCCESS;
1808 }
1809
1810 DEFUN (no_ipv6_ospf6_area,
1811 no_ipv6_ospf6_area_cmd,
1812 "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
1813 NO_STR
1814 IP6_STR
1815 OSPF6_STR
1816 "Specify the OSPF6 area ID\n"
1817 "OSPF6 area ID in IPv4 address notation\n"
1818 "OSPF6 area ID in decimal notation\n")
1819 {
1820 VTY_DECLVAR_CONTEXT(interface, ifp);
1821 struct ospf6_interface *oi;
1822
1823 assert(ifp);
1824
1825 oi = (struct ospf6_interface *)ifp->info;
1826 if (oi == NULL)
1827 oi = ospf6_interface_create(ifp);
1828 assert(oi);
1829
1830 ospf6_interface_stop(oi);
1831
1832 oi->area_id = 0;
1833 oi->area_id_format = OSPF6_AREA_FMT_UNSET;
1834
1835 return CMD_SUCCESS;
1836 }
1837
1838 DEFUN (ipv6_ospf6_ifmtu,
1839 ipv6_ospf6_ifmtu_cmd,
1840 "ipv6 ospf6 ifmtu (1-65535)",
1841 IP6_STR
1842 OSPF6_STR
1843 "Interface MTU\n"
1844 "OSPFv3 Interface MTU\n"
1845 )
1846 {
1847 VTY_DECLVAR_CONTEXT(interface, ifp);
1848 int idx_number = 3;
1849 struct ospf6_interface *oi;
1850 unsigned int ifmtu, iobuflen;
1851 struct listnode *node, *nnode;
1852 struct ospf6_neighbor *on;
1853
1854 assert(ifp);
1855
1856 oi = (struct ospf6_interface *)ifp->info;
1857 if (oi == NULL)
1858 oi = ospf6_interface_create(ifp);
1859 assert(oi);
1860
1861 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1862
1863 if (oi->c_ifmtu == ifmtu)
1864 return CMD_SUCCESS;
1865
1866 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1867 vty_out(vty,
1868 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1869 ifp->name, ifp->mtu6);
1870 return CMD_WARNING_CONFIG_FAILED;
1871 }
1872
1873 if (oi->ifmtu < ifmtu) {
1874 iobuflen = ospf6_iobuf_size(ifmtu);
1875 if (iobuflen < ifmtu) {
1876 vty_out(vty,
1877 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1878 ifp->name, iobuflen);
1879 oi->ifmtu = oi->c_ifmtu = iobuflen;
1880 } else
1881 oi->ifmtu = oi->c_ifmtu = ifmtu;
1882 } else
1883 oi->ifmtu = oi->c_ifmtu = ifmtu;
1884
1885 /* re-establish adjacencies */
1886 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1887 THREAD_OFF(on->inactivity_timer);
1888 thread_add_event(master, inactivity_timer, on, 0, NULL);
1889 }
1890
1891 return CMD_SUCCESS;
1892 }
1893
1894 DEFUN (no_ipv6_ospf6_ifmtu,
1895 no_ipv6_ospf6_ifmtu_cmd,
1896 "no ipv6 ospf6 ifmtu [(1-65535)]",
1897 NO_STR
1898 IP6_STR
1899 OSPF6_STR
1900 "Interface MTU\n"
1901 "OSPFv3 Interface MTU\n"
1902 )
1903 {
1904 VTY_DECLVAR_CONTEXT(interface, ifp);
1905 struct ospf6_interface *oi;
1906 unsigned int iobuflen;
1907 struct listnode *node, *nnode;
1908 struct ospf6_neighbor *on;
1909
1910 assert(ifp);
1911
1912 oi = (struct ospf6_interface *)ifp->info;
1913 if (oi == NULL)
1914 oi = ospf6_interface_create(ifp);
1915 assert(oi);
1916
1917 if (oi->ifmtu < ifp->mtu) {
1918 iobuflen = ospf6_iobuf_size(ifp->mtu);
1919 if (iobuflen < ifp->mtu) {
1920 vty_out(vty,
1921 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1922 ifp->name, iobuflen);
1923 oi->ifmtu = iobuflen;
1924 } else
1925 oi->ifmtu = ifp->mtu;
1926 } else
1927 oi->ifmtu = ifp->mtu;
1928
1929 oi->c_ifmtu = 0;
1930
1931 /* re-establish adjacencies */
1932 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1933 THREAD_OFF(on->inactivity_timer);
1934 thread_add_event(master, inactivity_timer, on, 0, NULL);
1935 }
1936
1937 return CMD_SUCCESS;
1938 }
1939
1940 DEFUN (ipv6_ospf6_cost,
1941 ipv6_ospf6_cost_cmd,
1942 "ipv6 ospf6 cost (1-65535)",
1943 IP6_STR
1944 OSPF6_STR
1945 "Interface cost\n"
1946 "Outgoing metric of this interface\n")
1947 {
1948 VTY_DECLVAR_CONTEXT(interface, ifp);
1949 int idx_number = 3;
1950 struct ospf6_interface *oi;
1951 unsigned long int lcost;
1952
1953 assert(ifp);
1954
1955 oi = (struct ospf6_interface *)ifp->info;
1956 if (oi == NULL)
1957 oi = ospf6_interface_create(ifp);
1958 assert(oi);
1959
1960 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1961
1962 if (lcost > UINT32_MAX) {
1963 vty_out(vty, "Cost %ld is out of range\n", lcost);
1964 return CMD_WARNING_CONFIG_FAILED;
1965 }
1966
1967 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1968 if (oi->cost == lcost)
1969 return CMD_SUCCESS;
1970
1971 oi->cost = lcost;
1972 ospf6_interface_force_recalculate_cost(oi);
1973
1974 return CMD_SUCCESS;
1975 }
1976
1977 DEFUN (no_ipv6_ospf6_cost,
1978 no_ipv6_ospf6_cost_cmd,
1979 "no ipv6 ospf6 cost [(1-65535)]",
1980 NO_STR
1981 IP6_STR
1982 OSPF6_STR
1983 "Calculate interface cost from bandwidth\n"
1984 "Outgoing metric of this interface\n")
1985 {
1986 VTY_DECLVAR_CONTEXT(interface, ifp);
1987 struct ospf6_interface *oi;
1988 assert(ifp);
1989
1990 oi = (struct ospf6_interface *)ifp->info;
1991 if (oi == NULL)
1992 oi = ospf6_interface_create(ifp);
1993 assert(oi);
1994
1995 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1996
1997 ospf6_interface_recalculate_cost(oi);
1998
1999 return CMD_SUCCESS;
2000 }
2001
2002 DEFUN (auto_cost_reference_bandwidth,
2003 auto_cost_reference_bandwidth_cmd,
2004 "auto-cost reference-bandwidth (1-4294967)",
2005 "Calculate OSPF interface cost according to bandwidth\n"
2006 "Use reference bandwidth method to assign OSPF cost\n"
2007 "The reference bandwidth in terms of Mbits per second\n")
2008 {
2009 VTY_DECLVAR_CONTEXT(ospf6, o);
2010 int idx_number = 2;
2011 struct ospf6_area *oa;
2012 struct ospf6_interface *oi;
2013 struct listnode *i, *j;
2014 uint32_t refbw;
2015
2016 refbw = strtol(argv[idx_number]->arg, NULL, 10);
2017 if (refbw < 1 || refbw > 4294967) {
2018 vty_out(vty, "reference-bandwidth value is invalid\n");
2019 return CMD_WARNING_CONFIG_FAILED;
2020 }
2021
2022 /* If reference bandwidth is changed. */
2023 if ((refbw) == o->ref_bandwidth)
2024 return CMD_SUCCESS;
2025
2026 o->ref_bandwidth = refbw;
2027 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
2028 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
2029 ospf6_interface_recalculate_cost(oi);
2030
2031 return CMD_SUCCESS;
2032 }
2033
2034 DEFUN (no_auto_cost_reference_bandwidth,
2035 no_auto_cost_reference_bandwidth_cmd,
2036 "no auto-cost reference-bandwidth [(1-4294967)]",
2037 NO_STR
2038 "Calculate OSPF interface cost according to bandwidth\n"
2039 "Use reference bandwidth method to assign OSPF cost\n"
2040 "The reference bandwidth in terms of Mbits per second\n")
2041 {
2042 VTY_DECLVAR_CONTEXT(ospf6, o);
2043 struct ospf6_area *oa;
2044 struct ospf6_interface *oi;
2045 struct listnode *i, *j;
2046
2047 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
2048 return CMD_SUCCESS;
2049
2050 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
2051 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
2052 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
2053 ospf6_interface_recalculate_cost(oi);
2054
2055 return CMD_SUCCESS;
2056 }
2057
2058
2059 DEFUN (ospf6_write_multiplier,
2060 ospf6_write_multiplier_cmd,
2061 "write-multiplier (1-100)",
2062 "Write multiplier\n"
2063 "Maximum number of interface serviced per write\n")
2064 {
2065 VTY_DECLVAR_CONTEXT(ospf6, o);
2066 uint32_t write_oi_count;
2067
2068 write_oi_count = strtol(argv[1]->arg, NULL, 10);
2069 if (write_oi_count < 1 || write_oi_count > 100) {
2070 vty_out(vty, "write-multiplier value is invalid\n");
2071 return CMD_WARNING_CONFIG_FAILED;
2072 }
2073
2074 o->write_oi_count = write_oi_count;
2075 return CMD_SUCCESS;
2076 }
2077
2078 DEFUN (no_ospf6_write_multiplier,
2079 no_ospf6_write_multiplier_cmd,
2080 "no write-multiplier (1-100)",
2081 NO_STR
2082 "Write multiplier\n"
2083 "Maximum number of interface serviced per write\n")
2084 {
2085 VTY_DECLVAR_CONTEXT(ospf6, o);
2086
2087 o->write_oi_count = OSPF6_WRITE_INTERFACE_COUNT_DEFAULT;
2088 return CMD_SUCCESS;
2089 }
2090
2091 DEFUN (ipv6_ospf6_hellointerval,
2092 ipv6_ospf6_hellointerval_cmd,
2093 "ipv6 ospf6 hello-interval (1-65535)",
2094 IP6_STR
2095 OSPF6_STR
2096 "Time between HELLO packets\n"
2097 SECONDS_STR)
2098 {
2099 VTY_DECLVAR_CONTEXT(interface, ifp);
2100 int idx_number = 3;
2101 struct ospf6_interface *oi;
2102 assert(ifp);
2103
2104 oi = (struct ospf6_interface *)ifp->info;
2105 if (oi == NULL)
2106 oi = ospf6_interface_create(ifp);
2107 assert(oi);
2108
2109 oi->hello_interval = strmatch(argv[0]->text, "no")
2110 ? OSPF_HELLO_INTERVAL_DEFAULT
2111 : strtoul(argv[idx_number]->arg, NULL, 10);
2112
2113 /*
2114 * If the thread is scheduled, send the new hello now.
2115 */
2116 if (thread_is_scheduled(oi->thread_send_hello)) {
2117 THREAD_OFF(oi->thread_send_hello);
2118
2119 thread_add_timer(master, ospf6_hello_send, oi, 0,
2120 &oi->thread_send_hello);
2121 }
2122 return CMD_SUCCESS;
2123 }
2124
2125 ALIAS (ipv6_ospf6_hellointerval,
2126 no_ipv6_ospf6_hellointerval_cmd,
2127 "no ipv6 ospf6 hello-interval [(1-65535)]",
2128 NO_STR
2129 IP6_STR
2130 OSPF6_STR
2131 "Time between HELLO packets\n"
2132 SECONDS_STR)
2133
2134 /* interface variable set command */
2135 DEFUN (ipv6_ospf6_deadinterval,
2136 ipv6_ospf6_deadinterval_cmd,
2137 "ipv6 ospf6 dead-interval (1-65535)",
2138 IP6_STR
2139 OSPF6_STR
2140 "Interval time after which a neighbor is declared down\n"
2141 SECONDS_STR)
2142 {
2143 VTY_DECLVAR_CONTEXT(interface, ifp);
2144 int idx_number = 3;
2145 struct ospf6_interface *oi;
2146 assert(ifp);
2147
2148 oi = (struct ospf6_interface *)ifp->info;
2149 if (oi == NULL)
2150 oi = ospf6_interface_create(ifp);
2151 assert(oi);
2152
2153 oi->dead_interval = strmatch(argv[0]->arg, "no")
2154 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
2155 : strtoul(argv[idx_number]->arg, NULL, 10);
2156 return CMD_SUCCESS;
2157 }
2158
2159 ALIAS (ipv6_ospf6_deadinterval,
2160 no_ipv6_ospf6_deadinterval_cmd,
2161 "no ipv6 ospf6 dead-interval [(1-65535)]",
2162 NO_STR
2163 IP6_STR
2164 OSPF6_STR
2165 "Interval time after which a neighbor is declared down\n"
2166 SECONDS_STR)
2167
2168 /* interface variable set command */
2169 DEFUN (ipv6_ospf6_transmitdelay,
2170 ipv6_ospf6_transmitdelay_cmd,
2171 "ipv6 ospf6 transmit-delay (1-3600)",
2172 IP6_STR
2173 OSPF6_STR
2174 "Link state transmit delay\n"
2175 SECONDS_STR)
2176 {
2177 VTY_DECLVAR_CONTEXT(interface, ifp);
2178 int idx_number = 3;
2179 struct ospf6_interface *oi;
2180 assert(ifp);
2181
2182 oi = (struct ospf6_interface *)ifp->info;
2183 if (oi == NULL)
2184 oi = ospf6_interface_create(ifp);
2185 assert(oi);
2186
2187 oi->transdelay = strmatch(argv[0]->text, "no")
2188 ? OSPF6_INTERFACE_TRANSDELAY
2189 : strtoul(argv[idx_number]->arg, NULL, 10);
2190 return CMD_SUCCESS;
2191 }
2192
2193 ALIAS (ipv6_ospf6_transmitdelay,
2194 no_ipv6_ospf6_transmitdelay_cmd,
2195 "no ipv6 ospf6 transmit-delay [(1-3600)]",
2196 NO_STR
2197 IP6_STR
2198 OSPF6_STR
2199 "Link state transmit delay\n"
2200 SECONDS_STR)
2201
2202 /* interface variable set command */
2203 DEFUN (ipv6_ospf6_retransmitinterval,
2204 ipv6_ospf6_retransmitinterval_cmd,
2205 "ipv6 ospf6 retransmit-interval (1-65535)",
2206 IP6_STR
2207 OSPF6_STR
2208 "Time between retransmitting lost link state advertisements\n"
2209 SECONDS_STR)
2210 {
2211 VTY_DECLVAR_CONTEXT(interface, ifp);
2212 int idx_number = 3;
2213 struct ospf6_interface *oi;
2214 assert(ifp);
2215
2216 oi = (struct ospf6_interface *)ifp->info;
2217 if (oi == NULL)
2218 oi = ospf6_interface_create(ifp);
2219 assert(oi);
2220
2221 oi->rxmt_interval = strmatch(argv[0]->text, "no")
2222 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
2223 : strtoul(argv[idx_number]->arg, NULL, 10);
2224 return CMD_SUCCESS;
2225 }
2226
2227 ALIAS (ipv6_ospf6_retransmitinterval,
2228 no_ipv6_ospf6_retransmitinterval_cmd,
2229 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
2230 NO_STR
2231 IP6_STR
2232 OSPF6_STR
2233 "Time between retransmitting lost link state advertisements\n"
2234 SECONDS_STR)
2235
2236 /* interface variable set command */
2237 DEFUN (ipv6_ospf6_priority,
2238 ipv6_ospf6_priority_cmd,
2239 "ipv6 ospf6 priority (0-255)",
2240 IP6_STR
2241 OSPF6_STR
2242 "Router priority\n"
2243 "Priority value\n")
2244 {
2245 VTY_DECLVAR_CONTEXT(interface, ifp);
2246 int idx_number = 3;
2247 struct ospf6_interface *oi;
2248 assert(ifp);
2249
2250 oi = (struct ospf6_interface *)ifp->info;
2251 if (oi == NULL)
2252 oi = ospf6_interface_create(ifp);
2253 assert(oi);
2254
2255 oi->priority = strmatch(argv[0]->text, "no")
2256 ? OSPF6_INTERFACE_PRIORITY
2257 : strtoul(argv[idx_number]->arg, NULL, 10);
2258
2259 if (oi->area
2260 && (oi->state == OSPF6_INTERFACE_DROTHER
2261 || oi->state == OSPF6_INTERFACE_BDR
2262 || oi->state == OSPF6_INTERFACE_DR)) {
2263 if (ospf6_interface_state_change(dr_election(oi), oi) == -1)
2264 OSPF6_LINK_LSA_SCHEDULE(oi);
2265 }
2266
2267 return CMD_SUCCESS;
2268 }
2269
2270 ALIAS (ipv6_ospf6_priority,
2271 no_ipv6_ospf6_priority_cmd,
2272 "no ipv6 ospf6 priority [(0-255)]",
2273 NO_STR
2274 IP6_STR
2275 OSPF6_STR
2276 "Router priority\n"
2277 "Priority value\n")
2278
2279 DEFUN (ipv6_ospf6_instance,
2280 ipv6_ospf6_instance_cmd,
2281 "ipv6 ospf6 instance-id (0-255)",
2282 IP6_STR
2283 OSPF6_STR
2284 "Instance ID for this interface\n"
2285 "Instance ID value\n")
2286 {
2287 VTY_DECLVAR_CONTEXT(interface, ifp);
2288 int idx_number = 3;
2289 struct ospf6_interface *oi;
2290 assert(ifp);
2291
2292 oi = (struct ospf6_interface *)ifp->info;
2293 if (oi == NULL)
2294 oi = ospf6_interface_create(ifp);
2295 assert(oi);
2296
2297 oi->instance_id = strmatch(argv[0]->text, "no")
2298 ? OSPF6_INTERFACE_INSTANCE_ID
2299 : strtoul(argv[idx_number]->arg, NULL, 10);
2300 return CMD_SUCCESS;
2301 }
2302
2303 ALIAS (ipv6_ospf6_instance,
2304 no_ipv6_ospf6_instance_cmd,
2305 "no ipv6 ospf6 instance-id [(0-255)]",
2306 NO_STR
2307 IP6_STR
2308 OSPF6_STR
2309 "Instance ID for this interface\n"
2310 "Instance ID value\n")
2311
2312 DEFUN (ipv6_ospf6_passive,
2313 ipv6_ospf6_passive_cmd,
2314 "ipv6 ospf6 passive",
2315 IP6_STR
2316 OSPF6_STR
2317 "Passive interface; no adjacency will be formed on this interface\n"
2318 )
2319 {
2320 VTY_DECLVAR_CONTEXT(interface, ifp);
2321 struct ospf6_interface *oi;
2322 struct listnode *node, *nnode;
2323 struct ospf6_neighbor *on;
2324
2325 assert(ifp);
2326
2327 oi = (struct ospf6_interface *)ifp->info;
2328 if (oi == NULL)
2329 oi = ospf6_interface_create(ifp);
2330 assert(oi);
2331
2332 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2333 THREAD_OFF(oi->thread_send_hello);
2334 THREAD_OFF(oi->thread_sso);
2335
2336 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
2337 THREAD_OFF(on->inactivity_timer);
2338 thread_add_event(master, inactivity_timer, on, 0, NULL);
2339 }
2340
2341 return CMD_SUCCESS;
2342 }
2343
2344 DEFUN (no_ipv6_ospf6_passive,
2345 no_ipv6_ospf6_passive_cmd,
2346 "no ipv6 ospf6 passive",
2347 NO_STR
2348 IP6_STR
2349 OSPF6_STR
2350 "passive interface: No Adjacency will be formed on this I/F\n"
2351 )
2352 {
2353 VTY_DECLVAR_CONTEXT(interface, ifp);
2354 struct ospf6_interface *oi;
2355 assert(ifp);
2356
2357 oi = (struct ospf6_interface *)ifp->info;
2358 if (oi == NULL)
2359 oi = ospf6_interface_create(ifp);
2360 assert(oi);
2361
2362 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2363 THREAD_OFF(oi->thread_send_hello);
2364 THREAD_OFF(oi->thread_sso);
2365
2366 /* don't send hellos over loopback interface */
2367 if (!if_is_loopback(oi->interface))
2368 thread_add_timer(master, ospf6_hello_send, oi, 0,
2369 &oi->thread_send_hello);
2370
2371 return CMD_SUCCESS;
2372 }
2373
2374 DEFUN (ipv6_ospf6_mtu_ignore,
2375 ipv6_ospf6_mtu_ignore_cmd,
2376 "ipv6 ospf6 mtu-ignore",
2377 IP6_STR
2378 OSPF6_STR
2379 "Disable MTU mismatch detection on this interface\n"
2380 )
2381 {
2382 VTY_DECLVAR_CONTEXT(interface, ifp);
2383 struct ospf6_interface *oi;
2384 assert(ifp);
2385
2386 oi = (struct ospf6_interface *)ifp->info;
2387 if (oi == NULL)
2388 oi = ospf6_interface_create(ifp);
2389 assert(oi);
2390
2391 oi->mtu_ignore = 1;
2392
2393 return CMD_SUCCESS;
2394 }
2395
2396 DEFUN (no_ipv6_ospf6_mtu_ignore,
2397 no_ipv6_ospf6_mtu_ignore_cmd,
2398 "no ipv6 ospf6 mtu-ignore",
2399 NO_STR
2400 IP6_STR
2401 OSPF6_STR
2402 "Disable MTU mismatch detection on this interface\n"
2403 )
2404 {
2405 VTY_DECLVAR_CONTEXT(interface, ifp);
2406 struct ospf6_interface *oi;
2407 assert(ifp);
2408
2409 oi = (struct ospf6_interface *)ifp->info;
2410 if (oi == NULL)
2411 oi = ospf6_interface_create(ifp);
2412 assert(oi);
2413
2414 oi->mtu_ignore = 0;
2415
2416 return CMD_SUCCESS;
2417 }
2418
2419 DEFUN (ipv6_ospf6_advertise_prefix_list,
2420 ipv6_ospf6_advertise_prefix_list_cmd,
2421 "ipv6 ospf6 advertise prefix-list WORD",
2422 IP6_STR
2423 OSPF6_STR
2424 "Advertising options\n"
2425 "Filter prefix using prefix-list\n"
2426 "Prefix list name\n"
2427 )
2428 {
2429 VTY_DECLVAR_CONTEXT(interface, ifp);
2430 int idx_word = 4;
2431 struct ospf6_interface *oi;
2432 assert(ifp);
2433
2434 oi = (struct ospf6_interface *)ifp->info;
2435 if (oi == NULL)
2436 oi = ospf6_interface_create(ifp);
2437 assert(oi);
2438
2439 if (oi->plist_name)
2440 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2441 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
2442
2443 ospf6_interface_connected_route_update(oi->interface);
2444
2445 if (oi->area) {
2446 OSPF6_LINK_LSA_SCHEDULE(oi);
2447 if (oi->state == OSPF6_INTERFACE_DR) {
2448 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2449 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2450 }
2451 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2452 }
2453
2454 return CMD_SUCCESS;
2455 }
2456
2457 DEFUN (no_ipv6_ospf6_advertise_prefix_list,
2458 no_ipv6_ospf6_advertise_prefix_list_cmd,
2459 "no ipv6 ospf6 advertise prefix-list [WORD]",
2460 NO_STR
2461 IP6_STR
2462 OSPF6_STR
2463 "Advertising options\n"
2464 "Filter prefix using prefix-list\n"
2465 "Prefix list name\n")
2466 {
2467 VTY_DECLVAR_CONTEXT(interface, ifp);
2468 struct ospf6_interface *oi;
2469 assert(ifp);
2470
2471 oi = (struct ospf6_interface *)ifp->info;
2472 if (oi == NULL)
2473 oi = ospf6_interface_create(ifp);
2474 assert(oi);
2475
2476 if (oi->plist_name)
2477 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2478
2479 ospf6_interface_connected_route_update(oi->interface);
2480
2481 if (oi->area) {
2482 OSPF6_LINK_LSA_SCHEDULE(oi);
2483 if (oi->state == OSPF6_INTERFACE_DR) {
2484 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2485 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2486 }
2487 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2488 }
2489
2490 return CMD_SUCCESS;
2491 }
2492
2493 DEFUN (ipv6_ospf6_network,
2494 ipv6_ospf6_network_cmd,
2495 "ipv6 ospf6 network <broadcast|point-to-point>",
2496 IP6_STR
2497 OSPF6_STR
2498 "Network type\n"
2499 "Specify OSPF6 broadcast network\n"
2500 "Specify OSPF6 point-to-point network\n"
2501 )
2502 {
2503 VTY_DECLVAR_CONTEXT(interface, ifp);
2504 int idx_network = 3;
2505 struct ospf6_interface *oi;
2506 assert(ifp);
2507
2508 oi = (struct ospf6_interface *)ifp->info;
2509 if (oi == NULL) {
2510 oi = ospf6_interface_create(ifp);
2511 }
2512 assert(oi);
2513
2514 oi->type_cfg = true;
2515
2516 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
2517 if (oi->type == OSPF_IFTYPE_BROADCAST)
2518 return CMD_SUCCESS;
2519
2520 oi->type = OSPF_IFTYPE_BROADCAST;
2521 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
2522 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
2523 return CMD_SUCCESS;
2524 }
2525 oi->type = OSPF_IFTYPE_POINTOPOINT;
2526 }
2527
2528 /* Reset the interface */
2529 thread_execute(master, interface_down, oi, 0);
2530 thread_execute(master, interface_up, oi, 0);
2531
2532 return CMD_SUCCESS;
2533 }
2534
2535 DEFUN (no_ipv6_ospf6_network,
2536 no_ipv6_ospf6_network_cmd,
2537 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2538 NO_STR
2539 IP6_STR
2540 OSPF6_STR
2541 "Set default network type\n"
2542 "Specify OSPF6 broadcast network\n"
2543 "Specify OSPF6 point-to-point network\n")
2544 {
2545 VTY_DECLVAR_CONTEXT(interface, ifp);
2546 struct ospf6_interface *oi;
2547 int type;
2548
2549 assert(ifp);
2550
2551 oi = (struct ospf6_interface *)ifp->info;
2552 if (oi == NULL) {
2553 return CMD_SUCCESS;
2554 }
2555
2556 oi->type_cfg = false;
2557
2558 type = ospf6_default_iftype(ifp);
2559 if (oi->type == type) {
2560 return CMD_SUCCESS;
2561 }
2562 oi->type = type;
2563
2564 /* Reset the interface */
2565 thread_execute(master, interface_down, oi, 0);
2566 thread_execute(master, interface_up, oi, 0);
2567
2568 return CMD_SUCCESS;
2569 }
2570
2571 static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
2572 {
2573 struct ospf6_interface *oi;
2574 struct interface *ifp;
2575 char buf[INET_ADDRSTRLEN];
2576
2577 FOR_ALL_INTERFACES (vrf, ifp) {
2578 oi = (struct ospf6_interface *)ifp->info;
2579 if (oi == NULL)
2580 continue;
2581
2582 if_vty_config_start(vty, ifp);
2583
2584 if (ifp->desc)
2585 vty_out(vty, " description %s\n", ifp->desc);
2586 if (oi->area_id_format != OSPF6_AREA_FMT_UNSET) {
2587 area_id2str(buf, sizeof(buf), oi->area_id,
2588 oi->area_id_format);
2589 vty_out(vty, " ipv6 ospf6 area %s\n", buf);
2590 }
2591 if (oi->c_ifmtu)
2592 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
2593
2594 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
2595 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
2596
2597 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
2598 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
2599 oi->hello_interval);
2600
2601 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
2602 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
2603 oi->dead_interval);
2604
2605 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
2606 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
2607 oi->rxmt_interval);
2608
2609 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
2610 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
2611
2612 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
2613 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
2614 oi->transdelay);
2615
2616 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
2617 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
2618 oi->instance_id);
2619
2620 if (oi->plist_name)
2621 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
2622 oi->plist_name);
2623
2624 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
2625 vty_out(vty, " ipv6 ospf6 passive\n");
2626
2627 if (oi->mtu_ignore)
2628 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
2629
2630 if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
2631 vty_out(vty, " ipv6 ospf6 network point-to-point\n");
2632 else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
2633 vty_out(vty, " ipv6 ospf6 network broadcast\n");
2634
2635 ospf6_bfd_write_config(vty, oi);
2636
2637 ospf6_auth_write_config(vty, &oi->at_data);
2638 if_vty_config_end(vty);
2639 }
2640 return 0;
2641 }
2642
2643 /* Configuration write function for ospfd. */
2644 static int config_write_interface(struct vty *vty)
2645 {
2646 int write = 0;
2647 struct vrf *vrf = NULL;
2648
2649 /* Display all VRF aware OSPF interface configuration */
2650 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2651 write += config_write_ospf6_interface(vty, vrf);
2652 }
2653
2654 return write;
2655 }
2656
2657 static int ospf6_ifp_create(struct interface *ifp)
2658 {
2659 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2660 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
2661 ifp->ifindex, ifp->mtu6);
2662
2663 if (ifp->info)
2664 ospf6_interface_start(ifp->info);
2665
2666 return 0;
2667 }
2668
2669 static int ospf6_ifp_up(struct interface *ifp)
2670 {
2671 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2672 zlog_debug(
2673 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2674 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2675 ifp->metric, ifp->mtu6, ifp->bandwidth);
2676
2677 ospf6_interface_state_update(ifp);
2678
2679 return 0;
2680 }
2681
2682 static int ospf6_ifp_down(struct interface *ifp)
2683 {
2684 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2685 zlog_debug(
2686 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2687 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2688 ifp->metric, ifp->mtu6, ifp->bandwidth);
2689
2690 ospf6_interface_state_update(ifp);
2691
2692 return 0;
2693 }
2694
2695 static int ospf6_ifp_destroy(struct interface *ifp)
2696 {
2697 if (if_is_up(ifp))
2698 zlog_warn("Zebra: got delete of %s, but interface is still up",
2699 ifp->name);
2700
2701 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2702 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2703 ifp->name, ifp->ifindex, ifp->mtu6);
2704
2705 if (ifp->info)
2706 ospf6_interface_stop(ifp->info);
2707
2708 return 0;
2709 }
2710
2711 void ospf6_interface_init(void)
2712 {
2713 /* Install interface node. */
2714 if_cmd_init(config_write_interface);
2715 if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
2716 ospf6_ifp_down, ospf6_ifp_destroy);
2717
2718 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
2719 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
2720 install_element(VIEW_NODE,
2721 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
2722 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
2723
2724 install_element(INTERFACE_NODE, &ipv6_ospf6_area_cmd);
2725 install_element(INTERFACE_NODE, &no_ipv6_ospf6_area_cmd);
2726 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
2727 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
2728 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
2729 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
2730
2731 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
2732 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
2733 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
2734 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
2735 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
2736 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
2737 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
2738 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
2739 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
2740 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
2741 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
2742 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
2743
2744 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
2745 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
2746
2747 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
2748 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
2749
2750 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
2751 install_element(INTERFACE_NODE,
2752 &no_ipv6_ospf6_advertise_prefix_list_cmd);
2753
2754 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
2755 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
2756
2757 /* reference bandwidth commands */
2758 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
2759 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
2760 /* write-multiplier commands */
2761 install_element(OSPF6_NODE, &ospf6_write_multiplier_cmd);
2762 install_element(OSPF6_NODE, &no_ospf6_write_multiplier_cmd);
2763 }
2764
2765 /* Clear the specified interface structure */
2766 void ospf6_interface_clear(struct interface *ifp)
2767 {
2768 struct ospf6_interface *oi;
2769
2770 if (!if_is_operative(ifp))
2771 return;
2772
2773 if (ifp->info == NULL)
2774 return;
2775
2776 oi = (struct ospf6_interface *)ifp->info;
2777
2778 if (IS_OSPF6_DEBUG_INTERFACE)
2779 zlog_debug("Interface %s: clear by reset", ifp->name);
2780
2781 /* Reset the interface */
2782 thread_execute(master, interface_down, oi, 0);
2783 thread_execute(master, interface_up, oi, 0);
2784 }
2785
2786 /* Clear interface */
2787 DEFUN (clear_ipv6_ospf6_interface,
2788 clear_ipv6_ospf6_interface_cmd,
2789 "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
2790 CLEAR_STR
2791 IP6_STR
2792 OSPF6_STR
2793 VRF_CMD_HELP_STR
2794 INTERFACE_STR
2795 IFNAME_STR
2796 )
2797 {
2798 struct vrf *vrf;
2799 int idx_vrf = 3;
2800 int idx_ifname = 4;
2801 struct interface *ifp;
2802 const char *vrf_name;
2803
2804 if (argv_find(argv, argc, "vrf", &idx_vrf))
2805 vrf_name = argv[idx_vrf + 1]->arg;
2806 else
2807 vrf_name = VRF_DEFAULT_NAME;
2808 vrf = vrf_lookup_by_name(vrf_name);
2809 if (!vrf) {
2810 vty_out(vty, "%% VRF %s not found\n", vrf_name);
2811 return CMD_WARNING;
2812 }
2813
2814 if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) {
2815 /* Clear all the ospfv3 interfaces. */
2816 FOR_ALL_INTERFACES (vrf, ifp)
2817 ospf6_interface_clear(ifp);
2818 } else {
2819 /* Interface name is specified. */
2820 ifp = if_lookup_by_name_vrf(argv[idx_ifname]->arg, vrf);
2821 if (!ifp) {
2822 vty_out(vty, "No such Interface: %s\n",
2823 argv[idx_ifname]->arg);
2824 return CMD_WARNING;
2825 }
2826 ospf6_interface_clear(ifp);
2827 }
2828
2829 return CMD_SUCCESS;
2830 }
2831
2832 void install_element_ospf6_clear_interface(void)
2833 {
2834 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
2835 }
2836
2837 DEFUN (debug_ospf6_interface,
2838 debug_ospf6_interface_cmd,
2839 "debug ospf6 interface",
2840 DEBUG_STR
2841 OSPF6_STR
2842 "Debug OSPFv3 Interface\n"
2843 )
2844 {
2845 OSPF6_DEBUG_INTERFACE_ON();
2846 return CMD_SUCCESS;
2847 }
2848
2849 DEFUN (no_debug_ospf6_interface,
2850 no_debug_ospf6_interface_cmd,
2851 "no debug ospf6 interface",
2852 NO_STR
2853 DEBUG_STR
2854 OSPF6_STR
2855 "Debug OSPFv3 Interface\n"
2856 )
2857 {
2858 OSPF6_DEBUG_INTERFACE_OFF();
2859 return CMD_SUCCESS;
2860 }
2861
2862 int config_write_ospf6_debug_interface(struct vty *vty)
2863 {
2864 if (IS_OSPF6_DEBUG_INTERFACE)
2865 vty_out(vty, "debug ospf6 interface\n");
2866 return 0;
2867 }
2868
2869 void install_element_ospf6_debug_interface(void)
2870 {
2871 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2872 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2873 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2874 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
2875 }
2876
2877 void ospf6_auth_write_config(struct vty *vty, struct ospf6_auth_data *at_data)
2878 {
2879 if (CHECK_FLAG(at_data->flags, OSPF6_AUTH_TRAILER_KEYCHAIN))
2880 vty_out(vty, " ipv6 ospf6 authentication keychain %s\n",
2881 at_data->keychain);
2882 else if (CHECK_FLAG(at_data->flags, OSPF6_AUTH_TRAILER_MANUAL_KEY))
2883 vty_out(vty,
2884 " ipv6 ospf6 authentication key-id %d hash-algo %s key %s\n",
2885 at_data->key_id,
2886 keychain_get_algo_name_by_id(at_data->hash_algo),
2887 at_data->auth_key);
2888 }
2889
2890 DEFUN(ipv6_ospf6_intf_auth_trailer_keychain,
2891 ipv6_ospf6_intf_auth_trailer_keychain_cmd,
2892 "ipv6 ospf6 authentication keychain KEYCHAIN_NAME",
2893 IP6_STR OSPF6_STR
2894 "Enable authentication on this interface\n"
2895 "Keychain\n"
2896 "Keychain name\n")
2897 {
2898 VTY_DECLVAR_CONTEXT(interface, ifp);
2899 int keychain_idx = 4;
2900 struct ospf6_interface *oi;
2901
2902 oi = (struct ospf6_interface *)ifp->info;
2903 if (oi == NULL)
2904 oi = ospf6_interface_create(ifp);
2905
2906 assert(oi);
2907 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_MANUAL_KEY)) {
2908 vty_out(vty,
2909 "Manual key configured, unconfigure it before configuring key chain\n");
2910 return CMD_WARNING_CONFIG_FAILED;
2911 }
2912
2913 SET_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN);
2914 if (oi->at_data.keychain)
2915 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN, oi->at_data.keychain);
2916
2917 oi->at_data.keychain =
2918 XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN, argv[keychain_idx]->arg);
2919
2920 return CMD_SUCCESS;
2921 }
2922
2923 DEFUN(no_ipv6_ospf6_intf_auth_trailer_keychain,
2924 no_ipv6_ospf6_intf_auth_trailer_keychain_cmd,
2925 "no ipv6 ospf6 authentication keychain [KEYCHAIN_NAME]",
2926 NO_STR IP6_STR OSPF6_STR
2927 "Enable authentication on this interface\n"
2928 "Keychain\n"
2929 "Keychain name\n")
2930 {
2931 VTY_DECLVAR_CONTEXT(interface, ifp);
2932 struct ospf6_interface *oi;
2933
2934 oi = (struct ospf6_interface *)ifp->info;
2935 if (oi == NULL)
2936 oi = ospf6_interface_create(ifp);
2937
2938 assert(oi);
2939 if (!CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN))
2940 return CMD_SUCCESS;
2941
2942 if (oi->at_data.keychain) {
2943 oi->at_data.flags = 0;
2944 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN, oi->at_data.keychain);
2945 oi->at_data.keychain = NULL;
2946 }
2947
2948 return CMD_SUCCESS;
2949 }
2950
2951 DEFUN(ipv6_ospf6_intf_auth_trailer_key, ipv6_ospf6_intf_auth_trailer_key_cmd,
2952 "ipv6 ospf6 authentication key-id (1-65535) hash-algo "
2953 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
2954 "key WORD",
2955 IP6_STR OSPF6_STR
2956 "Authentication\n"
2957 "Key ID\n"
2958 "Key ID value\n"
2959 "Cryptographic-algorithm\n"
2960 "Use MD5 algorithm\n"
2961 "Use HMAC-SHA-1 algorithm\n"
2962 "Use HMAC-SHA-256 algorithm\n"
2963 "Use HMAC-SHA-384 algorithm\n"
2964 "Use HMAC-SHA-512 algorithm\n"
2965 "Password\n"
2966 "Password string (key)\n")
2967 {
2968 VTY_DECLVAR_CONTEXT(interface, ifp);
2969 int key_id_idx = 4;
2970 int hash_algo_idx = 6;
2971 int password_idx = 8;
2972 struct ospf6_interface *oi;
2973 uint8_t hash_algo = KEYCHAIN_ALGO_NULL;
2974
2975 oi = (struct ospf6_interface *)ifp->info;
2976 if (oi == NULL)
2977 oi = ospf6_interface_create(ifp);
2978
2979 assert(oi);
2980 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN)) {
2981 vty_out(vty,
2982 "key chain configured, unconfigure it before configuring manual key\n");
2983 return CMD_WARNING_CONFIG_FAILED;
2984 }
2985
2986 hash_algo = keychain_get_algo_id_by_name(argv[hash_algo_idx]->arg);
2987 #ifndef CRYPTO_OPENSSL
2988 if (hash_algo == KEYCHAIN_ALGO_NULL) {
2989 vty_out(vty,
2990 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
2991 return CMD_WARNING_CONFIG_FAILED;
2992 }
2993 #endif /* CRYPTO_OPENSSL */
2994
2995 SET_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_MANUAL_KEY);
2996 oi->at_data.hash_algo = hash_algo;
2997 oi->at_data.key_id = (uint16_t)strtol(argv[key_id_idx]->arg, NULL, 10);
2998 if (oi->at_data.auth_key)
2999 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY, oi->at_data.auth_key);
3000 oi->at_data.auth_key =
3001 XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY, argv[password_idx]->arg);
3002
3003 return CMD_SUCCESS;
3004 }
3005
3006 DEFUN(no_ipv6_ospf6_intf_auth_trailer_key,
3007 no_ipv6_ospf6_intf_auth_trailer_key_cmd,
3008 "no ipv6 ospf6 authentication key-id [(1-65535) hash-algo "
3009 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
3010 "key WORD]",
3011 NO_STR IP6_STR OSPF6_STR
3012 "Authentication\n"
3013 "Key ID\n"
3014 "Key ID value\n"
3015 "Cryptographic-algorithm\n"
3016 "Use MD5 algorithm\n"
3017 "Use HMAC-SHA-1 algorithm\n"
3018 "Use HMAC-SHA-256 algorithm\n"
3019 "Use HMAC-SHA-384 algorithm\n"
3020 "Use HMAC-SHA-512 algorithm\n"
3021 "Password\n"
3022 "Password string (key)\n")
3023 {
3024 VTY_DECLVAR_CONTEXT(interface, ifp);
3025 struct ospf6_interface *oi;
3026 #ifndef CRYPTO_OPENSSL
3027 int hash_algo_idx = 7;
3028 uint8_t hash_algo = KEYCHAIN_ALGO_NULL;
3029 #endif /* CRYPTO_OPENSSL */
3030
3031 oi = (struct ospf6_interface *)ifp->info;
3032 if (oi == NULL)
3033 oi = ospf6_interface_create(ifp);
3034
3035 assert(oi);
3036 if (!CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_MANUAL_KEY))
3037 return CMD_SUCCESS;
3038
3039 #ifndef CRYPTO_OPENSSL
3040 hash_algo = keychain_get_algo_id_by_name(argv[hash_algo_idx]->arg);
3041 if (hash_algo == KEYCHAIN_ALGO_NULL) {
3042 vty_out(vty,
3043 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
3044 return CMD_WARNING_CONFIG_FAILED;
3045 }
3046 #endif /* CRYPTO_OPENSSL */
3047
3048 if (oi->at_data.auth_key) {
3049 oi->at_data.flags = 0;
3050 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY, oi->at_data.auth_key);
3051 oi->at_data.auth_key = NULL;
3052 }
3053
3054 return CMD_SUCCESS;
3055 }
3056
3057 void ospf6_interface_auth_trailer_cmd_init(void)
3058 {
3059 /*Install OSPF6 auth trailer commands at interface level */
3060 install_element(INTERFACE_NODE,
3061 &ipv6_ospf6_intf_auth_trailer_keychain_cmd);
3062 install_element(INTERFACE_NODE,
3063 &no_ipv6_ospf6_intf_auth_trailer_keychain_cmd);
3064 install_element(INTERFACE_NODE, &ipv6_ospf6_intf_auth_trailer_key_cmd);
3065 install_element(INTERFACE_NODE,
3066 &no_ipv6_ospf6_intf_auth_trailer_key_cmd);
3067 }