]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_interface.c
Merge pull request #5257 from ton31337/fix/update_rib_on_bgp_distance_changes
[mirror_frr.git] / ospf6d / ospf6_interface.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 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 *
896014f4
DL
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
718e3744 19 */
20
508e53e2 21#include <zebra.h>
718e3744 22
508e53e2 23#include "memory.h"
718e3744 24#include "if.h"
25#include "log.h"
26#include "command.h"
508e53e2 27#include "thread.h"
28#include "prefix.h"
29#include "plist.h"
88177fe3 30#include "zclient.h"
718e3744 31
508e53e2 32#include "ospf6_lsa.h"
718e3744 33#include "ospf6_lsdb.h"
508e53e2 34#include "ospf6_network.h"
35#include "ospf6_message.h"
36#include "ospf6_route.h"
718e3744 37#include "ospf6_top.h"
38#include "ospf6_area.h"
39#include "ospf6_interface.h"
508e53e2 40#include "ospf6_neighbor.h"
41#include "ospf6_intra.h"
42#include "ospf6_spf.h"
049207c3 43#include "ospf6d.h"
7f342629 44#include "ospf6_bfd.h"
ef7bd2a3 45#include "ospf6_zebra.h"
718e3744 46
4a1ab8e4 47DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
ae19c240 48DEFINE_QOBJ_TYPE(ospf6_interface)
3012671f 49DEFINE_HOOK(ospf6_interface_change,
d62a17ae 50 (struct ospf6_interface * oi, int state, int old_state),
51 (oi, state, old_state))
4a1ab8e4 52
508e53e2 53unsigned char conf_debug_ospf6_interface = 0;
54
d62a17ae 55const char *ospf6_interface_state_str[] = {
56 "None", "Down", "Loopback", "Waiting", "PointToPoint",
57 "DROther", "BDR", "DR", NULL};
718e3744 58
d62a17ae 59struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex)
718e3744 60{
d62a17ae 61 struct ospf6_interface *oi;
62 struct interface *ifp;
718e3744 63
d62a17ae 64 ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
65 if (ifp == NULL)
66 return (struct ospf6_interface *)NULL;
508e53e2 67
d62a17ae 68 oi = (struct ospf6_interface *)ifp->info;
69 return oi;
718e3744 70}
71
508e53e2 72/* schedule routing table recalculation */
d62a17ae 73static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa,
74 unsigned int reason)
718e3744 75{
d62a17ae 76 struct ospf6_interface *oi;
77
78 if (lsa == NULL)
79 return;
80
81 oi = lsa->lsdb->data;
82 switch (ntohs(lsa->header->type)) {
83 case OSPF6_LSTYPE_LINK:
84 if (oi->state == OSPF6_INTERFACE_DR)
85 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
86 if (oi->area)
87 ospf6_spf_schedule(oi->area->ospf6, reason);
88 break;
89
90 default:
91 break;
92 }
718e3744 93}
94
d62a17ae 95static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa *lsa)
a0edf674 96{
d62a17ae 97 ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa));
a0edf674
DD
98}
99
d62a17ae 100static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa *lsa)
a0edf674 101{
d62a17ae 102 ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa));
a0edf674
DD
103}
104
d7c0a89a 105static uint8_t ospf6_default_iftype(struct interface *ifp)
c5926a92 106{
d62a17ae 107 if (if_is_pointopoint(ifp))
108 return OSPF_IFTYPE_POINTOPOINT;
109 else if (if_is_loopback(ifp))
110 return OSPF_IFTYPE_LOOPBACK;
111 else
112 return OSPF_IFTYPE_BROADCAST;
c5926a92
DD
113}
114
d7c0a89a 115static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
c19543b2 116{
d62a17ae 117 /* If all else fails, use default OSPF cost */
d7c0a89a
QY
118 uint32_t cost;
119 uint32_t bw, refbw;
d62a17ae 120
27ae9bcd
CS
121 /* interface speed and bw can be 0 in some platforms,
122 * use ospf default bw. If bw is configured then it would
123 * be used.
124 */
125 if (!oi->interface->bandwidth && oi->interface->speed) {
126 bw = oi->interface->speed;
127 } else {
128 bw = oi->interface->bandwidth ? oi->interface->bandwidth
996c9314 129 : OSPF6_INTERFACE_BANDWIDTH;
27ae9bcd
CS
130 }
131
d62a17ae 132 refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
133
134 /* A specifed ip ospf cost overrides a calculated one. */
135 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
136 cost = oi->cost;
137 else {
d7c0a89a 138 cost = (uint32_t)((double)refbw / (double)bw + (double)0.5);
d62a17ae 139 if (cost < 1)
140 cost = 1;
141 else if (cost > UINT32_MAX)
142 cost = UINT32_MAX;
143 }
144
145 return cost;
c19543b2
VB
146}
147
0db8196a 148static void ospf6_interface_force_recalculate_cost(struct ospf6_interface *oi)
c19543b2 149{
d62a17ae 150 /* update cost held in route_connected list in ospf6_interface */
151 ospf6_interface_connected_route_update(oi->interface);
152
153 /* execute LSA hooks */
154 if (oi->area) {
155 OSPF6_LINK_LSA_SCHEDULE(oi);
156 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
157 OSPF6_NETWORK_LSA_SCHEDULE(oi);
158 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
159 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
160 }
c19543b2
VB
161}
162
0db8196a
JK
163static void ospf6_interface_recalculate_cost(struct ospf6_interface *oi)
164{
d7c0a89a 165 uint32_t newcost;
0db8196a
JK
166
167 newcost = ospf6_interface_get_cost(oi);
168 if (newcost == oi->cost)
169 return;
170 oi->cost = newcost;
171
172 ospf6_interface_force_recalculate_cost(oi);
173}
174
718e3744 175/* Create new ospf6 interface structure */
d62a17ae 176struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
718e3744 177{
d62a17ae 178 struct ospf6_interface *oi;
179 unsigned int iobuflen;
180
9f5dc319 181 oi = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
d62a17ae 182
d62a17ae 183 oi->area = (struct ospf6_area *)NULL;
184 oi->neighbor_list = list_new();
185 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
186 oi->linklocal_addr = (struct in6_addr *)NULL;
187 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
188 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
189 oi->priority = OSPF6_INTERFACE_PRIORITY;
190
191 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
192 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
193 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
194 oi->type = ospf6_default_iftype(ifp);
195 oi->state = OSPF6_INTERFACE_DOWN;
196 oi->flag = 0;
197 oi->mtu_ignore = 0;
198 oi->c_ifmtu = 0;
199
200 /* Try to adjust I/O buffer size with IfMtu */
201 oi->ifmtu = ifp->mtu6;
202 iobuflen = ospf6_iobuf_size(ifp->mtu6);
203 if (oi->ifmtu > iobuflen) {
204 if (IS_OSPF6_DEBUG_INTERFACE)
205 zlog_debug(
206 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
207 ifp->name, iobuflen);
208 oi->ifmtu = iobuflen;
209 }
210
211 QOBJ_REG(oi, ospf6_interface);
212
213 oi->lsupdate_list = ospf6_lsdb_create(oi);
214 oi->lsack_list = ospf6_lsdb_create(oi);
215 oi->lsdb = ospf6_lsdb_create(oi);
216 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
217 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
218 oi->lsdb_self = ospf6_lsdb_create(oi);
219
220 oi->route_connected =
221 OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
222 oi->route_connected->scope = oi;
223
224 /* link both */
225 oi->interface = ifp;
226 ifp->info = oi;
227
228 /* Compute cost. */
229 oi->cost = ospf6_interface_get_cost(oi);
230
231 return oi;
718e3744 232}
233
d62a17ae 234void ospf6_interface_delete(struct ospf6_interface *oi)
718e3744 235{
d62a17ae 236 struct listnode *node, *nnode;
237 struct ospf6_neighbor *on;
238
239 QOBJ_UNREG(oi);
718e3744 240
d62a17ae 241 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
242 ospf6_neighbor_delete(on);
ae19c240 243
6a154c88 244 list_delete(&oi->neighbor_list);
718e3744 245
d62a17ae 246 THREAD_OFF(oi->thread_send_hello);
247 THREAD_OFF(oi->thread_send_lsupdate);
248 THREAD_OFF(oi->thread_send_lsack);
f80003b0 249 THREAD_OFF(oi->thread_sso);
508e53e2 250
d62a17ae 251 ospf6_lsdb_remove_all(oi->lsdb);
252 ospf6_lsdb_remove_all(oi->lsupdate_list);
253 ospf6_lsdb_remove_all(oi->lsack_list);
508e53e2 254
d62a17ae 255 ospf6_lsdb_delete(oi->lsdb);
256 ospf6_lsdb_delete(oi->lsdb_self);
6452df09 257
d62a17ae 258 ospf6_lsdb_delete(oi->lsupdate_list);
259 ospf6_lsdb_delete(oi->lsack_list);
718e3744 260
d62a17ae 261 ospf6_route_table_delete(oi->route_connected);
718e3744 262
d62a17ae 263 /* cut link */
264 oi->interface->info = NULL;
718e3744 265
d62a17ae 266 /* plist_name */
267 if (oi->plist_name)
268 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
508e53e2 269
d62a17ae 270 ospf6_bfd_info_free(&(oi->bfd_info));
7f342629 271
22b982df
PG
272 /* disable from area list if possible */
273 ospf6_area_interface_delete(oi);
274
d62a17ae 275 XFREE(MTYPE_OSPF6_IF, oi);
508e53e2 276}
277
d62a17ae 278void ospf6_interface_enable(struct ospf6_interface *oi)
508e53e2 279{
d62a17ae 280 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
281 ospf6_interface_state_update(oi->interface);
508e53e2 282}
283
d62a17ae 284void ospf6_interface_disable(struct ospf6_interface *oi)
508e53e2 285{
d62a17ae 286 SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
508e53e2 287
d62a17ae 288 thread_execute(master, interface_down, oi, 0);
508e53e2 289
d62a17ae 290 ospf6_lsdb_remove_all(oi->lsdb);
291 ospf6_lsdb_remove_all(oi->lsdb_self);
292 ospf6_lsdb_remove_all(oi->lsupdate_list);
293 ospf6_lsdb_remove_all(oi->lsack_list);
508e53e2 294
d62a17ae 295 THREAD_OFF(oi->thread_send_hello);
296 THREAD_OFF(oi->thread_send_lsupdate);
297 THREAD_OFF(oi->thread_send_lsack);
f80003b0 298 THREAD_OFF(oi->thread_sso);
d9628728 299
d62a17ae 300 THREAD_OFF(oi->thread_network_lsa);
301 THREAD_OFF(oi->thread_link_lsa);
302 THREAD_OFF(oi->thread_intra_prefix_lsa);
76249532 303 THREAD_OFF(oi->thread_as_extern_lsa);
718e3744 304}
305
306static struct in6_addr *
d62a17ae 307ospf6_interface_get_linklocal_address(struct interface *ifp)
718e3744 308{
d62a17ae 309 struct listnode *n;
310 struct connected *c;
311 struct in6_addr *l = (struct in6_addr *)NULL;
312
313 /* for each connected address */
314 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
315 /* if family not AF_INET6, ignore */
316 if (c->address->family != AF_INET6)
317 continue;
318
319 /* linklocal scope check */
320 if (IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
321 l = &c->address->u.prefix6;
322 }
323 return l;
718e3744 324}
325
d62a17ae 326void ospf6_interface_if_add(struct interface *ifp)
718e3744 327{
d62a17ae 328 struct ospf6_interface *oi;
329 unsigned int iobuflen;
330
331 oi = (struct ospf6_interface *)ifp->info;
332 if (oi == NULL)
333 return;
334
335 /* Try to adjust I/O buffer size with IfMtu */
336 if (oi->ifmtu == 0)
337 oi->ifmtu = ifp->mtu6;
338 iobuflen = ospf6_iobuf_size(ifp->mtu6);
339 if (oi->ifmtu > iobuflen) {
340 if (IS_OSPF6_DEBUG_INTERFACE)
341 zlog_debug(
342 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
343 ifp->name, iobuflen);
344 oi->ifmtu = iobuflen;
345 }
346
347 /* interface start */
348 ospf6_interface_state_update(oi->interface);
718e3744 349}
350
d62a17ae 351void ospf6_interface_state_update(struct interface *ifp)
718e3744 352{
d62a17ae 353 struct ospf6_interface *oi;
354 unsigned int iobuflen;
355
356 oi = (struct ospf6_interface *)ifp->info;
357 if (oi == NULL)
358 return;
d62a17ae 359 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
360 return;
361
362 /* Adjust the mtu values if the kernel told us something new */
363 if (ifp->mtu6 != oi->ifmtu) {
364 /* If nothing configured, accept it and check for buffer size */
365 if (!oi->c_ifmtu) {
366 oi->ifmtu = ifp->mtu6;
367 iobuflen = ospf6_iobuf_size(ifp->mtu6);
368 if (oi->ifmtu > iobuflen) {
369 if (IS_OSPF6_DEBUG_INTERFACE)
370 zlog_debug(
371 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
372 ifp->name, iobuflen);
373 oi->ifmtu = iobuflen;
374 }
375 } else if (oi->c_ifmtu > ifp->mtu6) {
376 oi->ifmtu = ifp->mtu6;
377 zlog_warn(
378 "Configured mtu %u on %s overridden by kernel %u",
379 oi->c_ifmtu, ifp->name, ifp->mtu6);
380 } else
381 oi->ifmtu = oi->c_ifmtu;
382 }
383
384 if (if_is_operative(ifp)
385 && (ospf6_interface_get_linklocal_address(oi->interface)
386 || if_is_loopback(oi->interface)))
849576ee 387 thread_execute(master, interface_up, oi, 0);
d62a17ae 388 else
849576ee 389 thread_execute(master, interface_down, oi, 0);
d62a17ae 390
391 return;
718e3744 392}
393
d62a17ae 394void ospf6_interface_connected_route_update(struct interface *ifp)
718e3744 395{
d62a17ae 396 struct ospf6_interface *oi;
397 struct ospf6_route *route;
398 struct connected *c;
399 struct listnode *node, *nnode;
400 struct in6_addr nh_addr;
401
402 oi = (struct ospf6_interface *)ifp->info;
403 if (oi == NULL)
404 return;
405
406 /* reset linklocal pointer */
407 oi->linklocal_addr = ospf6_interface_get_linklocal_address(ifp);
408
409 /* if area is null, do not make connected-route list */
410 if (oi->area == NULL)
411 return;
412
413 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
414 return;
415
416 /* update "route to advertise" interface route table */
417 ospf6_route_remove_all(oi->route_connected);
418
419 for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
420 if (c->address->family != AF_INET6)
421 continue;
422
423 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE,
424 c->address);
425 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE,
426 c->address);
427 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE,
428 c->address);
429 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE,
430 c->address);
431 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE,
432 c->address);
433
434 /* apply filter */
435 if (oi->plist_name) {
436 struct prefix_list *plist;
437 enum prefix_list_type ret;
438 char buf[PREFIX2STR_BUFFER];
439
440 prefix2str(c->address, buf, sizeof(buf));
441 plist = prefix_list_lookup(AFI_IP6, oi->plist_name);
442 ret = prefix_list_apply(plist, (void *)c->address);
443 if (ret == PREFIX_DENY) {
444 if (IS_OSPF6_DEBUG_INTERFACE)
445 zlog_debug(
446 "%s on %s filtered by prefix-list %s ",
447 buf, oi->interface->name,
448 oi->plist_name);
449 continue;
450 }
451 }
452
453 route = ospf6_route_create();
454 memcpy(&route->prefix, c->address, sizeof(struct prefix));
455 apply_mask(&route->prefix);
456 route->type = OSPF6_DEST_TYPE_NETWORK;
457 route->path.area_id = oi->area->area_id;
458 route->path.type = OSPF6_PATH_TYPE_INTRA;
459 route->path.cost = oi->cost;
460 inet_pton(AF_INET6, "::1", &nh_addr);
461 ospf6_route_add_nexthop(route, oi->interface->ifindex,
462 &nh_addr);
463 ospf6_route_add(route, oi->route_connected);
464 }
465
466 /* create new Link-LSA */
467 OSPF6_LINK_LSA_SCHEDULE(oi);
468 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
469 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
718e3744 470}
471
d7c0a89a 472static void ospf6_interface_state_change(uint8_t next_state,
d62a17ae 473 struct ospf6_interface *oi)
718e3744 474{
d7c0a89a 475 uint8_t prev_state;
d62a17ae 476
477 prev_state = oi->state;
478 oi->state = next_state;
479
480 if (prev_state == next_state)
481 return;
482
483 /* log */
484 if (IS_OSPF6_DEBUG_INTERFACE) {
485 zlog_debug("Interface state change %s: %s -> %s",
486 oi->interface->name,
487 ospf6_interface_state_str[prev_state],
488 ospf6_interface_state_str[next_state]);
489 }
490 oi->state_change++;
491
492 if ((prev_state == OSPF6_INTERFACE_DR
493 || prev_state == OSPF6_INTERFACE_BDR)
494 && (next_state != OSPF6_INTERFACE_DR
495 && next_state != OSPF6_INTERFACE_BDR))
496 ospf6_sso(oi->interface->ifindex, &alldrouters6,
497 IPV6_LEAVE_GROUP);
498
499 if ((prev_state != OSPF6_INTERFACE_DR
500 && prev_state != OSPF6_INTERFACE_BDR)
501 && (next_state == OSPF6_INTERFACE_DR
502 || next_state == OSPF6_INTERFACE_BDR))
503 ospf6_sso(oi->interface->ifindex, &alldrouters6,
504 IPV6_JOIN_GROUP);
505
506 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
507 if (next_state == OSPF6_INTERFACE_DOWN) {
508 OSPF6_NETWORK_LSA_EXECUTE(oi);
509 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
510 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
76249532 511 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
d62a17ae 512 } else if (prev_state == OSPF6_INTERFACE_DR
513 || next_state == OSPF6_INTERFACE_DR) {
514 OSPF6_NETWORK_LSA_SCHEDULE(oi);
515 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
516 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
517 }
518
519 hook_call(ospf6_interface_change, oi, next_state, prev_state);
718e3744 520}
521
6b0655a2 522
508e53e2 523/* DR Election, RFC2328 section 9.4 */
718e3744 524
d62a17ae 525#define IS_ELIGIBLE(n) \
526 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
718e3744 527
d62a17ae 528static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a,
529 struct ospf6_neighbor *b)
508e53e2 530{
d62a17ae 531 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
532 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id))
533 return NULL;
534 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
535 return b;
536 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)
537 return a;
538
539 if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
540 return a;
541 if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
542 return b;
543
544 if (a->priority > b->priority)
545 return a;
546 if (a->priority < b->priority)
547 return b;
548
549 if (ntohl(a->router_id) > ntohl(b->router_id))
550 return a;
551 if (ntohl(a->router_id) < ntohl(b->router_id))
552 return b;
553
554 zlog_warn("Router-ID duplicate ?");
555 return a;
508e53e2 556}
718e3744 557
d62a17ae 558static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
559 struct ospf6_neighbor *b)
508e53e2 560{
d62a17ae 561 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
562 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id))
563 return NULL;
564 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
565 return b;
566 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)
567 return a;
568
569 if (a->drouter == a->router_id && b->drouter != b->router_id)
570 return a;
571 if (a->drouter != a->router_id && b->drouter == b->router_id)
572 return b;
573
574 if (a->priority > b->priority)
575 return a;
576 if (a->priority < b->priority)
577 return b;
578
579 if (ntohl(a->router_id) > ntohl(b->router_id))
580 return a;
581 if (ntohl(a->router_id) < ntohl(b->router_id))
582 return b;
583
584 zlog_warn("Router-ID duplicate ?");
585 return a;
718e3744 586}
587
d7c0a89a 588static uint8_t dr_election(struct ospf6_interface *oi)
718e3744 589{
d62a17ae 590 struct listnode *node, *nnode;
591 struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
592 struct ospf6_neighbor *best_drouter, *best_bdrouter;
d7c0a89a 593 uint8_t next_state = 0;
d62a17ae 594
595 drouter = bdrouter = NULL;
596 best_drouter = best_bdrouter = NULL;
597
598 /* pseudo neighbor myself, including noting current DR/BDR (1) */
599 memset(&myself, 0, sizeof(myself));
600 inet_ntop(AF_INET, &oi->area->ospf6->router_id, myself.name,
601 sizeof(myself.name));
602 myself.state = OSPF6_NEIGHBOR_TWOWAY;
603 myself.drouter = oi->drouter;
604 myself.bdrouter = oi->bdrouter;
605 myself.priority = oi->priority;
606 myself.router_id = oi->area->ospf6->router_id;
607
608 /* Electing BDR (2) */
609 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
610 bdrouter = better_bdrouter(bdrouter, on);
611
612 best_bdrouter = bdrouter;
613 bdrouter = better_bdrouter(best_bdrouter, &myself);
614
615 /* Electing DR (3) */
616 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
617 drouter = better_drouter(drouter, on);
618
619 best_drouter = drouter;
620 drouter = better_drouter(best_drouter, &myself);
621 if (drouter == NULL)
622 drouter = bdrouter;
623
624 /* the router itself is newly/no longer DR/BDR (4) */
625 if ((drouter == &myself && myself.drouter != myself.router_id)
626 || (drouter != &myself && myself.drouter == myself.router_id)
627 || (bdrouter == &myself && myself.bdrouter != myself.router_id)
628 || (bdrouter != &myself && myself.bdrouter == myself.router_id)) {
629 myself.drouter = (drouter ? drouter->router_id : htonl(0));
630 myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
631
632 /* compatible to Electing BDR (2) */
633 bdrouter = better_bdrouter(best_bdrouter, &myself);
634
635 /* compatible to Electing DR (3) */
636 drouter = better_drouter(best_drouter, &myself);
637 if (drouter == NULL)
638 drouter = bdrouter;
639 }
640
641 /* Set interface state accordingly (5) */
642 if (drouter && drouter == &myself)
643 next_state = OSPF6_INTERFACE_DR;
644 else if (bdrouter && bdrouter == &myself)
645 next_state = OSPF6_INTERFACE_BDR;
646 else
647 next_state = OSPF6_INTERFACE_DROTHER;
648
649 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
650 /* XXX */
651
652 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
653 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
654 accordingly after AdjOK */
655 if (oi->drouter != (drouter ? drouter->router_id : htonl(0))
656 || oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0))) {
657 if (IS_OSPF6_DEBUG_INTERFACE)
658 zlog_debug("DR Election on %s: DR: %s BDR: %s",
659 oi->interface->name,
660 (drouter ? drouter->name : "0.0.0.0"),
661 (bdrouter ? bdrouter->name : "0.0.0.0"));
662
663 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) {
664 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
665 continue;
666 /* Schedule AdjOK. */
667 thread_add_event(master, adj_ok, on, 0, NULL);
668 }
669 }
670
671 oi->drouter = (drouter ? drouter->router_id : htonl(0));
672 oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
673 return next_state;
718e3744 674}
675
6b0655a2 676
508e53e2 677/* Interface State Machine */
d62a17ae 678int interface_up(struct thread *thread)
718e3744 679{
d62a17ae 680 struct ospf6_interface *oi;
681
682 oi = (struct ospf6_interface *)THREAD_ARG(thread);
683 assert(oi && oi->interface);
684
5aeb4f3c
DL
685 if (!oi->type_cfg)
686 oi->type = ospf6_default_iftype(oi->interface);
687
f80003b0
RZ
688 /*
689 * Remove old pointer. If this thread wasn't a timer this
690 * operation won't make a difference, because it is already NULL.
691 */
692 oi->thread_sso = NULL;
693
d62a17ae 694 if (IS_OSPF6_DEBUG_INTERFACE)
695 zlog_debug("Interface Event %s: [InterfaceUp]",
696 oi->interface->name);
697
698 /* check physical interface is up */
699 if (!if_is_operative(oi->interface)) {
700 if (IS_OSPF6_DEBUG_INTERFACE)
701 zlog_debug(
702 "Interface %s is down, can't execute [InterfaceUp]",
703 oi->interface->name);
704 return 0;
705 }
706
707 /* check interface has a link-local address */
708 if (!(ospf6_interface_get_linklocal_address(oi->interface)
709 || if_is_loopback(oi->interface))) {
710 if (IS_OSPF6_DEBUG_INTERFACE)
711 zlog_debug(
712 "Interface %s has no link local address, can't execute [InterfaceUp]",
713 oi->interface->name);
714 return 0;
715 }
716
717 /* Recompute cost */
718 ospf6_interface_recalculate_cost(oi);
719
720 /* if already enabled, do nothing */
721 if (oi->state > OSPF6_INTERFACE_DOWN) {
722 if (IS_OSPF6_DEBUG_INTERFACE)
723 zlog_debug("Interface %s already enabled",
724 oi->interface->name);
725 return 0;
726 }
727
728 /* If no area assigned, return */
729 if (oi->area == NULL) {
730 zlog_debug(
731 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
732 __func__, oi->interface->name);
733 return 0;
734 }
735
bc482dc0
RZ
736#ifdef __FreeBSD__
737 /*
738 * XXX: Schedule IPv6 group join for later, otherwise we might
739 * lose the multicast group registration caused by IPv6 group
740 * leave race.
741 */
742 if (oi->sso_try_cnt == 0) {
743 oi->sso_try_cnt++;
744 zlog_info("Scheduling %s for sso", oi->interface->name);
745 thread_add_timer(master, interface_up, oi,
746 OSPF6_INTERFACE_SSO_RETRY_INT,
747 &oi->thread_sso);
748 return 0;
749 }
750#endif /* __FreeBSD__ */
751
d62a17ae 752 /* Join AllSPFRouters */
753 if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP)
754 < 0) {
755 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
756 zlog_info(
757 "Scheduling %s for sso retry, trial count: %d",
758 oi->interface->name, oi->sso_try_cnt);
759 thread_add_timer(master, interface_up, oi,
f80003b0
RZ
760 OSPF6_INTERFACE_SSO_RETRY_INT,
761 &oi->thread_sso);
d62a17ae 762 }
763 return 0;
764 }
765 oi->sso_try_cnt = 0; /* Reset on success */
766
767 /* Update interface route */
768 ospf6_interface_connected_route_update(oi->interface);
769
770 /* Schedule Hello */
771 if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
772 && !if_is_loopback(oi->interface)) {
773 oi->thread_send_hello = NULL;
774 thread_add_event(master, ospf6_hello_send, oi, 0,
775 &oi->thread_send_hello);
776 }
777
778 /* decide next interface state */
e5973353 779 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
d62a17ae 780 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
781 } else if (oi->priority == 0)
782 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
783 else {
784 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
785 thread_add_timer(master, wait_timer, oi, oi->dead_interval,
786 NULL);
787 }
788
789 return 0;
718e3744 790}
791
d62a17ae 792int wait_timer(struct thread *thread)
718e3744 793{
d62a17ae 794 struct ospf6_interface *oi;
718e3744 795
d62a17ae 796 oi = (struct ospf6_interface *)THREAD_ARG(thread);
797 assert(oi && oi->interface);
718e3744 798
d62a17ae 799 if (IS_OSPF6_DEBUG_INTERFACE)
800 zlog_debug("Interface Event %s: [WaitTimer]",
801 oi->interface->name);
718e3744 802
d62a17ae 803 if (oi->state == OSPF6_INTERFACE_WAITING)
804 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 805
d62a17ae 806 return 0;
718e3744 807}
808
d62a17ae 809int backup_seen(struct thread *thread)
508e53e2 810{
d62a17ae 811 struct ospf6_interface *oi;
508e53e2 812
d62a17ae 813 oi = (struct ospf6_interface *)THREAD_ARG(thread);
814 assert(oi && oi->interface);
508e53e2 815
d62a17ae 816 if (IS_OSPF6_DEBUG_INTERFACE)
817 zlog_debug("Interface Event %s: [BackupSeen]",
818 oi->interface->name);
508e53e2 819
d62a17ae 820 if (oi->state == OSPF6_INTERFACE_WAITING)
821 ospf6_interface_state_change(dr_election(oi), oi);
508e53e2 822
d62a17ae 823 return 0;
508e53e2 824}
825
d62a17ae 826int neighbor_change(struct thread *thread)
718e3744 827{
d62a17ae 828 struct ospf6_interface *oi;
508e53e2 829
d62a17ae 830 oi = (struct ospf6_interface *)THREAD_ARG(thread);
831 assert(oi && oi->interface);
508e53e2 832
d62a17ae 833 if (IS_OSPF6_DEBUG_INTERFACE)
834 zlog_debug("Interface Event %s: [NeighborChange]",
835 oi->interface->name);
508e53e2 836
d62a17ae 837 if (oi->state == OSPF6_INTERFACE_DROTHER
838 || oi->state == OSPF6_INTERFACE_BDR
839 || oi->state == OSPF6_INTERFACE_DR)
840 ospf6_interface_state_change(dr_election(oi), oi);
508e53e2 841
d62a17ae 842 return 0;
718e3744 843}
844
d62a17ae 845int interface_down(struct thread *thread)
718e3744 846{
d62a17ae 847 struct ospf6_interface *oi;
848 struct listnode *node, *nnode;
849 struct ospf6_neighbor *on;
508e53e2 850
d62a17ae 851 oi = (struct ospf6_interface *)THREAD_ARG(thread);
852 assert(oi && oi->interface);
508e53e2 853
d62a17ae 854 if (IS_OSPF6_DEBUG_INTERFACE)
855 zlog_debug("Interface Event %s: [InterfaceDown]",
856 oi->interface->name);
508e53e2 857
d62a17ae 858 /* Stop Hellos */
859 THREAD_OFF(oi->thread_send_hello);
424cc3bd 860
f80003b0
RZ
861 /* Stop trying to set socket options. */
862 THREAD_OFF(oi->thread_sso);
863
d62a17ae 864 /* Leave AllSPFRouters */
865 if (oi->state > OSPF6_INTERFACE_DOWN)
866 ospf6_sso(oi->interface->ifindex, &allspfrouters6,
867 IPV6_LEAVE_GROUP);
508e53e2 868
d62a17ae 869 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
508e53e2 870
d62a17ae 871 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
872 ospf6_neighbor_delete(on);
508e53e2 873
d62a17ae 874 list_delete_all_node(oi->neighbor_list);
875
876 /* When interface state is reset, also reset information about
877 * DR election, as it is no longer valid. */
878 oi->drouter = oi->prev_drouter = htonl(0);
879 oi->bdrouter = oi->prev_bdrouter = htonl(0);
880 return 0;
718e3744 881}
882
6b0655a2 883
5aeb4f3c
DL
884static const char *ospf6_iftype_str(uint8_t iftype)
885{
886 switch (iftype) {
887 case OSPF_IFTYPE_LOOPBACK:
888 return "LOOPBACK";
889 case OSPF_IFTYPE_BROADCAST:
890 return "BROADCAST";
891 case OSPF_IFTYPE_POINTOPOINT:
892 return "POINTOPOINT";
893 }
894 return "UNKNOWN";
895}
896
718e3744 897/* show specified interface structure */
d62a17ae 898static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
718e3744 899{
d62a17ae 900 struct ospf6_interface *oi;
901 struct connected *c;
902 struct prefix *p;
903 struct listnode *i;
904 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
5aeb4f3c 905 uint8_t default_iftype;
d62a17ae 906 struct timeval res, now;
907 char duration[32];
908 struct ospf6_lsa *lsa;
909
5aeb4f3c 910 default_iftype = ospf6_default_iftype(ifp);
d62a17ae 911
912 vty_out(vty, "%s is %s, type %s\n", ifp->name,
5aeb4f3c
DL
913 (if_is_operative(ifp) ? "up" : "down"),
914 ospf6_iftype_str(default_iftype));
d62a17ae 915 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
916
917 if (ifp->info == NULL) {
918 vty_out(vty, " OSPF not enabled on this interface\n");
919 return 0;
920 } else
921 oi = (struct ospf6_interface *)ifp->info;
922
5aeb4f3c
DL
923 if (if_is_operative(ifp) && oi->type != default_iftype)
924 vty_out(vty, " Operating as type %s\n",
925 ospf6_iftype_str(oi->type));
926
d62a17ae 927 vty_out(vty, " Internet Address:\n");
928
929 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
930 p = c->address;
931 prefix2str(p, strbuf, sizeof(strbuf));
932 switch (p->family) {
933 case AF_INET:
934 vty_out(vty, " inet : %s\n", strbuf);
935 break;
936 case AF_INET6:
937 vty_out(vty, " inet6: %s\n", strbuf);
938 break;
939 default:
940 vty_out(vty, " ??? : %s\n", strbuf);
941 break;
942 }
943 }
944
945 if (oi->area) {
946 vty_out(vty,
947 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
948 oi->instance_id, oi->ifmtu, ifp->mtu6);
949 vty_out(vty, " MTU mismatch detection: %s\n",
950 oi->mtu_ignore ? "disabled" : "enabled");
951 inet_ntop(AF_INET, &oi->area->area_id, strbuf, sizeof(strbuf));
952 vty_out(vty, " Area ID %s, Cost %u\n", strbuf, oi->cost);
953 } else
954 vty_out(vty, " Not Attached to Area\n");
955
956 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
957 ospf6_interface_state_str[oi->state], oi->transdelay,
958 oi->priority);
959 vty_out(vty, " Timer intervals configured:\n");
960 vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
961 oi->hello_interval, oi->dead_interval, oi->rxmt_interval);
962
963 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
964 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
965 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
966
967 vty_out(vty, " Number of I/F scoped LSAs is %u\n", oi->lsdb->count);
968
969 monotime(&now);
970
971 timerclear(&res);
972 if (oi->thread_send_lsupdate)
973 timersub(&oi->thread_send_lsupdate->u.sands, &now, &res);
974 timerstring(&res, duration, sizeof(duration));
975 vty_out(vty,
976 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
977 oi->lsupdate_list->count, duration,
978 (oi->thread_send_lsupdate ? "on" : "off"));
979 for (ALL_LSDB(oi->lsupdate_list, lsa))
980 vty_out(vty, " %s\n", lsa->name);
981
982 timerclear(&res);
983 if (oi->thread_send_lsack)
984 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
985 timerstring(&res, duration, sizeof(duration));
986 vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
987 oi->lsack_list->count, duration,
988 (oi->thread_send_lsack ? "on" : "off"));
989 for (ALL_LSDB(oi->lsack_list, lsa))
990 vty_out(vty, " %s\n", lsa->name);
991 ospf6_bfd_show_info(vty, oi->bfd_info, 1);
992 return 0;
718e3744 993}
994
995/* show interface */
996DEFUN (show_ipv6_ospf6_interface,
997 show_ipv6_ospf6_interface_ifname_cmd,
1d68dbfe 998 "show ipv6 ospf6 interface [IFNAME]",
718e3744 999 SHOW_STR
1000 IP6_STR
1001 OSPF6_STR
1002 INTERFACE_STR
1d68dbfe 1003 IFNAME_STR)
718e3744 1004{
f4e14fdb 1005 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1006 int idx_ifname = 4;
1007 struct interface *ifp;
d62a17ae 1008
1009 if (argc == 5) {
a36898e7 1010 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 1011 if (ifp == NULL) {
1012 vty_out(vty, "No such Interface: %s\n",
1013 argv[idx_ifname]->arg);
1014 return CMD_WARNING;
1015 }
1016 ospf6_interface_show(vty, ifp);
1017 } else {
451fda4f 1018 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1019 ospf6_interface_show(vty, ifp);
1020 }
1021
1022 return CMD_SUCCESS;
718e3744 1023}
1024
996c9314 1025static int ospf6_interface_show_traffic(struct vty *vty, uint32_t vrf_id,
43855e3d
CS
1026 struct interface *intf_ifp,
1027 int display_once)
1028{
1029 struct interface *ifp;
1030 struct vrf *vrf = NULL;
1031 struct ospf6_interface *oi = NULL;
1032
1033 vrf = vrf_lookup_by_id(vrf_id);
1034
1035 if (!display_once) {
1036 vty_out(vty, "\n");
996c9314
LB
1037 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1038 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1039 " LS-Ack");
43855e3d 1040 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
996c9314
LB
1041 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1042 " Rx/Tx");
43855e3d 1043 vty_out(vty,
996c9314 1044 "--------------------------------------------------------------------------------------------\n");
43855e3d
CS
1045 }
1046
1047 if (intf_ifp == NULL) {
1048 FOR_ALL_INTERFACES (vrf, ifp) {
1049 if (ifp->info)
1050 oi = (struct ospf6_interface *)ifp->info;
1051 else
1052 continue;
1053
1054 vty_out(vty,
996c9314 1055 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
43855e3d 1056 oi->interface->name, oi->hello_in,
996c9314
LB
1057 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1058 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1059 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
43855e3d
CS
1060 }
1061 } else {
1062 oi = intf_ifp->info;
1063 if (oi == NULL)
1064 return CMD_WARNING;
1065
1066 vty_out(vty,
1067 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
996c9314
LB
1068 oi->interface->name, oi->hello_in, oi->hello_out,
1069 oi->db_desc_in, oi->db_desc_out, oi->ls_req_in,
1070 oi->ls_req_out, oi->ls_upd_in, oi->ls_upd_out,
43855e3d
CS
1071 oi->ls_ack_in, oi->ls_ack_out);
1072 }
1073
1074 return CMD_SUCCESS;
1075}
1076
1077/* show interface */
1078DEFUN (show_ipv6_ospf6_interface_traffic,
1079 show_ipv6_ospf6_interface_traffic_cmd,
1080 "show ipv6 ospf6 interface traffic [IFNAME]",
1081 SHOW_STR
1082 IP6_STR
1083 OSPF6_STR
1084 INTERFACE_STR
1085 "Protocol Packet counters\n"
1086 IFNAME_STR)
1087{
1088 int idx_ifname = 0;
1089 int display_once = 0;
1090 char *intf_name = NULL;
1091 struct interface *ifp = NULL;
1092
1093 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1094 intf_name = argv[idx_ifname]->arg;
a36898e7 1095 ifp = if_lookup_by_name(intf_name, VRF_DEFAULT);
43855e3d 1096 if (ifp == NULL) {
996c9314 1097 vty_out(vty, "No such Interface: %s\n", intf_name);
43855e3d
CS
1098 return CMD_WARNING;
1099 }
1100 if (ifp->info == NULL) {
1101 vty_out(vty,
1102 " OSPF not enabled on this interface %s\n",
1103 intf_name);
1104 return 0;
1105 }
1106 }
1107
996c9314 1108 ospf6_interface_show_traffic(vty, VRF_DEFAULT, ifp, display_once);
43855e3d
CS
1109
1110
1111 return CMD_SUCCESS;
1112}
1113
1114
508e53e2 1115DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
1116 show_ipv6_ospf6_interface_ifname_prefix_cmd,
25ee05c9
RW
1117 "show ipv6 ospf6 interface IFNAME prefix\
1118 [<\
1119 detail\
1120 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1121 >]",
508e53e2 1122 SHOW_STR
1123 IP6_STR
1124 OSPF6_STR
1125 INTERFACE_STR
1126 IFNAME_STR
093d7a3a 1127 "Display connected prefixes to advertise\n"
25ee05c9 1128 "Display details of the prefixes\n"
093d7a3a
DW
1129 OSPF6_ROUTE_ADDRESS_STR
1130 OSPF6_ROUTE_PREFIX_STR
1131 OSPF6_ROUTE_MATCH_STR
1132 "Display details of the prefixes\n")
508e53e2 1133{
d62a17ae 1134 int idx_ifname = 4;
1135 int idx_prefix = 6;
1136 struct interface *ifp;
1137 struct ospf6_interface *oi;
1138
a36898e7 1139 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 1140 if (ifp == NULL) {
1141 vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
1142 return CMD_WARNING;
1143 }
1144
1145 oi = ifp->info;
1146 if (oi == NULL) {
1147 vty_out(vty, "OSPFv3 is not enabled on %s\n",
1148 argv[idx_ifname]->arg);
1149 return CMD_WARNING;
1150 }
1151
1152 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1153 oi->route_connected);
1154
1155 return CMD_SUCCESS;
508e53e2 1156}
1157
508e53e2 1158DEFUN (show_ipv6_ospf6_interface_prefix,
1159 show_ipv6_ospf6_interface_prefix_cmd,
25ee05c9
RW
1160 "show ipv6 ospf6 interface prefix\
1161 [<\
1162 detail\
1163 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1164 >]",
508e53e2 1165 SHOW_STR
1166 IP6_STR
1167 OSPF6_STR
1168 INTERFACE_STR
1169 "Display connected prefixes to advertise\n"
25ee05c9 1170 "Display details of the prefixes\n"
093d7a3a
DW
1171 OSPF6_ROUTE_ADDRESS_STR
1172 OSPF6_ROUTE_PREFIX_STR
1173 OSPF6_ROUTE_MATCH_STR
1174 "Display details of the prefixes\n")
508e53e2 1175{
f4e14fdb 1176 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1177 int idx_prefix = 5;
d62a17ae 1178 struct ospf6_interface *oi;
1179 struct interface *ifp;
1180
451fda4f 1181 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1182 oi = (struct ospf6_interface *)ifp->info;
1183 if (oi == NULL)
1184 continue;
1185
1186 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1187 oi->route_connected);
1188 }
508e53e2 1189
d62a17ae 1190 return CMD_SUCCESS;
508e53e2 1191}
1192
718e3744 1193/* interface variable set command */
b596c71e 1194DEFUN (ipv6_ospf6_ifmtu,
1195 ipv6_ospf6_ifmtu_cmd,
6147e2c6 1196 "ipv6 ospf6 ifmtu (1-65535)",
b596c71e 1197 IP6_STR
1198 OSPF6_STR
1199 "Interface MTU\n"
1200 "OSPFv3 Interface MTU\n"
1201 )
1202{
d62a17ae 1203 VTY_DECLVAR_CONTEXT(interface, ifp);
1204 int idx_number = 3;
1205 struct ospf6_interface *oi;
1206 unsigned int ifmtu, iobuflen;
1207 struct listnode *node, *nnode;
1208 struct ospf6_neighbor *on;
1209
1210 assert(ifp);
1211
1212 oi = (struct ospf6_interface *)ifp->info;
1213 if (oi == NULL)
1214 oi = ospf6_interface_create(ifp);
1215 assert(oi);
1216
1217 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1218
1219 if (oi->c_ifmtu == ifmtu)
1220 return CMD_SUCCESS;
1221
1222 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1223 vty_out(vty,
1224 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1225 ifp->name, ifp->mtu6);
1226 return CMD_WARNING_CONFIG_FAILED;
1227 }
1228
1229 if (oi->ifmtu < ifmtu) {
1230 iobuflen = ospf6_iobuf_size(ifmtu);
1231 if (iobuflen < ifmtu) {
1232 vty_out(vty,
1233 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1234 ifp->name, iobuflen);
1235 oi->ifmtu = oi->c_ifmtu = iobuflen;
1236 } else
1237 oi->ifmtu = oi->c_ifmtu = ifmtu;
1238 } else
1239 oi->ifmtu = oi->c_ifmtu = ifmtu;
1240
1241 /* re-establish adjacencies */
1242 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1243 THREAD_OFF(on->inactivity_timer);
1244 thread_add_event(master, inactivity_timer, on, 0, NULL);
1245 }
1246
1247 return CMD_SUCCESS;
b596c71e 1248}
1249
049207c3 1250DEFUN (no_ipv6_ospf6_ifmtu,
1251 no_ipv6_ospf6_ifmtu_cmd,
0c7ef48a 1252 "no ipv6 ospf6 ifmtu [(1-65535)]",
049207c3 1253 NO_STR
1254 IP6_STR
1255 OSPF6_STR
1256 "Interface MTU\n"
0c7ef48a 1257 "OSPFv3 Interface MTU\n"
049207c3 1258 )
1259{
d62a17ae 1260 VTY_DECLVAR_CONTEXT(interface, ifp);
1261 struct ospf6_interface *oi;
1262 unsigned int iobuflen;
1263 struct listnode *node, *nnode;
1264 struct ospf6_neighbor *on;
1265
1266 assert(ifp);
1267
1268 oi = (struct ospf6_interface *)ifp->info;
1269 if (oi == NULL)
1270 oi = ospf6_interface_create(ifp);
1271 assert(oi);
1272
1273 if (oi->ifmtu < ifp->mtu) {
1274 iobuflen = ospf6_iobuf_size(ifp->mtu);
1275 if (iobuflen < ifp->mtu) {
1276 vty_out(vty,
1277 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1278 ifp->name, iobuflen);
1279 oi->ifmtu = iobuflen;
1280 } else
1281 oi->ifmtu = ifp->mtu;
1282 } else
1283 oi->ifmtu = ifp->mtu;
1284
1285 oi->c_ifmtu = 0;
1286
1287 /* re-establish adjacencies */
1288 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1289 THREAD_OFF(on->inactivity_timer);
1290 thread_add_event(master, inactivity_timer, on, 0, NULL);
1291 }
1292
1293 return CMD_SUCCESS;
049207c3 1294}
1295
718e3744 1296DEFUN (ipv6_ospf6_cost,
1297 ipv6_ospf6_cost_cmd,
6147e2c6 1298 "ipv6 ospf6 cost (1-65535)",
718e3744 1299 IP6_STR
1300 OSPF6_STR
1301 "Interface cost\n"
32573073 1302 "Outgoing metric of this interface\n")
718e3744 1303{
d62a17ae 1304 VTY_DECLVAR_CONTEXT(interface, ifp);
1305 int idx_number = 3;
1306 struct ospf6_interface *oi;
1307 unsigned long int lcost;
1308
1309 assert(ifp);
1310
1311 oi = (struct ospf6_interface *)ifp->info;
1312 if (oi == NULL)
1313 oi = ospf6_interface_create(ifp);
1314 assert(oi);
1315
1316 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1317
1318 if (lcost > UINT32_MAX) {
1319 vty_out(vty, "Cost %ld is out of range\n", lcost);
1320 return CMD_WARNING_CONFIG_FAILED;
1321 }
1322
1323 if (oi->cost == lcost)
1324 return CMD_SUCCESS;
1325
1326 oi->cost = lcost;
1327 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1328
0db8196a 1329 ospf6_interface_force_recalculate_cost(oi);
d62a17ae 1330
1331 return CMD_SUCCESS;
c19543b2
VB
1332}
1333
1334DEFUN (no_ipv6_ospf6_cost,
1335 no_ipv6_ospf6_cost_cmd,
32573073 1336 "no ipv6 ospf6 cost [(1-65535)]",
c19543b2
VB
1337 NO_STR
1338 IP6_STR
1339 OSPF6_STR
1340 "Calculate interface cost from bandwidth\n"
32573073 1341 "Outgoing metric of this interface\n")
c19543b2 1342{
d62a17ae 1343 VTY_DECLVAR_CONTEXT(interface, ifp);
1344 struct ospf6_interface *oi;
1345 assert(ifp);
c19543b2 1346
d62a17ae 1347 oi = (struct ospf6_interface *)ifp->info;
1348 if (oi == NULL)
1349 oi = ospf6_interface_create(ifp);
1350 assert(oi);
c19543b2 1351
d62a17ae 1352 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
c19543b2 1353
d62a17ae 1354 ospf6_interface_recalculate_cost(oi);
718e3744 1355
d62a17ae 1356 return CMD_SUCCESS;
718e3744 1357}
1358
fd500689
VB
1359DEFUN (auto_cost_reference_bandwidth,
1360 auto_cost_reference_bandwidth_cmd,
6147e2c6 1361 "auto-cost reference-bandwidth (1-4294967)",
fd500689
VB
1362 "Calculate OSPF interface cost according to bandwidth\n"
1363 "Use reference bandwidth method to assign OSPF cost\n"
1364 "The reference bandwidth in terms of Mbits per second\n")
1365{
d62a17ae 1366 VTY_DECLVAR_CONTEXT(ospf6, o);
1367 int idx_number = 2;
1368 struct ospf6_area *oa;
1369 struct ospf6_interface *oi;
1370 struct listnode *i, *j;
d7c0a89a 1371 uint32_t refbw;
d62a17ae 1372
1373 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1374 if (refbw < 1 || refbw > 4294967) {
1375 vty_out(vty, "reference-bandwidth value is invalid\n");
1376 return CMD_WARNING_CONFIG_FAILED;
1377 }
1378
1379 /* If reference bandwidth is changed. */
1380 if ((refbw) == o->ref_bandwidth)
1381 return CMD_SUCCESS;
1382
1383 o->ref_bandwidth = refbw;
1384 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1385 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1386 ospf6_interface_recalculate_cost(oi);
1387
1388 return CMD_SUCCESS;
fd500689
VB
1389}
1390
1391DEFUN (no_auto_cost_reference_bandwidth,
1392 no_auto_cost_reference_bandwidth_cmd,
ccb8e0c7 1393 "no auto-cost reference-bandwidth [(1-4294967)]",
fd500689
VB
1394 NO_STR
1395 "Calculate OSPF interface cost according to bandwidth\n"
1d68dbfe
DW
1396 "Use reference bandwidth method to assign OSPF cost\n"
1397 "The reference bandwidth in terms of Mbits per second\n")
fd500689 1398{
d62a17ae 1399 VTY_DECLVAR_CONTEXT(ospf6, o);
1400 struct ospf6_area *oa;
1401 struct ospf6_interface *oi;
1402 struct listnode *i, *j;
fd500689 1403
d62a17ae 1404 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1405 return CMD_SUCCESS;
fd500689 1406
d62a17ae 1407 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1408 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1409 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1410 ospf6_interface_recalculate_cost(oi);
fd500689 1411
d62a17ae 1412 return CMD_SUCCESS;
fd500689
VB
1413}
1414
813d4307 1415
718e3744 1416DEFUN (ipv6_ospf6_hellointerval,
1417 ipv6_ospf6_hellointerval_cmd,
6147e2c6 1418 "ipv6 ospf6 hello-interval (1-65535)",
718e3744 1419 IP6_STR
1420 OSPF6_STR
99a522c7 1421 "Time between HELLO packets\n"
d23d6de8 1422 SECONDS_STR)
718e3744 1423{
d62a17ae 1424 VTY_DECLVAR_CONTEXT(interface, ifp);
1425 int idx_number = 3;
1426 struct ospf6_interface *oi;
1427 assert(ifp);
1428
1429 oi = (struct ospf6_interface *)ifp->info;
1430 if (oi == NULL)
1431 oi = ospf6_interface_create(ifp);
1432 assert(oi);
1433
d23d6de8
QY
1434 oi->hello_interval = strmatch(argv[0]->text, "no")
1435 ? OSPF_HELLO_INTERVAL_DEFAULT
1436 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1437 return CMD_SUCCESS;
718e3744 1438}
1439
d23d6de8
QY
1440ALIAS (ipv6_ospf6_hellointerval,
1441 no_ipv6_ospf6_hellointerval_cmd,
1442 "no ipv6 ospf6 hello-interval [(1-65535)]",
1443 NO_STR
1444 IP6_STR
1445 OSPF6_STR
1446 "Time between HELLO packets\n"
1447 SECONDS_STR)
1448
718e3744 1449/* interface variable set command */
1450DEFUN (ipv6_ospf6_deadinterval,
1451 ipv6_ospf6_deadinterval_cmd,
6147e2c6 1452 "ipv6 ospf6 dead-interval (1-65535)",
718e3744 1453 IP6_STR
1454 OSPF6_STR
508e53e2 1455 "Interval time after which a neighbor is declared down\n"
d23d6de8 1456 SECONDS_STR)
718e3744 1457{
d62a17ae 1458 VTY_DECLVAR_CONTEXT(interface, ifp);
1459 int idx_number = 3;
1460 struct ospf6_interface *oi;
1461 assert(ifp);
1462
1463 oi = (struct ospf6_interface *)ifp->info;
1464 if (oi == NULL)
1465 oi = ospf6_interface_create(ifp);
1466 assert(oi);
1467
d23d6de8
QY
1468 oi->dead_interval = strmatch(argv[0]->arg, "no")
1469 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1470 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1471 return CMD_SUCCESS;
718e3744 1472}
1473
d23d6de8
QY
1474ALIAS (ipv6_ospf6_deadinterval,
1475 no_ipv6_ospf6_deadinterval_cmd,
1476 "no ipv6 ospf6 dead-interval [(1-65535)]",
1477 NO_STR
1478 IP6_STR
1479 OSPF6_STR
1480 "Interval time after which a neighbor is declared down\n"
1481 SECONDS_STR)
1482
718e3744 1483/* interface variable set command */
1484DEFUN (ipv6_ospf6_transmitdelay,
1485 ipv6_ospf6_transmitdelay_cmd,
6147e2c6 1486 "ipv6 ospf6 transmit-delay (1-3600)",
718e3744 1487 IP6_STR
1488 OSPF6_STR
99a522c7 1489 "Link state transmit delay\n"
98cfd06b 1490 SECONDS_STR)
718e3744 1491{
d62a17ae 1492 VTY_DECLVAR_CONTEXT(interface, ifp);
1493 int idx_number = 3;
1494 struct ospf6_interface *oi;
1495 assert(ifp);
1496
1497 oi = (struct ospf6_interface *)ifp->info;
1498 if (oi == NULL)
1499 oi = ospf6_interface_create(ifp);
1500 assert(oi);
1501
d23d6de8
QY
1502 oi->transdelay = strmatch(argv[0]->text, "no")
1503 ? OSPF6_INTERFACE_TRANSDELAY
1504 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1505 return CMD_SUCCESS;
718e3744 1506}
1507
d23d6de8
QY
1508ALIAS (ipv6_ospf6_transmitdelay,
1509 no_ipv6_ospf6_transmitdelay_cmd,
1510 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1511 NO_STR
1512 IP6_STR
1513 OSPF6_STR
1514 "Link state transmit delay\n"
1515 SECONDS_STR)
1516
718e3744 1517/* interface variable set command */
1518DEFUN (ipv6_ospf6_retransmitinterval,
1519 ipv6_ospf6_retransmitinterval_cmd,
6147e2c6 1520 "ipv6 ospf6 retransmit-interval (1-65535)",
718e3744 1521 IP6_STR
1522 OSPF6_STR
1523 "Time between retransmitting lost link state advertisements\n"
d23d6de8 1524 SECONDS_STR)
718e3744 1525{
d62a17ae 1526 VTY_DECLVAR_CONTEXT(interface, ifp);
1527 int idx_number = 3;
1528 struct ospf6_interface *oi;
1529 assert(ifp);
1530
1531 oi = (struct ospf6_interface *)ifp->info;
1532 if (oi == NULL)
1533 oi = ospf6_interface_create(ifp);
1534 assert(oi);
1535
d23d6de8
QY
1536 oi->rxmt_interval = strmatch(argv[0]->text, "no")
1537 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1538 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1539 return CMD_SUCCESS;
718e3744 1540}
1541
d23d6de8
QY
1542ALIAS (ipv6_ospf6_retransmitinterval,
1543 no_ipv6_ospf6_retransmitinterval_cmd,
1544 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1545 NO_STR
1546 IP6_STR
1547 OSPF6_STR
1548 "Time between retransmitting lost link state advertisements\n"
1549 SECONDS_STR)
1550
718e3744 1551/* interface variable set command */
1552DEFUN (ipv6_ospf6_priority,
1553 ipv6_ospf6_priority_cmd,
6147e2c6 1554 "ipv6 ospf6 priority (0-255)",
718e3744 1555 IP6_STR
1556 OSPF6_STR
1557 "Router priority\n"
d23d6de8 1558 "Priority value\n")
718e3744 1559{
d62a17ae 1560 VTY_DECLVAR_CONTEXT(interface, ifp);
1561 int idx_number = 3;
1562 struct ospf6_interface *oi;
1563 assert(ifp);
718e3744 1564
d62a17ae 1565 oi = (struct ospf6_interface *)ifp->info;
1566 if (oi == NULL)
1567 oi = ospf6_interface_create(ifp);
1568 assert(oi);
508e53e2 1569
d23d6de8
QY
1570 oi->priority = strmatch(argv[0]->text, "no")
1571 ? OSPF6_INTERFACE_PRIORITY
1572 : strtoul(argv[idx_number]->arg, NULL, 10);
718e3744 1573
9d303b37
DL
1574 if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
1575 || oi->state == OSPF6_INTERFACE_BDR
1576 || oi->state == OSPF6_INTERFACE_DR))
d62a17ae 1577 ospf6_interface_state_change(dr_election(oi), oi);
718e3744 1578
d62a17ae 1579 return CMD_SUCCESS;
718e3744 1580}
1581
d23d6de8
QY
1582ALIAS (ipv6_ospf6_priority,
1583 no_ipv6_ospf6_priority_cmd,
1584 "no ipv6 ospf6 priority [(0-255)]",
1585 NO_STR
1586 IP6_STR
1587 OSPF6_STR
1588 "Router priority\n"
1589 "Priority value\n")
1590
718e3744 1591DEFUN (ipv6_ospf6_instance,
1592 ipv6_ospf6_instance_cmd,
6147e2c6 1593 "ipv6 ospf6 instance-id (0-255)",
718e3744 1594 IP6_STR
1595 OSPF6_STR
508e53e2 1596 "Instance ID for this interface\n"
d23d6de8 1597 "Instance ID value\n")
718e3744 1598{
d62a17ae 1599 VTY_DECLVAR_CONTEXT(interface, ifp);
1600 int idx_number = 3;
1601 struct ospf6_interface *oi;
1602 assert(ifp);
1603
1604 oi = (struct ospf6_interface *)ifp->info;
1605 if (oi == NULL)
1606 oi = ospf6_interface_create(ifp);
1607 assert(oi);
1608
d23d6de8
QY
1609 oi->instance_id = strmatch(argv[0]->text, "no")
1610 ? OSPF6_INTERFACE_INSTANCE_ID
1611 : strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 1612 return CMD_SUCCESS;
718e3744 1613}
1614
d23d6de8
QY
1615ALIAS (ipv6_ospf6_instance,
1616 no_ipv6_ospf6_instance_cmd,
1617 "no ipv6 ospf6 instance-id [(0-255)]",
1618 NO_STR
1619 IP6_STR
1620 OSPF6_STR
1621 "Instance ID for this interface\n"
1622 "Instance ID value\n")
1623
718e3744 1624DEFUN (ipv6_ospf6_passive,
1625 ipv6_ospf6_passive_cmd,
1626 "ipv6 ospf6 passive",
1627 IP6_STR
1628 OSPF6_STR
99a522c7 1629 "Passive interface; no adjacency will be formed on this interface\n"
718e3744 1630 )
1631{
d62a17ae 1632 VTY_DECLVAR_CONTEXT(interface, ifp);
1633 struct ospf6_interface *oi;
1634 struct listnode *node, *nnode;
1635 struct ospf6_neighbor *on;
718e3744 1636
d62a17ae 1637 assert(ifp);
718e3744 1638
d62a17ae 1639 oi = (struct ospf6_interface *)ifp->info;
1640 if (oi == NULL)
1641 oi = ospf6_interface_create(ifp);
1642 assert(oi);
718e3744 1643
d62a17ae 1644 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1645 THREAD_OFF(oi->thread_send_hello);
f80003b0 1646 THREAD_OFF(oi->thread_sso);
508e53e2 1647
d62a17ae 1648 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1649 THREAD_OFF(on->inactivity_timer);
1650 thread_add_event(master, inactivity_timer, on, 0, NULL);
1651 }
718e3744 1652
d62a17ae 1653 return CMD_SUCCESS;
718e3744 1654}
1655
1656DEFUN (no_ipv6_ospf6_passive,
1657 no_ipv6_ospf6_passive_cmd,
1658 "no ipv6 ospf6 passive",
1659 NO_STR
1660 IP6_STR
1661 OSPF6_STR
1662 "passive interface: No Adjacency will be formed on this I/F\n"
1663 )
1664{
d62a17ae 1665 VTY_DECLVAR_CONTEXT(interface, ifp);
1666 struct ospf6_interface *oi;
1667 assert(ifp);
718e3744 1668
d62a17ae 1669 oi = (struct ospf6_interface *)ifp->info;
1670 if (oi == NULL)
1671 oi = ospf6_interface_create(ifp);
1672 assert(oi);
718e3744 1673
d62a17ae 1674 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1675 THREAD_OFF(oi->thread_send_hello);
f80003b0 1676 THREAD_OFF(oi->thread_sso);
d62a17ae 1677 thread_add_event(master, ospf6_hello_send, oi, 0,
1678 &oi->thread_send_hello);
718e3744 1679
d62a17ae 1680 return CMD_SUCCESS;
718e3744 1681}
1682
d42306d9
DT
1683DEFUN (ipv6_ospf6_mtu_ignore,
1684 ipv6_ospf6_mtu_ignore_cmd,
1685 "ipv6 ospf6 mtu-ignore",
1686 IP6_STR
1687 OSPF6_STR
99a522c7 1688 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1689 )
1690{
d62a17ae 1691 VTY_DECLVAR_CONTEXT(interface, ifp);
1692 struct ospf6_interface *oi;
1693 assert(ifp);
d42306d9 1694
d62a17ae 1695 oi = (struct ospf6_interface *)ifp->info;
1696 if (oi == NULL)
1697 oi = ospf6_interface_create(ifp);
1698 assert(oi);
d42306d9 1699
d62a17ae 1700 oi->mtu_ignore = 1;
d42306d9 1701
d62a17ae 1702 return CMD_SUCCESS;
d42306d9
DT
1703}
1704
1705DEFUN (no_ipv6_ospf6_mtu_ignore,
1706 no_ipv6_ospf6_mtu_ignore_cmd,
1707 "no ipv6 ospf6 mtu-ignore",
1708 NO_STR
1709 IP6_STR
1710 OSPF6_STR
99a522c7 1711 "Disable MTU mismatch detection on this interface\n"
d42306d9
DT
1712 )
1713{
d62a17ae 1714 VTY_DECLVAR_CONTEXT(interface, ifp);
1715 struct ospf6_interface *oi;
1716 assert(ifp);
d42306d9 1717
d62a17ae 1718 oi = (struct ospf6_interface *)ifp->info;
1719 if (oi == NULL)
1720 oi = ospf6_interface_create(ifp);
1721 assert(oi);
d42306d9 1722
d62a17ae 1723 oi->mtu_ignore = 0;
d42306d9 1724
d62a17ae 1725 return CMD_SUCCESS;
d42306d9
DT
1726}
1727
718e3744 1728DEFUN (ipv6_ospf6_advertise_prefix_list,
1729 ipv6_ospf6_advertise_prefix_list_cmd,
1730 "ipv6 ospf6 advertise prefix-list WORD",
1731 IP6_STR
1732 OSPF6_STR
1733 "Advertising options\n"
1734 "Filter prefix using prefix-list\n"
1735 "Prefix list name\n"
1736 )
1737{
d62a17ae 1738 VTY_DECLVAR_CONTEXT(interface, ifp);
1739 int idx_word = 4;
1740 struct ospf6_interface *oi;
1741 assert(ifp);
1742
1743 oi = (struct ospf6_interface *)ifp->info;
1744 if (oi == NULL)
1745 oi = ospf6_interface_create(ifp);
1746 assert(oi);
1747
1748 if (oi->plist_name)
1749 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
1750 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
1751
1752 ospf6_interface_connected_route_update(oi->interface);
1753
1754 if (oi->area) {
1755 OSPF6_LINK_LSA_SCHEDULE(oi);
1756 if (oi->state == OSPF6_INTERFACE_DR) {
1757 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1758 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1759 }
1760 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1761 }
1762
1763 return CMD_SUCCESS;
718e3744 1764}
1765
1766DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1767 no_ipv6_ospf6_advertise_prefix_list_cmd,
d23d6de8 1768 "no ipv6 ospf6 advertise prefix-list [WORD]",
718e3744 1769 NO_STR
1770 IP6_STR
1771 OSPF6_STR
1772 "Advertising options\n"
1773 "Filter prefix using prefix-list\n"
d23d6de8 1774 "Prefix list name\n")
718e3744 1775{
d62a17ae 1776 VTY_DECLVAR_CONTEXT(interface, ifp);
1777 struct ospf6_interface *oi;
1778 assert(ifp);
1779
1780 oi = (struct ospf6_interface *)ifp->info;
1781 if (oi == NULL)
1782 oi = ospf6_interface_create(ifp);
1783 assert(oi);
1784
d23d6de8 1785 if (oi->plist_name)
d62a17ae 1786 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
d62a17ae 1787
1788 ospf6_interface_connected_route_update(oi->interface);
1789
1790 if (oi->area) {
1791 OSPF6_LINK_LSA_SCHEDULE(oi);
1792 if (oi->state == OSPF6_INTERFACE_DR) {
1793 OSPF6_NETWORK_LSA_SCHEDULE(oi);
1794 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
1795 }
1796 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
1797 }
1798
1799 return CMD_SUCCESS;
718e3744 1800}
1801
c5926a92
DD
1802DEFUN (ipv6_ospf6_network,
1803 ipv6_ospf6_network_cmd,
6147e2c6 1804 "ipv6 ospf6 network <broadcast|point-to-point>",
c5926a92
DD
1805 IP6_STR
1806 OSPF6_STR
99a522c7 1807 "Network type\n"
b2d4d039 1808 "Specify OSPF6 broadcast network\n"
c5926a92
DD
1809 "Specify OSPF6 point-to-point network\n"
1810 )
1811{
d62a17ae 1812 VTY_DECLVAR_CONTEXT(interface, ifp);
1813 int idx_network = 3;
1814 struct ospf6_interface *oi;
1815 assert(ifp);
1816
1817 oi = (struct ospf6_interface *)ifp->info;
1818 if (oi == NULL) {
1819 oi = ospf6_interface_create(ifp);
1820 }
1821 assert(oi);
1822
5aeb4f3c
DL
1823 oi->type_cfg = true;
1824
d62a17ae 1825 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
1826 if (oi->type == OSPF_IFTYPE_BROADCAST)
1827 return CMD_SUCCESS;
1828
1829 oi->type = OSPF_IFTYPE_BROADCAST;
1830 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
1831 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
1832 return CMD_SUCCESS;
1833 }
1834 oi->type = OSPF_IFTYPE_POINTOPOINT;
c5926a92 1835 }
c5926a92 1836
d62a17ae 1837 /* Reset the interface */
849576ee
RZ
1838 thread_execute(master, interface_down, oi, 0);
1839 thread_execute(master, interface_up, oi, 0);
c5926a92 1840
d62a17ae 1841 return CMD_SUCCESS;
c5926a92
DD
1842}
1843
1844DEFUN (no_ipv6_ospf6_network,
1845 no_ipv6_ospf6_network_cmd,
32573073 1846 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
c5926a92
DD
1847 NO_STR
1848 IP6_STR
1849 OSPF6_STR
32573073
QY
1850 "Set default network type\n"
1851 "Specify OSPF6 broadcast network\n"
1852 "Specify OSPF6 point-to-point network\n")
c5926a92 1853{
d62a17ae 1854 VTY_DECLVAR_CONTEXT(interface, ifp);
1855 struct ospf6_interface *oi;
1856 int type;
c5926a92 1857
d62a17ae 1858 assert(ifp);
c5926a92 1859
d62a17ae 1860 oi = (struct ospf6_interface *)ifp->info;
1861 if (oi == NULL) {
1862 return CMD_SUCCESS;
1863 }
c5926a92 1864
5aeb4f3c
DL
1865 oi->type_cfg = false;
1866
d62a17ae 1867 type = ospf6_default_iftype(ifp);
1868 if (oi->type == type) {
1869 return CMD_SUCCESS;
1870 }
1871 oi->type = type;
c5926a92 1872
d62a17ae 1873 /* Reset the interface */
849576ee
RZ
1874 thread_execute(master, interface_down, oi, 0);
1875 thread_execute(master, interface_up, oi, 0);
c5926a92 1876
d62a17ae 1877 return CMD_SUCCESS;
c5926a92
DD
1878}
1879
d62a17ae 1880static int config_write_ospf6_interface(struct vty *vty)
718e3744 1881{
f4e14fdb 1882 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 1883 struct ospf6_interface *oi;
1884 struct interface *ifp;
1885
451fda4f 1886 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1887 oi = (struct ospf6_interface *)ifp->info;
1888 if (oi == NULL)
1889 continue;
1890
a8b828f3 1891 vty_frame(vty, "interface %s\n", oi->interface->name);
d62a17ae 1892
1893 if (ifp->desc)
1894 vty_out(vty, " description %s\n", ifp->desc);
1895 if (oi->c_ifmtu)
1896 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
1897
1898 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
1899 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
1900
1901 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1902 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
1903 oi->hello_interval);
1904
1905 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1906 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
1907 oi->dead_interval);
1908
1909 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1910 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
1911 oi->rxmt_interval);
1912
1913 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1914 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
1915
1916 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1917 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
1918 oi->transdelay);
1919
1920 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1921 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
1922 oi->instance_id);
1923
1924 if (oi->plist_name)
1925 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
1926 oi->plist_name);
1927
1928 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
1929 vty_out(vty, " ipv6 ospf6 passive\n");
1930
1931 if (oi->mtu_ignore)
1932 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
1933
5aeb4f3c
DL
1934 if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
1935 vty_out(vty, " ipv6 ospf6 network point-to-point\n");
1936 else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
1937 vty_out(vty, " ipv6 ospf6 network broadcast\n");
d62a17ae 1938
1939 ospf6_bfd_write_config(vty, oi);
1940
a8b828f3 1941 vty_endframe(vty, "!\n");
d62a17ae 1942 }
1943 return 0;
718e3744 1944}
1945
d62a17ae 1946static struct cmd_node interface_node = {
1947 INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */
718e3744 1948};
1949
138c5a74
DS
1950static int ospf6_ifp_create(struct interface *ifp)
1951{
ef7bd2a3
DS
1952 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
1953 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
1954 ifp->ifindex, ifp->mtu6);
1955 ospf6_interface_if_add(ifp);
1956
138c5a74
DS
1957 return 0;
1958}
1959
1960static int ospf6_ifp_up(struct interface *ifp)
1961{
ddbf3e60
DS
1962 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
1963 zlog_debug(
1964 "Zebra Interface state change: "
1965 "%s index %d flags %llx metric %d mtu %d bandwidth %d",
1966 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
1967 ifp->metric, ifp->mtu6, ifp->bandwidth);
1968
1969 ospf6_interface_state_update(ifp);
1970
138c5a74
DS
1971 return 0;
1972}
1973
1974static int ospf6_ifp_down(struct interface *ifp)
1975{
b0b69e59
DS
1976 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
1977 zlog_debug(
1978 "Zebra Interface state change: "
1979 "%s index %d flags %llx metric %d mtu %d bandwidth %d",
1980 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
1981 ifp->metric, ifp->mtu6, ifp->bandwidth);
1982
1983 ospf6_interface_state_update(ifp);
1984
138c5a74
DS
1985 return 0;
1986}
1987
1988static int ospf6_ifp_destroy(struct interface *ifp)
1989{
3c3c3252
DS
1990 if (if_is_up(ifp))
1991 zlog_warn("Zebra: got delete of %s, but interface is still up",
1992 ifp->name);
1993
1994 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
1995 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
1996 ifp->name, ifp->ifindex, ifp->mtu6);
1997
138c5a74
DS
1998 return 0;
1999}
2000
d62a17ae 2001void ospf6_interface_init(void)
718e3744 2002{
d62a17ae 2003 /* Install interface node. */
2004 install_node(&interface_node, config_write_ospf6_interface);
2005 if_cmd_init();
138c5a74
DS
2006 if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
2007 ospf6_ifp_down, ospf6_ifp_destroy);
d62a17ae 2008
2009 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
2010 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
2011 install_element(VIEW_NODE,
2012 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
996c9314 2013 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
d62a17ae 2014
2015 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
2016 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
2017 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
2018 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
d23d6de8 2019
d62a17ae 2020 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
2021 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
2022 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
2023 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
2024 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
2025 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
d23d6de8
QY
2026 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
2027 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
2028 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
2029 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
2030 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
2031 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
d62a17ae 2032
2033 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
2034 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
2035
2036 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
2037 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
2038
2039 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
2040 install_element(INTERFACE_NODE,
2041 &no_ipv6_ospf6_advertise_prefix_list_cmd);
2042
2043 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
2044 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
2045
2046 /* reference bandwidth commands */
2047 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
2048 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
508e53e2 2049}
2050
a1b11f9b 2051/* Clear the specified interface structure */
d62a17ae 2052static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
a1b11f9b 2053{
d62a17ae 2054 struct ospf6_interface *oi;
a1b11f9b 2055
d62a17ae 2056 if (!if_is_operative(ifp))
2057 return;
a1b11f9b 2058
d62a17ae 2059 if (ifp->info == NULL)
2060 return;
a1b11f9b 2061
d62a17ae 2062 oi = (struct ospf6_interface *)ifp->info;
a1b11f9b 2063
d62a17ae 2064 if (IS_OSPF6_DEBUG_INTERFACE)
2065 zlog_debug("Interface %s: clear by reset", ifp->name);
a1b11f9b 2066
d62a17ae 2067 /* Reset the interface */
849576ee
RZ
2068 thread_execute(master, interface_down, oi, 0);
2069 thread_execute(master, interface_up, oi, 0);
a1b11f9b
DS
2070}
2071
2072/* Clear interface */
2073DEFUN (clear_ipv6_ospf6_interface,
2074 clear_ipv6_ospf6_interface_cmd,
2075 "clear ipv6 ospf6 interface [IFNAME]",
2076 CLEAR_STR
2077 IP6_STR
2078 OSPF6_STR
2079 INTERFACE_STR
2080 IFNAME_STR
2081 )
2082{
f4e14fdb 2083 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 2084 int idx_ifname = 4;
2085 struct interface *ifp;
d62a17ae 2086
2087 if (argc == 4) /* Clear all the ospfv3 interfaces. */
2088 {
451fda4f 2089 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 2090 ospf6_interface_clear(vty, ifp);
2091 } else /* Interface name is specified. */
2092 {
2093 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
a36898e7 2094 VRF_DEFAULT))
d62a17ae 2095 == NULL) {
2096 vty_out(vty, "No such Interface: %s\n",
2097 argv[idx_ifname]->arg);
2098 return CMD_WARNING;
2099 }
2100 ospf6_interface_clear(vty, ifp);
2101 }
2102
2103 return CMD_SUCCESS;
a1b11f9b
DS
2104}
2105
d62a17ae 2106void install_element_ospf6_clear_interface(void)
a1b11f9b 2107{
d62a17ae 2108 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
a1b11f9b
DS
2109}
2110
508e53e2 2111DEFUN (debug_ospf6_interface,
2112 debug_ospf6_interface_cmd,
2113 "debug ospf6 interface",
2114 DEBUG_STR
2115 OSPF6_STR
2116 "Debug OSPFv3 Interface\n"
2117 )
2118{
d62a17ae 2119 OSPF6_DEBUG_INTERFACE_ON();
2120 return CMD_SUCCESS;
508e53e2 2121}
2122
2123DEFUN (no_debug_ospf6_interface,
2124 no_debug_ospf6_interface_cmd,
2125 "no debug ospf6 interface",
2126 NO_STR
2127 DEBUG_STR
2128 OSPF6_STR
2129 "Debug OSPFv3 Interface\n"
2130 )
2131{
d62a17ae 2132 OSPF6_DEBUG_INTERFACE_OFF();
2133 return CMD_SUCCESS;
508e53e2 2134}
2135
d62a17ae 2136int config_write_ospf6_debug_interface(struct vty *vty)
508e53e2 2137{
d62a17ae 2138 if (IS_OSPF6_DEBUG_INTERFACE)
2139 vty_out(vty, "debug ospf6 interface\n");
2140 return 0;
508e53e2 2141}
2142
d62a17ae 2143void install_element_ospf6_debug_interface(void)
508e53e2 2144{
d62a17ae 2145 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2146 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2147 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2148 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
718e3744 2149}