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