Annotation of embedaddon/quagga/ospf6d/ospf6_interface.c, revision 1.1.1.3
1.1 misho 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:
32: #include "ospf6_lsa.h"
33: #include "ospf6_lsdb.h"
34: #include "ospf6_network.h"
35: #include "ospf6_message.h"
36: #include "ospf6_route.h"
37: #include "ospf6_top.h"
38: #include "ospf6_area.h"
39: #include "ospf6_interface.h"
40: #include "ospf6_neighbor.h"
41: #include "ospf6_intra.h"
42: #include "ospf6_spf.h"
43: #include "ospf6d.h"
44:
45: unsigned char conf_debug_ospf6_interface = 0;
46:
47: const char *ospf6_interface_state_str[] =
48: {
49: "None",
50: "Down",
51: "Loopback",
52: "Waiting",
53: "PointToPoint",
54: "DROther",
55: "BDR",
56: "DR",
57: NULL
58: };
59:
60: struct ospf6_interface *
61: ospf6_interface_lookup_by_ifindex (int ifindex)
62: {
63: struct ospf6_interface *oi;
64: struct interface *ifp;
65:
66: ifp = if_lookup_by_index (ifindex);
67: if (ifp == NULL)
68: return (struct ospf6_interface *) NULL;
69:
70: oi = (struct ospf6_interface *) ifp->info;
71: return oi;
72: }
73:
74: /* schedule routing table recalculation */
75: static void
76: ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa)
77: {
78: switch (ntohs (lsa->header->type))
79: {
80: case OSPF6_LSTYPE_LINK:
81: if (OSPF6_INTERFACE (lsa->lsdb->data)->state == OSPF6_INTERFACE_DR)
82: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (OSPF6_INTERFACE (lsa->lsdb->data));
83: ospf6_spf_schedule (OSPF6_INTERFACE (lsa->lsdb->data)->area);
84: break;
85:
86: default:
87: break;
88: }
89: }
90:
91: /* Create new ospf6 interface structure */
92: struct ospf6_interface *
93: ospf6_interface_create (struct interface *ifp)
94: {
95: struct ospf6_interface *oi;
96: unsigned int iobuflen;
97:
98: oi = (struct ospf6_interface *)
99: XCALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface));
100:
101: if (!oi)
102: {
103: zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex);
104: return (struct ospf6_interface *) NULL;
105: }
106:
107: oi->area = (struct ospf6_area *) NULL;
108: oi->neighbor_list = list_new ();
109: oi->neighbor_list->cmp = ospf6_neighbor_cmp;
110: oi->linklocal_addr = (struct in6_addr *) NULL;
1.1.1.2 misho 111: oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
112: oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
113: oi->priority = OSPF6_INTERFACE_PRIORITY;
114:
115: oi->hello_interval = OSPF6_INTERFACE_HELLO_INTERVAL;
116: oi->dead_interval = OSPF6_INTERFACE_DEAD_INTERVAL;
117: oi->rxmt_interval = OSPF6_INTERFACE_RXMT_INTERVAL;
118: oi->cost = OSPF6_INTERFACE_COST;
1.1 misho 119: oi->state = OSPF6_INTERFACE_DOWN;
120: oi->flag = 0;
121: oi->mtu_ignore = 0;
122:
123: /* Try to adjust I/O buffer size with IfMtu */
124: oi->ifmtu = ifp->mtu6;
125: iobuflen = ospf6_iobuf_size (ifp->mtu6);
126: if (oi->ifmtu > iobuflen)
127: {
128: if (IS_OSPF6_DEBUG_INTERFACE)
129: zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
130: ifp->name, iobuflen);
131: oi->ifmtu = iobuflen;
132: }
133:
134: oi->lsupdate_list = ospf6_lsdb_create (oi);
135: oi->lsack_list = ospf6_lsdb_create (oi);
136: oi->lsdb = ospf6_lsdb_create (oi);
137: oi->lsdb->hook_add = ospf6_interface_lsdb_hook;
138: oi->lsdb->hook_remove = ospf6_interface_lsdb_hook;
139: oi->lsdb_self = ospf6_lsdb_create (oi);
140:
141: oi->route_connected = OSPF6_ROUTE_TABLE_CREATE (INTERFACE, CONNECTED_ROUTES);
142: oi->route_connected->scope = oi;
143:
144: /* link both */
145: oi->interface = ifp;
146: ifp->info = oi;
147:
148: return oi;
149: }
150:
151: void
152: ospf6_interface_delete (struct ospf6_interface *oi)
153: {
154: struct listnode *node, *nnode;
155: struct ospf6_neighbor *on;
156:
157: for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
158: ospf6_neighbor_delete (on);
159:
160: list_delete (oi->neighbor_list);
161:
162: THREAD_OFF (oi->thread_send_hello);
163: THREAD_OFF (oi->thread_send_lsupdate);
164: THREAD_OFF (oi->thread_send_lsack);
165:
166: ospf6_lsdb_remove_all (oi->lsdb);
167: ospf6_lsdb_remove_all (oi->lsupdate_list);
168: ospf6_lsdb_remove_all (oi->lsack_list);
169:
170: ospf6_lsdb_delete (oi->lsdb);
171: ospf6_lsdb_delete (oi->lsdb_self);
172:
173: ospf6_lsdb_delete (oi->lsupdate_list);
174: ospf6_lsdb_delete (oi->lsack_list);
175:
176: ospf6_route_table_delete (oi->route_connected);
177:
178: /* cut link */
179: oi->interface->info = NULL;
180:
181: /* plist_name */
182: if (oi->plist_name)
183: XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
184:
185: XFREE (MTYPE_OSPF6_IF, oi);
186: }
187:
188: void
189: ospf6_interface_enable (struct ospf6_interface *oi)
190: {
191: UNSET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE);
192:
193: oi->thread_send_hello =
194: thread_add_event (master, ospf6_hello_send, oi, 0);
195: }
196:
197: void
198: ospf6_interface_disable (struct ospf6_interface *oi)
199: {
200: struct listnode *node, *nnode;
201: struct ospf6_neighbor *on;
202:
203: SET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE);
204:
205: for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
206: ospf6_neighbor_delete (on);
207:
208: list_delete_all_node (oi->neighbor_list);
209:
210: ospf6_lsdb_remove_all (oi->lsdb);
211: ospf6_lsdb_remove_all (oi->lsupdate_list);
212: ospf6_lsdb_remove_all (oi->lsack_list);
213:
214: THREAD_OFF (oi->thread_send_hello);
215: THREAD_OFF (oi->thread_send_lsupdate);
216: THREAD_OFF (oi->thread_send_lsack);
217: }
218:
219: static struct in6_addr *
220: ospf6_interface_get_linklocal_address (struct interface *ifp)
221: {
222: struct listnode *n;
223: struct connected *c;
224: struct in6_addr *l = (struct in6_addr *) NULL;
225:
226: /* for each connected address */
227: for (ALL_LIST_ELEMENTS_RO (ifp->connected, n, c))
228: {
229: /* if family not AF_INET6, ignore */
230: if (c->address->family != AF_INET6)
231: continue;
232:
233: /* linklocal scope check */
234: if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6))
235: l = &c->address->u.prefix6;
236: }
237: return l;
238: }
239:
240: void
241: ospf6_interface_if_add (struct interface *ifp)
242: {
243: struct ospf6_interface *oi;
244: unsigned int iobuflen;
245:
246: oi = (struct ospf6_interface *) ifp->info;
247: if (oi == NULL)
248: return;
249:
250: /* Try to adjust I/O buffer size with IfMtu */
251: if (oi->ifmtu == 0)
252: oi->ifmtu = ifp->mtu6;
253: iobuflen = ospf6_iobuf_size (ifp->mtu6);
254: if (oi->ifmtu > iobuflen)
255: {
256: if (IS_OSPF6_DEBUG_INTERFACE)
257: zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
258: ifp->name, iobuflen);
259: oi->ifmtu = iobuflen;
260: }
261:
262: /* interface start */
263: if (oi->area)
264: thread_add_event (master, interface_up, oi, 0);
265: }
266:
267: void
268: ospf6_interface_if_del (struct interface *ifp)
269: {
270: struct ospf6_interface *oi;
271:
272: oi = (struct ospf6_interface *) ifp->info;
273: if (oi == NULL)
274: return;
275:
276: /* interface stop */
277: if (oi->area)
278: thread_execute (master, interface_down, oi, 0);
279:
280: listnode_delete (oi->area->if_list, oi);
281: oi->area = (struct ospf6_area *) NULL;
282:
283: /* cut link */
284: oi->interface = NULL;
285: ifp->info = NULL;
286:
287: ospf6_interface_delete (oi);
288: }
289:
290: void
291: ospf6_interface_state_update (struct interface *ifp)
292: {
293: struct ospf6_interface *oi;
294:
295: oi = (struct ospf6_interface *) ifp->info;
296: if (oi == NULL)
297: return;
298: if (oi->area == NULL)
299: return;
300:
301: if (if_is_up (ifp))
302: thread_add_event (master, interface_up, oi, 0);
303: else
304: thread_add_event (master, interface_down, oi, 0);
305:
306: return;
307: }
308:
309: void
310: ospf6_interface_connected_route_update (struct interface *ifp)
311: {
312: struct ospf6_interface *oi;
313: struct ospf6_route *route;
314: struct connected *c;
315: struct listnode *node, *nnode;
316:
317: oi = (struct ospf6_interface *) ifp->info;
318: if (oi == NULL)
319: return;
320:
321: /* reset linklocal pointer */
322: oi->linklocal_addr = ospf6_interface_get_linklocal_address (ifp);
323:
324: /* if area is null, do not make connected-route list */
325: if (oi->area == NULL)
326: return;
327:
328: /* update "route to advertise" interface route table */
329: ospf6_route_remove_all (oi->route_connected);
330:
331: for (ALL_LIST_ELEMENTS (oi->interface->connected, node, nnode, c))
332: {
333: if (c->address->family != AF_INET6)
334: continue;
335:
336: CONTINUE_IF_ADDRESS_LINKLOCAL (IS_OSPF6_DEBUG_INTERFACE, c->address);
337: CONTINUE_IF_ADDRESS_UNSPECIFIED (IS_OSPF6_DEBUG_INTERFACE, c->address);
338: CONTINUE_IF_ADDRESS_LOOPBACK (IS_OSPF6_DEBUG_INTERFACE, c->address);
339: CONTINUE_IF_ADDRESS_V4COMPAT (IS_OSPF6_DEBUG_INTERFACE, c->address);
340: CONTINUE_IF_ADDRESS_V4MAPPED (IS_OSPF6_DEBUG_INTERFACE, c->address);
341:
342: /* apply filter */
343: if (oi->plist_name)
344: {
345: struct prefix_list *plist;
346: enum prefix_list_type ret;
347: char buf[128];
348:
349: prefix2str (c->address, buf, sizeof (buf));
350: plist = prefix_list_lookup (AFI_IP6, oi->plist_name);
351: ret = prefix_list_apply (plist, (void *) c->address);
352: if (ret == PREFIX_DENY)
353: {
354: if (IS_OSPF6_DEBUG_INTERFACE)
355: zlog_debug ("%s on %s filtered by prefix-list %s ",
356: buf, oi->interface->name, oi->plist_name);
357: continue;
358: }
359: }
360:
361: route = ospf6_route_create ();
362: memcpy (&route->prefix, c->address, sizeof (struct prefix));
363: apply_mask (&route->prefix);
364: route->type = OSPF6_DEST_TYPE_NETWORK;
365: route->path.area_id = oi->area->area_id;
366: route->path.type = OSPF6_PATH_TYPE_INTRA;
367: route->path.cost = oi->cost;
368: route->nexthop[0].ifindex = oi->interface->ifindex;
369: inet_pton (AF_INET6, "::1", &route->nexthop[0].address);
370: ospf6_route_add (route, oi->route_connected);
371: }
372:
373: /* create new Link-LSA */
374: OSPF6_LINK_LSA_SCHEDULE (oi);
375: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
376: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
377: }
378:
379: static void
380: ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
381: {
382: u_char prev_state;
383:
384: prev_state = oi->state;
385: oi->state = next_state;
386:
387: if (prev_state == next_state)
388: return;
389:
390: /* log */
391: if (IS_OSPF6_DEBUG_INTERFACE)
392: {
393: zlog_debug ("Interface state change %s: %s -> %s", oi->interface->name,
394: ospf6_interface_state_str[prev_state],
395: ospf6_interface_state_str[next_state]);
396: }
1.1.1.3 ! misho 397: oi->state_change++;
1.1 misho 398:
399: if ((prev_state == OSPF6_INTERFACE_DR ||
400: prev_state == OSPF6_INTERFACE_BDR) &&
401: (next_state != OSPF6_INTERFACE_DR &&
402: next_state != OSPF6_INTERFACE_BDR))
1.1.1.2 misho 403: ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP);
1.1 misho 404: if ((prev_state != OSPF6_INTERFACE_DR &&
405: prev_state != OSPF6_INTERFACE_BDR) &&
406: (next_state == OSPF6_INTERFACE_DR ||
407: next_state == OSPF6_INTERFACE_BDR))
1.1.1.2 misho 408: ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_JOIN_GROUP);
1.1 misho 409:
410: OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
411: if (next_state == OSPF6_INTERFACE_DOWN)
412: {
413: OSPF6_NETWORK_LSA_EXECUTE (oi);
414: OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT (oi);
415: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
416: }
417: else if (prev_state == OSPF6_INTERFACE_DR ||
418: next_state == OSPF6_INTERFACE_DR)
419: {
420: OSPF6_NETWORK_LSA_SCHEDULE (oi);
421: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
422: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
423: }
1.1.1.3 ! misho 424:
! 425: #ifdef HAVE_SNMP
! 426: /* Terminal state or regression */
! 427: if ((next_state == OSPF6_INTERFACE_POINTTOPOINT) ||
! 428: (next_state == OSPF6_INTERFACE_DROTHER) ||
! 429: (next_state == OSPF6_INTERFACE_BDR) ||
! 430: (next_state == OSPF6_INTERFACE_DR) ||
! 431: (next_state < prev_state))
! 432: ospf6TrapIfStateChange (oi);
! 433: #endif
! 434:
1.1 misho 435: }
436:
437:
438: /* DR Election, RFC2328 section 9.4 */
439:
440: #define IS_ELIGIBLE(n) \
441: ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
442:
443: static struct ospf6_neighbor *
444: better_bdrouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b)
445: {
446: if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id) &&
447: (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id))
448: return NULL;
449: else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id)
450: return b;
451: else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id)
452: return a;
453:
454: if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
455: return a;
456: if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
457: return b;
458:
459: if (a->priority > b->priority)
460: return a;
461: if (a->priority < b->priority)
462: return b;
463:
464: if (ntohl (a->router_id) > ntohl (b->router_id))
465: return a;
466: if (ntohl (a->router_id) < ntohl (b->router_id))
467: return b;
468:
469: zlog_warn ("Router-ID duplicate ?");
470: return a;
471: }
472:
473: static struct ospf6_neighbor *
474: better_drouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b)
475: {
476: if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id) &&
477: (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id))
478: return NULL;
479: else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id)
480: return b;
481: else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id)
482: return a;
483:
484: if (a->drouter == a->router_id && b->drouter != b->router_id)
485: return a;
486: if (a->drouter != a->router_id && b->drouter == b->router_id)
487: return b;
488:
489: if (a->priority > b->priority)
490: return a;
491: if (a->priority < b->priority)
492: return b;
493:
494: if (ntohl (a->router_id) > ntohl (b->router_id))
495: return a;
496: if (ntohl (a->router_id) < ntohl (b->router_id))
497: return b;
498:
499: zlog_warn ("Router-ID duplicate ?");
500: return a;
501: }
502:
503: static u_char
504: dr_election (struct ospf6_interface *oi)
505: {
506: struct listnode *node, *nnode;
507: struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
508: struct ospf6_neighbor *best_drouter, *best_bdrouter;
509: u_char next_state = 0;
510:
511: drouter = bdrouter = NULL;
512: best_drouter = best_bdrouter = NULL;
513:
514: /* pseudo neighbor myself, including noting current DR/BDR (1) */
515: memset (&myself, 0, sizeof (myself));
516: inet_ntop (AF_INET, &oi->area->ospf6->router_id, myself.name,
517: sizeof (myself.name));
518: myself.state = OSPF6_NEIGHBOR_TWOWAY;
519: myself.drouter = oi->drouter;
520: myself.bdrouter = oi->bdrouter;
521: myself.priority = oi->priority;
522: myself.router_id = oi->area->ospf6->router_id;
523:
524: /* Electing BDR (2) */
525: for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
526: bdrouter = better_bdrouter (bdrouter, on);
527:
528: best_bdrouter = bdrouter;
529: bdrouter = better_bdrouter (best_bdrouter, &myself);
530:
531: /* Electing DR (3) */
532: for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
533: drouter = better_drouter (drouter, on);
534:
535: best_drouter = drouter;
536: drouter = better_drouter (best_drouter, &myself);
537: if (drouter == NULL)
538: drouter = bdrouter;
539:
540: /* the router itself is newly/no longer DR/BDR (4) */
541: if ((drouter == &myself && myself.drouter != myself.router_id) ||
542: (drouter != &myself && myself.drouter == myself.router_id) ||
543: (bdrouter == &myself && myself.bdrouter != myself.router_id) ||
544: (bdrouter != &myself && myself.bdrouter == myself.router_id))
545: {
546: myself.drouter = (drouter ? drouter->router_id : htonl (0));
547: myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl (0));
548:
549: /* compatible to Electing BDR (2) */
550: bdrouter = better_bdrouter (best_bdrouter, &myself);
551:
552: /* compatible to Electing DR (3) */
553: drouter = better_drouter (best_drouter, &myself);
554: if (drouter == NULL)
555: drouter = bdrouter;
556: }
557:
558: /* Set interface state accordingly (5) */
559: if (drouter && drouter == &myself)
560: next_state = OSPF6_INTERFACE_DR;
561: else if (bdrouter && bdrouter == &myself)
562: next_state = OSPF6_INTERFACE_BDR;
563: else
564: next_state = OSPF6_INTERFACE_DROTHER;
565:
566: /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
567: /* XXX */
568:
569: /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
570: /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
571: accordingly after AdjOK */
572: if (oi->drouter != (drouter ? drouter->router_id : htonl (0)) ||
573: oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl (0)))
574: {
575: if (IS_OSPF6_DEBUG_INTERFACE)
576: zlog_debug ("DR Election on %s: DR: %s BDR: %s", oi->interface->name,
577: (drouter ? drouter->name : "0.0.0.0"),
578: (bdrouter ? bdrouter->name : "0.0.0.0"));
579:
580: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on))
581: {
582: if (on->state < OSPF6_NEIGHBOR_TWOWAY)
583: continue;
584: /* Schedule AdjOK. */
585: thread_add_event (master, adj_ok, on, 0);
586: }
587: }
588:
589: oi->drouter = (drouter ? drouter->router_id : htonl (0));
590: oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl (0));
591: return next_state;
592: }
593:
594:
595: /* Interface State Machine */
596: int
597: interface_up (struct thread *thread)
598: {
599: struct ospf6_interface *oi;
600:
601: oi = (struct ospf6_interface *) THREAD_ARG (thread);
602: assert (oi && oi->interface);
603:
604: if (IS_OSPF6_DEBUG_INTERFACE)
605: zlog_debug ("Interface Event %s: [InterfaceUp]",
606: oi->interface->name);
607:
608: /* check physical interface is up */
609: if (! if_is_up (oi->interface))
610: {
611: if (IS_OSPF6_DEBUG_INTERFACE)
612: zlog_debug ("Interface %s is down, can't execute [InterfaceUp]",
613: oi->interface->name);
614: return 0;
615: }
616:
617: /* if already enabled, do nothing */
618: if (oi->state > OSPF6_INTERFACE_DOWN)
619: {
620: if (IS_OSPF6_DEBUG_INTERFACE)
621: zlog_debug ("Interface %s already enabled",
622: oi->interface->name);
623: return 0;
624: }
625:
626: /* Join AllSPFRouters */
1.1.1.2 misho 627: ospf6_sso (oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP);
1.1 misho 628:
629: /* Update interface route */
630: ospf6_interface_connected_route_update (oi->interface);
631:
632: /* Schedule Hello */
633: if (! CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
634: thread_add_event (master, ospf6_hello_send, oi, 0);
635:
636: /* decide next interface state */
637: if (if_is_pointopoint (oi->interface))
638: ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi);
639: else if (oi->priority == 0)
640: ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
641: else
642: {
643: ospf6_interface_state_change (OSPF6_INTERFACE_WAITING, oi);
644: thread_add_timer (master, wait_timer, oi, oi->dead_interval);
645: }
646:
647: return 0;
648: }
649:
650: int
651: wait_timer (struct thread *thread)
652: {
653: struct ospf6_interface *oi;
654:
655: oi = (struct ospf6_interface *) THREAD_ARG (thread);
656: assert (oi && oi->interface);
657:
658: if (IS_OSPF6_DEBUG_INTERFACE)
659: zlog_debug ("Interface Event %s: [WaitTimer]",
660: oi->interface->name);
661:
662: if (oi->state == OSPF6_INTERFACE_WAITING)
663: ospf6_interface_state_change (dr_election (oi), oi);
664:
665: return 0;
666: }
667:
668: int
669: backup_seen (struct thread *thread)
670: {
671: struct ospf6_interface *oi;
672:
673: oi = (struct ospf6_interface *) THREAD_ARG (thread);
674: assert (oi && oi->interface);
675:
676: if (IS_OSPF6_DEBUG_INTERFACE)
677: zlog_debug ("Interface Event %s: [BackupSeen]",
678: oi->interface->name);
679:
680: if (oi->state == OSPF6_INTERFACE_WAITING)
681: ospf6_interface_state_change (dr_election (oi), oi);
682:
683: return 0;
684: }
685:
686: int
687: neighbor_change (struct thread *thread)
688: {
689: struct ospf6_interface *oi;
690:
691: oi = (struct ospf6_interface *) THREAD_ARG (thread);
692: assert (oi && oi->interface);
693:
694: if (IS_OSPF6_DEBUG_INTERFACE)
695: zlog_debug ("Interface Event %s: [NeighborChange]",
696: oi->interface->name);
697:
698: if (oi->state == OSPF6_INTERFACE_DROTHER ||
699: oi->state == OSPF6_INTERFACE_BDR ||
700: oi->state == OSPF6_INTERFACE_DR)
701: ospf6_interface_state_change (dr_election (oi), oi);
702:
703: return 0;
704: }
705:
706: int
707: interface_down (struct thread *thread)
708: {
709: struct ospf6_interface *oi;
710: struct listnode *node, *nnode;
711: struct ospf6_neighbor *on;
712:
713: oi = (struct ospf6_interface *) THREAD_ARG (thread);
714: assert (oi && oi->interface);
715:
716: if (IS_OSPF6_DEBUG_INTERFACE)
717: zlog_debug ("Interface Event %s: [InterfaceDown]",
718: oi->interface->name);
719:
720: /* Leave AllSPFRouters */
721: if (oi->state > OSPF6_INTERFACE_DOWN)
1.1.1.2 misho 722: ospf6_sso (oi->interface->ifindex, &allspfrouters6, IPV6_LEAVE_GROUP);
1.1 misho 723:
724: ospf6_interface_state_change (OSPF6_INTERFACE_DOWN, oi);
725:
726: for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
727: ospf6_neighbor_delete (on);
728:
729: list_delete_all_node (oi->neighbor_list);
730:
731: return 0;
732: }
733:
734:
735: /* show specified interface structure */
736: static int
737: ospf6_interface_show (struct vty *vty, struct interface *ifp)
738: {
739: struct ospf6_interface *oi;
740: struct connected *c;
741: struct prefix *p;
742: struct listnode *i;
743: char strbuf[64], drouter[32], bdrouter[32];
744: const char *updown[3] = {"down", "up", NULL};
745: const char *type;
746: struct timeval res, now;
747: char duration[32];
748: struct ospf6_lsa *lsa;
749:
750: /* check physical interface type */
751: if (if_is_loopback (ifp))
752: type = "LOOPBACK";
753: else if (if_is_broadcast (ifp))
754: type = "BROADCAST";
755: else if (if_is_pointopoint (ifp))
756: type = "POINTOPOINT";
757: else
758: type = "UNKNOWN";
759:
760: vty_out (vty, "%s is %s, type %s%s",
761: ifp->name, updown[if_is_up (ifp)], type,
762: VNL);
763: vty_out (vty, " Interface ID: %d%s", ifp->ifindex, VNL);
764:
765: if (ifp->info == NULL)
766: {
767: vty_out (vty, " OSPF not enabled on this interface%s", VNL);
768: return 0;
769: }
770: else
771: oi = (struct ospf6_interface *) ifp->info;
772:
773: vty_out (vty, " Internet Address:%s", VNL);
774:
775: for (ALL_LIST_ELEMENTS_RO (ifp->connected, i, c))
776: {
777: p = c->address;
778: prefix2str (p, strbuf, sizeof (strbuf));
779: switch (p->family)
780: {
781: case AF_INET:
782: vty_out (vty, " inet : %s%s", strbuf,
783: VNL);
784: break;
785: case AF_INET6:
786: vty_out (vty, " inet6: %s%s", strbuf,
787: VNL);
788: break;
789: default:
790: vty_out (vty, " ??? : %s%s", strbuf,
791: VNL);
792: break;
793: }
794: }
795:
796: if (oi->area)
797: {
798: vty_out (vty, " Instance ID %d, Interface MTU %d (autodetect: %d)%s",
799: oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
800: vty_out (vty, " MTU mismatch detection: %s%s", oi->mtu_ignore ?
801: "disabled" : "enabled", VNL);
802: inet_ntop (AF_INET, &oi->area->area_id,
803: strbuf, sizeof (strbuf));
804: vty_out (vty, " Area ID %s, Cost %hu%s", strbuf, oi->cost,
805: VNL);
806: }
807: else
808: vty_out (vty, " Not Attached to Area%s", VNL);
809:
810: vty_out (vty, " State %s, Transmit Delay %d sec, Priority %d%s",
811: ospf6_interface_state_str[oi->state],
812: oi->transdelay, oi->priority,
813: VNL);
814: vty_out (vty, " Timer intervals configured:%s", VNL);
815: vty_out (vty, " Hello %d, Dead %d, Retransmit %d%s",
816: oi->hello_interval, oi->dead_interval, oi->rxmt_interval,
817: VNL);
818:
819: inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter));
820: inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter));
821: vty_out (vty, " DR: %s BDR: %s%s", drouter, bdrouter, VNL);
822:
823: vty_out (vty, " Number of I/F scoped LSAs is %u%s",
824: oi->lsdb->count, VNL);
825:
826: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
827:
828: timerclear (&res);
829: if (oi->thread_send_lsupdate)
830: timersub (&oi->thread_send_lsupdate->u.sands, &now, &res);
831: timerstring (&res, duration, sizeof (duration));
832: vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
833: oi->lsupdate_list->count, duration,
834: (oi->thread_send_lsupdate ? "on" : "off"),
835: VNL);
836: for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
837: lsa = ospf6_lsdb_next (lsa))
838: vty_out (vty, " %s%s", lsa->name, VNL);
839:
840: timerclear (&res);
841: if (oi->thread_send_lsack)
842: timersub (&oi->thread_send_lsack->u.sands, &now, &res);
843: timerstring (&res, duration, sizeof (duration));
844: vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]%s",
845: oi->lsack_list->count, duration,
846: (oi->thread_send_lsack ? "on" : "off"),
847: VNL);
848: for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
849: lsa = ospf6_lsdb_next (lsa))
850: vty_out (vty, " %s%s", lsa->name, VNL);
851:
852: return 0;
853: }
854:
855: /* show interface */
856: DEFUN (show_ipv6_ospf6_interface,
857: show_ipv6_ospf6_interface_ifname_cmd,
858: "show ipv6 ospf6 interface IFNAME",
859: SHOW_STR
860: IP6_STR
861: OSPF6_STR
862: INTERFACE_STR
863: IFNAME_STR
864: )
865: {
866: struct interface *ifp;
867: struct listnode *i;
868:
869: if (argc)
870: {
871: ifp = if_lookup_by_name (argv[0]);
872: if (ifp == NULL)
873: {
874: vty_out (vty, "No such Interface: %s%s", argv[0],
875: VNL);
876: return CMD_WARNING;
877: }
878: ospf6_interface_show (vty, ifp);
879: }
880: else
881: {
882: for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp))
883: ospf6_interface_show (vty, ifp);
884: }
885:
886: return CMD_SUCCESS;
887: }
888:
889: ALIAS (show_ipv6_ospf6_interface,
890: show_ipv6_ospf6_interface_cmd,
891: "show ipv6 ospf6 interface",
892: SHOW_STR
893: IP6_STR
894: OSPF6_STR
895: INTERFACE_STR
896: )
897:
898: DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
899: show_ipv6_ospf6_interface_ifname_prefix_cmd,
900: "show ipv6 ospf6 interface IFNAME prefix",
901: SHOW_STR
902: IP6_STR
903: OSPF6_STR
904: INTERFACE_STR
905: IFNAME_STR
906: "Display connected prefixes to advertise\n"
907: )
908: {
909: struct interface *ifp;
910: struct ospf6_interface *oi;
911:
912: ifp = if_lookup_by_name (argv[0]);
913: if (ifp == NULL)
914: {
915: vty_out (vty, "No such Interface: %s%s", argv[0], VNL);
916: return CMD_WARNING;
917: }
918:
919: oi = ifp->info;
920: if (oi == NULL)
921: {
922: vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[0], VNL);
923: return CMD_WARNING;
924: }
925:
926: argc--;
927: argv++;
928: ospf6_route_table_show (vty, argc, argv, oi->route_connected);
929:
930: return CMD_SUCCESS;
931: }
932:
933: ALIAS (show_ipv6_ospf6_interface_ifname_prefix,
934: show_ipv6_ospf6_interface_ifname_prefix_detail_cmd,
935: "show ipv6 ospf6 interface IFNAME prefix (X:X::X:X|X:X::X:X/M|detail)",
936: SHOW_STR
937: IP6_STR
938: OSPF6_STR
939: INTERFACE_STR
940: IFNAME_STR
941: "Display connected prefixes to advertise\n"
942: OSPF6_ROUTE_ADDRESS_STR
943: OSPF6_ROUTE_PREFIX_STR
944: "Display details of the prefixes\n"
945: )
946:
947: ALIAS (show_ipv6_ospf6_interface_ifname_prefix,
948: show_ipv6_ospf6_interface_ifname_prefix_match_cmd,
949: "show ipv6 ospf6 interface IFNAME prefix X:X::X:X/M (match|detail)",
950: SHOW_STR
951: IP6_STR
952: OSPF6_STR
953: INTERFACE_STR
954: IFNAME_STR
955: "Display connected prefixes to advertise\n"
956: OSPF6_ROUTE_PREFIX_STR
957: OSPF6_ROUTE_MATCH_STR
958: "Display details of the prefixes\n"
959: )
960:
961: DEFUN (show_ipv6_ospf6_interface_prefix,
962: show_ipv6_ospf6_interface_prefix_cmd,
963: "show ipv6 ospf6 interface prefix",
964: SHOW_STR
965: IP6_STR
966: OSPF6_STR
967: INTERFACE_STR
968: "Display connected prefixes to advertise\n"
969: )
970: {
971: struct listnode *i;
972: struct ospf6_interface *oi;
973: struct interface *ifp;
974:
975: for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp))
976: {
977: oi = (struct ospf6_interface *) ifp->info;
978: if (oi == NULL)
979: continue;
980:
981: ospf6_route_table_show (vty, argc, argv, oi->route_connected);
982: }
983:
984: return CMD_SUCCESS;
985: }
986:
987: ALIAS (show_ipv6_ospf6_interface_prefix,
988: show_ipv6_ospf6_interface_prefix_detail_cmd,
989: "show ipv6 ospf6 interface prefix (X:X::X:X|X:X::X:X/M|detail)",
990: SHOW_STR
991: IP6_STR
992: OSPF6_STR
993: INTERFACE_STR
994: "Display connected prefixes to advertise\n"
995: OSPF6_ROUTE_ADDRESS_STR
996: OSPF6_ROUTE_PREFIX_STR
997: "Display details of the prefixes\n"
998: )
999:
1000: ALIAS (show_ipv6_ospf6_interface_prefix,
1001: show_ipv6_ospf6_interface_prefix_match_cmd,
1002: "show ipv6 ospf6 interface prefix X:X::X:X/M (match|detail)",
1003: SHOW_STR
1004: IP6_STR
1005: OSPF6_STR
1006: INTERFACE_STR
1007: "Display connected prefixes to advertise\n"
1008: OSPF6_ROUTE_PREFIX_STR
1009: OSPF6_ROUTE_MATCH_STR
1010: "Display details of the prefixes\n"
1011: )
1012:
1013:
1014: /* interface variable set command */
1015: DEFUN (ipv6_ospf6_ifmtu,
1016: ipv6_ospf6_ifmtu_cmd,
1017: "ipv6 ospf6 ifmtu <1-65535>",
1018: IP6_STR
1019: OSPF6_STR
1020: "Interface MTU\n"
1021: "OSPFv3 Interface MTU\n"
1022: )
1023: {
1024: struct ospf6_interface *oi;
1025: struct interface *ifp;
1026: unsigned int ifmtu, iobuflen;
1027: struct listnode *node, *nnode;
1028: struct ospf6_neighbor *on;
1029:
1030: ifp = (struct interface *) vty->index;
1031: assert (ifp);
1032:
1033: oi = (struct ospf6_interface *) ifp->info;
1034: if (oi == NULL)
1035: oi = ospf6_interface_create (ifp);
1036: assert (oi);
1037:
1038: ifmtu = strtol (argv[0], NULL, 10);
1039:
1040: if (oi->ifmtu == ifmtu)
1041: return CMD_SUCCESS;
1042:
1043: if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu)
1044: {
1045: vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s",
1046: ifp->name, ifp->mtu6, VNL);
1047: return CMD_WARNING;
1048: }
1049:
1050: if (oi->ifmtu < ifmtu)
1051: {
1052: iobuflen = ospf6_iobuf_size (ifmtu);
1053: if (iobuflen < ifmtu)
1054: {
1055: vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
1056: ifp->name, iobuflen, VNL);
1057: oi->ifmtu = iobuflen;
1058: }
1059: else
1060: oi->ifmtu = ifmtu;
1061: }
1062: else
1063: oi->ifmtu = ifmtu;
1064:
1065: /* re-establish adjacencies */
1066: for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1067: {
1068: THREAD_OFF (on->inactivity_timer);
1069: thread_add_event (master, inactivity_timer, on, 0);
1070: }
1071:
1072: return CMD_SUCCESS;
1073: }
1074:
1075: DEFUN (no_ipv6_ospf6_ifmtu,
1076: no_ipv6_ospf6_ifmtu_cmd,
1077: "no ipv6 ospf6 ifmtu",
1078: NO_STR
1079: IP6_STR
1080: OSPF6_STR
1081: "Interface MTU\n"
1082: )
1083: {
1084: struct ospf6_interface *oi;
1085: struct interface *ifp;
1086: unsigned int iobuflen;
1087: struct listnode *node, *nnode;
1088: struct ospf6_neighbor *on;
1089:
1090: ifp = (struct interface *) vty->index;
1091: assert (ifp);
1092:
1093: oi = (struct ospf6_interface *) ifp->info;
1094: if (oi == NULL)
1095: oi = ospf6_interface_create (ifp);
1096: assert (oi);
1097:
1098: if (oi->ifmtu < ifp->mtu)
1099: {
1100: iobuflen = ospf6_iobuf_size (ifp->mtu);
1101: if (iobuflen < ifp->mtu)
1102: {
1103: vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
1104: ifp->name, iobuflen, VNL);
1105: oi->ifmtu = iobuflen;
1106: }
1107: else
1108: oi->ifmtu = ifp->mtu;
1109: }
1110: else
1111: oi->ifmtu = ifp->mtu;
1112:
1113: /* re-establish adjacencies */
1114: for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1115: {
1116: THREAD_OFF (on->inactivity_timer);
1117: thread_add_event (master, inactivity_timer, on, 0);
1118: }
1119:
1120: return CMD_SUCCESS;
1121: }
1122:
1123: DEFUN (ipv6_ospf6_cost,
1124: ipv6_ospf6_cost_cmd,
1125: "ipv6 ospf6 cost <1-65535>",
1126: IP6_STR
1127: OSPF6_STR
1128: "Interface cost\n"
1129: "Outgoing metric of this interface\n"
1130: )
1131: {
1132: struct ospf6_interface *oi;
1133: struct interface *ifp;
1134: unsigned long int lcost;
1135:
1136: ifp = (struct interface *) vty->index;
1137: assert (ifp);
1138:
1139: oi = (struct ospf6_interface *) ifp->info;
1140: if (oi == NULL)
1141: oi = ospf6_interface_create (ifp);
1142: assert (oi);
1143:
1144: lcost = strtol (argv[0], NULL, 10);
1145:
1146: if (lcost > UINT32_MAX)
1147: {
1148: vty_out (vty, "Cost %ld is out of range%s", lcost, VNL);
1149: return CMD_WARNING;
1150: }
1151:
1152: if (oi->cost == lcost)
1153: return CMD_SUCCESS;
1154:
1155: oi->cost = lcost;
1156:
1157: /* update cost held in route_connected list in ospf6_interface */
1158: ospf6_interface_connected_route_update (oi->interface);
1159:
1160: /* execute LSA hooks */
1161: if (oi->area)
1162: {
1163: OSPF6_LINK_LSA_SCHEDULE (oi);
1164: OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
1165: OSPF6_NETWORK_LSA_SCHEDULE (oi);
1166: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
1167: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
1168: }
1169:
1170: return CMD_SUCCESS;
1171: }
1172:
1173: DEFUN (ipv6_ospf6_hellointerval,
1174: ipv6_ospf6_hellointerval_cmd,
1175: "ipv6 ospf6 hello-interval <1-65535>",
1176: IP6_STR
1177: OSPF6_STR
1178: "Interval time of Hello packets\n"
1179: SECONDS_STR
1180: )
1181: {
1182: struct ospf6_interface *oi;
1183: struct interface *ifp;
1184:
1185: ifp = (struct interface *) vty->index;
1186: assert (ifp);
1187:
1188: oi = (struct ospf6_interface *) ifp->info;
1189: if (oi == NULL)
1190: oi = ospf6_interface_create (ifp);
1191: assert (oi);
1192:
1193: oi->hello_interval = strtol (argv[0], NULL, 10);
1194: return CMD_SUCCESS;
1195: }
1196:
1197: /* interface variable set command */
1198: DEFUN (ipv6_ospf6_deadinterval,
1199: ipv6_ospf6_deadinterval_cmd,
1200: "ipv6 ospf6 dead-interval <1-65535>",
1201: IP6_STR
1202: OSPF6_STR
1203: "Interval time after which a neighbor is declared down\n"
1204: SECONDS_STR
1205: )
1206: {
1207: struct ospf6_interface *oi;
1208: struct interface *ifp;
1209:
1210: ifp = (struct interface *) vty->index;
1211: assert (ifp);
1212:
1213: oi = (struct ospf6_interface *) ifp->info;
1214: if (oi == NULL)
1215: oi = ospf6_interface_create (ifp);
1216: assert (oi);
1217:
1218: oi->dead_interval = strtol (argv[0], NULL, 10);
1219: return CMD_SUCCESS;
1220: }
1221:
1222: /* interface variable set command */
1223: DEFUN (ipv6_ospf6_transmitdelay,
1224: ipv6_ospf6_transmitdelay_cmd,
1225: "ipv6 ospf6 transmit-delay <1-3600>",
1226: IP6_STR
1227: OSPF6_STR
1228: "Transmit delay of this interface\n"
1229: SECONDS_STR
1230: )
1231: {
1232: struct ospf6_interface *oi;
1233: struct interface *ifp;
1234:
1235: ifp = (struct interface *) vty->index;
1236: assert (ifp);
1237:
1238: oi = (struct ospf6_interface *) ifp->info;
1239: if (oi == NULL)
1240: oi = ospf6_interface_create (ifp);
1241: assert (oi);
1242:
1243: oi->transdelay = strtol (argv[0], NULL, 10);
1244: return CMD_SUCCESS;
1245: }
1246:
1247: /* interface variable set command */
1248: DEFUN (ipv6_ospf6_retransmitinterval,
1249: ipv6_ospf6_retransmitinterval_cmd,
1250: "ipv6 ospf6 retransmit-interval <1-65535>",
1251: IP6_STR
1252: OSPF6_STR
1253: "Time between retransmitting lost link state advertisements\n"
1254: SECONDS_STR
1255: )
1256: {
1257: struct ospf6_interface *oi;
1258: struct interface *ifp;
1259:
1260: ifp = (struct interface *) vty->index;
1261: assert (ifp);
1262:
1263: oi = (struct ospf6_interface *) ifp->info;
1264: if (oi == NULL)
1265: oi = ospf6_interface_create (ifp);
1266: assert (oi);
1267:
1268: oi->rxmt_interval = strtol (argv[0], NULL, 10);
1269: return CMD_SUCCESS;
1270: }
1271:
1272: /* interface variable set command */
1273: DEFUN (ipv6_ospf6_priority,
1274: ipv6_ospf6_priority_cmd,
1275: "ipv6 ospf6 priority <0-255>",
1276: IP6_STR
1277: OSPF6_STR
1278: "Router priority\n"
1279: "Priority value\n"
1280: )
1281: {
1282: struct ospf6_interface *oi;
1283: struct interface *ifp;
1284:
1285: ifp = (struct interface *) vty->index;
1286: assert (ifp);
1287:
1288: oi = (struct ospf6_interface *) ifp->info;
1289: if (oi == NULL)
1290: oi = ospf6_interface_create (ifp);
1291: assert (oi);
1292:
1293: oi->priority = strtol (argv[0], NULL, 10);
1294:
1295: if (oi->area)
1296: ospf6_interface_state_change (dr_election (oi), oi);
1297:
1298: return CMD_SUCCESS;
1299: }
1300:
1301: DEFUN (ipv6_ospf6_instance,
1302: ipv6_ospf6_instance_cmd,
1303: "ipv6 ospf6 instance-id <0-255>",
1304: IP6_STR
1305: OSPF6_STR
1306: "Instance ID for this interface\n"
1307: "Instance ID value\n"
1308: )
1309: {
1310: struct ospf6_interface *oi;
1311: struct interface *ifp;
1312:
1313: ifp = (struct interface *)vty->index;
1314: assert (ifp);
1315:
1316: oi = (struct ospf6_interface *)ifp->info;
1317: if (oi == NULL)
1318: oi = ospf6_interface_create (ifp);
1319: assert (oi);
1320:
1321: oi->instance_id = strtol (argv[0], NULL, 10);
1322: return CMD_SUCCESS;
1323: }
1324:
1325: DEFUN (ipv6_ospf6_passive,
1326: ipv6_ospf6_passive_cmd,
1327: "ipv6 ospf6 passive",
1328: IP6_STR
1329: OSPF6_STR
1330: "passive interface, No adjacency will be formed on this interface\n"
1331: )
1332: {
1333: struct ospf6_interface *oi;
1334: struct interface *ifp;
1335: struct listnode *node, *nnode;
1336: struct ospf6_neighbor *on;
1337:
1338: ifp = (struct interface *) vty->index;
1339: assert (ifp);
1340:
1341: oi = (struct ospf6_interface *) ifp->info;
1342: if (oi == NULL)
1343: oi = ospf6_interface_create (ifp);
1344: assert (oi);
1345:
1346: SET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
1347: THREAD_OFF (oi->thread_send_hello);
1348:
1349: for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1350: {
1351: THREAD_OFF (on->inactivity_timer);
1352: thread_add_event (master, inactivity_timer, on, 0);
1353: }
1354:
1355: return CMD_SUCCESS;
1356: }
1357:
1358: DEFUN (no_ipv6_ospf6_passive,
1359: no_ipv6_ospf6_passive_cmd,
1360: "no ipv6 ospf6 passive",
1361: NO_STR
1362: IP6_STR
1363: OSPF6_STR
1364: "passive interface: No Adjacency will be formed on this I/F\n"
1365: )
1366: {
1367: struct ospf6_interface *oi;
1368: struct interface *ifp;
1369:
1370: ifp = (struct interface *) vty->index;
1371: assert (ifp);
1372:
1373: oi = (struct ospf6_interface *) ifp->info;
1374: if (oi == NULL)
1375: oi = ospf6_interface_create (ifp);
1376: assert (oi);
1377:
1378: UNSET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
1379: THREAD_OFF (oi->thread_send_hello);
1380: oi->thread_send_hello =
1381: thread_add_event (master, ospf6_hello_send, oi, 0);
1382:
1383: return CMD_SUCCESS;
1384: }
1385:
1386: DEFUN (ipv6_ospf6_mtu_ignore,
1387: ipv6_ospf6_mtu_ignore_cmd,
1388: "ipv6 ospf6 mtu-ignore",
1389: IP6_STR
1390: OSPF6_STR
1391: "Ignore MTU mismatch on this interface\n"
1392: )
1393: {
1394: struct ospf6_interface *oi;
1395: struct interface *ifp;
1396:
1397: ifp = (struct interface *) vty->index;
1398: assert (ifp);
1399:
1400: oi = (struct ospf6_interface *) ifp->info;
1401: if (oi == NULL)
1402: oi = ospf6_interface_create (ifp);
1403: assert (oi);
1404:
1405: oi->mtu_ignore = 1;
1406:
1407: return CMD_SUCCESS;
1408: }
1409:
1410: DEFUN (no_ipv6_ospf6_mtu_ignore,
1411: no_ipv6_ospf6_mtu_ignore_cmd,
1412: "no ipv6 ospf6 mtu-ignore",
1413: NO_STR
1414: IP6_STR
1415: OSPF6_STR
1416: "Ignore MTU mismatch on this interface\n"
1417: )
1418: {
1419: struct ospf6_interface *oi;
1420: struct interface *ifp;
1421:
1422: ifp = (struct interface *) vty->index;
1423: assert (ifp);
1424:
1425: oi = (struct ospf6_interface *) ifp->info;
1426: if (oi == NULL)
1427: oi = ospf6_interface_create (ifp);
1428: assert (oi);
1429:
1430: oi->mtu_ignore = 0;
1431:
1432: return CMD_SUCCESS;
1433: }
1434:
1435: DEFUN (ipv6_ospf6_advertise_prefix_list,
1436: ipv6_ospf6_advertise_prefix_list_cmd,
1437: "ipv6 ospf6 advertise prefix-list WORD",
1438: IP6_STR
1439: OSPF6_STR
1440: "Advertising options\n"
1441: "Filter prefix using prefix-list\n"
1442: "Prefix list name\n"
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: if (oi->plist_name)
1457: XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
1458: oi->plist_name = XSTRDUP (MTYPE_PREFIX_LIST_STR, argv[0]);
1459:
1460: ospf6_interface_connected_route_update (oi->interface);
1461:
1462: if (oi->area)
1463: {
1464: OSPF6_LINK_LSA_SCHEDULE (oi);
1465: if (oi->state == OSPF6_INTERFACE_DR)
1466: {
1467: OSPF6_NETWORK_LSA_SCHEDULE (oi);
1468: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
1469: }
1470: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
1471: }
1472:
1473: return CMD_SUCCESS;
1474: }
1475:
1476: DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1477: no_ipv6_ospf6_advertise_prefix_list_cmd,
1478: "no ipv6 ospf6 advertise prefix-list",
1479: NO_STR
1480: IP6_STR
1481: OSPF6_STR
1482: "Advertising options\n"
1483: "Filter prefix using prefix-list\n"
1484: )
1485: {
1486: struct ospf6_interface *oi;
1487: struct interface *ifp;
1488:
1489: ifp = (struct interface *) vty->index;
1490: assert (ifp);
1491:
1492: oi = (struct ospf6_interface *) ifp->info;
1493: if (oi == NULL)
1494: oi = ospf6_interface_create (ifp);
1495: assert (oi);
1496:
1497: if (oi->plist_name)
1498: {
1499: XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
1500: oi->plist_name = NULL;
1501: }
1502:
1503: ospf6_interface_connected_route_update (oi->interface);
1504:
1505: if (oi->area)
1506: {
1507: OSPF6_LINK_LSA_SCHEDULE (oi);
1508: if (oi->state == OSPF6_INTERFACE_DR)
1509: {
1510: OSPF6_NETWORK_LSA_SCHEDULE (oi);
1511: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
1512: }
1513: OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
1514: }
1515:
1516: return CMD_SUCCESS;
1517: }
1518:
1519: static int
1520: config_write_ospf6_interface (struct vty *vty)
1521: {
1522: struct listnode *i;
1523: struct ospf6_interface *oi;
1524: struct interface *ifp;
1525:
1526: for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp))
1527: {
1528: oi = (struct ospf6_interface *) ifp->info;
1529: if (oi == NULL)
1530: continue;
1531:
1532: vty_out (vty, "interface %s%s",
1533: oi->interface->name, VNL);
1534:
1535: if (ifp->desc)
1536: vty_out (vty, " description %s%s", ifp->desc, VNL);
1537: if (ifp->mtu6 != oi->ifmtu)
1538: vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL);
1.1.1.2 misho 1539:
1540: if (oi->cost != OSPF6_INTERFACE_COST)
1541: vty_out (vty, " ipv6 ospf6 cost %d%s",
1542: oi->cost, VNL);
1543:
1544: if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1545: vty_out (vty, " ipv6 ospf6 hello-interval %d%s",
1546: oi->hello_interval, VNL);
1547:
1548: if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1549: vty_out (vty, " ipv6 ospf6 dead-interval %d%s",
1550: oi->dead_interval, VNL);
1551:
1552: if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1553: vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s",
1554: oi->rxmt_interval, VNL);
1555:
1556: if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1557: vty_out (vty, " ipv6 ospf6 priority %d%s",
1558: oi->priority, VNL);
1559:
1560: if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1561: vty_out (vty, " ipv6 ospf6 transmit-delay %d%s",
1562: oi->transdelay, VNL);
1563:
1564: if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1565: vty_out (vty, " ipv6 ospf6 instance-id %d%s",
1566: oi->instance_id, VNL);
1.1 misho 1567:
1568: if (oi->plist_name)
1569: vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s",
1570: oi->plist_name, VNL);
1571:
1572: if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
1573: vty_out (vty, " ipv6 ospf6 passive%s", VNL);
1574:
1575: if (oi->mtu_ignore)
1576: vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
1577:
1578: vty_out (vty, "!%s", VNL);
1579: }
1580: return 0;
1581: }
1582:
1583: static struct cmd_node interface_node =
1584: {
1585: INTERFACE_NODE,
1586: "%s(config-if)# ",
1587: 1 /* VTYSH */
1588: };
1589:
1590: void
1591: ospf6_interface_init (void)
1592: {
1593: /* Install interface node. */
1594: install_node (&interface_node, config_write_ospf6_interface);
1595:
1596: install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd);
1597: install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
1598: install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd);
1599: install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd);
1600: install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1601: install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
1602: install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd);
1603: install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd);
1604: install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_cmd);
1605: install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
1606: install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd);
1607: install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd);
1608: install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1609: install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
1610: install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd);
1611: install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd);
1612:
1613: install_element (CONFIG_NODE, &interface_cmd);
1614: install_default (INTERFACE_NODE);
1615: install_element (INTERFACE_NODE, &interface_desc_cmd);
1616: install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1617: install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
1618: install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
1619: install_element (INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
1620: install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1621: install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1622: install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1623: install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1624: install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1625: install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
1626:
1627: install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1628: install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
1629:
1630: install_element (INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
1631: install_element (INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
1632:
1633: install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1634: install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
1635: }
1636:
1637: DEFUN (debug_ospf6_interface,
1638: debug_ospf6_interface_cmd,
1639: "debug ospf6 interface",
1640: DEBUG_STR
1641: OSPF6_STR
1642: "Debug OSPFv3 Interface\n"
1643: )
1644: {
1645: OSPF6_DEBUG_INTERFACE_ON ();
1646: return CMD_SUCCESS;
1647: }
1648:
1649: DEFUN (no_debug_ospf6_interface,
1650: no_debug_ospf6_interface_cmd,
1651: "no debug ospf6 interface",
1652: NO_STR
1653: DEBUG_STR
1654: OSPF6_STR
1655: "Debug OSPFv3 Interface\n"
1656: )
1657: {
1658: OSPF6_DEBUG_INTERFACE_OFF ();
1659: return CMD_SUCCESS;
1660: }
1661:
1662: int
1663: config_write_ospf6_debug_interface (struct vty *vty)
1664: {
1665: if (IS_OSPF6_DEBUG_INTERFACE)
1666: vty_out (vty, "debug ospf6 interface%s", VNL);
1667: return 0;
1668: }
1669:
1670: void
1671: install_element_ospf6_debug_interface (void)
1672: {
1673: install_element (ENABLE_NODE, &debug_ospf6_interface_cmd);
1674: install_element (ENABLE_NODE, &no_debug_ospf6_interface_cmd);
1675: install_element (CONFIG_NODE, &debug_ospf6_interface_cmd);
1676: install_element (CONFIG_NODE, &no_debug_ospf6_interface_cmd);
1677: }
1678:
1679:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>