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