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