Annotation of embedaddon/quagga/ospf6d/ospf6_intra.c, revision 1.1.1.2
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 "log.h"
25: #include "linklist.h"
26: #include "thread.h"
27: #include "memory.h"
28: #include "if.h"
29: #include "prefix.h"
30: #include "table.h"
31: #include "vty.h"
32: #include "command.h"
33:
34: #include "ospf6_proto.h"
35: #include "ospf6_message.h"
36: #include "ospf6_route.h"
37: #include "ospf6_lsa.h"
38: #include "ospf6_lsdb.h"
39:
40: #include "ospf6_top.h"
41: #include "ospf6_area.h"
42: #include "ospf6_interface.h"
43: #include "ospf6_neighbor.h"
44: #include "ospf6_intra.h"
45: #include "ospf6_asbr.h"
46: #include "ospf6_abr.h"
47: #include "ospf6_flood.h"
48: #include "ospf6d.h"
1.1.1.2 ! misho 49: #include "ospf6_spf.h"
1.1 misho 50:
51: unsigned char conf_debug_ospf6_brouter = 0;
52: u_int32_t conf_debug_ospf6_brouter_specific_router_id;
53: u_int32_t conf_debug_ospf6_brouter_specific_area_id;
54:
55: /******************************/
56: /* RFC2740 3.4.3.1 Router-LSA */
57: /******************************/
58:
1.1.1.2 ! misho 59: static char *
! 60: ospf6_router_lsa_get_nbr_id (struct ospf6_lsa *lsa, char *buf, int buflen,
! 61: int pos)
! 62: {
! 63: struct ospf6_router_lsa *router_lsa;
! 64: struct ospf6_router_lsdesc *lsdesc;
! 65: char *start, *end;
! 66: char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN];
! 67:
! 68: if (lsa)
! 69: {
! 70: router_lsa = (struct ospf6_router_lsa *)
! 71: ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
! 72: start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
! 73: end = (char *) lsa->header + ntohs (lsa->header->length);
! 74:
! 75: lsdesc = (struct ospf6_router_lsdesc *)
! 76: (start + pos*(sizeof (struct ospf6_router_lsdesc)));
! 77: if ((char *)lsdesc < end)
! 78: {
! 79: if (buf && (buflen > INET_ADDRSTRLEN*2))
! 80: {
! 81: inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
! 82: buf1, sizeof(buf1));
! 83: inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
! 84: buf2, sizeof(buf2));
! 85: sprintf (buf, "%s/%s", buf2, buf1);
! 86: }
! 87: }
! 88: else
! 89: return NULL;
! 90: }
! 91:
! 92: return buf;
! 93: }
! 94:
1.1 misho 95: static int
96: ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
97: {
98: char *start, *end, *current;
99: char buf[32], name[32], bits[16], options[32];
100: struct ospf6_router_lsa *router_lsa;
101: struct ospf6_router_lsdesc *lsdesc;
102:
103: router_lsa = (struct ospf6_router_lsa *)
104: ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
105:
106: ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
107: ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
108: vty_out (vty, " Bits: %s Options: %s%s", bits, options, VNL);
109:
110: start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
111: end = (char *) lsa->header + ntohs (lsa->header->length);
112: for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end;
113: current += sizeof (struct ospf6_router_lsdesc))
114: {
115: lsdesc = (struct ospf6_router_lsdesc *) current;
116:
117: if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT)
118: snprintf (name, sizeof (name), "Point-To-Point");
119: else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK)
120: snprintf (name, sizeof (name), "Transit-Network");
121: else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK)
122: snprintf (name, sizeof (name), "Stub-Network");
123: else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK)
124: snprintf (name, sizeof (name), "Virtual-Link");
125: else
126: snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
127:
128: vty_out (vty, " Type: %s Metric: %d%s",
129: name, ntohs (lsdesc->metric), VNL);
130: vty_out (vty, " Interface ID: %s%s",
131: inet_ntop (AF_INET, &lsdesc->interface_id,
132: buf, sizeof (buf)), VNL);
133: vty_out (vty, " Neighbor Interface ID: %s%s",
134: inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
135: buf, sizeof (buf)), VNL);
136: vty_out (vty, " Neighbor Router ID: %s%s",
137: inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
138: buf, sizeof (buf)), VNL);
139: }
140: return 0;
141: }
142:
143: int
1.1.1.2 ! misho 144: ospf6_router_is_stub_router (struct ospf6_lsa *lsa)
! 145: {
! 146: struct ospf6_router_lsa *rtr_lsa;
! 147:
! 148: if (lsa != NULL && OSPF6_LSA_IS_TYPE (ROUTER, lsa))
! 149: {
! 150: rtr_lsa = (struct ospf6_router_lsa *)
! 151: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
! 152:
! 153: if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_R))
! 154: {
! 155: return (OSPF6_IS_STUB_ROUTER);
! 156: }
! 157: else if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_V6))
! 158: {
! 159: return (OSPF6_IS_STUB_ROUTER_V6);
! 160: }
! 161: }
! 162:
! 163: return (OSPF6_NOT_STUB_ROUTER);
! 164: }
! 165:
! 166: int
1.1 misho 167: ospf6_router_lsa_originate (struct thread *thread)
168: {
169: struct ospf6_area *oa;
170:
171: char buffer [OSPF6_MAX_LSASIZE];
172: struct ospf6_lsa_header *lsa_header;
173: struct ospf6_lsa *lsa;
174:
175: u_int32_t link_state_id = 0;
176: struct listnode *node, *nnode;
177: struct listnode *j;
178: struct ospf6_interface *oi;
179: struct ospf6_neighbor *on, *drouter = NULL;
180: struct ospf6_router_lsa *router_lsa;
181: struct ospf6_router_lsdesc *lsdesc;
182: u_int16_t type;
183: u_int32_t router;
184: int count;
185:
186: oa = (struct ospf6_area *) THREAD_ARG (thread);
187: oa->thread_router_lsa = NULL;
188:
189: if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
190: zlog_debug ("Originate Router-LSA for Area %s", oa->name);
191:
192: memset (buffer, 0, sizeof (buffer));
193: lsa_header = (struct ospf6_lsa_header *) buffer;
194: router_lsa = (struct ospf6_router_lsa *)
195: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
196:
197: OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
198: OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
199: OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
200: OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
201: OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
202: OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
203:
204: if (ospf6_is_router_abr (ospf6))
205: SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
206: else
207: UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
208: if (ospf6_asbr_is_asbr (ospf6))
209: SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
210: else
211: UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
212: UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
213: UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
214:
215: /* describe links for each interfaces */
216: lsdesc = (struct ospf6_router_lsdesc *)
217: ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
218:
219: for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
220: {
221: /* Interfaces in state Down or Loopback are not described */
222: if (oi->state == OSPF6_INTERFACE_DOWN ||
223: oi->state == OSPF6_INTERFACE_LOOPBACK)
224: continue;
225:
226: /* Nor are interfaces without any full adjacencies described */
227: count = 0;
228: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
229: if (on->state == OSPF6_NEIGHBOR_FULL)
230: count++;
231:
232: if (count == 0)
233: continue;
234:
235: /* Multiple Router-LSA instance according to size limit setting */
236: if ( (oa->router_lsa_size_limit != 0)
1.1.1.2 ! misho 237: && ((size_t)((char *)lsdesc - buffer)
! 238: + sizeof (struct ospf6_router_lsdesc)
! 239: > oa->router_lsa_size_limit))
1.1 misho 240: {
241: if ((caddr_t) lsdesc == (caddr_t) router_lsa +
242: sizeof (struct ospf6_router_lsa))
243: {
244: if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
245: zlog_debug ("Size limit setting for Router-LSA too short");
246: return 0;
247: }
248:
249: /* Fill LSA Header */
250: lsa_header->age = 0;
251: lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
252: lsa_header->id = htonl (link_state_id);
253: lsa_header->adv_router = oa->ospf6->router_id;
254: lsa_header->seqnum =
255: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
256: lsa_header->adv_router, oa->lsdb);
257: lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
258:
259: /* LSA checksum */
260: ospf6_lsa_checksum (lsa_header);
261:
262: /* create LSA */
263: lsa = ospf6_lsa_create (lsa_header);
264:
265: /* Originate */
266: ospf6_lsa_originate_area (lsa, oa);
267:
268: /* Reset setting for consecutive origination */
269: memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
270: 0, (caddr_t) lsdesc - (caddr_t) router_lsa);
271: lsdesc = (struct ospf6_router_lsdesc *)
272: ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
273: link_state_id ++;
274: }
275:
276: /* Point-to-Point interfaces */
1.1.1.2 ! misho 277: if (oi->type == OSPF_IFTYPE_POINTOPOINT)
1.1 misho 278: {
279: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
280: {
281: if (on->state != OSPF6_NEIGHBOR_FULL)
282: continue;
283:
284: lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
285: lsdesc->metric = htons (oi->cost);
286: lsdesc->interface_id = htonl (oi->interface->ifindex);
287: lsdesc->neighbor_interface_id = htonl (on->ifindex);
288: lsdesc->neighbor_router_id = on->router_id;
289:
290: lsdesc++;
291: }
292: }
293:
294: /* Broadcast and NBMA interfaces */
1.1.1.2 ! misho 295: else if (oi->type == OSPF_IFTYPE_BROADCAST)
1.1 misho 296: {
297: /* If this router is not DR,
298: and If this router not fully adjacent with DR,
299: this interface is not transit yet: ignore. */
300: if (oi->state != OSPF6_INTERFACE_DR)
301: {
302: drouter = ospf6_neighbor_lookup (oi->drouter, oi);
303: if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
304: continue;
305: }
306:
307: lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
308: lsdesc->metric = htons (oi->cost);
309: lsdesc->interface_id = htonl (oi->interface->ifindex);
310: if (oi->state != OSPF6_INTERFACE_DR)
311: {
312: lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
313: lsdesc->neighbor_router_id = drouter->router_id;
314: }
315: else
316: {
317: lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
318: lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
319: }
320:
321: lsdesc++;
322: }
1.1.1.2 ! misho 323: else
! 324: {
! 325: assert (0); /* Unknown interface type */
! 326: }
1.1 misho 327:
328: /* Virtual links */
329: /* xxx */
330: /* Point-to-Multipoint interfaces */
331: /* xxx */
332: }
333:
1.1.1.2 ! misho 334: /* Fill LSA Header */
! 335: lsa_header->age = 0;
! 336: lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
! 337: lsa_header->id = htonl (link_state_id);
! 338: lsa_header->adv_router = oa->ospf6->router_id;
! 339: lsa_header->seqnum =
! 340: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
! 341: lsa_header->adv_router, oa->lsdb);
! 342: lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
1.1 misho 343:
1.1.1.2 ! misho 344: /* LSA checksum */
! 345: ospf6_lsa_checksum (lsa_header);
! 346:
! 347: /* create LSA */
! 348: lsa = ospf6_lsa_create (lsa_header);
1.1 misho 349:
1.1.1.2 ! misho 350: /* Originate */
! 351: ospf6_lsa_originate_area (lsa, oa);
1.1 misho 352:
1.1.1.2 ! misho 353: link_state_id ++;
1.1 misho 354:
355: /* Do premature-aging of rest, undesired Router-LSAs */
356: type = ntohs (OSPF6_LSTYPE_ROUTER);
357: router = oa->ospf6->router_id;
358: for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
359: lsa = ospf6_lsdb_type_router_next (type, router, lsa))
360: {
361: if (ntohl (lsa->header->id) < link_state_id)
362: continue;
363: ospf6_lsa_purge (lsa);
364: }
365:
366: return 0;
367: }
368:
369: /*******************************/
370: /* RFC2740 3.4.3.2 Network-LSA */
371: /*******************************/
372:
1.1.1.2 ! misho 373: static char *
! 374: ospf6_network_lsa_get_ar_id (struct ospf6_lsa *lsa, char *buf, int buflen,
! 375: int pos)
! 376: {
! 377: char *start, *end, *current;
! 378: struct ospf6_network_lsa *network_lsa;
! 379: struct ospf6_network_lsdesc *lsdesc;
! 380:
! 381: if (lsa)
! 382: {
! 383: network_lsa = (struct ospf6_network_lsa *)
! 384: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
! 385:
! 386: start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
! 387: end = (char *) lsa->header + ntohs (lsa->header->length);
! 388: current = start + pos*(sizeof (struct ospf6_network_lsdesc));
! 389:
! 390: if ((current + sizeof(struct ospf6_network_lsdesc)) <= end)
! 391: {
! 392: lsdesc = (struct ospf6_network_lsdesc *)current;
! 393: if (buf)
! 394: inet_ntop (AF_INET, &lsdesc->router_id, buf, buflen);
! 395: }
! 396: else
! 397: return NULL;
! 398: }
! 399:
! 400: return (buf);
! 401: }
! 402:
1.1 misho 403: static int
404: ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
405: {
406: char *start, *end, *current;
407: struct ospf6_network_lsa *network_lsa;
408: struct ospf6_network_lsdesc *lsdesc;
409: char buf[128], options[32];
410:
411: network_lsa = (struct ospf6_network_lsa *)
412: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
413:
414: ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
415: vty_out (vty, " Options: %s%s", options, VNL);
416:
417: start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
418: end = (char *) lsa->header + ntohs (lsa->header->length);
419: for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
420: current += sizeof (struct ospf6_network_lsdesc))
421: {
422: lsdesc = (struct ospf6_network_lsdesc *) current;
423: inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
424: vty_out (vty, " Attached Router: %s%s", buf, VNL);
425: }
426: return 0;
427: }
428:
429: int
430: ospf6_network_lsa_originate (struct thread *thread)
431: {
432: struct ospf6_interface *oi;
433:
434: char buffer [OSPF6_MAX_LSASIZE];
435: struct ospf6_lsa_header *lsa_header;
436:
437: int count;
438: struct ospf6_lsa *old, *lsa;
439: struct ospf6_network_lsa *network_lsa;
440: struct ospf6_network_lsdesc *lsdesc;
441: struct ospf6_neighbor *on;
442: struct ospf6_link_lsa *link_lsa;
443: struct listnode *i;
444: u_int16_t type;
445:
446: oi = (struct ospf6_interface *) THREAD_ARG (thread);
447: oi->thread_network_lsa = NULL;
448:
449: /* The interface must be enabled until here. A Network-LSA of a
450: disabled interface (but was once enabled) should be flushed
451: by ospf6_lsa_refresh (), and does not come here. */
452: assert (oi->area);
453:
454: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
455: htonl (oi->interface->ifindex),
456: oi->area->ospf6->router_id, oi->area->lsdb);
457:
458: /* Do not originate Network-LSA if not DR */
459: if (oi->state != OSPF6_INTERFACE_DR)
460: {
461: if (old)
462: ospf6_lsa_purge (old);
463: return 0;
464: }
465:
466: if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
467: zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
468:
469: /* If none of neighbor is adjacent to us */
470: count = 0;
471:
472: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
473: if (on->state == OSPF6_NEIGHBOR_FULL)
474: count++;
475:
476: if (count == 0)
477: {
478: if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
479: zlog_debug ("Interface stub, ignore");
480: if (old)
481: ospf6_lsa_purge (old);
482: return 0;
483: }
484:
485: /* prepare buffer */
486: memset (buffer, 0, sizeof (buffer));
487: lsa_header = (struct ospf6_lsa_header *) buffer;
488: network_lsa = (struct ospf6_network_lsa *)
489: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
490:
491: /* Collect the interface's Link-LSAs to describe
492: network's optional capabilities */
493: type = htons (OSPF6_LSTYPE_LINK);
494: for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
495: lsa = ospf6_lsdb_type_next (type, lsa))
496: {
497: link_lsa = (struct ospf6_link_lsa *)
498: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
499: network_lsa->options[0] |= link_lsa->options[0];
500: network_lsa->options[1] |= link_lsa->options[1];
501: network_lsa->options[2] |= link_lsa->options[2];
502: }
503:
504: lsdesc = (struct ospf6_network_lsdesc *)
505: ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
506:
507: /* set Link Description to the router itself */
508: lsdesc->router_id = oi->area->ospf6->router_id;
509: lsdesc++;
510:
511: /* Walk through the neighbors */
512: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
513: {
514: if (on->state != OSPF6_NEIGHBOR_FULL)
515: continue;
516:
517: /* set this neighbor's Router-ID to LSA */
518: lsdesc->router_id = on->router_id;
519: lsdesc++;
520: }
521:
522: /* Fill LSA Header */
523: lsa_header->age = 0;
524: lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
525: lsa_header->id = htonl (oi->interface->ifindex);
526: lsa_header->adv_router = oi->area->ospf6->router_id;
527: lsa_header->seqnum =
528: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
529: lsa_header->adv_router, oi->area->lsdb);
530: lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
531:
532: /* LSA checksum */
533: ospf6_lsa_checksum (lsa_header);
534:
535: /* create LSA */
536: lsa = ospf6_lsa_create (lsa_header);
537:
538: /* Originate */
539: ospf6_lsa_originate_area (lsa, oi->area);
540:
541: return 0;
542: }
543:
544:
545: /****************************/
546: /* RFC2740 3.4.3.6 Link-LSA */
547: /****************************/
548:
1.1.1.2 ! misho 549: static char *
! 550: ospf6_link_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, int buflen,
! 551: int pos)
! 552: {
! 553: char *start, *end, *current;
! 554: struct ospf6_link_lsa *link_lsa;
! 555: struct in6_addr in6;
! 556: struct ospf6_prefix *prefix;
! 557: int cnt = 0, prefixnum;
! 558:
! 559: if (lsa)
! 560: {
! 561: link_lsa = (struct ospf6_link_lsa *)
! 562: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
! 563:
! 564: if (pos == 0) {
! 565: inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, buflen);
! 566: return (buf);
! 567: }
! 568:
! 569: prefixnum = ntohl (link_lsa->prefix_num);
! 570: if (pos > prefixnum)
! 571: return (NULL);
! 572:
! 573: start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
! 574: end = (char *) lsa->header + ntohs (lsa->header->length);
! 575: current = start;
! 576:
! 577: do
! 578: {
! 579: prefix = (struct ospf6_prefix *) current;
! 580: if (prefix->prefix_length == 0 ||
! 581: current + OSPF6_PREFIX_SIZE (prefix) > end)
! 582: {
! 583: return (NULL);
! 584: }
! 585:
! 586: if (cnt < pos)
! 587: {
! 588: current = start + pos*OSPF6_PREFIX_SIZE(prefix);
! 589: cnt++;
! 590: }
! 591: else
! 592: {
! 593: memset (&in6, 0, sizeof (in6));
! 594: memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
! 595: OSPF6_PREFIX_SPACE (prefix->prefix_length));
! 596: inet_ntop (AF_INET6, &in6, buf, buflen);
! 597: return (buf);
! 598: }
! 599: } while (current <= end);
! 600: }
! 601: return (NULL);
! 602: }
! 603:
1.1 misho 604: static int
605: ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
606: {
607: char *start, *end, *current;
608: struct ospf6_link_lsa *link_lsa;
609: int prefixnum;
610: char buf[128], options[32];
611: struct ospf6_prefix *prefix;
612: const char *p, *mc, *la, *nu;
613: struct in6_addr in6;
614:
615: link_lsa = (struct ospf6_link_lsa *)
616: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
617:
618: ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
619: inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
620: prefixnum = ntohl (link_lsa->prefix_num);
621:
622: vty_out (vty, " Priority: %d Options: %s%s",
623: link_lsa->priority, options, VNL);
624: vty_out (vty, " LinkLocal Address: %s%s", buf, VNL);
625: vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
626:
627: start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
628: end = (char *) lsa->header + ntohs (lsa->header->length);
629: for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
630: {
631: prefix = (struct ospf6_prefix *) current;
632: if (prefix->prefix_length == 0 ||
633: current + OSPF6_PREFIX_SIZE (prefix) > end)
634: break;
635:
636: p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
637: "P" : "--");
638: mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
639: "MC" : "--");
640: la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
641: "LA" : "--");
642: nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
643: "NU" : "--");
644: vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
645: p, mc, la, nu, VNL);
646:
647: memset (&in6, 0, sizeof (in6));
648: memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
649: OSPF6_PREFIX_SPACE (prefix->prefix_length));
650: inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
651: vty_out (vty, " Prefix: %s/%d%s",
652: buf, prefix->prefix_length, VNL);
653: }
654:
655: return 0;
656: }
657:
658: int
659: ospf6_link_lsa_originate (struct thread *thread)
660: {
661: struct ospf6_interface *oi;
662:
663: char buffer[OSPF6_MAX_LSASIZE];
664: struct ospf6_lsa_header *lsa_header;
665: struct ospf6_lsa *old, *lsa;
666:
667: struct ospf6_link_lsa *link_lsa;
668: struct ospf6_route *route;
669: struct ospf6_prefix *op;
670:
671: oi = (struct ospf6_interface *) THREAD_ARG (thread);
672: oi->thread_link_lsa = NULL;
673:
674: assert (oi->area);
675:
676: /* find previous LSA */
677: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
678: htonl (oi->interface->ifindex),
679: oi->area->ospf6->router_id, oi->lsdb);
680:
681: if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
682: {
683: if (old)
684: ospf6_lsa_purge (old);
685: return 0;
686: }
687:
688: if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
689: zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
690:
691: /* can't make Link-LSA if linklocal address not set */
692: if (oi->linklocal_addr == NULL)
693: {
694: if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
695: zlog_debug ("No Linklocal address on %s, defer originating",
696: oi->interface->name);
697: if (old)
698: ospf6_lsa_purge (old);
699: return 0;
700: }
701:
702: /* prepare buffer */
703: memset (buffer, 0, sizeof (buffer));
704: lsa_header = (struct ospf6_lsa_header *) buffer;
705: link_lsa = (struct ospf6_link_lsa *)
706: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
707:
708: /* Fill Link-LSA */
709: link_lsa->priority = oi->priority;
710: memcpy (link_lsa->options, oi->area->options, 3);
711: memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
712: sizeof (struct in6_addr));
713: link_lsa->prefix_num = htonl (oi->route_connected->count);
714:
715: op = (struct ospf6_prefix *)
716: ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
717:
718: /* connected prefix to advertise */
719: for (route = ospf6_route_head (oi->route_connected); route;
720: route = ospf6_route_next (route))
721: {
722: op->prefix_length = route->prefix.prefixlen;
723: op->prefix_options = route->path.prefix_options;
724: op->prefix_metric = htons (0);
725: memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
726: OSPF6_PREFIX_SPACE (op->prefix_length));
727: op = OSPF6_PREFIX_NEXT (op);
728: }
729:
730: /* Fill LSA Header */
731: lsa_header->age = 0;
732: lsa_header->type = htons (OSPF6_LSTYPE_LINK);
733: lsa_header->id = htonl (oi->interface->ifindex);
734: lsa_header->adv_router = oi->area->ospf6->router_id;
735: lsa_header->seqnum =
736: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
737: lsa_header->adv_router, oi->lsdb);
738: lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
739:
740: /* LSA checksum */
741: ospf6_lsa_checksum (lsa_header);
742:
743: /* create LSA */
744: lsa = ospf6_lsa_create (lsa_header);
745:
746: /* Originate */
747: ospf6_lsa_originate_interface (lsa, oi);
748:
749: return 0;
750: }
751:
752:
753: /*****************************************/
754: /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
755: /*****************************************/
1.1.1.2 ! misho 756: static char *
! 757: ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
! 758: int buflen, int pos)
! 759: {
! 760: char *start, *end, *current;
! 761: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
! 762: struct in6_addr in6;
! 763: int prefixnum, cnt = 0;
! 764: struct ospf6_prefix *prefix;
! 765:
! 766: if (lsa)
! 767: {
! 768: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
! 769: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
! 770:
! 771: prefixnum = ntohs (intra_prefix_lsa->prefix_num);
! 772: if (pos > prefixnum)
! 773: return (NULL);
! 774:
! 775: start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
! 776: end = (char *) lsa->header + ntohs (lsa->header->length);
! 777: current = start;
! 778:
! 779: do
! 780: {
! 781: prefix = (struct ospf6_prefix *) current;
! 782: if (prefix->prefix_length == 0 ||
! 783: current + OSPF6_PREFIX_SIZE (prefix) > end)
! 784: {
! 785: return NULL;
! 786: }
! 787:
! 788: if (cnt < pos)
! 789: {
! 790: current = start + pos*OSPF6_PREFIX_SIZE(prefix);
! 791: cnt++;
! 792: }
! 793: else
! 794: {
! 795: memset (&in6, 0, sizeof (in6));
! 796: memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
! 797: OSPF6_PREFIX_SPACE (prefix->prefix_length));
! 798: inet_ntop (AF_INET6, &in6, buf, buflen);
! 799: sprintf(&buf[strlen(buf)], "/%d", prefix->prefix_length);
! 800: return (buf);
! 801: }
! 802: } while (current <= end);
! 803: }
! 804: return (buf);
! 805: }
1.1 misho 806:
807: static int
808: ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
809: {
810: char *start, *end, *current;
811: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
812: int prefixnum;
813: char buf[128];
814: struct ospf6_prefix *prefix;
815: char id[16], adv_router[16];
816: const char *p, *mc, *la, *nu;
817: struct in6_addr in6;
818:
819: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
820: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
821:
822: prefixnum = ntohs (intra_prefix_lsa->prefix_num);
823:
824: vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
825:
826: inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
827: inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
828: adv_router, sizeof (adv_router));
829: vty_out (vty, " Reference: %s Id: %s Adv: %s%s",
830: ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
831: VNL);
832:
833: start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
834: end = (char *) lsa->header + ntohs (lsa->header->length);
835: for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
836: {
837: prefix = (struct ospf6_prefix *) current;
838: if (prefix->prefix_length == 0 ||
839: current + OSPF6_PREFIX_SIZE (prefix) > end)
840: break;
841:
842: p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
843: "P" : "--");
844: mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
845: "MC" : "--");
846: la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
847: "LA" : "--");
848: nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
849: "NU" : "--");
850: vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
851: p, mc, la, nu, VNL);
852:
853: memset (&in6, 0, sizeof (in6));
854: memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
855: OSPF6_PREFIX_SPACE (prefix->prefix_length));
856: inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
857: vty_out (vty, " Prefix: %s/%d%s",
858: buf, prefix->prefix_length, VNL);
859: }
860:
861: return 0;
862: }
863:
864: int
865: ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
866: {
867: struct ospf6_area *oa;
868:
869: char buffer[OSPF6_MAX_LSASIZE];
870: struct ospf6_lsa_header *lsa_header;
871: struct ospf6_lsa *old, *lsa;
872:
873: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
874: struct ospf6_interface *oi;
875: struct ospf6_neighbor *on;
876: struct ospf6_route *route;
877: struct ospf6_prefix *op;
878: struct listnode *i, *j;
879: int full_count = 0;
880: unsigned short prefix_num = 0;
881: char buf[BUFSIZ];
882: struct ospf6_route_table *route_advertise;
883:
884: oa = (struct ospf6_area *) THREAD_ARG (thread);
885: oa->thread_intra_prefix_lsa = NULL;
886:
887: /* find previous LSA */
888: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
889: htonl (0), oa->ospf6->router_id, oa->lsdb);
890:
891: if (! IS_AREA_ENABLED (oa))
892: {
893: if (old)
894: ospf6_lsa_purge (old);
895: return 0;
896: }
897:
898: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
899: zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
900: oa->name);
901:
902: /* prepare buffer */
903: memset (buffer, 0, sizeof (buffer));
904: lsa_header = (struct ospf6_lsa_header *) buffer;
905: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
906: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
907:
908: /* Fill Intra-Area-Prefix-LSA */
909: intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
910: intra_prefix_lsa->ref_id = htonl (0);
911: intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
912:
913: route_advertise = ospf6_route_table_create (0, 0);
914:
915: for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
916: {
917: if (oi->state == OSPF6_INTERFACE_DOWN)
918: {
919: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
920: zlog_debug (" Interface %s is down, ignore", oi->interface->name);
921: continue;
922: }
923:
924: full_count = 0;
925:
926: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
927: if (on->state == OSPF6_NEIGHBOR_FULL)
928: full_count++;
929:
930: if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
931: oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
932: full_count != 0)
933: {
934: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
935: zlog_debug (" Interface %s is not stub, ignore",
936: oi->interface->name);
937: continue;
938: }
939:
940: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
941: zlog_debug (" Interface %s:", oi->interface->name);
942:
943: /* connected prefix to advertise */
944: for (route = ospf6_route_head (oi->route_connected); route;
945: route = ospf6_route_best_next (route))
946: {
947: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
948: {
949: prefix2str (&route->prefix, buf, sizeof (buf));
950: zlog_debug (" include %s", buf);
951: }
952: ospf6_route_add (ospf6_route_copy (route), route_advertise);
953: }
954: }
955:
956: if (route_advertise->count == 0)
957: {
958: if (old)
959: ospf6_lsa_purge (old);
960: ospf6_route_table_delete (route_advertise);
961: return 0;
962: }
963:
964: /* put prefixes to advertise */
965: prefix_num = 0;
966: op = (struct ospf6_prefix *)
967: ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
968: for (route = ospf6_route_head (route_advertise); route;
969: route = ospf6_route_best_next (route))
970: {
971: op->prefix_length = route->prefix.prefixlen;
972: op->prefix_options = route->path.prefix_options;
973: op->prefix_metric = htons (route->path.cost);
974: memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
975: OSPF6_PREFIX_SPACE (op->prefix_length));
976: op = OSPF6_PREFIX_NEXT (op);
977: prefix_num++;
978: }
979:
980: ospf6_route_table_delete (route_advertise);
981:
982: if (prefix_num == 0)
983: {
984: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
985: zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
986: return 0;
987: }
988:
989: intra_prefix_lsa->prefix_num = htons (prefix_num);
990:
991: /* Fill LSA Header */
992: lsa_header->age = 0;
993: lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
994: lsa_header->id = htonl (0);
995: lsa_header->adv_router = oa->ospf6->router_id;
996: lsa_header->seqnum =
997: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
998: lsa_header->adv_router, oa->lsdb);
999: lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
1000:
1001: /* LSA checksum */
1002: ospf6_lsa_checksum (lsa_header);
1003:
1004: /* create LSA */
1005: lsa = ospf6_lsa_create (lsa_header);
1006:
1007: /* Originate */
1008: ospf6_lsa_originate_area (lsa, oa);
1009:
1010: return 0;
1011: }
1012:
1013:
1014: int
1015: ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
1016: {
1017: struct ospf6_interface *oi;
1018:
1019: char buffer[OSPF6_MAX_LSASIZE];
1020: struct ospf6_lsa_header *lsa_header;
1021: struct ospf6_lsa *old, *lsa;
1022:
1023: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1024: struct ospf6_neighbor *on;
1025: struct ospf6_route *route;
1026: struct ospf6_prefix *op;
1027: struct listnode *i;
1028: int full_count = 0;
1029: unsigned short prefix_num = 0;
1030: struct ospf6_route_table *route_advertise;
1031: struct ospf6_link_lsa *link_lsa;
1032: char *start, *end, *current;
1033: u_int16_t type;
1034: char buf[BUFSIZ];
1035:
1036: oi = (struct ospf6_interface *) THREAD_ARG (thread);
1037: oi->thread_intra_prefix_lsa = NULL;
1038:
1039: assert (oi->area);
1040:
1041: /* find previous LSA */
1042: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
1043: htonl (oi->interface->ifindex),
1044: oi->area->ospf6->router_id, oi->area->lsdb);
1045:
1046: if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
1047: {
1048: if (old)
1049: ospf6_lsa_purge (old);
1050: return 0;
1051: }
1052:
1053: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1054: zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
1055: oi->interface->name);
1056:
1057: /* prepare buffer */
1058: memset (buffer, 0, sizeof (buffer));
1059: lsa_header = (struct ospf6_lsa_header *) buffer;
1060: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1061: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
1062:
1063: /* Fill Intra-Area-Prefix-LSA */
1064: intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
1065: intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
1066: intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
1067:
1068: if (oi->state != OSPF6_INTERFACE_DR)
1069: {
1070: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1071: zlog_debug (" Interface is not DR");
1072: if (old)
1073: ospf6_lsa_purge (old);
1074: return 0;
1075: }
1076:
1077: full_count = 0;
1078: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
1079: if (on->state == OSPF6_NEIGHBOR_FULL)
1080: full_count++;
1081:
1082: if (full_count == 0)
1083: {
1084: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1085: zlog_debug (" Interface is stub");
1086: if (old)
1087: ospf6_lsa_purge (old);
1088: return 0;
1089: }
1090:
1091: /* connected prefix to advertise */
1092: route_advertise = ospf6_route_table_create (0, 0);
1093:
1094: type = ntohs (OSPF6_LSTYPE_LINK);
1095: for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
1096: lsa = ospf6_lsdb_type_next (type, lsa))
1097: {
1098: if (OSPF6_LSA_IS_MAXAGE (lsa))
1099: continue;
1100:
1101: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1102: zlog_debug (" include prefix from %s", lsa->name);
1103:
1104: if (lsa->header->adv_router != oi->area->ospf6->router_id)
1105: {
1106: on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
1107: if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
1108: {
1109: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1110: zlog_debug (" Neighbor not found or not Full, ignore");
1111: continue;
1112: }
1113: }
1114:
1115: link_lsa = (struct ospf6_link_lsa *)
1116: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
1117:
1118: prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
1119: start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
1120: end = (char *) lsa->header + ntohs (lsa->header->length);
1121: for (current = start; current < end && prefix_num;
1122: current += OSPF6_PREFIX_SIZE (op))
1123: {
1124: op = (struct ospf6_prefix *) current;
1125: if (op->prefix_length == 0 ||
1126: current + OSPF6_PREFIX_SIZE (op) > end)
1127: break;
1128:
1129: route = ospf6_route_create ();
1130:
1131: route->type = OSPF6_DEST_TYPE_NETWORK;
1132: route->prefix.family = AF_INET6;
1133: route->prefix.prefixlen = op->prefix_length;
1134: memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
1135: memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
1136: OSPF6_PREFIX_SPACE (op->prefix_length));
1137:
1138: route->path.origin.type = lsa->header->type;
1139: route->path.origin.id = lsa->header->id;
1140: route->path.origin.adv_router = lsa->header->adv_router;
1141: route->path.options[0] = link_lsa->options[0];
1142: route->path.options[1] = link_lsa->options[1];
1143: route->path.options[2] = link_lsa->options[2];
1144: route->path.prefix_options = op->prefix_options;
1145: route->path.area_id = oi->area->area_id;
1146: route->path.type = OSPF6_PATH_TYPE_INTRA;
1147:
1148: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1149: {
1150: prefix2str (&route->prefix, buf, sizeof (buf));
1151: zlog_debug (" include %s", buf);
1152: }
1153:
1154: ospf6_route_add (route, route_advertise);
1155: prefix_num--;
1156: }
1157: if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1158: zlog_debug ("Trailing garbage in %s", lsa->name);
1159: }
1160:
1161: op = (struct ospf6_prefix *)
1162: ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
1163:
1164: prefix_num = 0;
1165: for (route = ospf6_route_head (route_advertise); route;
1166: route = ospf6_route_best_next (route))
1167: {
1168: op->prefix_length = route->prefix.prefixlen;
1169: op->prefix_options = route->path.prefix_options;
1170: op->prefix_metric = htons (0);
1171: memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
1172: OSPF6_PREFIX_SPACE (op->prefix_length));
1173: op = OSPF6_PREFIX_NEXT (op);
1174: prefix_num++;
1175: }
1176:
1177: ospf6_route_table_delete (route_advertise);
1178:
1179: if (prefix_num == 0)
1180: {
1181: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1182: zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
1183: return 0;
1184: }
1185:
1186: intra_prefix_lsa->prefix_num = htons (prefix_num);
1187:
1188: /* Fill LSA Header */
1189: lsa_header->age = 0;
1190: lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1191: lsa_header->id = htonl (oi->interface->ifindex);
1192: lsa_header->adv_router = oi->area->ospf6->router_id;
1193: lsa_header->seqnum =
1194: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
1195: lsa_header->adv_router, oi->area->lsdb);
1196: lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
1197:
1198: /* LSA checksum */
1199: ospf6_lsa_checksum (lsa_header);
1200:
1201: /* create LSA */
1202: lsa = ospf6_lsa_create (lsa_header);
1203:
1204: /* Originate */
1205: ospf6_lsa_originate_area (lsa, oi->area);
1206:
1207: return 0;
1208: }
1209:
1210: void
1211: ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
1212: {
1213: struct ospf6_area *oa;
1214: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1215: struct prefix ls_prefix;
1216: struct ospf6_route *route, *ls_entry;
1217: int i, prefix_num;
1218: struct ospf6_prefix *op;
1219: char *start, *current, *end;
1220: char buf[64];
1.1.1.2 ! misho 1221: struct interface *ifp;
! 1222: int direct_connect = 0;
1.1 misho 1223:
1224: if (OSPF6_LSA_IS_MAXAGE (lsa))
1225: return;
1226:
1227: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1228: zlog_debug ("%s found", lsa->name);
1229:
1230: oa = OSPF6_AREA (lsa->lsdb->data);
1231:
1232: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1233: OSPF6_LSA_HEADER_END (lsa->header);
1234: if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
1235: ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1236: htonl (0), &ls_prefix);
1237: else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
1238: ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1239: intra_prefix_lsa->ref_id, &ls_prefix);
1240: else
1241: {
1242: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1243: zlog_debug ("Unknown reference LS-type: %#hx",
1244: ntohs (intra_prefix_lsa->ref_type));
1245: return;
1246: }
1247:
1248: ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
1249: if (ls_entry == NULL)
1250: {
1251: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1252: {
1253: ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
1254: zlog_debug ("LS entry does not exist: %s", buf);
1255: }
1256: return;
1257: }
1258:
1.1.1.2 ! misho 1259: if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id)
! 1260: {
! 1261: /* the intra-prefix are directly connected */
! 1262: direct_connect = 1;
! 1263: }
! 1264:
1.1 misho 1265: prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1266: start = (caddr_t) intra_prefix_lsa +
1267: sizeof (struct ospf6_intra_prefix_lsa);
1268: end = OSPF6_LSA_END (lsa->header);
1269: for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1270: {
1271: op = (struct ospf6_prefix *) current;
1272: if (prefix_num == 0)
1273: break;
1274: if (end < current + OSPF6_PREFIX_SIZE (op))
1275: break;
1276:
1.1.1.2 ! misho 1277: /* Appendix A.4.1.1 */
! 1278: if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU) ||
! 1279: CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_LA))
! 1280: {
! 1281: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
! 1282: {
! 1283: ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op),
! 1284: buf, sizeof (buf));
! 1285: zlog_debug ("%s: Skipping Prefix %s has NU/LA option set",
! 1286: __func__, buf);
! 1287: }
! 1288: continue;
! 1289: }
! 1290:
1.1 misho 1291: route = ospf6_route_create ();
1292:
1293: memset (&route->prefix, 0, sizeof (struct prefix));
1294: route->prefix.family = AF_INET6;
1295: route->prefix.prefixlen = op->prefix_length;
1296: ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
1297:
1298: route->type = OSPF6_DEST_TYPE_NETWORK;
1299: route->path.origin.type = lsa->header->type;
1300: route->path.origin.id = lsa->header->id;
1301: route->path.origin.adv_router = lsa->header->adv_router;
1302: route->path.prefix_options = op->prefix_options;
1303: route->path.area_id = oa->area_id;
1304: route->path.type = OSPF6_PATH_TYPE_INTRA;
1305: route->path.metric_type = 1;
1306: route->path.cost = ls_entry->path.cost +
1307: ntohs (op->prefix_metric);
1308:
1.1.1.2 ! misho 1309: if (direct_connect)
! 1310: {
! 1311: ifp = if_lookup_prefix(&route->prefix);
! 1312: if (ifp)
! 1313: route->nexthop[0].ifindex = ifp->ifindex;
! 1314: }
! 1315: else
! 1316: {
! 1317: for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
! 1318: i < OSPF6_MULTI_PATH_LIMIT; i++)
! 1319: ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
! 1320: }
1.1 misho 1321:
1322: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1323: {
1324: prefix2str (&route->prefix, buf, sizeof (buf));
1325: zlog_debug (" add %s", buf);
1326: }
1327:
1328: ospf6_route_add (route, oa->route_table);
1329: prefix_num--;
1330: }
1331:
1332: if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1333: zlog_debug ("Trailing garbage ignored");
1334: }
1335:
1336: void
1337: ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
1338: {
1339: struct ospf6_area *oa;
1340: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1341: struct prefix prefix;
1342: struct ospf6_route *route;
1343: int prefix_num;
1344: struct ospf6_prefix *op;
1345: char *start, *current, *end;
1346: char buf[64];
1347:
1348: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1349: zlog_debug ("%s disappearing", lsa->name);
1350:
1351: oa = OSPF6_AREA (lsa->lsdb->data);
1352:
1353: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1354: OSPF6_LSA_HEADER_END (lsa->header);
1355:
1356: prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1357: start = (caddr_t) intra_prefix_lsa +
1358: sizeof (struct ospf6_intra_prefix_lsa);
1359: end = OSPF6_LSA_END (lsa->header);
1360: for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1361: {
1362: op = (struct ospf6_prefix *) current;
1363: if (prefix_num == 0)
1364: break;
1365: if (end < current + OSPF6_PREFIX_SIZE (op))
1366: break;
1367: prefix_num--;
1368:
1369: memset (&prefix, 0, sizeof (struct prefix));
1370: prefix.family = AF_INET6;
1371: prefix.prefixlen = op->prefix_length;
1372: ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
1373:
1374: route = ospf6_route_lookup (&prefix, oa->route_table);
1375: if (route == NULL)
1376: continue;
1377:
1378: for (ospf6_route_lock (route);
1379: route && ospf6_route_is_prefix (&prefix, route);
1380: route = ospf6_route_next (route))
1381: {
1382: if (route->type != OSPF6_DEST_TYPE_NETWORK)
1383: continue;
1384: if (route->path.area_id != oa->area_id)
1385: continue;
1386: if (route->path.type != OSPF6_PATH_TYPE_INTRA)
1387: continue;
1388: if (route->path.origin.type != lsa->header->type ||
1389: route->path.origin.id != lsa->header->id ||
1390: route->path.origin.adv_router != lsa->header->adv_router)
1391: continue;
1392:
1393: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1394: {
1395: prefix2str (&route->prefix, buf, sizeof (buf));
1396: zlog_debug ("remove %s", buf);
1397: }
1398: ospf6_route_remove (route, oa->route_table);
1399: }
1400: if (route)
1401: ospf6_route_unlock (route);
1402: }
1403:
1404: if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1405: zlog_debug ("Trailing garbage ignored");
1406: }
1407:
1408: void
1409: ospf6_intra_route_calculation (struct ospf6_area *oa)
1410: {
1411: struct ospf6_route *route;
1412: u_int16_t type;
1413: struct ospf6_lsa *lsa;
1414: void (*hook_add) (struct ospf6_route *) = NULL;
1415: void (*hook_remove) (struct ospf6_route *) = NULL;
1416:
1417: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1418: zlog_debug ("Re-examin intra-routes for area %s", oa->name);
1419:
1420: hook_add = oa->route_table->hook_add;
1421: hook_remove = oa->route_table->hook_remove;
1422: oa->route_table->hook_add = NULL;
1423: oa->route_table->hook_remove = NULL;
1424:
1425: for (route = ospf6_route_head (oa->route_table); route;
1426: route = ospf6_route_next (route))
1427: route->flag = OSPF6_ROUTE_REMOVE;
1428:
1429: type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1430: for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
1431: lsa = ospf6_lsdb_type_next (type, lsa))
1432: ospf6_intra_prefix_lsa_add (lsa);
1433:
1434: oa->route_table->hook_add = hook_add;
1435: oa->route_table->hook_remove = hook_remove;
1436:
1437: for (route = ospf6_route_head (oa->route_table); route;
1438: route = ospf6_route_next (route))
1439: {
1440: if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
1441: CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
1442: {
1443: UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
1444: UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
1445: }
1446:
1447: if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
1448: ospf6_route_remove (route, oa->route_table);
1449: else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
1450: CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
1451: {
1452: if (hook_add)
1453: (*hook_add) (route);
1454: }
1455:
1456: route->flag = 0;
1457: }
1458:
1459: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1460: zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
1461: }
1462:
1463: static void
1464: ospf6_brouter_debug_print (struct ospf6_route *brouter)
1465: {
1466: u_int32_t brouter_id;
1467: char brouter_name[16];
1468: char area_name[16];
1469: char destination[64];
1470: char installed[16], changed[16];
1471: struct timeval now, res;
1472: char id[16], adv_router[16];
1473: char capa[16], options[16];
1474:
1475: brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1476: inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1477: inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
1478: ospf6_linkstate_prefix2str (&brouter->prefix, destination,
1479: sizeof (destination));
1480:
1481: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1482: timersub (&now, &brouter->installed, &res);
1483: timerstring (&res, installed, sizeof (installed));
1484:
1485: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1486: timersub (&now, &brouter->changed, &res);
1487: timerstring (&res, changed, sizeof (changed));
1488:
1489: inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
1490: inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
1491: sizeof (adv_router));
1492:
1493: ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
1494: ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
1495:
1496: zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
1497: zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
1.1.1.2 ! misho 1498: (void *)brouter->prev, (void *)brouter, (void *)brouter->next,
! 1499: (void *)brouter->rnode);
1.1 misho 1500: zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1501: brouter->type, destination, installed, changed);
1502: zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock,
1503: (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
1504: (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
1505: (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
1506: (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
1507: zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1508: OSPF6_PATH_TYPE_NAME (brouter->path.type),
1509: ospf6_lstype_name (brouter->path.origin.type),
1510: id, adv_router);
1511: zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1512: options, capa, brouter->path.metric_type,
1513: brouter->path.cost, brouter->path.cost_e2);
1514: }
1515:
1516: void
1517: ospf6_intra_brouter_calculation (struct ospf6_area *oa)
1518: {
1519: struct ospf6_route *brouter, *copy;
1520: void (*hook_add) (struct ospf6_route *) = NULL;
1521: void (*hook_remove) (struct ospf6_route *) = NULL;
1522: u_int32_t brouter_id;
1523: char brouter_name[16];
1524:
1525: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1526: zlog_info ("border-router calculation for area %s", oa->name);
1527:
1528: hook_add = oa->ospf6->brouter_table->hook_add;
1529: hook_remove = oa->ospf6->brouter_table->hook_remove;
1530: oa->ospf6->brouter_table->hook_add = NULL;
1531: oa->ospf6->brouter_table->hook_remove = NULL;
1532:
1533: /* withdraw the previous router entries for the area */
1534: for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1535: brouter = ospf6_route_next (brouter))
1536: {
1537: brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1538: inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1539: if (brouter->path.area_id != oa->area_id)
1540: continue;
1541: brouter->flag = OSPF6_ROUTE_REMOVE;
1542:
1543: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1544: IS_OSPF6_DEBUG_ROUTE (MEMORY))
1545: {
1546: zlog_info ("%p: mark as removing: area %s brouter %s",
1.1.1.2 ! misho 1547: (void *)brouter, oa->name, brouter_name);
1.1 misho 1548: ospf6_brouter_debug_print (brouter);
1549: }
1550: }
1551:
1552: for (brouter = ospf6_route_head (oa->spf_table); brouter;
1553: brouter = ospf6_route_next (brouter))
1554: {
1555: brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1556: inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1557:
1558: if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
1559: continue;
1560: if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
1561: continue;
1562: if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
1563: ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
1564: continue;
1565:
1.1.1.2 ! misho 1566: if (! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_V6) ||
! 1567: ! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_R))
! 1568: continue;
! 1569:
1.1 misho 1570: copy = ospf6_route_copy (brouter);
1571: copy->type = OSPF6_DEST_TYPE_ROUTER;
1572: copy->path.area_id = oa->area_id;
1573: ospf6_route_add (copy, oa->ospf6->brouter_table);
1574:
1575: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1576: IS_OSPF6_DEBUG_ROUTE (MEMORY))
1577: {
1578: zlog_info ("%p: transfer: area %s brouter %s",
1.1.1.2 ! misho 1579: (void *)brouter, oa->name, brouter_name);
1.1 misho 1580: ospf6_brouter_debug_print (brouter);
1581: }
1582: }
1583:
1584: oa->ospf6->brouter_table->hook_add = hook_add;
1585: oa->ospf6->brouter_table->hook_remove = hook_remove;
1586:
1587: for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1588: brouter = ospf6_route_next (brouter))
1589: {
1590: brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1591: inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1592:
1593: if (brouter->path.area_id != oa->area_id)
1594: continue;
1595:
1596: if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
1597: continue;
1598:
1599: if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
1600: CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
1601: {
1602: UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
1603: UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
1604: }
1605:
1606: if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
1607: {
1608: if (IS_OSPF6_DEBUG_BROUTER ||
1609: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1610: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1611: zlog_info ("brouter %s disappears via area %s",
1612: brouter_name, oa->name);
1613: ospf6_route_remove (brouter, oa->ospf6->brouter_table);
1614: }
1615: else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
1616: CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
1617: {
1618: if (IS_OSPF6_DEBUG_BROUTER ||
1619: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1620: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1621: zlog_info ("brouter %s appears via area %s",
1622: brouter_name, oa->name);
1623:
1624: /* newly added */
1625: if (hook_add)
1626: (*hook_add) (brouter);
1627: }
1628: else
1629: {
1630: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1631: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1632: zlog_info ("brouter %s still exists via area %s",
1633: brouter_name, oa->name);
1634: }
1635:
1636: brouter->flag = 0;
1637: }
1638:
1639: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1640: zlog_info ("border-router calculation for area %s: done", oa->name);
1641: }
1642:
1643: struct ospf6_lsa_handler router_handler =
1644: {
1645: OSPF6_LSTYPE_ROUTER,
1646: "Router",
1.1.1.2 ! misho 1647: "Rtr",
! 1648: ospf6_router_lsa_show,
! 1649: ospf6_router_lsa_get_nbr_id
1.1 misho 1650: };
1651:
1652: struct ospf6_lsa_handler network_handler =
1653: {
1654: OSPF6_LSTYPE_NETWORK,
1655: "Network",
1.1.1.2 ! misho 1656: "Net",
! 1657: ospf6_network_lsa_show,
! 1658: ospf6_network_lsa_get_ar_id
1.1 misho 1659: };
1660:
1661: struct ospf6_lsa_handler link_handler =
1662: {
1663: OSPF6_LSTYPE_LINK,
1664: "Link",
1.1.1.2 ! misho 1665: "Lnk",
! 1666: ospf6_link_lsa_show,
! 1667: ospf6_link_lsa_get_prefix_str
1.1 misho 1668: };
1669:
1670: struct ospf6_lsa_handler intra_prefix_handler =
1671: {
1672: OSPF6_LSTYPE_INTRA_PREFIX,
1673: "Intra-Prefix",
1.1.1.2 ! misho 1674: "INP",
! 1675: ospf6_intra_prefix_lsa_show,
! 1676: ospf6_intra_prefix_lsa_get_prefix_str
1.1 misho 1677: };
1678:
1679: void
1680: ospf6_intra_init (void)
1681: {
1682: ospf6_install_lsa_handler (&router_handler);
1683: ospf6_install_lsa_handler (&network_handler);
1684: ospf6_install_lsa_handler (&link_handler);
1685: ospf6_install_lsa_handler (&intra_prefix_handler);
1686: }
1687:
1688: DEFUN (debug_ospf6_brouter,
1689: debug_ospf6_brouter_cmd,
1690: "debug ospf6 border-routers",
1691: DEBUG_STR
1692: OSPF6_STR
1693: "Debug border router\n"
1694: )
1695: {
1696: OSPF6_DEBUG_BROUTER_ON ();
1697: return CMD_SUCCESS;
1698: }
1699:
1700: DEFUN (no_debug_ospf6_brouter,
1701: no_debug_ospf6_brouter_cmd,
1702: "no debug ospf6 border-routers",
1703: NO_STR
1704: DEBUG_STR
1705: OSPF6_STR
1706: "Debug border router\n"
1707: )
1708: {
1709: OSPF6_DEBUG_BROUTER_OFF ();
1710: return CMD_SUCCESS;
1711: }
1712:
1713: DEFUN (debug_ospf6_brouter_router,
1714: debug_ospf6_brouter_router_cmd,
1715: "debug ospf6 border-routers router-id A.B.C.D",
1716: DEBUG_STR
1717: OSPF6_STR
1718: "Debug border router\n"
1719: "Debug specific border router\n"
1720: "Specify border-router's router-id\n"
1721: )
1722: {
1723: u_int32_t router_id;
1724: inet_pton (AF_INET, argv[0], &router_id);
1725: OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
1726: return CMD_SUCCESS;
1727: }
1728:
1729: DEFUN (no_debug_ospf6_brouter_router,
1730: no_debug_ospf6_brouter_router_cmd,
1731: "no debug ospf6 border-routers router-id",
1732: NO_STR
1733: DEBUG_STR
1734: OSPF6_STR
1735: "Debug border router\n"
1736: "Debug specific border router\n"
1737: )
1738: {
1739: OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1740: return CMD_SUCCESS;
1741: }
1742:
1743: DEFUN (debug_ospf6_brouter_area,
1744: debug_ospf6_brouter_area_cmd,
1745: "debug ospf6 border-routers area-id A.B.C.D",
1746: DEBUG_STR
1747: OSPF6_STR
1748: "Debug border router\n"
1749: "Debug border routers in specific Area\n"
1750: "Specify Area-ID\n"
1751: )
1752: {
1753: u_int32_t area_id;
1754: inet_pton (AF_INET, argv[0], &area_id);
1755: OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
1756: return CMD_SUCCESS;
1757: }
1758:
1759: DEFUN (no_debug_ospf6_brouter_area,
1760: no_debug_ospf6_brouter_area_cmd,
1761: "no debug ospf6 border-routers area-id",
1762: NO_STR
1763: DEBUG_STR
1764: OSPF6_STR
1765: "Debug border router\n"
1766: "Debug border routers in specific Area\n"
1767: )
1768: {
1769: OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1770: return CMD_SUCCESS;
1771: }
1772:
1773: int
1774: config_write_ospf6_debug_brouter (struct vty *vty)
1775: {
1776: char buf[16];
1777: if (IS_OSPF6_DEBUG_BROUTER)
1778: vty_out (vty, "debug ospf6 border-routers%s", VNL);
1779: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
1780: {
1781: inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
1782: buf, sizeof (buf));
1783: vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
1784: }
1785: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
1786: {
1787: inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
1788: buf, sizeof (buf));
1789: vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
1790: }
1791: return 0;
1792: }
1793:
1794: void
1795: install_element_ospf6_debug_brouter (void)
1796: {
1797: install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
1798: install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
1799: install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
1800: install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
1801: install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
1802: install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
1803: install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
1804: install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
1805: install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
1806: install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
1807: install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
1808: install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
1809: }
1810:
1811:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>