3 * Copyright (C) 1999 Yasuhiro Ohara
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
25 /* Include other stuffs */
33 #include "sockunion.h"
43 #include "ospf6_proto.h"
44 #include "ospf6_prefix.h"
45 #include "ospf6_lsa.h"
46 #include "ospf6_lsdb.h"
47 #include "ospf6_message.h"
48 #include "ospf6_dump.h"
50 #include "ospf6_top.h"
51 #include "ospf6_area.h"
52 #include "ospf6_interface.h"
53 #include "ospf6_neighbor.h"
54 #include "ospf6_redistribute.h"
55 #include "ospf6_ism.h"
56 #include "ospf6_nsm.h"
57 #include "ospf6_dbex.h"
59 #define HEADER_DEPENDENCY
61 #undef HEADER_DEPENDENCY
63 char *ospf6_lsa_type_strings
[] =
65 "None", "Router", "Network", "InterPrefix", "InterRouter",
66 "ASExternal", "GroupMembership", "Type7", "Link", "IntraPrefix",
70 char *ospf6_router_lsd_type_strings
[] =
71 { "None", "PointToPoint", "Transit", "Stub", "Virtual", NULL
};
74 ospf6_lsa_print_id (struct ospf6_lsa_header
*lsa_header
, char *buf
, int size
)
77 inet_ntop (AF_INET
, &lsa_header
->advrtr
, adv_router
, sizeof (adv_router
));
78 snprintf (buf
, size
, "%s[id:%lu %s]",
79 ospf6_lsa_type_string (lsa_header
->type
),
80 (unsigned long) ntohl (lsa_header
->ls_id
), adv_router
);
84 /* test LSAs identity */
86 ospf6_lsa_issame (struct ospf6_lsa_header
*lsh1
,
87 struct ospf6_lsa_header
*lsh2
)
89 assert (lsh1
&& lsh2
);
91 if (lsh1
->advrtr
!= lsh2
->advrtr
)
94 if (lsh1
->ls_id
!= lsh2
->ls_id
)
97 if (lsh1
->type
!= lsh2
->type
)
103 /* RFC2328: Section 13.2 */
105 ospf6_lsa_differ (struct ospf6_lsa
*lsa1
,
106 struct ospf6_lsa
*lsa2
)
109 struct ospf6_lsa_header
*lsh1
, *lsh2
;
111 ospf6_lsa_age_current (lsa1
);
112 ospf6_lsa_age_current (lsa2
);
113 lsh1
= (struct ospf6_lsa_header
*) lsa1
->lsa_hdr
;
114 lsh2
= (struct ospf6_lsa_header
*) lsa2
->lsa_hdr
;
116 if (! ospf6_lsa_issame (lsh1
, lsh2
))
119 /* check Options field */
122 if (ntohs (lsh1
->age
) == MAXAGE
&& ntohs (lsh2
->age
) != MAXAGE
)
124 if (ntohs (lsh1
->age
) != MAXAGE
&& ntohs (lsh2
->age
) == MAXAGE
)
128 if (ntohs (lsh1
->length
) != ntohs (lsh2
->length
))
131 diff
= memcmp (lsh1
+ 1, lsh2
+ 1,
132 ntohs (lsh1
->length
) - sizeof (struct ospf6_lsa_header
));
138 ospf6_lsa_match (u_int16_t type
, u_int32_t ls_id
, u_int32_t advrtr
,
139 struct ospf6_lsa_header
*lsh
)
141 if (lsh
->advrtr
!= advrtr
)
144 if (lsh
->ls_id
!= ls_id
)
147 if (lsh
->type
!= type
)
153 /* ospf6 age functions */
154 /* calculate birth and set expire timer */
156 ospf6_lsa_age_set (struct ospf6_lsa
*lsa
)
160 assert (lsa
&& lsa
->lsa_hdr
);
162 if (gettimeofday (&now
, (struct timezone
*)NULL
) < 0)
163 zlog_warn ("Lsa: gettimeofday failed, may fail LSA AGEs: %s",
166 lsa
->birth
= now
.tv_sec
- ntohs (lsa
->lsa_hdr
->lsh_age
);
167 lsa
->expire
= thread_add_timer (master
, ospf6_lsa_expire
, lsa
,
168 lsa
->birth
+ MAXAGE
- now
.tv_sec
);
172 /* this function calculates current age from its birth,
173 then update age field of LSA header. return value is current age */
175 ospf6_lsa_age_current (struct ospf6_lsa
*lsa
)
180 struct ospf6_lsa_header
*lsa_header
;
183 lsa_header
= (struct ospf6_lsa_header
*) lsa
->lsa_hdr
;
187 if (gettimeofday (&now
, (struct timezone
*)NULL
) < 0)
188 zlog_warn ("Lsa: gettimeofday failed, may fail ages: %s",
192 ulage
= now
.tv_sec
- lsa
->birth
;
194 /* if over MAXAGE, set to it */
200 lsa_header
->age
= htons (age
);
204 /* returns 1 if LSA's age is MAXAGE. else returns 0 */
206 ospf6_lsa_is_maxage (struct ospf6_lsa
*lsa
)
208 if (ospf6_lsa_age_current (lsa
) == MAXAGE
)
213 /* update age field of LSA header with adding InfTransDelay */
215 ospf6_lsa_age_update_to_send (struct ospf6_lsa
*lsa
, u_int32_t transdelay
)
218 struct ospf6_lsa_header
*lsa_header
;
220 lsa_header
= (struct ospf6_lsa_header
*) lsa
->lsa_hdr
;
221 age
= ospf6_lsa_age_current (lsa
) + transdelay
;
224 lsa_header
->age
= htons (age
);
229 ospf6_lsa_premature_aging (struct ospf6_lsa
*lsa
)
232 if (IS_OSPF6_DUMP_LSA
)
233 zlog_info ("Lsa: Premature aging: %s", lsa
->str
);
236 thread_cancel (lsa
->expire
);
237 lsa
->expire
= (struct thread
*) NULL
;
239 thread_cancel (lsa
->refresh
);
240 lsa
->refresh
= (struct thread
*) NULL
;
243 thread_execute (master
, ospf6_lsa_expire
, lsa
, 0);
246 /* check which is more recent. if a is more recent, return -1;
247 if the same, return 0; otherwise(b is more recent), return 1 */
249 ospf6_lsa_check_recent (struct ospf6_lsa
*a
, struct ospf6_lsa
*b
)
251 signed long seqnuma
, seqnumb
;
252 u_int16_t cksuma
, cksumb
;
253 u_int16_t agea
, ageb
;
255 assert (a
&& a
->lsa_hdr
);
256 assert (b
&& b
->lsa_hdr
);
257 assert (ospf6_lsa_issame ((struct ospf6_lsa_header
*) a
->lsa_hdr
,
258 (struct ospf6_lsa_header
*) b
->lsa_hdr
));
260 seqnuma
= ((signed long) ntohl (a
->lsa_hdr
->lsh_seqnum
))
261 - (signed long)INITIAL_SEQUENCE_NUMBER
;
262 seqnumb
= ((signed long) ntohl (b
->lsa_hdr
->lsh_seqnum
))
263 - (signed long)INITIAL_SEQUENCE_NUMBER
;
265 /* compare by sequence number */
266 /* xxx, care about LS sequence number wrapping */
267 recent_reason
= "seqnum";
268 if (IS_OSPF6_DUMP_LSA
&& seqnuma
!= seqnumb
)
269 zlog_info ("LSA: recent: %s:[seqnum %d] %s:[seqnum %d]",
270 a
->str
, ntohl(a
->header
->seqnum
),
271 b
->str
, ntohl(b
->header
->seqnum
));
272 if (seqnuma
> seqnumb
)
274 else if (seqnuma
< seqnumb
)
278 cksuma
= ntohs (a
->header
->checksum
);
279 cksumb
= ntohs (b
->header
->checksum
);
286 agea
= ospf6_lsa_age_current (a
);
287 ageb
= ospf6_lsa_age_current (b
);
290 recent_reason
= "max age";
291 if (IS_OSPF6_DUMP_LSA
&&
292 ((agea
== OSPF6_LSA_MAXAGE
&& ageb
!= OSPF6_LSA_MAXAGE
) ||
293 (agea
!= OSPF6_LSA_MAXAGE
&& ageb
== OSPF6_LSA_MAXAGE
)))
294 zlog_info ("LSA: recent: %s:[age %hu] %s:[age %hu]", a
->str
, agea
, b
->str
, ageb
);
295 if (agea
== OSPF6_LSA_MAXAGE
&& ageb
!= OSPF6_LSA_MAXAGE
)
297 else if (agea
!= OSPF6_LSA_MAXAGE
&& ageb
== OSPF6_LSA_MAXAGE
)
300 recent_reason
= "age differ";
301 if (IS_OSPF6_DUMP_LSA
&&
302 ((agea
> ageb
&& agea
- ageb
>= OSPF6_LSA_MAXAGEDIFF
) ||
303 (agea
< ageb
&& ageb
- agea
>= OSPF6_LSA_MAXAGEDIFF
)))
304 zlog_info ("LSA: recent: %s:[age %hu] %s:[age %hu]", a
->str
, agea
, b
->str
, ageb
);
305 if (agea
> ageb
&& agea
- ageb
>= OSPF6_LSA_MAXAGEDIFF
)
307 else if (agea
< ageb
&& ageb
- agea
>= OSPF6_LSA_MAXAGEDIFF
)
311 recent_reason
= "the same instance";
312 if (IS_OSPF6_DUMP_LSA
)
313 zlog_info ("LSA: recent: %s == %s", a
->str
, b
->str
);
318 ospf6_lsa_lsd_num (struct ospf6_lsa_header
*lsa_header
)
323 len
= ntohs (lsa_header
->length
);
324 len
-= sizeof (struct ospf6_lsa_header
);
325 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_ROUTER
))
327 len
-= sizeof (struct ospf6_router_lsa
);
328 ldnum
= len
/ sizeof (struct ospf6_router_lsd
);
330 else /* (lsa_header->type == htons (OSPF6_LSA_TYPE_NETWORK)) */
332 len
-= sizeof (struct ospf6_network_lsa
);
333 ldnum
= len
/ sizeof (u_int32_t
);
340 ospf6_lsa_lsd_get (int index
, struct ospf6_lsa_header
*lsa_header
)
343 struct ospf6_router_lsa
*router_lsa
;
344 struct ospf6_router_lsd
*router_lsd
;
345 struct ospf6_network_lsa
*network_lsa
;
346 struct ospf6_network_lsd
*network_lsd
;
348 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_ROUTER
))
350 router_lsa
= (struct ospf6_router_lsa
*) (lsa_header
+ 1);
351 router_lsd
= (struct ospf6_router_lsd
*) (router_lsa
+ 1);
353 p
= (void *) router_lsd
;
355 else if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_NETWORK
))
357 network_lsa
= (struct ospf6_network_lsa
*) (lsa_header
+ 1);
358 network_lsd
= (struct ospf6_network_lsd
*) (network_lsa
+ 1);
359 network_lsd
+= index
;
360 p
= (void *) network_lsd
;
370 /* network_lsd <-> router_lsd */
372 ospf6_lsa_lsd_network_reference_match (struct ospf6_network_lsd
*network_lsd1
,
373 struct ospf6_lsa_header
*lsa_header1
,
374 struct ospf6_router_lsd
*router_lsd2
,
375 struct ospf6_lsa_header
*lsa_header2
)
377 if (network_lsd1
->adv_router
!= lsa_header2
->advrtr
)
379 if (router_lsd2
->type
!= OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK
)
381 if (router_lsd2
->neighbor_router_id
!= lsa_header1
->advrtr
)
383 if (router_lsd2
->neighbor_interface_id
!= lsa_header1
->ls_id
)
388 /* router_lsd <-> router_lsd */
390 ospf6_lsa_lsd_router_reference_match (struct ospf6_router_lsd
*router_lsd1
,
391 struct ospf6_lsa_header
*lsa_header1
,
392 struct ospf6_router_lsd
*router_lsd2
,
393 struct ospf6_lsa_header
*lsa_header2
)
395 if (router_lsd1
->type
!= OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT
)
397 if (router_lsd2
->type
!= OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT
)
399 if (router_lsd1
->neighbor_router_id
!= lsa_header2
->advrtr
)
401 if (router_lsd2
->neighbor_router_id
!= lsa_header1
->advrtr
)
403 if (router_lsd1
->neighbor_interface_id
!= router_lsd2
->interface_id
)
405 if (router_lsd2
->neighbor_interface_id
!= router_lsd1
->interface_id
)
411 ospf6_lsa_lsd_is_refer_ok (int index1
, struct ospf6_lsa_header
*lsa_header1
,
412 int index2
, struct ospf6_lsa_header
*lsa_header2
)
414 struct ospf6_router_lsd
*r1
, *r2
;
415 struct ospf6_network_lsd
*n
;
417 r1
= (struct ospf6_router_lsd
*) NULL
;
418 r2
= (struct ospf6_router_lsd
*) NULL
;
419 n
= (struct ospf6_network_lsd
*) NULL
;
420 if (lsa_header1
->type
== htons (OSPF6_LSA_TYPE_ROUTER
))
421 r1
= (struct ospf6_router_lsd
*) ospf6_lsa_lsd_get (index1
, lsa_header1
);
423 n
= (struct ospf6_network_lsd
*) ospf6_lsa_lsd_get (index1
, lsa_header1
);
425 if (lsa_header2
->type
== htons (OSPF6_LSA_TYPE_ROUTER
))
426 r2
= (struct ospf6_router_lsd
*) ospf6_lsa_lsd_get (index2
, lsa_header2
);
428 n
= (struct ospf6_network_lsd
*) ospf6_lsa_lsd_get (index2
, lsa_header2
);
431 return ospf6_lsa_lsd_router_reference_match (r1
, lsa_header1
,
434 return ospf6_lsa_lsd_network_reference_match (n
, lsa_header2
,
437 return ospf6_lsa_lsd_network_reference_match (n
, lsa_header1
,
442 /* vty function for LSAs */
444 ospf6_lsa_show_body_unknown (struct vty
*vty
,
445 struct ospf6_lsa_header
*lsa_header
)
447 vty_out (vty
, " Unknown Type%s", VTY_NEWLINE
);
451 ospf6_lsa_show_body_router (struct vty
*vty
,
452 struct ospf6_lsa_header
*lsa_header
)
456 struct ospf6_router_lsa
*router_lsa
;
457 struct ospf6_router_lsd
*router_lsd
;
460 router_lsa
= (struct ospf6_router_lsa
*)(lsa_header
+ 1);
461 router_lsd
= (struct ospf6_router_lsd
*)(router_lsa
+ 1);
463 lsdnum
= ospf6_lsa_lsd_num (lsa_header
);
464 assert (lsdnum
>= 0);
468 vty_out (vty
, " Type: %s Metric: %d%s",
469 ospf6_router_lsd_type_strings
[router_lsd
->type
],
470 ntohs(router_lsd
->metric
), VTY_NEWLINE
);
471 vty_out (vty
, " Interface ID: %d%s",
472 ntohl (router_lsd
->interface_id
), VTY_NEWLINE
);
473 vty_out (vty
, " Neighbor Interface ID: %d%s",
474 ntohl (router_lsd
->neighbor_interface_id
), VTY_NEWLINE
);
475 vty_out (vty
, " Neighbor Router ID: %s%s",
476 inet_ntop (AF_INET
, &router_lsd
->neighbor_router_id
,
477 buf
, sizeof (buf
)), VTY_NEWLINE
);
483 ospf6_lsa_show_body_network (struct vty
*vty
,
484 struct ospf6_lsa_header
*lsa_header
)
487 struct ospf6_network_lsa
*lsa
;
488 u_int32_t
*router_id
;
492 lsa
= (struct ospf6_network_lsa
*) (lsa_header
+ 1);
493 router_id
= (u_int32_t
*)(lsa
+ 1);
495 ospf6_opt_capability_string (lsa
->options
, buf
, sizeof (buf
));
496 vty_out (vty
, " Options: %s%s", buf
, VTY_NEWLINE
);
498 lsdnum
= ospf6_lsa_lsd_num (lsa_header
);
499 assert (lsdnum
>= 0);
503 inet_ntop (AF_INET
, router_id
, buf
, sizeof (buf
));
504 vty_out (vty
, " Attached Router: %s%s", buf
, VTY_NEWLINE
);
510 ospf6_lsa_show_body_inter_prefix (struct vty
*vty
,
511 struct ospf6_lsa_header
*lsa_header
)
513 struct ospf6_lsa_inter_area_prefix_lsa
*inter_prefix_lsa
;
514 struct ospf6_prefix
*prefix
;
519 inter_prefix_lsa
= (struct ospf6_lsa_inter_area_prefix_lsa
*) (lsa_header
+ 1);
522 vty_out (vty
, " Metric: %d%s", ntohl (inter_prefix_lsa
->metric
),
525 prefix
= (struct ospf6_prefix
*)(inter_prefix_lsa
+ 1);
528 ospf6_prefix_options_str (prefix
, buf
, sizeof (buf
));
529 vty_out (vty
, " Prefix Options: %s%s", buf
, VTY_NEWLINE
);
532 ospf6_prefix_in6_addr (prefix
, &in6
);
533 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
534 vty_out (vty
, " Prefix: %s/%d%s",
535 buf
, prefix
->prefix_length
, VTY_NEWLINE
);
539 ospf6_lsa_show_body_inter_router (struct vty
*vty
,
540 struct ospf6_lsa_header
*lsa_header
)
542 struct ospf6_lsa_inter_area_router_lsa
*inter_router_lsa
;
546 inter_router_lsa
= (struct ospf6_lsa_inter_area_router_lsa
*) (lsa_header
+ 1);
549 ospf6_opt_capability_string (inter_router_lsa
->options
, buf
, sizeof (buf
));
550 vty_out (vty
, " Options: %s%s", buf
, VTY_NEWLINE
);
553 vty_out (vty
, " Metric: %d%s", ntohl (inter_router_lsa
->metric
),
556 /* Destination Router ID */
557 inet_ntop (AF_INET
, &inter_router_lsa
->router_id
, buf
, sizeof (buf
));
558 vty_out (vty
, " Destination Router ID: %s", buf
);
562 ospf6_lsa_show_body_as_external (struct vty
*vty
,
563 struct ospf6_lsa_header
*lsa_header
)
565 struct ospf6_as_external_lsa
*elsa
;
570 elsa
= (struct ospf6_as_external_lsa
*)(lsa_header
+ 1);
573 snprintf (buf
, sizeof (buf
), "%s%s%s",
574 (ASE_LSA_ISSET (elsa
, ASE_LSA_BIT_E
) ? "E" : "-"),
575 (ASE_LSA_ISSET (elsa
, ASE_LSA_BIT_F
) ? "F" : "-"),
576 (ASE_LSA_ISSET (elsa
, ASE_LSA_BIT_T
) ? "T" : "-"));
578 vty_out (vty
, " Bits: %s%s", buf
, VTY_NEWLINE
);
579 vty_out (vty
, " Metric: %5hu%s", ntohs (elsa
->ase_metric
), VTY_NEWLINE
);
581 ospf6_prefix_options_str (&elsa
->ospf6_prefix
, buf
, sizeof (buf
));
582 vty_out (vty
, " Prefix Options: %s%s", buf
, VTY_NEWLINE
);
584 vty_out (vty
, " Referenced LSType: %d%s",
585 ntohs (elsa
->ospf6_prefix
.prefix_refer_lstype
), VTY_NEWLINE
);
587 ospf6_prefix_in6_addr (&elsa
->ospf6_prefix
, &in6
);
588 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
589 vty_out (vty
, " Prefix: %s/%d%s",
590 buf
, elsa
->ospf6_prefix
.prefix_length
, VTY_NEWLINE
);
592 /* Forwarding-Address */
593 if (ASE_LSA_ISSET (elsa
, ASE_LSA_BIT_F
))
595 ptr
= ((char *)(elsa
+ 1))
596 + OSPF6_PREFIX_SPACE (elsa
->ospf6_prefix
.prefix_length
);
597 inet_ntop (AF_INET6
, (struct in6_addr
*) ptr
, buf
, sizeof (buf
));
598 vty_out (vty
, " Forwarding-Address: %s%s", buf
, VTY_NEWLINE
);
603 ospf6_lsa_show_body_group_membership (struct vty
*vty
,
604 struct ospf6_lsa_header
*lsa_header
)
609 ospf6_lsa_show_body_type_7 (struct vty
*vty
,
610 struct ospf6_lsa_header
*lsa_header
)
615 ospf6_lsa_show_body_link (struct vty
*vty
,
616 struct ospf6_lsa_header
*lsa_header
)
618 struct ospf6_link_lsa
*llsap
;
620 struct ospf6_prefix
*prefix
;
626 llsap
= (struct ospf6_link_lsa
*) (lsa_header
+ 1);
627 prefixnum
= ntohl (llsap
->llsa_prefix_num
);
629 inet_ntop (AF_INET6
, (void *)&llsap
->llsa_linklocal
, buf
, sizeof (buf
));
630 vty_out (vty
, " LinkLocal Address: %s%s", buf
, VTY_NEWLINE
);
631 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VTY_NEWLINE
);
633 prefix
= (struct ospf6_prefix
*)(llsap
+ 1);
637 ospf6_prefix_options_str (prefix
, buf
, sizeof (buf
));
638 vty_out (vty
, " Prefix Options: %s%s", buf
, VTY_NEWLINE
);
640 ospf6_prefix_in6_addr (prefix
, &in6
);
641 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
642 vty_out (vty
, " Prefix: %s/%d%s",
643 buf
, prefix
->prefix_length
, VTY_NEWLINE
);
645 prefix
= OSPF6_NEXT_PREFIX (prefix
);
650 ospf6_lsa_show_body_intra_prefix (struct vty
*vty
,
651 struct ospf6_lsa_header
*lsa_header
)
653 struct ospf6_intra_area_prefix_lsa
*iap_lsa
;
654 struct ospf6_prefix
*prefix
;
655 unsigned short prefixnum
;
660 iap_lsa
= (struct ospf6_intra_area_prefix_lsa
*) (lsa_header
+ 1);
661 prefixnum
= ntohs (iap_lsa
->prefix_number
);
663 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VTY_NEWLINE
);
664 vty_out (vty
, " Referenced LS Type: %s%s",
665 ospf6_lsa_type_string (iap_lsa
->refer_lstype
),
667 vty_out (vty
, " Referenced LS ID: %d%s",
668 ntohl (iap_lsa
->refer_lsid
), VTY_NEWLINE
);
669 inet_ntop (AF_INET
, &iap_lsa
->refer_advrtr
, buf
, sizeof (buf
));
670 vty_out (vty
, " Referenced Advertising Router: %s%s",
673 prefix
= (struct ospf6_prefix
*)(iap_lsa
+ 1);
676 ospf6_prefix_options_str (prefix
, buf
, sizeof (buf
));
677 vty_out (vty
, " Prefix Options: %s%s", buf
, VTY_NEWLINE
);
679 ospf6_prefix_in6_addr (prefix
, &in6
);
680 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
681 vty_out (vty
, " Prefix: %s/%d%s",
682 buf
, prefix
->prefix_length
, VTY_NEWLINE
);
684 prefix
= OSPF6_NEXT_PREFIX (prefix
);
689 (*ospf6_lsa_show_body
[OSPF6_LSA_TYPE_MAX
]) (struct vty
*,
690 struct ospf6_lsa_header
*) =
692 ospf6_lsa_show_body_unknown
,
693 ospf6_lsa_show_body_router
,
694 ospf6_lsa_show_body_network
,
695 ospf6_lsa_show_body_inter_prefix
,
696 ospf6_lsa_show_body_inter_router
,
697 ospf6_lsa_show_body_as_external
,
698 ospf6_lsa_show_body_group_membership
,
699 ospf6_lsa_show_body_type_7
,
700 ospf6_lsa_show_body_link
,
701 ospf6_lsa_show_body_intra_prefix
,
705 ospf6_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
707 struct ospf6_lsa_header
*lsa_header
;
711 lsa_header
= (struct ospf6_lsa_header
*) lsa
->lsa_hdr
;
714 inet_ntop (AF_INET
, &lsa_header
->advrtr
, advrtr
, sizeof (advrtr
));
716 vty_out (vty
, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa
),
717 ospf6_lsa_type_string (lsa_header
->type
), VTY_NEWLINE
);
718 vty_out (vty
, "Link State ID: %d%s", ntohl (lsa_header
->ls_id
),
720 vty_out (vty
, "Advertising Router: %s%s", advrtr
, VTY_NEWLINE
);
721 vty_out (vty
, "LS Sequence Number: %#x%s", ntohl (lsa_header
->seqnum
),
723 vty_out (vty
, "CheckSum: %#hx Length: %hu%s", ntohs (lsa_header
->checksum
),
724 ntohs (lsa_header
->length
), VTY_NEWLINE
);
726 if (OSPF6_LSA_TYPESW_ISKNOWN (lsa_header
->type
))
727 (*ospf6_lsa_show_body
[OSPF6_LSA_TYPESW (lsa_header
->type
)])
730 ospf6_lsa_show_body_unknown (vty
, lsa_header
);
732 vty_out (vty
, "%s", VTY_NEWLINE
);
735 /* OSPFv3 LSA creation/deletion function */
737 /* calculate LS sequence number for my new LSA.
738 return value is network byte order */
740 ospf6_seqnum_new (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
)
742 struct ospf6_lsa
*lsa
;
745 /* get current database copy */
746 lsa
= ospf6_lsdb_lookup (type
, id
, adv_router
);
748 /* if current database copy not found, return InitialSequenceNumber */
750 seqnum
= INITIAL_SEQUENCE_NUMBER
;
752 seqnum
= (signed long) ntohl (lsa
->header
->seqnum
) + 1;
754 return (htonl (seqnum
));
758 ospf6_lsa_header_set (u_int16_t type
, u_int32_t ls_id
, u_int32_t advrtr
,
759 struct ospf6_lsa_header
*lsa_header
, int bodysize
)
761 /* fill LSA header */
763 lsa_header
->type
= type
;
764 lsa_header
->ls_id
= ls_id
;
765 lsa_header
->advrtr
= advrtr
;
767 ospf6_seqnum_new (lsa_header
->type
, lsa_header
->ls_id
,
769 lsa_header
->length
= htons (sizeof (struct ospf6_lsa_header
) + bodysize
);
772 ospf6_lsa_checksum (lsa_header
);
776 ospf6_lsa_create (struct ospf6_lsa_header
*source
)
778 struct ospf6_lsa
*lsa
= NULL
;
779 struct ospf6_lsa_header
*lsa_header
= NULL
;
780 u_int16_t lsa_size
= 0;
783 /* whole length of this LSA */
784 lsa_size
= ntohs (source
->length
);
786 /* allocate memory for this LSA */
787 lsa_header
= (struct ospf6_lsa_header
*)
788 XMALLOC (MTYPE_OSPF6_LSA
, lsa_size
);
791 zlog_err ("Lsa: Can't allocate memory for LSA Header");
792 return (struct ospf6_lsa
*) NULL
;
794 memset (lsa_header
, 0, lsa_size
);
796 /* copy LSA from source */
797 memcpy (lsa_header
, source
, lsa_size
);
799 /* LSA information structure */
800 /* allocate memory */
801 lsa
= (struct ospf6_lsa
*)
802 XMALLOC (MTYPE_OSPF6_LSA
, sizeof (struct ospf6_lsa
));
803 memset (lsa
, 0, sizeof (struct ospf6_lsa
));
806 snprintf (lsa
->str
, sizeof (lsa
->str
), "%s(%s[%lu])",
807 ospf6_lsa_type_string (lsa_header
->type
),
808 inet_ntop (AF_INET
, &lsa_header
->advrtr
, buf
, sizeof (buf
)),
809 (unsigned long) ntohl (lsa_header
->ls_id
));
811 lsa
->lsa_hdr
= (struct ospf6_lsa_hdr
*) lsa_header
;
812 lsa
->header
= (struct ospf6_lsa_header__
*) lsa_header
;
814 lsa
->summary
= 0; /* this is not LSA summary */
816 /* calculate birth, expire and refresh of this lsa */
817 ospf6_lsa_age_set (lsa
);
820 if (IS_OSPF6_DUMP_LSA
)
821 zlog_info ("Lsa: created %s(%#x)", lsa
->str
, lsa
);
828 ospf6_lsa_summary_create (struct ospf6_lsa_header__
*source
)
830 struct ospf6_lsa
*lsa
= NULL
;
831 struct ospf6_lsa_header
*lsa_header
= NULL
;
832 u_int16_t lsa_size
= 0;
835 /* LSA summary contains LSA Header only */
836 lsa_size
= sizeof (struct ospf6_lsa_header
);
838 /* allocate memory for this LSA */
839 lsa_header
= (struct ospf6_lsa_header
*)
840 XMALLOC (MTYPE_OSPF6_LSA_SUMMARY
, lsa_size
);
841 memset (lsa_header
, 0, lsa_size
);
843 /* copy LSA from source */
844 memcpy (lsa_header
, source
, lsa_size
);
846 /* LSA information structure */
847 /* allocate memory */
848 lsa
= (struct ospf6_lsa
*)
849 XMALLOC (MTYPE_OSPF6_LSA_SUMMARY
, sizeof (struct ospf6_lsa
));
850 memset (lsa
, 0, sizeof (struct ospf6_lsa
));
853 snprintf (lsa
->str
, sizeof (lsa
->str
), "%s(%s[%lu])[S]",
854 ospf6_lsa_type_string (lsa_header
->type
),
855 inet_ntop (AF_INET
, &lsa_header
->advrtr
, buf
, sizeof (buf
)),
856 (unsigned long) ntohl (lsa_header
->ls_id
));
858 lsa
->lsa_hdr
= (struct ospf6_lsa_hdr
*) lsa_header
;
859 lsa
->header
= (struct ospf6_lsa_header__
*) lsa_header
;
861 lsa
->summary
= 1; /* this is LSA summary */
863 /* calculate birth, expire and refresh of this lsa */
864 ospf6_lsa_age_set (lsa
);
867 if (IS_OSPF6_DUMP_LSA
)
868 zlog_info ("Lsa: created summary %s(%#x)", lsa
->str
, lsa
);
875 ospf6_lsa_delete (struct ospf6_lsa
*lsa
)
877 /* just to make sure */
880 zlog_err ("Can't delete %s: lock: %ld", lsa
->str
, lsa
->lock
);
886 thread_cancel (lsa
->expire
);
887 lsa
->expire
= (struct thread
*) NULL
;
889 thread_cancel (lsa
->refresh
);
890 lsa
->refresh
= (struct thread
*) NULL
;
892 if (IS_OSPF6_DUMP_LSA
)
895 zlog_info ("LSA: delete summary %s(%p)", lsa
->str
, lsa
);
897 zlog_info ("LSA: delete %s(%p)", lsa
->str
, lsa
);
902 XFREE (MTYPE_OSPF6_LSA_SUMMARY
, lsa
->header
);
904 XFREE (MTYPE_OSPF6_LSA
, lsa
->header
);
908 XFREE (MTYPE_OSPF6_LSA_SUMMARY
, lsa
);
910 XFREE (MTYPE_OSPF6_LSA
, lsa
);
913 /* increment reference counter of struct ospf6_lsa */
915 ospf6_lsa_lock (struct ospf6_lsa
*lsa
)
921 /* decrement reference counter of struct ospf6_lsa */
923 ospf6_lsa_unlock (struct ospf6_lsa
*lsa
)
925 /* decrement reference counter */
929 zlog_warn ("Can't unlock %s: already no lock", lsa
->str
);
932 /* check necessity to update LSA:
933 returns 1 if it's necessary to reoriginate */
935 ospf6_lsa_is_really_reoriginate (struct ospf6_lsa
*new)
937 struct ospf6_lsa
*old
;
940 /* find previous LSA */
941 old
= ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
942 new->header
->adv_router
);
946 /* Check if this is refresh */
947 if (old
->refresh
== (struct thread
*) NULL
)
949 zlog_warn ("LSA: reoriginate: %s: cause it's refresh", new->str
);
953 /* Are these contents different ? */
954 diff
= ospf6_lsa_differ (new, old
);
959 if (IS_OSPF6_DUMP_LSA
)
960 zlog_info ("LSA: Suppress updating %s", new->str
);
964 /* RFC2740 3.4.3.1 Router-LSA */
966 ospf6_lsa_update_router (u_int32_t area_id
)
968 char buffer
[MAXLSASIZE
];
970 struct ospf6_lsa
*lsa
, *prev_lsa
;
971 struct ospf6_area
*o6a
;
974 struct ospf6_router_lsa
*router_lsa
;
975 struct ospf6_router_lsd
*router_lsd
;
977 struct ospf6_interface
*o6i
;
978 struct ospf6_neighbor
*o6n
= NULL
;
980 o6a
= ospf6_area_lookup (area_id
, ospf6
);
983 inet_ntop (AF_INET
, &area_id
, buffer
, sizeof (buffer
));
984 zlog_warn ("LSA: Update Router-LSA: No such area: %s", buffer
);
988 if (IS_OSPF6_DUMP_LSA
)
989 zlog_info ("Lsa: Update Router-LSA for %s", o6a
->str
);
991 /* find previous LSA */
992 prev_lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_ROUTER
),
993 htonl (0), o6a
->ospf6
->router_id
);
995 size
= sizeof (struct ospf6_router_lsa
);
996 memset (buffer
, 0, sizeof (buffer
));
997 router_lsa
= (struct ospf6_router_lsa
*)
998 (buffer
+ sizeof (struct ospf6_lsa_header
));
1000 OSPF6_OPT_CLEAR_ALL (router_lsa
->options
);
1001 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_V6
);
1002 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_E
);
1003 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_MC
);
1004 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_N
);
1005 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_R
);
1006 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_DC
);
1008 OSPF6_ROUTER_LSA_CLEAR_ALL_BITS (router_lsa
);
1009 OSPF6_ROUTER_LSA_CLEAR (router_lsa
, OSPF6_ROUTER_LSA_BIT_B
);
1011 if (ospf6_is_asbr (o6a
->ospf6
))
1012 OSPF6_ROUTER_LSA_SET (router_lsa
, OSPF6_ROUTER_LSA_BIT_E
);
1014 OSPF6_ROUTER_LSA_CLEAR (router_lsa
, OSPF6_ROUTER_LSA_BIT_E
);
1016 OSPF6_ROUTER_LSA_CLEAR (router_lsa
, OSPF6_ROUTER_LSA_BIT_V
);
1017 OSPF6_ROUTER_LSA_CLEAR (router_lsa
, OSPF6_ROUTER_LSA_BIT_W
);
1019 /* describe links for each interfaces */
1020 router_lsd
= (struct ospf6_router_lsd
*) (router_lsa
+ 1);
1021 for (i
= listhead (o6a
->if_list
); i
; nextnode (i
))
1023 o6i
= (struct ospf6_interface
*) getdata (i
);
1026 /* Interfaces in state Down or Loopback are not described */
1027 if (o6i
->state
== IFS_DOWN
|| o6i
->state
== IFS_LOOPBACK
)
1030 /* Nor are interfaces without any full adjacencies described */
1032 o6i
->foreach_nei (o6i
, &count
, NBS_FULL
, ospf6_count_state
);
1036 /* Point-to-Point interfaces */
1037 if (if_is_pointopoint (o6i
->interface
))
1039 if (listcount (o6i
->neighbor_list
) == 0)
1042 if (listcount (o6i
->neighbor_list
) != 1)
1043 zlog_warn ("LSA: Multiple neighbors on PoinToPoint: %s",
1044 o6i
->interface
->name
);
1046 o6n
= (struct ospf6_neighbor
*)
1047 getdata (listhead (o6i
->neighbor_list
));
1050 router_lsd
->type
= OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT
;
1051 router_lsd
->metric
= htons (o6i
->cost
);
1052 router_lsd
->interface_id
= htonl (o6i
->if_id
);
1053 router_lsd
->neighbor_interface_id
= htonl (o6n
->ifid
);
1054 router_lsd
->neighbor_router_id
= o6n
->router_id
;
1056 size
+= sizeof (struct ospf6_router_lsd
);
1062 /* Broadcast and NBMA interfaces */
1063 if (if_is_broadcast (o6i
->interface
))
1065 /* If this router is not DR,
1066 and If this router not fully adjacent with DR,
1067 this interface is not transit yet: ignore. */
1068 if (o6i
->state
!= IFS_DR
)
1070 o6n
= ospf6_neighbor_lookup (o6i
->dr
, o6i
); /* find DR */
1072 if (o6n
->state
!= NBS_FULL
)
1078 o6i
->foreach_nei (o6i
, &count
, NBS_FULL
, ospf6_count_state
);
1083 router_lsd
->type
= OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK
;
1084 router_lsd
->metric
= htons (o6i
->cost
);
1085 router_lsd
->interface_id
= htonl (o6i
->if_id
);
1086 if (o6i
->state
!= IFS_DR
)
1088 router_lsd
->neighbor_interface_id
= htonl (o6n
->ifid
);
1089 router_lsd
->neighbor_router_id
= o6n
->router_id
;
1093 router_lsd
->neighbor_interface_id
= htonl (o6i
->if_id
);
1094 router_lsd
->neighbor_router_id
= o6i
->area
->ospf6
->router_id
;
1097 size
+= sizeof (struct ospf6_router_lsd
);
1105 /* Point-to-Multipoint interfaces */
1109 /* Fill LSA Header */
1110 ospf6_lsa_header_set (htons (OSPF6_LSA_TYPE_ROUTER
), htonl (0),
1111 o6a
->ospf6
->router_id
,
1112 (struct ospf6_lsa_header
*)buffer
, size
);
1115 lsa
= ospf6_lsa_create ((struct ospf6_lsa_header
*) buffer
);
1116 lsa
->refresh
= thread_add_timer (master
, ospf6_lsa_refresh
, lsa
,
1117 OSPF6_LS_REFRESH_TIME
);
1118 lsa
->scope
= (void *) o6a
;
1120 if (ospf6_lsa_is_really_reoriginate (lsa
))
1122 ospf6_dbex_remove_from_all_retrans_list (lsa
);
1123 ospf6_dbex_flood (lsa
, NULL
);
1124 ospf6_lsdb_install (lsa
);
1127 ospf6_lsa_delete (lsa
);
1130 /* RFC2740 3.4.3.2 Network-LSA */
1132 ospf6_lsa_update_network (char *ifname
)
1134 char buffer
[MAXLSASIZE
];
1136 struct ospf6_lsa
*lsa
, *prev_lsa
;
1137 struct interface
*ifp
;
1138 struct ospf6_interface
*o6i
;
1141 struct ospf6_network_lsa
*nlsa
;
1143 struct ospf6_neighbor
*o6n
;
1144 u_int32_t
*router_id
;
1146 ifp
= if_lookup_by_name (ifname
);
1149 zlog_warn ("LSA: Update Network: No such Interface: %s", ifname
);
1152 o6i
= (struct ospf6_interface
*) ifp
->info
;
1155 zlog_warn ("LSA: Update Network: Interface not enabled: %s", ifname
);
1159 /* find previous LSA */
1160 prev_lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_NETWORK
),
1162 o6i
->area
->ospf6
->router_id
);
1164 /* Don't originate Network-LSA if not DR */
1165 if (o6i
->state
!= IFS_DR
)
1167 if (IS_OSPF6_DUMP_LSA
)
1168 zlog_info ("LSA Update Network: Interface %s is not DR",
1169 o6i
->interface
->name
);
1171 ospf6_lsa_premature_aging (prev_lsa
);
1175 /* If none of neighbor is adjacent to us */
1177 o6i
->foreach_nei (o6i
, &count
, NBS_FULL
, ospf6_count_state
);
1180 if (IS_OSPF6_DUMP_LSA
)
1181 zlog_info ("LSA Update Network: Interface %s is Stub",
1182 o6i
->interface
->name
);
1184 ospf6_lsa_premature_aging (prev_lsa
);
1188 if (IS_OSPF6_DUMP_LSA
)
1189 zlog_info ("LSA Update Network: Interface %s", o6i
->interface
->name
);
1191 /* prepare buffer */
1192 size
= sizeof (struct ospf6_network_lsa
);
1193 memset (buffer
, 0, sizeof (buffer
));
1194 nlsa
= (struct ospf6_network_lsa
*)
1195 (buffer
+ sizeof (struct ospf6_lsa_header
));
1196 router_id
= (u_int32_t
*)(nlsa
+ 1);
1198 /* set fields of myself */
1199 *router_id
++ = o6i
->area
->ospf6
->router_id
;
1200 size
+= sizeof (u_int32_t
);
1201 nlsa
->options
[0] |= o6i
->area
->options
[0];
1202 nlsa
->options
[1] |= o6i
->area
->options
[1];
1203 nlsa
->options
[2] |= o6i
->area
->options
[2];
1205 /* Walk through neighbors */
1206 for (i
= listhead (o6i
->neighbor_list
); i
; nextnode (i
))
1208 o6n
= (struct ospf6_neighbor
*) getdata (i
);
1210 if (o6n
->state
!= NBS_FULL
)
1213 /* set this neighbor's Router-ID to LSA */
1214 *router_id
++ = o6n
->router_id
;
1215 size
+= sizeof (u_int32_t
);
1217 /* options field is logical OR */
1218 nlsa
->options
[0] |= o6n
->options
[0];
1219 nlsa
->options
[1] |= o6n
->options
[1];
1220 nlsa
->options
[2] |= o6n
->options
[2];
1223 /* Fill LSA Header */
1224 ospf6_lsa_header_set (htons (OSPF6_LSA_TYPE_NETWORK
), htonl (o6i
->if_id
),
1225 o6i
->area
->ospf6
->router_id
,
1226 (struct ospf6_lsa_header
*) buffer
, size
);
1229 lsa
= ospf6_lsa_create ((struct ospf6_lsa_header
*) buffer
);
1230 lsa
->refresh
= thread_add_timer (master
, ospf6_lsa_refresh
, lsa
,
1231 OSPF6_LS_REFRESH_TIME
);
1232 lsa
->scope
= (void *) o6i
->area
;
1234 if (ospf6_lsa_is_really_reoriginate (lsa
))
1236 ospf6_dbex_remove_from_all_retrans_list (lsa
);
1237 ospf6_dbex_flood (lsa
, NULL
);
1238 ospf6_lsdb_install (lsa
);
1241 ospf6_lsa_delete (lsa
);
1244 /* RFC2740 3.4.3.5 AS-External-LSA */
1246 ospf6_lsa_update_as_external (u_int32_t lsid
)
1248 char buffer
[MAXLSASIZE
];
1250 struct ospf6_lsa
*lsa
, *prev_lsa
;
1252 struct ospf6_as_external_lsa
*elsa
;
1253 struct route_node
*rn
, *target
;
1254 struct ospf6_redistribute_info
*info
= NULL
;
1257 /* find previous LSA */
1258 prev_lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_AS_EXTERNAL
),
1259 ntohl (lsid
), ospf6
->router_id
);
1261 /* find corresponding route node */
1263 for (rn
= route_top (ospf6
->external_table
); rn
; rn
= route_next (rn
))
1265 info
= (struct ospf6_redistribute_info
*) rn
->info
;
1266 if (info
&& info
->id
== lsid
)
1272 if (IS_OSPF6_DUMP_LSA
)
1273 zlog_info ("LSA: Don't create AS-External-LSA for ID %d: No entry",
1278 zlog_info ("LSA: Delete old Self-originated AS-External-LSA");
1279 ospf6_lsa_premature_aging (prev_lsa
);
1284 if (IS_OSPF6_DUMP_LSA
)
1285 zlog_info ("LSA Update AS-External: ID:%d", lsid
);
1287 /* prepare buffer */
1288 size
= sizeof (struct ospf6_as_external_lsa
);
1289 memset (buffer
, 0, sizeof (buffer
));
1290 elsa
= (struct ospf6_as_external_lsa
*)
1291 (buffer
+ sizeof (struct ospf6_lsa_header
));
1292 p
= (char *) (elsa
+ 1);
1294 info
= (struct ospf6_redistribute_info
*) target
->info
;
1295 if (info
->metric_type
== 2)
1296 ASE_LSA_SET (elsa
, ASE_LSA_BIT_E
); /* type2 */
1298 ASE_LSA_CLEAR (elsa
, ASE_LSA_BIT_E
); /* type1 */
1300 if (! IN6_IS_ADDR_UNSPECIFIED (&info
->forward
))
1301 ASE_LSA_SET (elsa
, ASE_LSA_BIT_F
); /* forwarding address */
1303 ASE_LSA_CLEAR (elsa
, ASE_LSA_BIT_F
); /* forwarding address */
1305 ASE_LSA_CLEAR (elsa
, ASE_LSA_BIT_T
); /* external route tag */
1307 /* don't know how to use */
1308 elsa
->ase_pre_metric
= 0;
1310 /* set metric. note: related to E bit */
1311 elsa
->ase_metric
= htons (info
->metric
);
1314 elsa
->ospf6_prefix
.prefix_length
= target
->p
.prefixlen
;
1317 elsa
->ospf6_prefix
.prefix_options
= info
->prefix_options
;
1319 /* don't use refer LS-type */
1320 elsa
->ospf6_prefix
.prefix_refer_lstype
= htons (0);
1323 memcpy (p
, &target
->p
.u
.prefix6
, OSPF6_PREFIX_SPACE (target
->p
.prefixlen
));
1324 ospf6_prefix_apply_mask (&elsa
->ospf6_prefix
);
1325 size
+= OSPF6_PREFIX_SPACE (target
->p
.prefixlen
);
1326 p
+= OSPF6_PREFIX_SPACE (target
->p
.prefixlen
);
1328 /* Forwarding address */
1329 if (ASE_LSA_ISSET (elsa
, ASE_LSA_BIT_F
))
1331 memcpy (p
, &info
->forward
, sizeof (struct in6_addr
));
1332 size
+= sizeof (struct in6_addr
);
1333 p
+= sizeof (struct in6_addr
);
1336 /* External Route Tag */
1337 if (ASE_LSA_ISSET (elsa
, ASE_LSA_BIT_T
))
1342 /* Fill LSA Header */
1343 ospf6_lsa_header_set (htons (OSPF6_LSA_TYPE_AS_EXTERNAL
), htonl (lsid
),
1345 (struct ospf6_lsa_header
*) buffer
, size
);
1348 lsa
= ospf6_lsa_create ((struct ospf6_lsa_header
*) buffer
);
1349 lsa
->refresh
= thread_add_timer (master
, ospf6_lsa_refresh
, lsa
,
1350 OSPF6_LS_REFRESH_TIME
);
1351 lsa
->scope
= (void *) ospf6
;
1353 if (ospf6_lsa_is_really_reoriginate (lsa
))
1355 ospf6_dbex_remove_from_all_retrans_list (lsa
);
1356 ospf6_dbex_flood (lsa
, NULL
);
1357 ospf6_lsdb_install (lsa
);
1360 ospf6_lsa_delete (lsa
);
1363 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
1365 ospf6_lsa_update_intra_prefix_transit (char *ifname
)
1367 char buffer
[MAXLSASIZE
];
1369 struct ospf6_lsa
*lsa
, *prev_lsa
;
1370 struct interface
*ifp
;
1371 struct ospf6_interface
*o6i
;
1374 struct ospf6_intra_area_prefix_lsa
*intra_prefix_lsa
;
1375 struct ospf6_lsdb_node
*node
;
1376 struct ospf6_neighbor
*o6n
;
1377 struct ospf6_prefix
*o6_pstart
, *o6_pcurrent
, *o6_p1
, *o6_p2
;
1378 struct ospf6_link_lsa
*link_body
;
1379 u_int16_t prefix_number
, link_prefix_number
;
1380 struct in6_addr in6
;
1384 ifp
= if_lookup_by_name (ifname
);
1387 zlog_warn ("LSA: Update Intra-Area-Prefix-LSA(Transit): "
1388 "No such Interface: %s", ifname
);
1391 o6i
= (struct ospf6_interface
*) ifp
->info
;
1394 zlog_warn ("LSA: Update Intra-Area-Prefix-LSA(Transit): "
1395 "Interface not enabled: %s", ifname
);
1399 /* find previous LSA */
1400 prev_lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_INTRA_PREFIX
),
1402 o6i
->area
->ospf6
->router_id
);
1404 /* Don't originate Network-LSA if not DR */
1405 if (o6i
->state
!= IFS_DR
)
1407 if (IS_OSPF6_DUMP_LSA
)
1408 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1409 "Interface %s is not DR", o6i
->interface
->name
);
1411 ospf6_lsa_premature_aging (prev_lsa
);
1415 /* If none of neighbor is adjacent to us */
1417 o6i
->foreach_nei (o6i
, &count
, NBS_FULL
, ospf6_count_state
);
1420 if (IS_OSPF6_DUMP_LSA
)
1421 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1422 "Interface %s is Stub", o6i
->interface
->name
);
1424 ospf6_lsa_premature_aging (prev_lsa
);
1428 if (IS_OSPF6_DUMP_LSA
)
1429 zlog_info ("LSA Update Intra-Area-Prefix(Transit): Interface %s",
1430 o6i
->interface
->name
);
1432 /* prepare buffer */
1433 size
= sizeof (struct ospf6_intra_area_prefix_lsa
);
1434 memset (buffer
, 0, sizeof (buffer
));
1435 intra_prefix_lsa
= (struct ospf6_intra_area_prefix_lsa
*)
1436 (buffer
+ sizeof (struct ospf6_lsa_header
));
1437 o6_pstart
= (struct ospf6_prefix
*)(intra_prefix_lsa
+ 1);
1438 o6_pcurrent
= o6_pstart
;
1441 /* Set Referenced LSA field */
1442 intra_prefix_lsa
->refer_lstype
= htons (OSPF6_LSA_TYPE_NETWORK
);
1443 intra_prefix_lsa
->refer_lsid
= htonl (o6i
->if_id
);
1444 intra_prefix_lsa
->refer_advrtr
= o6i
->area
->ospf6
->router_id
;
1446 /* foreach Link-LSA associated with this Link */
1447 for (node
= ospf6_lsdb_head (o6i
->lsdb
); node
; node
= ospf6_lsdb_next (node
))
1449 if (node
->lsa
->header
->type
!= htons (OSPF6_LSA_TYPE_LINK
))
1452 if (ospf6_lsa_is_maxage (node
->lsa
))
1455 if (IS_OSPF6_DUMP_LSA
)
1456 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1457 "Checking %s", node
->lsa
->str
);
1459 if (node
->lsa
->header
->adv_router
!= o6i
->area
->ospf6
->router_id
)
1461 o6n
= ospf6_neighbor_lookup (node
->lsa
->header
->adv_router
, o6i
);
1462 if (! o6n
|| o6n
->state
!= NBS_FULL
)
1464 if (IS_OSPF6_DUMP_LSA
)
1465 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1466 "neighbor not found or not FULL");
1471 /* For each Prefix in this Link-LSA */
1472 link_body
= (struct ospf6_link_lsa
*) (node
->lsa
->header
+ 1);
1473 link_prefix_number
= ntohl (link_body
->llsa_prefix_num
);
1475 if (IS_OSPF6_DUMP_LSA
)
1476 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1477 "Prefix #%d", link_prefix_number
);
1479 for (o6_p1
= (struct ospf6_prefix
*) (link_body
+ 1);
1480 link_prefix_number
; link_prefix_number
--)
1482 ospf6_prefix_in6_addr (o6_p1
, &in6
);
1483 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
1485 if (IS_OSPF6_DUMP_LSA
)
1486 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1489 /* filter linklocal prefix */
1490 if (IN6_IS_ADDR_LINKLOCAL (&in6
))
1492 if (IS_OSPF6_DUMP_LSA
)
1493 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1494 "%s is Linklocal", buf
);
1495 o6_p1
= OSPF6_NEXT_PREFIX (o6_p1
);
1499 /* filter unspecified(default) prefix */
1500 if (IN6_IS_ADDR_UNSPECIFIED (&in6
))
1502 if (IS_OSPF6_DUMP_LSA
)
1503 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1504 "%s is Unspecified", buf
);
1505 o6_p1
= OSPF6_NEXT_PREFIX (o6_p1
);
1509 /* filter loopback prefix */
1510 if (IN6_IS_ADDR_LOOPBACK (&in6
))
1512 if (IS_OSPF6_DUMP_LSA
)
1513 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1514 "%s is Loopback", buf
);
1515 o6_p1
= OSPF6_NEXT_PREFIX (o6_p1
);
1519 /* filter IPv4 compatible prefix */
1520 if (IN6_IS_ADDR_V4COMPAT (&in6
))
1522 if (IS_OSPF6_DUMP_LSA
)
1523 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1524 "%s is v4-Compatible", buf
);
1525 o6_p1
= OSPF6_NEXT_PREFIX (o6_p1
);
1529 /* filter IPv4 Mapped prefix */
1530 if (IN6_IS_ADDR_V4MAPPED (&in6
))
1532 if (IS_OSPF6_DUMP_LSA
)
1533 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1534 "%s is v4-Mapped", buf
);
1535 o6_p1
= OSPF6_NEXT_PREFIX (o6_p1
);
1539 /* Check duplicate prefix */
1541 for (o6_p2
= o6_pstart
; o6_p2
< o6_pcurrent
;
1542 o6_p2
= OSPF6_NEXT_PREFIX (o6_p2
))
1544 if (! ospf6_prefix_issame (o6_p1
, o6_p2
))
1548 o6_p2
->prefix_options
|= o6_p1
->prefix_options
;
1552 if (IS_OSPF6_DUMP_LSA
)
1553 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1554 "Duplicate %s", buf
);
1555 o6_p1
= OSPF6_NEXT_PREFIX (o6_p1
);
1559 /* copy prefix to new LSA */
1560 if (IS_OSPF6_DUMP_LSA
)
1561 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1562 "including %s", buf
);
1563 o6_pcurrent
->prefix_length
= o6_p1
->prefix_length
;
1564 o6_pcurrent
->prefix_options
= o6_p1
->prefix_options
;
1565 memcpy (o6_pcurrent
+ 1, o6_p1
+ 1,
1566 OSPF6_PREFIX_SPACE (o6_p1
->prefix_length
));
1568 size
+= OSPF6_PREFIX_SIZE (o6_pcurrent
);
1569 o6_pcurrent
= OSPF6_NEXT_PREFIX (o6_pcurrent
);
1570 o6_p1
= OSPF6_NEXT_PREFIX (o6_p1
);
1575 /* if no prefix to advertise, return */
1576 if (prefix_number
== 0)
1578 if (IS_OSPF6_DUMP_LSA
)
1579 zlog_info ("LSA Update Intra-Area-Prefix(Transit): "
1580 "No Prefix to advertise");
1584 intra_prefix_lsa
->prefix_number
= htons (prefix_number
);
1586 /* Fill LSA Header */
1587 ospf6_lsa_header_set (htons (OSPF6_LSA_TYPE_INTRA_PREFIX
),
1589 o6i
->area
->ospf6
->router_id
,
1590 (struct ospf6_lsa_header
*) buffer
, size
);
1593 lsa
= ospf6_lsa_create ((struct ospf6_lsa_header
*) buffer
);
1594 lsa
->refresh
= thread_add_timer (master
, ospf6_lsa_refresh
, lsa
,
1595 OSPF6_LS_REFRESH_TIME
);
1596 lsa
->scope
= (void *) o6i
->area
;
1598 if (ospf6_lsa_is_really_reoriginate (lsa
))
1600 ospf6_dbex_remove_from_all_retrans_list (lsa
);
1601 ospf6_dbex_flood (lsa
, NULL
);
1602 ospf6_lsdb_install (lsa
);
1605 ospf6_lsa_delete (lsa
);
1608 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
1610 ospf6_lsa_update_intra_prefix_stub (u_int32_t area_id
)
1612 char buffer
[MAXLSASIZE
];
1614 struct ospf6_lsa
*lsa
, *prev_lsa
;
1615 struct ospf6_area
*o6a
;
1618 struct ospf6_intra_area_prefix_lsa
*intra_prefix_lsa
;
1620 struct ospf6_interface
*o6i
= NULL
;
1621 struct ospf6_prefix
*prefix_dst
;
1622 struct connected
*c
;
1623 struct prefix_ipv6 prefix_ipv6
;
1625 u_int16_t prefix_number
;
1627 o6a
= ospf6_area_lookup (area_id
, ospf6
);
1630 inet_ntop (AF_INET
, &area_id
, buffer
, sizeof (buffer
));
1631 zlog_warn ("LSA: Update Intra-Area-Prefix-LSA(Stub): "
1632 "No such area: %s", buffer
);
1636 /* find previous LSA */
1637 prev_lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_INTRA_PREFIX
),
1638 htonl (0), /* xxx */
1639 o6a
->ospf6
->router_id
);
1641 /* prepare buffer */
1642 size
= sizeof (struct ospf6_intra_area_prefix_lsa
);
1643 memset (buffer
, 0, sizeof (buffer
));
1644 intra_prefix_lsa
= (struct ospf6_intra_area_prefix_lsa
*)
1645 (buffer
+ sizeof (struct ospf6_lsa_header
));
1646 prefix_dst
= (struct ospf6_prefix
*)(intra_prefix_lsa
+ 1);
1649 /* Examin for each interface */
1650 for (i
= listhead (o6a
->if_list
); i
; nextnode (i
))
1652 o6i
= (struct ospf6_interface
*) getdata (i
);
1654 if (IS_OSPF6_DUMP_LSA
)
1655 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1656 "Checking Interface %s", o6i
->interface
->name
);
1658 if (o6i
->state
== IFS_DOWN
)
1660 if (IS_OSPF6_DUMP_LSA
)
1661 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1662 "Interface %s down", o6i
->interface
->name
);
1667 o6i
->foreach_nei (o6i
, &count
, NBS_FULL
, ospf6_count_state
);
1668 if (o6i
->state
!= IFS_LOOPBACK
&& o6i
->state
!= IFS_PTOP
&&
1671 /* This interface's prefix will be included in DR's */
1672 if (IS_OSPF6_DUMP_LSA
)
1673 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1674 "Interface %s is not stub", o6i
->interface
->name
);
1678 /* copy foreach site-local or global prefix */
1679 for (j
= listhead (o6i
->interface
->connected
); j
; nextnode (j
))
1681 c
= (struct connected
*) getdata (j
);
1683 /* filter prefix not IPv6 */
1684 if (c
->address
->family
!= AF_INET6
)
1687 inet_ntop (AF_INET6
, &c
->address
->u
.prefix6
, buf
, sizeof (buf
));
1689 if (IS_OSPF6_DUMP_LSA
)
1690 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1691 "Checking %s", buf
);
1693 /* filter linklocal prefix */
1694 if (IN6_IS_ADDR_LINKLOCAL (&c
->address
->u
.prefix6
))
1696 if (IS_OSPF6_DUMP_LSA
)
1697 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1698 "%s is Linklocal", buf
);
1702 /* filter unspecified(default) prefix */
1703 if (IN6_IS_ADDR_UNSPECIFIED (&c
->address
->u
.prefix6
))
1705 if (IS_OSPF6_DUMP_LSA
)
1706 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1707 "%s is Unspecified", buf
);
1711 /* filter loopback prefix */
1712 if (IN6_IS_ADDR_LOOPBACK (&c
->address
->u
.prefix6
))
1714 if (IS_OSPF6_DUMP_LSA
)
1715 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1716 "%s is Loopback", buf
);
1720 /* filter IPv4 compatible prefix */
1721 if (IN6_IS_ADDR_V4COMPAT (&c
->address
->u
.prefix6
))
1723 if (IS_OSPF6_DUMP_LSA
)
1724 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1725 "%s is v4-Compatible", buf
);
1729 /* filter IPv4 Mapped prefix */
1730 if (IN6_IS_ADDR_V4MAPPED (&c
->address
->u
.prefix6
))
1732 if (IS_OSPF6_DUMP_LSA
)
1733 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1734 "%s is v4-Mapped", buf
);
1738 /* set ospf6 prefix according to its state */
1739 /* xxx, virtual links */
1740 prefix_copy ((struct prefix
*) &prefix_ipv6
, c
->address
);
1741 if (o6i
->state
== IFS_LOOPBACK
|| o6i
->state
== IFS_PTOP
1742 /* xxx, PoinToMultiPoint I/F type */ )
1744 prefix_dst
->prefix_length
= 128;
1745 prefix_dst
->prefix_options
= OSPF6_PREFIX_OPTION_LA
;
1746 prefix_dst
->prefix_metric
= htons (0);
1747 memcpy (prefix_dst
+ 1, &prefix_ipv6
.prefix
,
1748 OSPF6_PREFIX_SPACE (prefix_dst
->prefix_length
));
1753 apply_mask_ipv6 (&prefix_ipv6
);
1754 inet_ntop (AF_INET6
, &c
->address
->u
.prefix6
, buf
, sizeof (buf
));
1756 prefix_dst
->prefix_length
= prefix_ipv6
.prefixlen
;
1757 prefix_dst
->prefix_options
= 0; /* xxx, no options yet */
1758 prefix_dst
->prefix_metric
= htons (o6i
->cost
);
1759 memcpy (prefix_dst
+ 1, &prefix_ipv6
.prefix
,
1760 OSPF6_PREFIX_SPACE (prefix_dst
->prefix_length
));
1763 if (IS_OSPF6_DUMP_LSA
)
1764 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1767 /* forward current buffer pointer */
1769 size
+= OSPF6_PREFIX_SIZE (prefix_dst
);
1770 prefix_dst
= OSPF6_NEXT_PREFIX (prefix_dst
);
1774 /* If no prefix to advertise */
1775 if (prefix_number
== 0)
1777 if (IS_OSPF6_DUMP_LSA
)
1778 zlog_info ("LSA Update Intra-Area-Prefix(Stub): "
1779 "No prefix to advertise for area %s", o6a
->str
);
1781 ospf6_lsa_premature_aging (prev_lsa
);
1785 if (IS_OSPF6_DUMP_LSA
)
1786 zlog_info ("LSA Update Intra-Area-Prefix(Stub): Area %s", o6a
->str
);
1788 /* Set Referenced LSA field */
1789 intra_prefix_lsa
->refer_lstype
= htons (OSPF6_LSA_TYPE_ROUTER
);
1790 intra_prefix_lsa
->refer_lsid
= htonl (0);
1791 intra_prefix_lsa
->refer_advrtr
= o6a
->ospf6
->router_id
;
1793 intra_prefix_lsa
->prefix_number
= htons (prefix_number
);
1795 /* Fill LSA Header */
1796 ospf6_lsa_header_set (htons (OSPF6_LSA_TYPE_INTRA_PREFIX
),
1797 htonl (0), /* xxx */
1798 o6i
->area
->ospf6
->router_id
,
1799 (struct ospf6_lsa_header
*) buffer
, size
);
1802 lsa
= ospf6_lsa_create ((struct ospf6_lsa_header
*) buffer
);
1803 lsa
->refresh
= thread_add_timer (master
, ospf6_lsa_refresh
, lsa
,
1804 OSPF6_LS_REFRESH_TIME
);
1805 lsa
->scope
= (void *) o6a
;
1807 if (ospf6_lsa_is_really_reoriginate (lsa
))
1809 ospf6_dbex_remove_from_all_retrans_list (lsa
);
1810 ospf6_dbex_flood (lsa
, NULL
);
1811 ospf6_lsdb_install (lsa
);
1814 ospf6_lsa_delete (lsa
);
1818 ospf6_lsa_update_link (char *ifname
)
1820 char *cp
, buffer
[MAXLSASIZE
];
1822 struct ospf6_lsa
*lsa
, *prev_lsa
;
1823 struct interface
*ifp
;
1824 struct ospf6_interface
*o6i
;
1826 struct ospf6_link_lsa
*llsa
;
1827 struct ospf6_prefix
*p
;
1828 list prefix_connected
;
1830 struct connected
*c
;
1832 ifp
= if_lookup_by_name (ifname
);
1835 if (IS_OSPF6_DUMP_LSA
)
1836 zlog_info ("LSA: Update Link-LSA: No such Interface: %s", ifname
);
1839 o6i
= (struct ospf6_interface
*) ifp
->info
;
1842 if (IS_OSPF6_DUMP_LSA
)
1843 zlog_info ("LSA: Update Link-LSA: Interface not enabled: %s", ifname
);
1847 /* find previous LSA */
1848 prev_lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_LINK
),
1852 /* can't make Link-LSA if linklocal address not set */
1855 zlog_err ("LSA Update Link: No Linklocal Address: %s",
1856 o6i
->interface
->name
);
1858 ospf6_lsa_premature_aging (prev_lsa
);
1862 if (IS_OSPF6_DUMP_LSA
)
1863 zlog_info ("LSA Update Link: Interface %s", o6i
->interface
->name
);
1865 /* check connected prefix */
1866 prefix_connected
= list_new ();
1867 for (n
= listhead (o6i
->interface
->connected
); n
; nextnode (n
))
1869 c
= (struct connected
*) getdata (n
);
1871 /* filter prefix not IPv6 */
1872 if (c
->address
->family
!= AF_INET6
)
1875 /* filter linklocal prefix */
1876 if (IN6_IS_ADDR_LINKLOCAL (&c
->address
->u
.prefix6
))
1879 /* filter unspecified(default) prefix */
1880 if (IN6_IS_ADDR_UNSPECIFIED (&c
->address
->u
.prefix6
))
1883 /* filter loopback prefix */
1884 if (IN6_IS_ADDR_LOOPBACK (&c
->address
->u
.prefix6
))
1887 /* filter IPv4 compatible prefix */
1888 if (IN6_IS_ADDR_V4COMPAT (&c
->address
->u
.prefix6
))
1891 /* filter IPv4 Mapped prefix */
1892 if (IN6_IS_ADDR_V4MAPPED (&c
->address
->u
.prefix6
))
1895 /* hold prefix in list. duplicate is filtered in ospf6_prefix_add() */
1896 p
= ospf6_prefix_make (0, 0, (struct prefix_ipv6
*) c
->address
);
1897 ospf6_prefix_add (prefix_connected
, p
);
1900 /* Note: if no prefix configured, still we have to create Link-LSA
1901 for next-hop resolution */
1903 /* fill Link LSA and calculate size */
1904 size
= sizeof (struct ospf6_link_lsa
);
1905 memset (buffer
, 0, sizeof (buffer
));
1906 llsa
= (struct ospf6_link_lsa
*)
1907 (buffer
+ sizeof (struct ospf6_lsa_header
));
1908 llsa
->llsa_rtr_pri
= o6i
->priority
;
1909 llsa
->llsa_options
[0] = o6i
->area
->options
[0];
1910 llsa
->llsa_options
[1] = o6i
->area
->options
[1];
1911 llsa
->llsa_options
[2] = o6i
->area
->options
[2];
1913 /* linklocal address */
1914 memcpy (&llsa
->llsa_linklocal
, o6i
->lladdr
, sizeof (struct in6_addr
));
1915 #ifdef KAME /* clear ifindex */
1916 if (llsa
->llsa_linklocal
.s6_addr
[3] & 0x0f)
1917 llsa
->llsa_linklocal
.s6_addr
[3] &= ~((char)0x0f);
1920 llsa
->llsa_prefix_num
= htonl (listcount (prefix_connected
));
1921 cp
= (char *)(llsa
+ 1);
1922 for (n
= listhead (prefix_connected
); n
; nextnode (n
))
1924 p
= (struct ospf6_prefix
*) getdata (n
);
1925 size
+= OSPF6_PREFIX_SIZE (p
);
1926 memcpy (cp
, p
, OSPF6_PREFIX_SIZE (p
));
1927 cp
+= OSPF6_PREFIX_SIZE (p
);
1930 for (n
= listhead (prefix_connected
); n
; nextnode (n
))
1932 p
= (struct ospf6_prefix
*) getdata (n
);
1933 ospf6_prefix_free (p
);
1935 list_delete (prefix_connected
);
1937 /* Fill LSA Header */
1938 ospf6_lsa_header_set (htons (OSPF6_LSA_TYPE_LINK
), htonl (o6i
->if_id
),
1939 o6i
->area
->ospf6
->router_id
,
1940 (struct ospf6_lsa_header
*) buffer
, size
);
1943 lsa
= ospf6_lsa_create ((struct ospf6_lsa_header
*) buffer
);
1944 lsa
->refresh
= thread_add_timer (master
, ospf6_lsa_refresh
, lsa
,
1945 OSPF6_LS_REFRESH_TIME
);
1946 lsa
->scope
= (void *) o6i
;
1948 if (ospf6_lsa_is_really_reoriginate (lsa
))
1950 ospf6_dbex_remove_from_all_retrans_list (lsa
);
1951 ospf6_dbex_flood (lsa
, NULL
);
1952 ospf6_lsdb_install (lsa
);
1955 ospf6_lsa_delete (lsa
);
1960 ospf6_lsa_update_inter_prefix (struct ospf6_area
*o6a
)
1962 char *cp
, buffer
[MAXLSASIZE
];
1964 struct ospf6_lsa
*lsa
, *prev_lsa
;
1966 struct ospf6_lsa_inter_prefix
*inter_prefix
;
1967 struct ospf6_prefix
*o6p
;
1969 /* find previous LSA */
1970 prev_lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_INTER_PREFIX
),
1971 htonl (0), /* xxx */
1974 if (o6a
->area_range
.prefixlen
== 0)
1976 zlog_err ("LSA Update Inter-Area-Prefix: No Area range Configured for %s",
1979 ospf6_lsa_premature_aging (prev_lsa
);
1983 if (IS_OSPF6_DUMP_LSA
)
1984 zlog_info ("LSA Update Inter-Area-Prefix: Area %s", o6a
->str
);
1986 size
= sizeof (struct ospf6_lsa_inter_prefix_lsa
);
1987 memset (buffer
, 0, sizeof (buffer
));
1988 inter_prefix
= (struct ospf6_lsa_inter_prefix_lsa
*)
1989 (buffer
+ sizeof (struct ospf6_lsa_header
));
1991 /* linklocal address */
1992 memcpy (&llsa
->llsa_linklocal
, o6i
->lladdr
, sizeof (struct in6_addr
));
1993 #ifdef KAME /* clear ifindex */
1994 if (llsa
->llsa_linklocal
.s6_addr
[3] & 0x0f)
1995 llsa
->llsa_linklocal
.s6_addr
[3] &= ~((char)0x0f);
1998 llsa
->llsa_prefix_num
= htonl (listcount (prefix_connected
));
1999 cp
= (char *)(llsa
+ 1);
2000 for (n
= listhead (prefix_connected
); n
; nextnode (n
))
2002 p
= (struct ospf6_prefix
*) getdata (n
);
2003 size
+= OSPF6_PREFIX_SIZE (p
);
2004 memcpy (cp
, p
, OSPF6_PREFIX_SIZE (p
));
2005 cp
+= OSPF6_PREFIX_SIZE (p
);
2008 /* Fill LSA Header */
2009 ospf6_lsa_header_set (htons (OSPF6_LSA_TYPE_LINK
), htonl (o6i
->if_id
),
2010 o6i
->area
->ospf6
->router_id
,
2011 (struct ospf6_lsa_header
*) buffer
, size
);
2014 lsa
= ospf6_lsa_create ((struct ospf6_lsa_header
*) buffer
);
2015 lsa
->refresh
= thread_add_timer (master
, ospf6_lsa_refresh
, lsa
,
2016 OSPF6_LS_REFRESH_TIME
);
2017 lsa
->scope
= (void *) o6i
;
2019 if (ospf6_lsa_is_really_reoriginate (lsa
))
2021 ospf6_dbex_remove_from_all_retrans_list (lsa
);
2022 ospf6_dbex_flood (lsa
, NULL
);
2023 ospf6_lsdb_install (lsa
);
2026 ospf6_lsa_delete (lsa
);
2032 ospf6_lsa_reoriginate (struct ospf6_lsa
*lsa
)
2034 struct ospf6_lsa_header
*lsa_header
;
2037 struct ospf6_area
*o6a
;
2038 struct ospf6_interface
*o6i
;
2040 lsa_header
= (struct ospf6_lsa_header
*) lsa
->lsa_hdr
;
2042 if (IS_OSPF6_DUMP_LSA
)
2043 zlog_info ("Re-originate %s", lsa
->str
);
2045 switch (ntohs (lsa_header
->type
))
2047 case OSPF6_LSA_TYPE_ROUTER
:
2048 o6a
= (struct ospf6_area
*) lsa
->scope
;
2050 ospf6_lsa_update_router (o6a
->area_id
);
2053 case OSPF6_LSA_TYPE_NETWORK
:
2054 o6a
= (struct ospf6_area
*) lsa
->scope
;
2056 o6i
= ospf6_interface_lookup_by_index (ntohl (lsa_header
->ls_id
));
2058 ospf6_lsa_update_network (o6i
->interface
->name
);
2060 ospf6_lsa_premature_aging (lsa
);
2063 case OSPF6_LSA_TYPE_INTRA_PREFIX
:
2064 /* xxx, assume LS-ID has addressing semantics */
2065 o6a
= (struct ospf6_area
*) lsa
->scope
;
2068 if (ntohl (lsa_header
->ls_id
) != 0)
2069 o6i
= ospf6_interface_lookup_by_index (ntohl (lsa_header
->ls_id
));
2072 ospf6_lsa_update_intra_prefix_transit (o6i
->interface
->name
);
2073 else if (ntohl (lsa_header
->ls_id
) == 0)
2074 ospf6_lsa_update_intra_prefix_stub (o6a
->area_id
);
2076 ospf6_lsa_premature_aging (lsa
);
2079 case OSPF6_LSA_TYPE_LINK
:
2080 o6i
= (struct ospf6_interface
*) lsa
->scope
;
2082 ospf6_lsa_update_link (o6i
->interface
->name
);
2085 case OSPF6_LSA_TYPE_AS_EXTERNAL
:
2086 o6
= (struct ospf6
*) lsa
->scope
;
2088 ospf6_lsa_update_as_external (ntohl (lsa_header
->ls_id
));
2097 /* ospf6_lsa expired */
2099 ospf6_lsa_expire (struct thread
*thread
)
2101 struct ospf6_lsa
*lsa
;
2103 lsa
= (struct ospf6_lsa
*) THREAD_ARG (thread
);
2104 assert (lsa
&& lsa
->lsa_hdr
);
2107 assert (ospf6_lsa_is_maxage (lsa
));
2108 assert (!lsa
->refresh
);
2110 lsa
->expire
= (struct thread
*) NULL
;
2113 if (IS_OSPF6_DUMP_LSA
)
2114 zlog_info ("LSA: Expire: %s", lsa
->str
);
2119 ospf6_dbex_flood (lsa
, NULL
);
2121 /* do not free LSA, and do nothing about lslists.
2122 wait event (ospf6_lsdb_check_maxage) */
2129 ospf6_lsa_refresh (struct thread
*thread
)
2131 struct ospf6_lsa
*lsa
;
2134 lsa
= (struct ospf6_lsa
*) THREAD_ARG (thread
);
2135 assert (lsa
&& lsa
->lsa_hdr
);
2137 /* this will be used later as flag to decide really originate */
2138 lsa
->refresh
= (struct thread
*)NULL
;
2141 if (IS_OSPF6_DUMP_LSA
)
2143 zlog_info ("LSA Refresh: %s", lsa
->str
);
2146 ospf6_lsa_reoriginate (lsa
);
2153 /* enhanced Fletcher checksum algorithm, RFC1008 7.2 */
2155 #define LSA_CHECKSUM_OFFSET 15
2158 ospf6_lsa_checksum (struct ospf6_lsa_header
*lsa_header
)
2160 u_char
*sp
, *ep
, *p
, *q
;
2165 lsa_header
->checksum
= 0;
2166 length
= ntohs (lsa_header
->length
) - 2;
2167 sp
= (char *) &lsa_header
->type
;
2169 for (ep
= sp
+ length
; sp
< ep
; sp
= q
)
2174 for (p
= sp
; p
< q
; p
++)
2183 /* r = (c1 << 8) + c0; */
2184 x
= ((length
- LSA_CHECKSUM_OFFSET
) * c0
- c1
) % 255;
2191 lsa_header
->checksum
= htons ((x
<< 8) + y
);
2193 return (lsa_header
->checksum
);
2197 ospf6_lsa_get_scope_type (u_int16_t type
)
2199 return (ntohs (type
) & OSPF6_LSA_SCOPE_MASK
);
2203 ospf6_lsa_is_known_type (struct ospf6_lsa_header
*lsa_header
)
2205 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_ROUTER
))
2207 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_NETWORK
))
2210 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_INTER_PREFIX
))
2212 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_INTER_ROUTER
))
2215 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_AS_EXTERNAL
))
2217 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_LINK
))
2219 if (lsa_header
->type
== htons (OSPF6_LSA_TYPE_INTRA_PREFIX
))