blob: e78441149143d3c347782a3da87f6aabde0dd29f [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
hasso508e53e2004-05-18 18:57:06 +00002 * Copyright (C) 2003 Yasuhiro Ohara
paul718e3742002-12-13 20:15:29 +00003 *
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
hasso508e53e2004-05-18 18:57:06 +000022#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
hasso508e53e2004-05-18 18:57:06 +000034#include "ospf6_proto.h"
35#include "ospf6_message.h"
36#include "ospf6_route.h"
37#include "ospf6_lsa.h"
38#include "ospf6_lsdb.h"
paul718e3742002-12-13 20:15:29 +000039
hasso508e53e2004-05-18 18:57:06 +000040#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"
hasso6452df02004-08-15 05:52:07 +000046#include "ospf6_abr.h"
47#include "ospf6_flood.h"
hasso049207c2004-08-04 20:02:13 +000048#include "ospf6d.h"
paul718e3742002-12-13 20:15:29 +000049
hasso508e53e2004-05-18 18:57:06 +000050/******************************/
51/* RFC2740 3.4.3.1 Router-LSA */
52/******************************/
paul718e3742002-12-13 20:15:29 +000053
hasso508e53e2004-05-18 18:57:06 +000054int
55ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +000056{
hasso508e53e2004-05-18 18:57:06 +000057 char *start, *end, *current;
58 char buf[32], name[32], bits[16], options[32];
59 struct ospf6_router_lsa *router_lsa;
60 struct ospf6_router_lsdesc *lsdesc;
paul718e3742002-12-13 20:15:29 +000061
hasso508e53e2004-05-18 18:57:06 +000062 router_lsa = (struct ospf6_router_lsa *)
63 ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +000064
hasso508e53e2004-05-18 18:57:06 +000065 ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
66 ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
hasso049207c2004-08-04 20:02:13 +000067 vty_out (vty, " Bits: %s Options: %s%s", bits, options, VNL);
paul718e3742002-12-13 20:15:29 +000068
hasso508e53e2004-05-18 18:57:06 +000069 start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
paul718e3742002-12-13 20:15:29 +000070 end = (char *) lsa->header + ntohs (lsa->header->length);
hasso508e53e2004-05-18 18:57:06 +000071 for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end;
72 current += sizeof (struct ospf6_router_lsdesc))
paul718e3742002-12-13 20:15:29 +000073 {
hasso508e53e2004-05-18 18:57:06 +000074 lsdesc = (struct ospf6_router_lsdesc *) current;
paul718e3742002-12-13 20:15:29 +000075
hasso508e53e2004-05-18 18:57:06 +000076 if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT)
77 snprintf (name, sizeof (name), "Point-To-Point");
78 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK)
79 snprintf (name, sizeof (name), "Transit-Network");
80 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK)
81 snprintf (name, sizeof (name), "Stub-Network");
82 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK)
83 snprintf (name, sizeof (name), "Virtual-Link");
paul718e3742002-12-13 20:15:29 +000084 else
hasso508e53e2004-05-18 18:57:06 +000085 snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
paul718e3742002-12-13 20:15:29 +000086
hasso508e53e2004-05-18 18:57:06 +000087 vty_out (vty, " Type: %s Metric: %d%s",
hasso049207c2004-08-04 20:02:13 +000088 name, ntohs (lsdesc->metric), VNL);
hasso508e53e2004-05-18 18:57:06 +000089 vty_out (vty, " Interface ID: %s%s",
90 inet_ntop (AF_INET, &lsdesc->interface_id,
hasso049207c2004-08-04 20:02:13 +000091 buf, sizeof (buf)), VNL);
hasso508e53e2004-05-18 18:57:06 +000092 vty_out (vty, " Neighbor Interface ID: %s%s",
93 inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
hasso049207c2004-08-04 20:02:13 +000094 buf, sizeof (buf)), VNL);
hasso508e53e2004-05-18 18:57:06 +000095 vty_out (vty, " Neighbor Router ID: %s%s",
96 inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
hasso049207c2004-08-04 20:02:13 +000097 buf, sizeof (buf)), VNL);
paul718e3742002-12-13 20:15:29 +000098 }
99 return 0;
100}
101
hasso6452df02004-08-15 05:52:07 +0000102int
103ospf6_router_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000104{
hasso6452df02004-08-15 05:52:07 +0000105 struct ospf6_area *oa;
106
hasso508e53e2004-05-18 18:57:06 +0000107 char buffer [OSPF6_MAX_LSASIZE];
108 struct ospf6_lsa_header *lsa_header;
109 struct ospf6_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000110
hasso508e53e2004-05-18 18:57:06 +0000111 u_int32_t link_state_id = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000112 struct listnode *i, *j;
hasso508e53e2004-05-18 18:57:06 +0000113 struct ospf6_interface *oi;
114 struct ospf6_neighbor *on, *drouter = NULL;
115 struct ospf6_router_lsa *router_lsa;
116 struct ospf6_router_lsdesc *lsdesc;
117 u_int16_t type;
118 u_int32_t router;
119 int count;
paul718e3742002-12-13 20:15:29 +0000120
hasso6452df02004-08-15 05:52:07 +0000121 oa = (struct ospf6_area *) THREAD_ARG (thread);
122 oa->thread_router_lsa = NULL;
123
hasso1e058382004-09-01 21:36:14 +0000124 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
hassoc6487d62004-12-24 06:00:11 +0000125 zlog_debug ("Originate Router-LSA for Area %s", oa->name);
paul718e3742002-12-13 20:15:29 +0000126
hasso508e53e2004-05-18 18:57:06 +0000127 memset (buffer, 0, sizeof (buffer));
128 lsa_header = (struct ospf6_lsa_header *) buffer;
129 router_lsa = (struct ospf6_router_lsa *)
130 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
131
132 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
133 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
134 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
135 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
136 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
137 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
138
hasso6452df02004-08-15 05:52:07 +0000139 if (ospf6_is_router_abr (ospf6))
140 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
141 else
142 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
hasso508e53e2004-05-18 18:57:06 +0000143 if (ospf6_asbr_is_asbr (ospf6))
144 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
145 else
146 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
147 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
148 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
149
150 /* describe links for each interfaces */
151 lsdesc = (struct ospf6_router_lsdesc *)
152 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
153
154 for (i = listhead (oa->if_list); i; nextnode (i))
paul718e3742002-12-13 20:15:29 +0000155 {
hasso508e53e2004-05-18 18:57:06 +0000156 oi = (struct ospf6_interface *) getdata (i);
157
158 /* Interfaces in state Down or Loopback are not described */
159 if (oi->state == OSPF6_INTERFACE_DOWN ||
160 oi->state == OSPF6_INTERFACE_LOOPBACK)
paul718e3742002-12-13 20:15:29 +0000161 continue;
162
hasso508e53e2004-05-18 18:57:06 +0000163 /* Nor are interfaces without any full adjacencies described */
164 count = 0;
165 for (j = listhead (oi->neighbor_list); j; nextnode (j))
paul718e3742002-12-13 20:15:29 +0000166 {
hasso508e53e2004-05-18 18:57:06 +0000167 on = (struct ospf6_neighbor *) getdata (j);
168 if (on->state == OSPF6_NEIGHBOR_FULL)
169 count++;
170 }
171 if (count == 0)
172 continue;
173
174 /* Multiple Router-LSA instance according to size limit setting */
paul0c083ee2004-10-10 12:54:58 +0000175 if ( (oa->router_lsa_size_limit != 0)
176 && ((caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) -
gdt1686f932004-12-09 14:47:09 +0000177 /* XXX warning: comparison between signed and unsigned */
paul0c083ee2004-10-10 12:54:58 +0000178 (caddr_t) buffer > oa->router_lsa_size_limit))
hasso508e53e2004-05-18 18:57:06 +0000179 {
180 if ((caddr_t) lsdesc == (caddr_t) router_lsa +
181 sizeof (struct ospf6_router_lsa))
182 {
hasso1e058382004-09-01 21:36:14 +0000183 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
hassoc6487d62004-12-24 06:00:11 +0000184 zlog_debug ("Size limit setting for Router-LSA too short");
hasso6452df02004-08-15 05:52:07 +0000185 return 0;
hasso508e53e2004-05-18 18:57:06 +0000186 }
187
188 /* Fill LSA Header */
189 lsa_header->age = 0;
190 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
191 lsa_header->id = htonl (link_state_id);
192 lsa_header->adv_router = oa->ospf6->router_id;
193 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000194 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
195 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000196 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
197
198 /* LSA checksum */
199 ospf6_lsa_checksum (lsa_header);
200
201 /* create LSA */
202 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000203
204 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000205 ospf6_lsa_originate_area (lsa, oa);
hasso508e53e2004-05-18 18:57:06 +0000206
207 /* Reset setting for consecutive origination */
208 memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
209 0, (caddr_t) lsdesc - (caddr_t) router_lsa);
210 lsdesc = (struct ospf6_router_lsdesc *)
211 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
212 link_state_id ++;
paul718e3742002-12-13 20:15:29 +0000213 }
214
hasso508e53e2004-05-18 18:57:06 +0000215 /* Point-to-Point interfaces */
216 if (if_is_pointopoint (oi->interface))
217 {
218 for (j = listhead (oi->neighbor_list); j; nextnode (j))
219 {
220 on = (struct ospf6_neighbor *) getdata (j);
221 if (on->state != OSPF6_NEIGHBOR_FULL)
222 continue;
paul718e3742002-12-13 20:15:29 +0000223
hasso508e53e2004-05-18 18:57:06 +0000224 lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
225 lsdesc->metric = htons (oi->cost);
226 lsdesc->interface_id = htonl (oi->interface->ifindex);
227 lsdesc->neighbor_interface_id = htonl (on->ifindex);
228 lsdesc->neighbor_router_id = on->router_id;
229
230 lsdesc++;
231 }
232 }
233
234 /* Broadcast and NBMA interfaces */
235 if (if_is_broadcast (oi->interface))
236 {
237 /* If this router is not DR,
238 and If this router not fully adjacent with DR,
239 this interface is not transit yet: ignore. */
240 if (oi->state != OSPF6_INTERFACE_DR)
241 {
242 drouter = ospf6_neighbor_lookup (oi->drouter, oi);
243 if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
244 continue;
245 }
246
247 lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
248 lsdesc->metric = htons (oi->cost);
249 lsdesc->interface_id = htonl (oi->interface->ifindex);
250 if (oi->state != OSPF6_INTERFACE_DR)
251 {
252 lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
253 lsdesc->neighbor_router_id = drouter->router_id;
254 }
255 else
256 {
257 lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
258 lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
259 }
260
261 lsdesc++;
262 }
263
264 /* Virtual links */
265 /* xxx */
266 /* Point-to-Multipoint interfaces */
267 /* xxx */
paul718e3742002-12-13 20:15:29 +0000268 }
hasso508e53e2004-05-18 18:57:06 +0000269
270 if ((caddr_t) lsdesc != (caddr_t) router_lsa +
271 sizeof (struct ospf6_router_lsa))
272 {
273 /* Fill LSA Header */
274 lsa_header->age = 0;
275 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
276 lsa_header->id = htonl (link_state_id);
277 lsa_header->adv_router = oa->ospf6->router_id;
278 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000279 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
280 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000281 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
282
283 /* LSA checksum */
284 ospf6_lsa_checksum (lsa_header);
285
286 /* create LSA */
287 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000288
289 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000290 ospf6_lsa_originate_area (lsa, oa);
hasso508e53e2004-05-18 18:57:06 +0000291
292 link_state_id ++;
293 }
hasso6452df02004-08-15 05:52:07 +0000294 else
295 {
hasso1e058382004-09-01 21:36:14 +0000296 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
hassoc6487d62004-12-24 06:00:11 +0000297 zlog_debug ("Nothing to describe in Router-LSA, suppress");
hasso6452df02004-08-15 05:52:07 +0000298 }
hasso508e53e2004-05-18 18:57:06 +0000299
300 /* Do premature-aging of rest, undesired Router-LSAs */
301 type = ntohs (OSPF6_LSTYPE_ROUTER);
302 router = oa->ospf6->router_id;
303 for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
304 lsa = ospf6_lsdb_type_router_next (type, router, lsa))
305 {
306 if (ntohl (lsa->header->id) < link_state_id)
307 continue;
hasso6452df02004-08-15 05:52:07 +0000308 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000309 }
hasso508e53e2004-05-18 18:57:06 +0000310
311 return 0;
312}
313
hasso508e53e2004-05-18 18:57:06 +0000314/*******************************/
315/* RFC2740 3.4.3.2 Network-LSA */
316/*******************************/
317
318int
319ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
320{
321 char *start, *end, *current;
322 struct ospf6_network_lsa *network_lsa;
323 struct ospf6_network_lsdesc *lsdesc;
324 char buf[128], options[32];
325
326 network_lsa = (struct ospf6_network_lsa *)
327 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
328
329 ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
hasso049207c2004-08-04 20:02:13 +0000330 vty_out (vty, " Options: %s%s", options, VNL);
hasso508e53e2004-05-18 18:57:06 +0000331
332 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
333 end = (char *) lsa->header + ntohs (lsa->header->length);
334 for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
335 current += sizeof (struct ospf6_network_lsdesc))
336 {
337 lsdesc = (struct ospf6_network_lsdesc *) current;
338 inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +0000339 vty_out (vty, " Attached Router: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +0000340 }
341 return 0;
paul718e3742002-12-13 20:15:29 +0000342}
343
hasso6452df02004-08-15 05:52:07 +0000344int
345ospf6_network_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000346{
hasso6452df02004-08-15 05:52:07 +0000347 struct ospf6_interface *oi;
348
hasso508e53e2004-05-18 18:57:06 +0000349 char buffer [OSPF6_MAX_LSASIZE];
350 struct ospf6_lsa_header *lsa_header;
paul718e3742002-12-13 20:15:29 +0000351
hasso508e53e2004-05-18 18:57:06 +0000352 int count;
353 struct ospf6_lsa *old, *lsa;
354 struct ospf6_network_lsa *network_lsa;
355 struct ospf6_network_lsdesc *lsdesc;
356 struct ospf6_neighbor *on;
357 struct ospf6_link_lsa *link_lsa;
hasso52dc7ee2004-09-23 19:18:23 +0000358 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000359 u_int16_t type;
360
hasso6452df02004-08-15 05:52:07 +0000361 oi = (struct ospf6_interface *) THREAD_ARG (thread);
362 oi->thread_network_lsa = NULL;
363
364 /* The interface must be enabled until here. A Network-LSA of a
365 disabled interface (but was once enabled) should be flushed
366 by ospf6_lsa_refresh (), and does not come here. */
367 assert (oi->area);
paul718e3742002-12-13 20:15:29 +0000368
hasso508e53e2004-05-18 18:57:06 +0000369 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
370 htonl (oi->interface->ifindex),
371 oi->area->ospf6->router_id, oi->area->lsdb);
paul718e3742002-12-13 20:15:29 +0000372
hasso508e53e2004-05-18 18:57:06 +0000373 /* Do not originate Network-LSA if not DR */
374 if (oi->state != OSPF6_INTERFACE_DR)
paul718e3742002-12-13 20:15:29 +0000375 {
hasso508e53e2004-05-18 18:57:06 +0000376 if (old)
hasso6452df02004-08-15 05:52:07 +0000377 ospf6_lsa_purge (old);
378 return 0;
paul718e3742002-12-13 20:15:29 +0000379 }
hasso508e53e2004-05-18 18:57:06 +0000380
hasso1e058382004-09-01 21:36:14 +0000381 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
hassoc6487d62004-12-24 06:00:11 +0000382 zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000383
384 /* If none of neighbor is adjacent to us */
385 count = 0;
386 for (i = listhead (oi->neighbor_list); i; nextnode (i))
387 {
388 on = (struct ospf6_neighbor *) getdata (i);
389 if (on->state == OSPF6_NEIGHBOR_FULL)
390 count++;
391 }
392 if (count == 0)
393 {
hasso1e058382004-09-01 21:36:14 +0000394 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
hassoc6487d62004-12-24 06:00:11 +0000395 zlog_debug ("Interface stub, ignore");
hasso508e53e2004-05-18 18:57:06 +0000396 if (old)
hasso6452df02004-08-15 05:52:07 +0000397 ospf6_lsa_purge (old);
398 return 0;
hasso508e53e2004-05-18 18:57:06 +0000399 }
400
401 /* prepare buffer */
402 memset (buffer, 0, sizeof (buffer));
403 lsa_header = (struct ospf6_lsa_header *) buffer;
404 network_lsa = (struct ospf6_network_lsa *)
405 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
406
407 /* Collect the interface's Link-LSAs to describe
408 network's optional capabilities */
409 type = htons (OSPF6_LSTYPE_LINK);
410 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
411 lsa = ospf6_lsdb_type_next (type, lsa))
412 {
413 link_lsa = (struct ospf6_link_lsa *)
414 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
415 network_lsa->options[0] |= link_lsa->options[0];
416 network_lsa->options[1] |= link_lsa->options[1];
417 network_lsa->options[2] |= link_lsa->options[2];
418 }
419
420 lsdesc = (struct ospf6_network_lsdesc *)
421 ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
422
423 /* set Link Description to the router itself */
424 lsdesc->router_id = oi->area->ospf6->router_id;
425 lsdesc++;
426
427 /* Walk through the neighbors */
428 for (i = listhead (oi->neighbor_list); i; nextnode (i))
429 {
430 on = (struct ospf6_neighbor *) getdata (i);
431
432 if (on->state != OSPF6_NEIGHBOR_FULL)
433 continue;
434
435 /* set this neighbor's Router-ID to LSA */
436 lsdesc->router_id = on->router_id;
437 lsdesc++;
438 }
439
440 /* Fill LSA Header */
441 lsa_header->age = 0;
442 lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
443 lsa_header->id = htonl (oi->interface->ifindex);
444 lsa_header->adv_router = oi->area->ospf6->router_id;
445 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000446 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
447 lsa_header->adv_router, oi->area->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000448 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
449
450 /* LSA checksum */
451 ospf6_lsa_checksum (lsa_header);
452
453 /* create LSA */
454 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000455
456 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000457 ospf6_lsa_originate_area (lsa, oi->area);
hasso508e53e2004-05-18 18:57:06 +0000458
459 return 0;
460}
461
462
463/****************************/
464/* RFC2740 3.4.3.6 Link-LSA */
465/****************************/
466
467int
468ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
469{
paul718e3742002-12-13 20:15:29 +0000470 char *start, *end, *current;
hasso508e53e2004-05-18 18:57:06 +0000471 struct ospf6_link_lsa *link_lsa;
472 int prefixnum;
473 char buf[128], options[32];
474 struct ospf6_prefix *prefix;
paul0c083ee2004-10-10 12:54:58 +0000475 const char *p, *mc, *la, *nu;
hasso508e53e2004-05-18 18:57:06 +0000476 struct in6_addr in6;
paul718e3742002-12-13 20:15:29 +0000477
hasso508e53e2004-05-18 18:57:06 +0000478 link_lsa = (struct ospf6_link_lsa *)
479 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +0000480
hasso508e53e2004-05-18 18:57:06 +0000481 ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
482 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
483 prefixnum = ntohl (link_lsa->prefix_num);
paul718e3742002-12-13 20:15:29 +0000484
hasso508e53e2004-05-18 18:57:06 +0000485 vty_out (vty, " Priority: %d Options: %s%s",
hasso049207c2004-08-04 20:02:13 +0000486 link_lsa->priority, options, VNL);
487 vty_out (vty, " LinkLocal Address: %s%s", buf, VNL);
488 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
paul718e3742002-12-13 20:15:29 +0000489
hasso508e53e2004-05-18 18:57:06 +0000490 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
491 end = (char *) lsa->header + ntohs (lsa->header->length);
paul718e3742002-12-13 20:15:29 +0000492 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
493 {
494 prefix = (struct ospf6_prefix *) current;
hasso508e53e2004-05-18 18:57:06 +0000495 if (prefix->prefix_length == 0 ||
496 current + OSPF6_PREFIX_SIZE (prefix) > end)
497 break;
paul718e3742002-12-13 20:15:29 +0000498
hasso508e53e2004-05-18 18:57:06 +0000499 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
500 "P" : "--");
501 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
502 "MC" : "--");
503 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
504 "LA" : "--");
505 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
506 "NU" : "--");
507 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
hasso049207c2004-08-04 20:02:13 +0000508 p, mc, la, nu, VNL);
paul718e3742002-12-13 20:15:29 +0000509
hasso508e53e2004-05-18 18:57:06 +0000510 memset (&in6, 0, sizeof (in6));
511 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
512 OSPF6_PREFIX_SPACE (prefix->prefix_length));
paul718e3742002-12-13 20:15:29 +0000513 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
514 vty_out (vty, " Prefix: %s/%d%s",
hasso049207c2004-08-04 20:02:13 +0000515 buf, prefix->prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +0000516 }
517
518 return 0;
519}
520
hasso6452df02004-08-15 05:52:07 +0000521int
522ospf6_link_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000523{
hasso6452df02004-08-15 05:52:07 +0000524 struct ospf6_interface *oi;
525
hasso508e53e2004-05-18 18:57:06 +0000526 char buffer[OSPF6_MAX_LSASIZE];
527 struct ospf6_lsa_header *lsa_header;
528 struct ospf6_lsa *old, *lsa;
paul718e3742002-12-13 20:15:29 +0000529
hasso508e53e2004-05-18 18:57:06 +0000530 struct ospf6_link_lsa *link_lsa;
531 struct ospf6_route *route;
532 struct ospf6_prefix *op;
paul718e3742002-12-13 20:15:29 +0000533
hasso6452df02004-08-15 05:52:07 +0000534 oi = (struct ospf6_interface *) THREAD_ARG (thread);
535 oi->thread_link_lsa = NULL;
536
537 assert (oi->area);
paul718e3742002-12-13 20:15:29 +0000538
539 /* find previous LSA */
hasso508e53e2004-05-18 18:57:06 +0000540 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
541 htonl (oi->interface->ifindex),
542 oi->area->ospf6->router_id, oi->lsdb);
paul718e3742002-12-13 20:15:29 +0000543
hasso508e53e2004-05-18 18:57:06 +0000544 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
paul718e3742002-12-13 20:15:29 +0000545 {
546 if (old)
hasso6452df02004-08-15 05:52:07 +0000547 ospf6_lsa_purge (old);
548 return 0;
paul718e3742002-12-13 20:15:29 +0000549 }
550
hasso1e058382004-09-01 21:36:14 +0000551 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
hassoc6487d62004-12-24 06:00:11 +0000552 zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
paul718e3742002-12-13 20:15:29 +0000553
hasso508e53e2004-05-18 18:57:06 +0000554 /* can't make Link-LSA if linklocal address not set */
555 if (oi->linklocal_addr == NULL)
paul718e3742002-12-13 20:15:29 +0000556 {
hasso1e058382004-09-01 21:36:14 +0000557 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
hassoc6487d62004-12-24 06:00:11 +0000558 zlog_debug ("No Linklocal address on %s, defer originating",
hasso508e53e2004-05-18 18:57:06 +0000559 oi->interface->name);
560 if (old)
hasso6452df02004-08-15 05:52:07 +0000561 ospf6_lsa_purge (old);
562 return 0;
hasso508e53e2004-05-18 18:57:06 +0000563 }
564
565 /* prepare buffer */
566 memset (buffer, 0, sizeof (buffer));
567 lsa_header = (struct ospf6_lsa_header *) buffer;
568 link_lsa = (struct ospf6_link_lsa *)
569 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
570
571 /* Fill Link-LSA */
572 link_lsa->priority = oi->priority;
573 memcpy (link_lsa->options, oi->area->options, 3);
574 memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
575 sizeof (struct in6_addr));
576 link_lsa->prefix_num = htonl (oi->route_connected->count);
577
578 op = (struct ospf6_prefix *)
579 ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
580
581 /* connected prefix to advertise */
582 for (route = ospf6_route_head (oi->route_connected); route;
583 route = ospf6_route_next (route))
584 {
585 op->prefix_length = route->prefix.prefixlen;
586 op->prefix_options = route->path.prefix_options;
587 op->prefix_metric = htons (0);
588 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
589 OSPF6_PREFIX_SPACE (op->prefix_length));
590 op = OSPF6_PREFIX_NEXT (op);
591 }
592
593 /* Fill LSA Header */
594 lsa_header->age = 0;
595 lsa_header->type = htons (OSPF6_LSTYPE_LINK);
596 lsa_header->id = htonl (oi->interface->ifindex);
597 lsa_header->adv_router = oi->area->ospf6->router_id;
598 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000599 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
600 lsa_header->adv_router, oi->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000601 lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
602
603 /* LSA checksum */
604 ospf6_lsa_checksum (lsa_header);
605
606 /* create LSA */
607 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000608
609 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000610 ospf6_lsa_originate_interface (lsa, oi);
hasso508e53e2004-05-18 18:57:06 +0000611
612 return 0;
613}
614
615
616/*****************************************/
617/* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
618/*****************************************/
619
620int
621ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
622{
623 char *start, *end, *current;
624 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
625 int prefixnum;
626 char buf[128];
627 struct ospf6_prefix *prefix;
628 char id[16], adv_router[16];
paul0c083ee2004-10-10 12:54:58 +0000629 const char *p, *mc, *la, *nu;
hasso508e53e2004-05-18 18:57:06 +0000630 struct in6_addr in6;
631
632 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
633 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
634
635 prefixnum = ntohs (intra_prefix_lsa->prefix_num);
636
hasso049207c2004-08-04 20:02:13 +0000637 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
hasso508e53e2004-05-18 18:57:06 +0000638
639 inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
640 inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
641 adv_router, sizeof (adv_router));
642 vty_out (vty, " Reference: %s Id: %s Adv: %s%s",
hasso1e058382004-09-01 21:36:14 +0000643 ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
hasso049207c2004-08-04 20:02:13 +0000644 VNL);
hasso508e53e2004-05-18 18:57:06 +0000645
646 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
647 end = (char *) lsa->header + ntohs (lsa->header->length);
648 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
649 {
650 prefix = (struct ospf6_prefix *) current;
651 if (prefix->prefix_length == 0 ||
652 current + OSPF6_PREFIX_SIZE (prefix) > end)
653 break;
654
655 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
656 "P" : "--");
657 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
658 "MC" : "--");
659 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
660 "LA" : "--");
661 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
662 "NU" : "--");
663 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
hasso049207c2004-08-04 20:02:13 +0000664 p, mc, la, nu, VNL);
hasso508e53e2004-05-18 18:57:06 +0000665
666 memset (&in6, 0, sizeof (in6));
667 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
668 OSPF6_PREFIX_SPACE (prefix->prefix_length));
669 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
670 vty_out (vty, " Prefix: %s/%d%s",
hasso049207c2004-08-04 20:02:13 +0000671 buf, prefix->prefix_length, VNL);
hasso508e53e2004-05-18 18:57:06 +0000672 }
673
674 return 0;
675}
676
hasso6452df02004-08-15 05:52:07 +0000677int
678ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
hasso508e53e2004-05-18 18:57:06 +0000679{
hasso6452df02004-08-15 05:52:07 +0000680 struct ospf6_area *oa;
681
hasso508e53e2004-05-18 18:57:06 +0000682 char buffer[OSPF6_MAX_LSASIZE];
683 struct ospf6_lsa_header *lsa_header;
684 struct ospf6_lsa *old, *lsa;
685
686 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
687 struct ospf6_interface *oi;
688 struct ospf6_neighbor *on;
689 struct ospf6_route *route;
690 struct ospf6_prefix *op;
hasso52dc7ee2004-09-23 19:18:23 +0000691 struct listnode *i, *j;
hasso508e53e2004-05-18 18:57:06 +0000692 int full_count = 0;
693 unsigned short prefix_num = 0;
694 char buf[BUFSIZ];
695 struct ospf6_route_table *route_advertise;
696
hasso6452df02004-08-15 05:52:07 +0000697 oa = (struct ospf6_area *) THREAD_ARG (thread);
698 oa->thread_intra_prefix_lsa = NULL;
699
hasso508e53e2004-05-18 18:57:06 +0000700 /* find previous LSA */
701 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
702 htonl (0), oa->ospf6->router_id, oa->lsdb);
703
hasso6452df02004-08-15 05:52:07 +0000704 if (! IS_AREA_ENABLED (oa))
hasso508e53e2004-05-18 18:57:06 +0000705 {
706 if (old)
hasso6452df02004-08-15 05:52:07 +0000707 ospf6_lsa_purge (old);
708 return 0;
hasso508e53e2004-05-18 18:57:06 +0000709 }
710
hasso1e058382004-09-01 21:36:14 +0000711 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000712 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
hasso508e53e2004-05-18 18:57:06 +0000713 oa->name);
714
715 /* prepare buffer */
716 memset (buffer, 0, sizeof (buffer));
717 lsa_header = (struct ospf6_lsa_header *) buffer;
718 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
719 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
720
721 /* Fill Intra-Area-Prefix-LSA */
722 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
723 intra_prefix_lsa->ref_id = htonl (0);
724 intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
725
726 route_advertise = ospf6_route_table_create ();
727
728 for (i = listhead (oa->if_list); i; nextnode (i))
729 {
730 oi = (struct ospf6_interface *) getdata (i);
731
732 if (oi->state == OSPF6_INTERFACE_DOWN)
733 {
hasso1e058382004-09-01 21:36:14 +0000734 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000735 zlog_debug (" Interface %s is down, ignore", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000736 continue;
737 }
738
739 full_count = 0;
740 for (j = listhead (oi->neighbor_list); j; nextnode (j))
741 {
742 on = (struct ospf6_neighbor *) getdata (j);
743 if (on->state == OSPF6_NEIGHBOR_FULL)
744 full_count++;
745 }
746 if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
747 oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
748 full_count != 0)
749 {
hasso1e058382004-09-01 21:36:14 +0000750 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000751 zlog_debug (" Interface %s is not stub, ignore",
hasso508e53e2004-05-18 18:57:06 +0000752 oi->interface->name);
753 continue;
754 }
755
hasso1e058382004-09-01 21:36:14 +0000756 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000757 zlog_debug (" Interface %s:", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000758
759 /* connected prefix to advertise */
760 for (route = ospf6_route_head (oi->route_connected); route;
761 route = ospf6_route_best_next (route))
762 {
hasso1e058382004-09-01 21:36:14 +0000763 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +0000764 {
765 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000766 zlog_debug (" include %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000767 }
768 ospf6_route_add (ospf6_route_copy (route), route_advertise);
769 }
770 }
771
772 if (route_advertise->count == 0)
773 {
774 if (old)
hasso6452df02004-08-15 05:52:07 +0000775 ospf6_lsa_purge (old);
hasso508e53e2004-05-18 18:57:06 +0000776 ospf6_route_table_delete (route_advertise);
hasso6452df02004-08-15 05:52:07 +0000777 return 0;
hasso508e53e2004-05-18 18:57:06 +0000778 }
779
780 /* put prefixes to advertise */
781 prefix_num = 0;
782 op = (struct ospf6_prefix *)
783 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
784 for (route = ospf6_route_head (route_advertise); route;
785 route = ospf6_route_best_next (route))
786 {
787 op->prefix_length = route->prefix.prefixlen;
788 op->prefix_options = route->path.prefix_options;
789 op->prefix_metric = htons (route->path.cost);
790 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
791 OSPF6_PREFIX_SPACE (op->prefix_length));
792 op = OSPF6_PREFIX_NEXT (op);
793 prefix_num++;
794 }
795
796 ospf6_route_table_delete (route_advertise);
797
798 if (prefix_num == 0)
799 {
hasso1e058382004-09-01 21:36:14 +0000800 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000801 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
hasso6452df02004-08-15 05:52:07 +0000802 return 0;
hasso508e53e2004-05-18 18:57:06 +0000803 }
804
805 intra_prefix_lsa->prefix_num = htons (prefix_num);
806
807 /* Fill LSA Header */
808 lsa_header->age = 0;
809 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
810 lsa_header->id = htonl (0);
811 lsa_header->adv_router = oa->ospf6->router_id;
812 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000813 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
814 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000815 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
816
817 /* LSA checksum */
818 ospf6_lsa_checksum (lsa_header);
819
820 /* create LSA */
821 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000822
823 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000824 ospf6_lsa_originate_area (lsa, oa);
825
826 return 0;
hasso508e53e2004-05-18 18:57:06 +0000827}
828
hasso6452df02004-08-15 05:52:07 +0000829
830int
831ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
hasso508e53e2004-05-18 18:57:06 +0000832{
hasso6452df02004-08-15 05:52:07 +0000833 struct ospf6_interface *oi;
834
hasso508e53e2004-05-18 18:57:06 +0000835 char buffer[OSPF6_MAX_LSASIZE];
836 struct ospf6_lsa_header *lsa_header;
837 struct ospf6_lsa *old, *lsa;
838
839 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
840 struct ospf6_neighbor *on;
841 struct ospf6_route *route;
842 struct ospf6_prefix *op;
hasso52dc7ee2004-09-23 19:18:23 +0000843 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000844 int full_count = 0;
845 unsigned short prefix_num = 0;
846 struct ospf6_route_table *route_advertise;
847 struct ospf6_link_lsa *link_lsa;
848 char *start, *end, *current;
849 u_int16_t type;
850 char buf[BUFSIZ];
851
hasso6452df02004-08-15 05:52:07 +0000852 oi = (struct ospf6_interface *) THREAD_ARG (thread);
853 oi->thread_intra_prefix_lsa = NULL;
854
855 assert (oi->area);
hasso508e53e2004-05-18 18:57:06 +0000856
857 /* find previous LSA */
858 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
859 htonl (oi->interface->ifindex),
860 oi->area->ospf6->router_id, oi->area->lsdb);
861
862 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
863 {
864 if (old)
hasso6452df02004-08-15 05:52:07 +0000865 ospf6_lsa_purge (old);
866 return 0;
hasso508e53e2004-05-18 18:57:06 +0000867 }
868
hasso1e058382004-09-01 21:36:14 +0000869 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000870 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
hasso508e53e2004-05-18 18:57:06 +0000871 oi->interface->name);
872
873 /* prepare buffer */
874 memset (buffer, 0, sizeof (buffer));
875 lsa_header = (struct ospf6_lsa_header *) buffer;
876 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
877 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
878
879 /* Fill Intra-Area-Prefix-LSA */
880 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
881 intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
882 intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
883
884 if (oi->state != OSPF6_INTERFACE_DR)
885 {
hasso1e058382004-09-01 21:36:14 +0000886 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000887 zlog_debug (" Interface is not DR");
hasso508e53e2004-05-18 18:57:06 +0000888 if (old)
hasso6452df02004-08-15 05:52:07 +0000889 ospf6_lsa_purge (old);
890 return 0;
hasso508e53e2004-05-18 18:57:06 +0000891 }
892
893 full_count = 0;
894 for (i = listhead (oi->neighbor_list); i; nextnode (i))
895 {
896 on = (struct ospf6_neighbor *) getdata (i);
897 if (on->state == OSPF6_NEIGHBOR_FULL)
898 full_count++;
899 }
900 if (full_count == 0)
901 {
hasso1e058382004-09-01 21:36:14 +0000902 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000903 zlog_debug (" Interface is stub");
hasso508e53e2004-05-18 18:57:06 +0000904 if (old)
hasso6452df02004-08-15 05:52:07 +0000905 ospf6_lsa_purge (old);
906 return 0;
hasso508e53e2004-05-18 18:57:06 +0000907 }
908
909 /* connected prefix to advertise */
910 route_advertise = ospf6_route_table_create ();
911
912 type = ntohs (OSPF6_LSTYPE_LINK);
913 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
914 lsa = ospf6_lsdb_type_next (type, lsa))
915 {
916 if (OSPF6_LSA_IS_MAXAGE (lsa))
paul718e3742002-12-13 20:15:29 +0000917 continue;
918
hasso1e058382004-09-01 21:36:14 +0000919 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000920 zlog_debug (" include prefix from %s", lsa->name);
paul718e3742002-12-13 20:15:29 +0000921
hasso508e53e2004-05-18 18:57:06 +0000922 if (lsa->header->adv_router != oi->area->ospf6->router_id)
paul718e3742002-12-13 20:15:29 +0000923 {
hasso508e53e2004-05-18 18:57:06 +0000924 on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
925 if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
paul718e3742002-12-13 20:15:29 +0000926 {
hasso1e058382004-09-01 21:36:14 +0000927 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000928 zlog_debug (" Neighbor not found or not Full, ignore");
paul718e3742002-12-13 20:15:29 +0000929 continue;
930 }
931 }
932
hasso508e53e2004-05-18 18:57:06 +0000933 link_lsa = (struct ospf6_link_lsa *)
934 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +0000935
hasso508e53e2004-05-18 18:57:06 +0000936 prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
937 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
938 end = (char *) lsa->header + ntohs (lsa->header->length);
939 for (current = start; current < end && prefix_num;
940 current += OSPF6_PREFIX_SIZE (op))
paul718e3742002-12-13 20:15:29 +0000941 {
hasso508e53e2004-05-18 18:57:06 +0000942 op = (struct ospf6_prefix *) current;
943 if (op->prefix_length == 0 ||
944 current + OSPF6_PREFIX_SIZE (op) > end)
945 break;
paul718e3742002-12-13 20:15:29 +0000946
hasso508e53e2004-05-18 18:57:06 +0000947 route = ospf6_route_create ();
948
949 route->type = OSPF6_DEST_TYPE_NETWORK;
950 route->prefix.family = AF_INET6;
951 route->prefix.prefixlen = op->prefix_length;
952 memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
953 memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
954 OSPF6_PREFIX_SPACE (op->prefix_length));
955
956 route->path.origin.type = lsa->header->type;
957 route->path.origin.id = lsa->header->id;
958 route->path.origin.adv_router = lsa->header->adv_router;
959 route->path.options[0] = link_lsa->options[0];
960 route->path.options[1] = link_lsa->options[1];
961 route->path.options[2] = link_lsa->options[2];
962 route->path.prefix_options = op->prefix_options;
963 route->path.area_id = oi->area->area_id;
964 route->path.type = OSPF6_PATH_TYPE_INTRA;
965
hasso1e058382004-09-01 21:36:14 +0000966 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
paul718e3742002-12-13 20:15:29 +0000967 {
hasso508e53e2004-05-18 18:57:06 +0000968 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000969 zlog_debug (" include %s", buf);
paul718e3742002-12-13 20:15:29 +0000970 }
971
hasso508e53e2004-05-18 18:57:06 +0000972 ospf6_route_add (route, route_advertise);
973 prefix_num--;
paul718e3742002-12-13 20:15:29 +0000974 }
hasso1e058382004-09-01 21:36:14 +0000975 if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000976 zlog_debug ("Trailing garbage in %s", lsa->name);
paul718e3742002-12-13 20:15:29 +0000977 }
978
hasso508e53e2004-05-18 18:57:06 +0000979 op = (struct ospf6_prefix *)
980 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
981
982 prefix_num = 0;
983 for (route = ospf6_route_head (route_advertise); route;
984 route = ospf6_route_best_next (route))
paul718e3742002-12-13 20:15:29 +0000985 {
hasso508e53e2004-05-18 18:57:06 +0000986 op->prefix_length = route->prefix.prefixlen;
987 op->prefix_options = route->path.prefix_options;
988 op->prefix_metric = htons (0);
989 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
990 OSPF6_PREFIX_SPACE (op->prefix_length));
991 op = OSPF6_PREFIX_NEXT (op);
992 prefix_num++;
993 }
994
995 ospf6_route_table_delete (route_advertise);
996
997 if (prefix_num == 0)
998 {
hasso1e058382004-09-01 21:36:14 +0000999 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001000 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
hasso6452df02004-08-15 05:52:07 +00001001 return 0;
paul718e3742002-12-13 20:15:29 +00001002 }
1003
hasso508e53e2004-05-18 18:57:06 +00001004 intra_prefix_lsa->prefix_num = htons (prefix_num);
paul718e3742002-12-13 20:15:29 +00001005
hasso508e53e2004-05-18 18:57:06 +00001006 /* Fill LSA Header */
1007 lsa_header->age = 0;
1008 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1009 lsa_header->id = htonl (oi->interface->ifindex);
1010 lsa_header->adv_router = oi->area->ospf6->router_id;
1011 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +00001012 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
1013 lsa_header->adv_router, oi->area->lsdb);
hasso508e53e2004-05-18 18:57:06 +00001014 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
paul718e3742002-12-13 20:15:29 +00001015
hasso508e53e2004-05-18 18:57:06 +00001016 /* LSA checksum */
1017 ospf6_lsa_checksum (lsa_header);
paul718e3742002-12-13 20:15:29 +00001018
hasso508e53e2004-05-18 18:57:06 +00001019 /* create LSA */
1020 lsa = ospf6_lsa_create (lsa_header);
paul718e3742002-12-13 20:15:29 +00001021
hasso508e53e2004-05-18 18:57:06 +00001022 /* Originate */
hasso6452df02004-08-15 05:52:07 +00001023 ospf6_lsa_originate_area (lsa, oi->area);
paul718e3742002-12-13 20:15:29 +00001024
1025 return 0;
1026}
1027
1028void
hasso508e53e2004-05-18 18:57:06 +00001029ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001030{
hasso508e53e2004-05-18 18:57:06 +00001031 struct ospf6_area *oa;
1032 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1033 struct prefix ls_prefix;
1034 struct ospf6_route *route, *ls_entry;
1035 int i, prefix_num;
1036 struct ospf6_prefix *op;
1037 char *start, *current, *end;
1038 char buf[64];
paul718e3742002-12-13 20:15:29 +00001039
hassoccb59b12004-08-25 09:10:37 +00001040 if (OSPF6_LSA_IS_MAXAGE (lsa))
1041 return;
1042
hasso1e058382004-09-01 21:36:14 +00001043 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001044 zlog_debug ("%s found", lsa->name);
paul718e3742002-12-13 20:15:29 +00001045
hasso6452df02004-08-15 05:52:07 +00001046 oa = OSPF6_AREA (lsa->lsdb->data);
1047
hasso508e53e2004-05-18 18:57:06 +00001048 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1049 OSPF6_LSA_HEADER_END (lsa->header);
1050 if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
1051 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1052 htonl (0), &ls_prefix);
1053 else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
1054 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1055 intra_prefix_lsa->ref_id, &ls_prefix);
1056 else
1057 {
hasso1e058382004-09-01 21:36:14 +00001058 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001059 zlog_debug ("Unknown reference LS-type: %#hx",
1060 ntohs (intra_prefix_lsa->ref_type));
hasso508e53e2004-05-18 18:57:06 +00001061 return;
1062 }
paul718e3742002-12-13 20:15:29 +00001063
hasso508e53e2004-05-18 18:57:06 +00001064 ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
1065 if (ls_entry == NULL)
1066 {
hasso1e058382004-09-01 21:36:14 +00001067 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001068 {
1069 ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001070 zlog_debug ("LS entry does not exist: %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001071 }
1072 return;
1073 }
paul718e3742002-12-13 20:15:29 +00001074
hasso508e53e2004-05-18 18:57:06 +00001075 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1076 start = (caddr_t) intra_prefix_lsa +
1077 sizeof (struct ospf6_intra_prefix_lsa);
1078 end = OSPF6_LSA_END (lsa->header);
1079 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1080 {
1081 op = (struct ospf6_prefix *) current;
1082 if (prefix_num == 0)
1083 break;
1084 if (end < current + OSPF6_PREFIX_SIZE (op))
1085 break;
1086
1087 route = ospf6_route_create ();
hassoccb59b12004-08-25 09:10:37 +00001088
1089 memset (&route->prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001090 route->prefix.family = AF_INET6;
hassoccb59b12004-08-25 09:10:37 +00001091 route->prefix.prefixlen = op->prefix_length;
1092 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
1093
hasso508e53e2004-05-18 18:57:06 +00001094 route->type = OSPF6_DEST_TYPE_NETWORK;
1095 route->path.origin.type = lsa->header->type;
1096 route->path.origin.id = lsa->header->id;
1097 route->path.origin.adv_router = lsa->header->adv_router;
1098 route->path.prefix_options = op->prefix_options;
1099 route->path.area_id = oa->area_id;
1100 route->path.type = OSPF6_PATH_TYPE_INTRA;
1101 route->path.metric_type = 1;
1102 route->path.cost = ls_entry->path.cost +
1103 ntohs (op->prefix_metric);
1104
1105 for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
1106 i < OSPF6_MULTI_PATH_LIMIT; i++)
1107 ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
1108
hasso1e058382004-09-01 21:36:14 +00001109 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001110 {
1111 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001112 zlog_debug (" add %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001113 }
1114
1115 ospf6_route_add (route, oa->route_table);
1116 prefix_num--;
1117 }
1118
hasso1e058382004-09-01 21:36:14 +00001119 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001120 zlog_debug ("Trailing garbage ignored");
paul718e3742002-12-13 20:15:29 +00001121}
1122
1123void
hasso508e53e2004-05-18 18:57:06 +00001124ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001125{
hasso508e53e2004-05-18 18:57:06 +00001126 struct ospf6_area *oa;
1127 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1128 struct prefix prefix;
1129 struct ospf6_route *route;
1130 int prefix_num;
1131 struct ospf6_prefix *op;
1132 char *start, *current, *end;
1133 char buf[64];
1134
hasso1e058382004-09-01 21:36:14 +00001135 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001136 zlog_debug ("%s disappearing", lsa->name);
hasso508e53e2004-05-18 18:57:06 +00001137
hasso6452df02004-08-15 05:52:07 +00001138 oa = OSPF6_AREA (lsa->lsdb->data);
1139
hasso508e53e2004-05-18 18:57:06 +00001140 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1141 OSPF6_LSA_HEADER_END (lsa->header);
1142
1143 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1144 start = (caddr_t) intra_prefix_lsa +
1145 sizeof (struct ospf6_intra_prefix_lsa);
1146 end = OSPF6_LSA_END (lsa->header);
1147 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1148 {
1149 op = (struct ospf6_prefix *) current;
1150 if (prefix_num == 0)
1151 break;
1152 if (end < current + OSPF6_PREFIX_SIZE (op))
1153 break;
1154 prefix_num--;
1155
hassoccb59b12004-08-25 09:10:37 +00001156 memset (&prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001157 prefix.family = AF_INET6;
1158 prefix.prefixlen = op->prefix_length;
1159 ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
1160
1161 route = ospf6_route_lookup (&prefix, oa->route_table);
1162 if (route == NULL)
1163 continue;
1164
1165 for (ospf6_route_lock (route);
1166 route && ospf6_route_is_prefix (&prefix, route);
1167 route = ospf6_route_next (route))
1168 {
1169 if (route->type != OSPF6_DEST_TYPE_NETWORK)
1170 continue;
1171 if (route->path.area_id != oa->area_id)
1172 continue;
1173 if (route->path.type != OSPF6_PATH_TYPE_INTRA)
1174 continue;
1175 if (route->path.origin.type != lsa->header->type ||
1176 route->path.origin.id != lsa->header->id ||
1177 route->path.origin.adv_router != lsa->header->adv_router)
1178 continue;
1179
hasso1e058382004-09-01 21:36:14 +00001180 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001181 {
1182 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001183 zlog_debug ("remove %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001184 }
1185 ospf6_route_remove (route, oa->route_table);
1186 }
1187 }
1188
hasso1e058382004-09-01 21:36:14 +00001189 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001190 zlog_debug ("Trailing garbage ignored");
paul718e3742002-12-13 20:15:29 +00001191}
1192
1193void
hasso508e53e2004-05-18 18:57:06 +00001194ospf6_intra_route_calculation (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +00001195{
hasso508e53e2004-05-18 18:57:06 +00001196 struct ospf6_route *route;
1197 u_int16_t type;
1198 struct ospf6_lsa *lsa;
1199 void (*hook_add) (struct ospf6_route *) = NULL;
1200 void (*hook_remove) (struct ospf6_route *) = NULL;
1201
hasso1e058382004-09-01 21:36:14 +00001202 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001203 zlog_debug ("Re-examin intra-routes for area %s", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001204
1205 hook_add = oa->route_table->hook_add;
1206 hook_remove = oa->route_table->hook_remove;
1207 oa->route_table->hook_add = NULL;
1208 oa->route_table->hook_remove = NULL;
1209
1210 for (route = ospf6_route_head (oa->route_table); route;
1211 route = ospf6_route_next (route))
1212 route->flag = OSPF6_ROUTE_REMOVE;
1213
1214 type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1215 for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
1216 lsa = ospf6_lsdb_type_next (type, lsa))
1217 ospf6_intra_prefix_lsa_add (lsa);
1218
1219 oa->route_table->hook_add = hook_add;
1220 oa->route_table->hook_remove = hook_remove;
1221
1222 for (route = ospf6_route_head (oa->route_table); route;
1223 route = ospf6_route_next (route))
1224 {
1225 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
1226 CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
1227 {
1228 UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
1229 UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
1230 }
1231
1232 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
1233 ospf6_route_remove (route, oa->route_table);
1234 else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
1235 CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
1236 {
1237 if (hook_add)
1238 (*hook_add) (route);
1239 }
1240
1241 route->flag = 0;
1242 }
1243
hasso1e058382004-09-01 21:36:14 +00001244 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001245 zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001246}
1247
1248void
hasso6452df02004-08-15 05:52:07 +00001249ospf6_intra_brouter_calculation (struct ospf6_area *oa)
hasso508e53e2004-05-18 18:57:06 +00001250{
1251 struct ospf6_route *lsentry, *copy;
1252 void (*hook_add) (struct ospf6_route *) = NULL;
1253 void (*hook_remove) (struct ospf6_route *) = NULL;
hassoccb59b12004-08-25 09:10:37 +00001254 char buf[16];
hasso508e53e2004-05-18 18:57:06 +00001255
hasso6452df02004-08-15 05:52:07 +00001256 if (IS_OSPF6_DEBUG_ROUTE (INTRA))
hassoc6487d62004-12-24 06:00:11 +00001257 zlog_debug ("Border-router calculation for area %s", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001258
hasso6452df02004-08-15 05:52:07 +00001259 hook_add = oa->ospf6->brouter_table->hook_add;
1260 hook_remove = oa->ospf6->brouter_table->hook_remove;
1261 oa->ospf6->brouter_table->hook_add = NULL;
1262 oa->ospf6->brouter_table->hook_remove = NULL;
hasso508e53e2004-05-18 18:57:06 +00001263
hasso6452df02004-08-15 05:52:07 +00001264 /* withdraw the previous router entries for the area */
1265 for (lsentry = ospf6_route_head (oa->ospf6->brouter_table); lsentry;
hasso508e53e2004-05-18 18:57:06 +00001266 lsentry = ospf6_route_next (lsentry))
1267 {
1268 if (lsentry->path.area_id != oa->area_id)
1269 continue;
1270 lsentry->flag = OSPF6_ROUTE_REMOVE;
1271 }
1272
1273 for (lsentry = ospf6_route_head (oa->spf_table); lsentry;
1274 lsentry = ospf6_route_next (lsentry))
1275 {
1276 if (lsentry->type != OSPF6_DEST_TYPE_LINKSTATE)
1277 continue;
1278 if (ospf6_linkstate_prefix_id (&lsentry->prefix) != htonl (0))
1279 continue;
hasso6452df02004-08-15 05:52:07 +00001280 if (! CHECK_FLAG (lsentry->path.router_bits, OSPF6_ROUTER_BIT_E) &&
1281 ! CHECK_FLAG (lsentry->path.router_bits, OSPF6_ROUTER_BIT_B))
hasso508e53e2004-05-18 18:57:06 +00001282 continue;
1283
1284 copy = ospf6_route_copy (lsentry);
1285 copy->type = OSPF6_DEST_TYPE_ROUTER;
hassoccb59b12004-08-25 09:10:37 +00001286 copy->path.area_id = oa->area_id;
hasso6452df02004-08-15 05:52:07 +00001287 ospf6_route_add (copy, oa->ospf6->brouter_table);
hassoccb59b12004-08-25 09:10:37 +00001288
1289 if (IS_OSPF6_DEBUG_ROUTE (INTRA))
1290 {
1291 inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&copy->prefix),
1292 buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001293 zlog_debug ("Re-install router entry %s", buf);
hassoccb59b12004-08-25 09:10:37 +00001294 }
hasso508e53e2004-05-18 18:57:06 +00001295 }
1296
hasso6452df02004-08-15 05:52:07 +00001297 oa->ospf6->brouter_table->hook_add = hook_add;
1298 oa->ospf6->brouter_table->hook_remove = hook_remove;
hasso508e53e2004-05-18 18:57:06 +00001299
hasso6452df02004-08-15 05:52:07 +00001300 for (lsentry = ospf6_route_head (oa->ospf6->brouter_table); lsentry;
hasso508e53e2004-05-18 18:57:06 +00001301 lsentry = ospf6_route_next (lsentry))
1302 {
1303 if (lsentry->path.area_id != oa->area_id)
1304 continue;
1305
hasso9428f2d2004-09-13 14:01:12 +00001306 if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_WAS_REMOVED))
1307 continue;
1308
hasso508e53e2004-05-18 18:57:06 +00001309 if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_REMOVE) &&
1310 CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_ADD))
1311 {
1312 UNSET_FLAG (lsentry->flag, OSPF6_ROUTE_REMOVE);
1313 UNSET_FLAG (lsentry->flag, OSPF6_ROUTE_ADD);
1314 }
1315
1316 if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_REMOVE))
hasso6452df02004-08-15 05:52:07 +00001317 ospf6_route_remove (lsentry, oa->ospf6->brouter_table);
hasso508e53e2004-05-18 18:57:06 +00001318 else if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_ADD) ||
1319 CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_CHANGE))
1320 {
hassoccb59b12004-08-25 09:10:37 +00001321 if (IS_OSPF6_DEBUG_ROUTE (INTRA))
1322 {
1323 inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&lsentry->prefix),
1324 buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001325 zlog_debug ("Call hook for router entry %s", buf);
hassoccb59b12004-08-25 09:10:37 +00001326 }
hasso508e53e2004-05-18 18:57:06 +00001327 if (hook_add)
1328 (*hook_add) (lsentry);
1329 }
1330
1331 lsentry->flag = 0;
1332 }
1333
hasso6452df02004-08-15 05:52:07 +00001334 if (IS_OSPF6_DEBUG_ROUTE (INTRA))
hassoc6487d62004-12-24 06:00:11 +00001335 zlog_debug ("Border-router calculation for area %s: Done", oa->name);
paul718e3742002-12-13 20:15:29 +00001336}
1337
hasso6452df02004-08-15 05:52:07 +00001338struct ospf6_lsa_handler router_handler =
1339{
1340 OSPF6_LSTYPE_ROUTER,
1341 "Router",
1342 ospf6_router_lsa_show
1343};
1344
1345struct ospf6_lsa_handler network_handler =
1346{
1347 OSPF6_LSTYPE_NETWORK,
1348 "Network",
1349 ospf6_network_lsa_show
1350};
1351
1352struct ospf6_lsa_handler link_handler =
1353{
1354 OSPF6_LSTYPE_LINK,
1355 "Link",
1356 ospf6_link_lsa_show
1357};
1358
1359struct ospf6_lsa_handler intra_prefix_handler =
1360{
1361 OSPF6_LSTYPE_INTRA_PREFIX,
1362 "Intra-Prefix",
1363 ospf6_intra_prefix_lsa_show
1364};
1365
paul718e3742002-12-13 20:15:29 +00001366void
1367ospf6_intra_init ()
1368{
hasso6452df02004-08-15 05:52:07 +00001369 ospf6_install_lsa_handler (&router_handler);
1370 ospf6_install_lsa_handler (&network_handler);
1371 ospf6_install_lsa_handler (&link_handler);
1372 ospf6_install_lsa_handler (&intra_prefix_handler);
paul718e3742002-12-13 20:15:29 +00001373}
1374
1375