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