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