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