blob: 86f414606039d60cf16ac2e624cce97c9b7455d2 [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
Paul Jakmacb4b8842006-05-15 10:39:30 +000050
51unsigned char conf_debug_ospf6_brouter = 0;
52u_int32_t conf_debug_ospf6_brouter_specific_router_id;
53u_int32_t conf_debug_ospf6_brouter_specific_area_id;
54
hasso508e53e2004-05-18 18:57:06 +000055/******************************/
56/* RFC2740 3.4.3.1 Router-LSA */
57/******************************/
paul718e3742002-12-13 20:15:29 +000058
Paul Jakma6ac29a52008-08-15 13:45:30 +010059static int
hasso508e53e2004-05-18 18:57:06 +000060ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +000061{
hasso508e53e2004-05-18 18:57:06 +000062 char *start, *end, *current;
63 char buf[32], name[32], bits[16], options[32];
64 struct ospf6_router_lsa *router_lsa;
65 struct ospf6_router_lsdesc *lsdesc;
paul718e3742002-12-13 20:15:29 +000066
hasso508e53e2004-05-18 18:57:06 +000067 router_lsa = (struct ospf6_router_lsa *)
68 ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +000069
hasso508e53e2004-05-18 18:57:06 +000070 ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
71 ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
hasso049207c2004-08-04 20:02:13 +000072 vty_out (vty, " Bits: %s Options: %s%s", bits, options, VNL);
paul718e3742002-12-13 20:15:29 +000073
hasso508e53e2004-05-18 18:57:06 +000074 start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
paul718e3742002-12-13 20:15:29 +000075 end = (char *) lsa->header + ntohs (lsa->header->length);
hasso508e53e2004-05-18 18:57:06 +000076 for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end;
77 current += sizeof (struct ospf6_router_lsdesc))
paul718e3742002-12-13 20:15:29 +000078 {
hasso508e53e2004-05-18 18:57:06 +000079 lsdesc = (struct ospf6_router_lsdesc *) current;
paul718e3742002-12-13 20:15:29 +000080
hasso508e53e2004-05-18 18:57:06 +000081 if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT)
82 snprintf (name, sizeof (name), "Point-To-Point");
83 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK)
84 snprintf (name, sizeof (name), "Transit-Network");
85 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK)
86 snprintf (name, sizeof (name), "Stub-Network");
87 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK)
88 snprintf (name, sizeof (name), "Virtual-Link");
paul718e3742002-12-13 20:15:29 +000089 else
hasso508e53e2004-05-18 18:57:06 +000090 snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
paul718e3742002-12-13 20:15:29 +000091
hasso508e53e2004-05-18 18:57:06 +000092 vty_out (vty, " Type: %s Metric: %d%s",
hasso049207c2004-08-04 20:02:13 +000093 name, ntohs (lsdesc->metric), VNL);
hasso508e53e2004-05-18 18:57:06 +000094 vty_out (vty, " Interface ID: %s%s",
95 inet_ntop (AF_INET, &lsdesc->interface_id,
hasso049207c2004-08-04 20:02:13 +000096 buf, sizeof (buf)), VNL);
hasso508e53e2004-05-18 18:57:06 +000097 vty_out (vty, " Neighbor Interface ID: %s%s",
98 inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
hasso049207c2004-08-04 20:02:13 +000099 buf, sizeof (buf)), VNL);
hasso508e53e2004-05-18 18:57:06 +0000100 vty_out (vty, " Neighbor Router ID: %s%s",
101 inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
hasso049207c2004-08-04 20:02:13 +0000102 buf, sizeof (buf)), VNL);
paul718e3742002-12-13 20:15:29 +0000103 }
104 return 0;
105}
106
hasso6452df02004-08-15 05:52:07 +0000107int
108ospf6_router_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000109{
hasso6452df02004-08-15 05:52:07 +0000110 struct ospf6_area *oa;
111
hasso508e53e2004-05-18 18:57:06 +0000112 char buffer [OSPF6_MAX_LSASIZE];
113 struct ospf6_lsa_header *lsa_header;
114 struct ospf6_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000115
hasso508e53e2004-05-18 18:57:06 +0000116 u_int32_t link_state_id = 0;
paul1eb8ef22005-04-07 07:30:20 +0000117 struct listnode *node, *nnode;
118 struct listnode *j;
hasso508e53e2004-05-18 18:57:06 +0000119 struct ospf6_interface *oi;
120 struct ospf6_neighbor *on, *drouter = NULL;
121 struct ospf6_router_lsa *router_lsa;
122 struct ospf6_router_lsdesc *lsdesc;
123 u_int16_t type;
124 u_int32_t router;
125 int count;
paul718e3742002-12-13 20:15:29 +0000126
hasso6452df02004-08-15 05:52:07 +0000127 oa = (struct ospf6_area *) THREAD_ARG (thread);
128 oa->thread_router_lsa = NULL;
129
hasso1e058382004-09-01 21:36:14 +0000130 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
hassoc6487d62004-12-24 06:00:11 +0000131 zlog_debug ("Originate Router-LSA for Area %s", oa->name);
paul718e3742002-12-13 20:15:29 +0000132
hasso508e53e2004-05-18 18:57:06 +0000133 memset (buffer, 0, sizeof (buffer));
134 lsa_header = (struct ospf6_lsa_header *) buffer;
135 router_lsa = (struct ospf6_router_lsa *)
136 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
137
138 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
139 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
140 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
141 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
142 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
143 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
144
hasso6452df02004-08-15 05:52:07 +0000145 if (ospf6_is_router_abr (ospf6))
146 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
147 else
148 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
hasso508e53e2004-05-18 18:57:06 +0000149 if (ospf6_asbr_is_asbr (ospf6))
150 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
151 else
152 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
153 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
154 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
155
156 /* describe links for each interfaces */
157 lsdesc = (struct ospf6_router_lsdesc *)
158 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
159
paul1eb8ef22005-04-07 07:30:20 +0000160 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +0000161 {
hasso508e53e2004-05-18 18:57:06 +0000162 /* Interfaces in state Down or Loopback are not described */
163 if (oi->state == OSPF6_INTERFACE_DOWN ||
164 oi->state == OSPF6_INTERFACE_LOOPBACK)
paul718e3742002-12-13 20:15:29 +0000165 continue;
166
hasso508e53e2004-05-18 18:57:06 +0000167 /* Nor are interfaces without any full adjacencies described */
168 count = 0;
paul1eb8ef22005-04-07 07:30:20 +0000169 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
170 if (on->state == OSPF6_NEIGHBOR_FULL)
171 count++;
172
hasso508e53e2004-05-18 18:57:06 +0000173 if (count == 0)
174 continue;
175
176 /* Multiple Router-LSA instance according to size limit setting */
paul0c083ee2004-10-10 12:54:58 +0000177 if ( (oa->router_lsa_size_limit != 0)
178 && ((caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) -
gdt1686f932004-12-09 14:47:09 +0000179 /* XXX warning: comparison between signed and unsigned */
paul0c083ee2004-10-10 12:54:58 +0000180 (caddr_t) buffer > oa->router_lsa_size_limit))
hasso508e53e2004-05-18 18:57:06 +0000181 {
182 if ((caddr_t) lsdesc == (caddr_t) router_lsa +
183 sizeof (struct ospf6_router_lsa))
184 {
hasso1e058382004-09-01 21:36:14 +0000185 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
hassoc6487d62004-12-24 06:00:11 +0000186 zlog_debug ("Size limit setting for Router-LSA too short");
hasso6452df02004-08-15 05:52:07 +0000187 return 0;
hasso508e53e2004-05-18 18:57:06 +0000188 }
189
190 /* Fill LSA Header */
191 lsa_header->age = 0;
192 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
193 lsa_header->id = htonl (link_state_id);
194 lsa_header->adv_router = oa->ospf6->router_id;
195 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000196 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
197 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000198 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
199
200 /* LSA checksum */
201 ospf6_lsa_checksum (lsa_header);
202
203 /* create LSA */
204 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000205
206 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000207 ospf6_lsa_originate_area (lsa, oa);
hasso508e53e2004-05-18 18:57:06 +0000208
209 /* Reset setting for consecutive origination */
210 memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
211 0, (caddr_t) lsdesc - (caddr_t) router_lsa);
212 lsdesc = (struct ospf6_router_lsdesc *)
213 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
214 link_state_id ++;
paul718e3742002-12-13 20:15:29 +0000215 }
216
hasso508e53e2004-05-18 18:57:06 +0000217 /* Point-to-Point interfaces */
Dinesh Duttc5926a92013-08-24 07:55:00 +0000218 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
hasso508e53e2004-05-18 18:57:06 +0000219 {
paul1eb8ef22005-04-07 07:30:20 +0000220 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
hasso508e53e2004-05-18 18:57:06 +0000221 {
hasso508e53e2004-05-18 18:57:06 +0000222 if (on->state != OSPF6_NEIGHBOR_FULL)
223 continue;
paul718e3742002-12-13 20:15:29 +0000224
hasso508e53e2004-05-18 18:57:06 +0000225 lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
226 lsdesc->metric = htons (oi->cost);
227 lsdesc->interface_id = htonl (oi->interface->ifindex);
228 lsdesc->neighbor_interface_id = htonl (on->ifindex);
229 lsdesc->neighbor_router_id = on->router_id;
230
231 lsdesc++;
232 }
233 }
234
235 /* Broadcast and NBMA interfaces */
Dinesh Duttc5926a92013-08-24 07:55:00 +0000236 else if (oi->type == OSPF_IFTYPE_BROADCAST)
hasso508e53e2004-05-18 18:57:06 +0000237 {
238 /* If this router is not DR,
239 and If this router not fully adjacent with DR,
240 this interface is not transit yet: ignore. */
241 if (oi->state != OSPF6_INTERFACE_DR)
242 {
243 drouter = ospf6_neighbor_lookup (oi->drouter, oi);
244 if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
245 continue;
246 }
247
248 lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
249 lsdesc->metric = htons (oi->cost);
250 lsdesc->interface_id = htonl (oi->interface->ifindex);
251 if (oi->state != OSPF6_INTERFACE_DR)
252 {
253 lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
254 lsdesc->neighbor_router_id = drouter->router_id;
255 }
256 else
257 {
258 lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
259 lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
260 }
261
262 lsdesc++;
263 }
Dinesh Duttc5926a92013-08-24 07:55:00 +0000264 else
265 {
266 assert (0); /* Unknown interface type */
267 }
hasso508e53e2004-05-18 18:57:06 +0000268
269 /* Virtual links */
270 /* xxx */
271 /* Point-to-Multipoint interfaces */
272 /* xxx */
paul718e3742002-12-13 20:15:29 +0000273 }
hasso508e53e2004-05-18 18:57:06 +0000274
275 if ((caddr_t) lsdesc != (caddr_t) router_lsa +
276 sizeof (struct ospf6_router_lsa))
277 {
278 /* Fill LSA Header */
279 lsa_header->age = 0;
280 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
281 lsa_header->id = htonl (link_state_id);
282 lsa_header->adv_router = oa->ospf6->router_id;
283 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000284 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
285 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000286 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
287
288 /* LSA checksum */
289 ospf6_lsa_checksum (lsa_header);
290
291 /* create LSA */
292 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000293
294 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000295 ospf6_lsa_originate_area (lsa, oa);
hasso508e53e2004-05-18 18:57:06 +0000296
297 link_state_id ++;
298 }
hasso6452df02004-08-15 05:52:07 +0000299 else
300 {
hasso1e058382004-09-01 21:36:14 +0000301 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
hassoc6487d62004-12-24 06:00:11 +0000302 zlog_debug ("Nothing to describe in Router-LSA, suppress");
hasso6452df02004-08-15 05:52:07 +0000303 }
hasso508e53e2004-05-18 18:57:06 +0000304
305 /* Do premature-aging of rest, undesired Router-LSAs */
306 type = ntohs (OSPF6_LSTYPE_ROUTER);
307 router = oa->ospf6->router_id;
308 for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
309 lsa = ospf6_lsdb_type_router_next (type, router, lsa))
310 {
311 if (ntohl (lsa->header->id) < link_state_id)
312 continue;
hasso6452df02004-08-15 05:52:07 +0000313 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000314 }
hasso508e53e2004-05-18 18:57:06 +0000315
316 return 0;
317}
318
hasso508e53e2004-05-18 18:57:06 +0000319/*******************************/
320/* RFC2740 3.4.3.2 Network-LSA */
321/*******************************/
322
Paul Jakma6ac29a52008-08-15 13:45:30 +0100323static int
hasso508e53e2004-05-18 18:57:06 +0000324ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
325{
326 char *start, *end, *current;
327 struct ospf6_network_lsa *network_lsa;
328 struct ospf6_network_lsdesc *lsdesc;
329 char buf[128], options[32];
330
331 network_lsa = (struct ospf6_network_lsa *)
332 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
333
334 ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
hasso049207c2004-08-04 20:02:13 +0000335 vty_out (vty, " Options: %s%s", options, VNL);
hasso508e53e2004-05-18 18:57:06 +0000336
337 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
338 end = (char *) lsa->header + ntohs (lsa->header->length);
339 for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
340 current += sizeof (struct ospf6_network_lsdesc))
341 {
342 lsdesc = (struct ospf6_network_lsdesc *) current;
343 inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +0000344 vty_out (vty, " Attached Router: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +0000345 }
346 return 0;
paul718e3742002-12-13 20:15:29 +0000347}
348
hasso6452df02004-08-15 05:52:07 +0000349int
350ospf6_network_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000351{
hasso6452df02004-08-15 05:52:07 +0000352 struct ospf6_interface *oi;
353
hasso508e53e2004-05-18 18:57:06 +0000354 char buffer [OSPF6_MAX_LSASIZE];
355 struct ospf6_lsa_header *lsa_header;
paul718e3742002-12-13 20:15:29 +0000356
hasso508e53e2004-05-18 18:57:06 +0000357 int count;
358 struct ospf6_lsa *old, *lsa;
359 struct ospf6_network_lsa *network_lsa;
360 struct ospf6_network_lsdesc *lsdesc;
361 struct ospf6_neighbor *on;
362 struct ospf6_link_lsa *link_lsa;
hasso52dc7ee2004-09-23 19:18:23 +0000363 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000364 u_int16_t type;
365
hasso6452df02004-08-15 05:52:07 +0000366 oi = (struct ospf6_interface *) THREAD_ARG (thread);
367 oi->thread_network_lsa = NULL;
368
369 /* The interface must be enabled until here. A Network-LSA of a
370 disabled interface (but was once enabled) should be flushed
371 by ospf6_lsa_refresh (), and does not come here. */
372 assert (oi->area);
paul718e3742002-12-13 20:15:29 +0000373
hasso508e53e2004-05-18 18:57:06 +0000374 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
375 htonl (oi->interface->ifindex),
376 oi->area->ospf6->router_id, oi->area->lsdb);
paul718e3742002-12-13 20:15:29 +0000377
hasso508e53e2004-05-18 18:57:06 +0000378 /* Do not originate Network-LSA if not DR */
379 if (oi->state != OSPF6_INTERFACE_DR)
paul718e3742002-12-13 20:15:29 +0000380 {
hasso508e53e2004-05-18 18:57:06 +0000381 if (old)
hasso6452df02004-08-15 05:52:07 +0000382 ospf6_lsa_purge (old);
383 return 0;
paul718e3742002-12-13 20:15:29 +0000384 }
hasso508e53e2004-05-18 18:57:06 +0000385
hasso1e058382004-09-01 21:36:14 +0000386 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
hassoc6487d62004-12-24 06:00:11 +0000387 zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000388
389 /* If none of neighbor is adjacent to us */
390 count = 0;
paul1eb8ef22005-04-07 07:30:20 +0000391
392 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
393 if (on->state == OSPF6_NEIGHBOR_FULL)
394 count++;
395
hasso508e53e2004-05-18 18:57:06 +0000396 if (count == 0)
397 {
hasso1e058382004-09-01 21:36:14 +0000398 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
hassoc6487d62004-12-24 06:00:11 +0000399 zlog_debug ("Interface stub, ignore");
hasso508e53e2004-05-18 18:57:06 +0000400 if (old)
hasso6452df02004-08-15 05:52:07 +0000401 ospf6_lsa_purge (old);
402 return 0;
hasso508e53e2004-05-18 18:57:06 +0000403 }
404
405 /* prepare buffer */
406 memset (buffer, 0, sizeof (buffer));
407 lsa_header = (struct ospf6_lsa_header *) buffer;
408 network_lsa = (struct ospf6_network_lsa *)
409 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
410
411 /* Collect the interface's Link-LSAs to describe
412 network's optional capabilities */
413 type = htons (OSPF6_LSTYPE_LINK);
414 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
415 lsa = ospf6_lsdb_type_next (type, lsa))
416 {
417 link_lsa = (struct ospf6_link_lsa *)
418 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
419 network_lsa->options[0] |= link_lsa->options[0];
420 network_lsa->options[1] |= link_lsa->options[1];
421 network_lsa->options[2] |= link_lsa->options[2];
422 }
423
424 lsdesc = (struct ospf6_network_lsdesc *)
425 ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
426
427 /* set Link Description to the router itself */
428 lsdesc->router_id = oi->area->ospf6->router_id;
429 lsdesc++;
430
431 /* Walk through the neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000432 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
hasso508e53e2004-05-18 18:57:06 +0000433 {
hasso508e53e2004-05-18 18:57:06 +0000434 if (on->state != OSPF6_NEIGHBOR_FULL)
435 continue;
436
437 /* set this neighbor's Router-ID to LSA */
438 lsdesc->router_id = on->router_id;
439 lsdesc++;
440 }
441
442 /* Fill LSA Header */
443 lsa_header->age = 0;
444 lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
445 lsa_header->id = htonl (oi->interface->ifindex);
446 lsa_header->adv_router = oi->area->ospf6->router_id;
447 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000448 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
449 lsa_header->adv_router, oi->area->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000450 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
451
452 /* LSA checksum */
453 ospf6_lsa_checksum (lsa_header);
454
455 /* create LSA */
456 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000457
458 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000459 ospf6_lsa_originate_area (lsa, oi->area);
hasso508e53e2004-05-18 18:57:06 +0000460
461 return 0;
462}
463
464
465/****************************/
466/* RFC2740 3.4.3.6 Link-LSA */
467/****************************/
468
Paul Jakma6ac29a52008-08-15 13:45:30 +0100469static int
hasso508e53e2004-05-18 18:57:06 +0000470ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
471{
paul718e3742002-12-13 20:15:29 +0000472 char *start, *end, *current;
hasso508e53e2004-05-18 18:57:06 +0000473 struct ospf6_link_lsa *link_lsa;
474 int prefixnum;
475 char buf[128], options[32];
476 struct ospf6_prefix *prefix;
paul0c083ee2004-10-10 12:54:58 +0000477 const char *p, *mc, *la, *nu;
hasso508e53e2004-05-18 18:57:06 +0000478 struct in6_addr in6;
paul718e3742002-12-13 20:15:29 +0000479
hasso508e53e2004-05-18 18:57:06 +0000480 link_lsa = (struct ospf6_link_lsa *)
481 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +0000482
hasso508e53e2004-05-18 18:57:06 +0000483 ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
484 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
485 prefixnum = ntohl (link_lsa->prefix_num);
paul718e3742002-12-13 20:15:29 +0000486
hasso508e53e2004-05-18 18:57:06 +0000487 vty_out (vty, " Priority: %d Options: %s%s",
hasso049207c2004-08-04 20:02:13 +0000488 link_lsa->priority, options, VNL);
489 vty_out (vty, " LinkLocal Address: %s%s", buf, VNL);
490 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
paul718e3742002-12-13 20:15:29 +0000491
hasso508e53e2004-05-18 18:57:06 +0000492 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
493 end = (char *) lsa->header + ntohs (lsa->header->length);
paul718e3742002-12-13 20:15:29 +0000494 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
495 {
496 prefix = (struct ospf6_prefix *) current;
hasso508e53e2004-05-18 18:57:06 +0000497 if (prefix->prefix_length == 0 ||
498 current + OSPF6_PREFIX_SIZE (prefix) > end)
499 break;
paul718e3742002-12-13 20:15:29 +0000500
hasso508e53e2004-05-18 18:57:06 +0000501 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
502 "P" : "--");
503 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
504 "MC" : "--");
505 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
506 "LA" : "--");
507 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
508 "NU" : "--");
509 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
hasso049207c2004-08-04 20:02:13 +0000510 p, mc, la, nu, VNL);
paul718e3742002-12-13 20:15:29 +0000511
hasso508e53e2004-05-18 18:57:06 +0000512 memset (&in6, 0, sizeof (in6));
513 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
514 OSPF6_PREFIX_SPACE (prefix->prefix_length));
paul718e3742002-12-13 20:15:29 +0000515 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
516 vty_out (vty, " Prefix: %s/%d%s",
hasso049207c2004-08-04 20:02:13 +0000517 buf, prefix->prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +0000518 }
519
520 return 0;
521}
522
hasso6452df02004-08-15 05:52:07 +0000523int
524ospf6_link_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000525{
hasso6452df02004-08-15 05:52:07 +0000526 struct ospf6_interface *oi;
527
hasso508e53e2004-05-18 18:57:06 +0000528 char buffer[OSPF6_MAX_LSASIZE];
529 struct ospf6_lsa_header *lsa_header;
530 struct ospf6_lsa *old, *lsa;
paul718e3742002-12-13 20:15:29 +0000531
hasso508e53e2004-05-18 18:57:06 +0000532 struct ospf6_link_lsa *link_lsa;
533 struct ospf6_route *route;
534 struct ospf6_prefix *op;
paul718e3742002-12-13 20:15:29 +0000535
hasso6452df02004-08-15 05:52:07 +0000536 oi = (struct ospf6_interface *) THREAD_ARG (thread);
537 oi->thread_link_lsa = NULL;
538
539 assert (oi->area);
paul718e3742002-12-13 20:15:29 +0000540
541 /* find previous LSA */
hasso508e53e2004-05-18 18:57:06 +0000542 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
543 htonl (oi->interface->ifindex),
544 oi->area->ospf6->router_id, oi->lsdb);
paul718e3742002-12-13 20:15:29 +0000545
hasso508e53e2004-05-18 18:57:06 +0000546 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
paul718e3742002-12-13 20:15:29 +0000547 {
548 if (old)
hasso6452df02004-08-15 05:52:07 +0000549 ospf6_lsa_purge (old);
550 return 0;
paul718e3742002-12-13 20:15:29 +0000551 }
552
hasso1e058382004-09-01 21:36:14 +0000553 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
hassoc6487d62004-12-24 06:00:11 +0000554 zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
paul718e3742002-12-13 20:15:29 +0000555
hasso508e53e2004-05-18 18:57:06 +0000556 /* can't make Link-LSA if linklocal address not set */
557 if (oi->linklocal_addr == NULL)
paul718e3742002-12-13 20:15:29 +0000558 {
hasso1e058382004-09-01 21:36:14 +0000559 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
hassoc6487d62004-12-24 06:00:11 +0000560 zlog_debug ("No Linklocal address on %s, defer originating",
hasso508e53e2004-05-18 18:57:06 +0000561 oi->interface->name);
562 if (old)
hasso6452df02004-08-15 05:52:07 +0000563 ospf6_lsa_purge (old);
564 return 0;
hasso508e53e2004-05-18 18:57:06 +0000565 }
566
567 /* prepare buffer */
568 memset (buffer, 0, sizeof (buffer));
569 lsa_header = (struct ospf6_lsa_header *) buffer;
570 link_lsa = (struct ospf6_link_lsa *)
571 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
572
573 /* Fill Link-LSA */
574 link_lsa->priority = oi->priority;
575 memcpy (link_lsa->options, oi->area->options, 3);
576 memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
577 sizeof (struct in6_addr));
578 link_lsa->prefix_num = htonl (oi->route_connected->count);
579
580 op = (struct ospf6_prefix *)
581 ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
582
583 /* connected prefix to advertise */
584 for (route = ospf6_route_head (oi->route_connected); route;
585 route = ospf6_route_next (route))
586 {
587 op->prefix_length = route->prefix.prefixlen;
588 op->prefix_options = route->path.prefix_options;
589 op->prefix_metric = htons (0);
590 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
591 OSPF6_PREFIX_SPACE (op->prefix_length));
592 op = OSPF6_PREFIX_NEXT (op);
593 }
594
595 /* Fill LSA Header */
596 lsa_header->age = 0;
597 lsa_header->type = htons (OSPF6_LSTYPE_LINK);
598 lsa_header->id = htonl (oi->interface->ifindex);
599 lsa_header->adv_router = oi->area->ospf6->router_id;
600 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000601 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
602 lsa_header->adv_router, oi->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000603 lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
604
605 /* LSA checksum */
606 ospf6_lsa_checksum (lsa_header);
607
608 /* create LSA */
609 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000610
611 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000612 ospf6_lsa_originate_interface (lsa, oi);
hasso508e53e2004-05-18 18:57:06 +0000613
614 return 0;
615}
616
617
618/*****************************************/
619/* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
620/*****************************************/
621
Paul Jakma6ac29a52008-08-15 13:45:30 +0100622static int
hasso508e53e2004-05-18 18:57:06 +0000623ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
624{
625 char *start, *end, *current;
626 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
627 int prefixnum;
628 char buf[128];
629 struct ospf6_prefix *prefix;
630 char id[16], adv_router[16];
paul0c083ee2004-10-10 12:54:58 +0000631 const char *p, *mc, *la, *nu;
hasso508e53e2004-05-18 18:57:06 +0000632 struct in6_addr in6;
633
634 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
635 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
636
637 prefixnum = ntohs (intra_prefix_lsa->prefix_num);
638
hasso049207c2004-08-04 20:02:13 +0000639 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
hasso508e53e2004-05-18 18:57:06 +0000640
641 inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
642 inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
643 adv_router, sizeof (adv_router));
644 vty_out (vty, " Reference: %s Id: %s Adv: %s%s",
hasso1e058382004-09-01 21:36:14 +0000645 ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
hasso049207c2004-08-04 20:02:13 +0000646 VNL);
hasso508e53e2004-05-18 18:57:06 +0000647
648 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
649 end = (char *) lsa->header + ntohs (lsa->header->length);
650 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
651 {
652 prefix = (struct ospf6_prefix *) current;
653 if (prefix->prefix_length == 0 ||
654 current + OSPF6_PREFIX_SIZE (prefix) > end)
655 break;
656
657 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
658 "P" : "--");
659 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
660 "MC" : "--");
661 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
662 "LA" : "--");
663 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
664 "NU" : "--");
665 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
hasso049207c2004-08-04 20:02:13 +0000666 p, mc, la, nu, VNL);
hasso508e53e2004-05-18 18:57:06 +0000667
668 memset (&in6, 0, sizeof (in6));
669 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
670 OSPF6_PREFIX_SPACE (prefix->prefix_length));
671 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
672 vty_out (vty, " Prefix: %s/%d%s",
hasso049207c2004-08-04 20:02:13 +0000673 buf, prefix->prefix_length, VNL);
hasso508e53e2004-05-18 18:57:06 +0000674 }
675
676 return 0;
677}
678
hasso6452df02004-08-15 05:52:07 +0000679int
680ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
hasso508e53e2004-05-18 18:57:06 +0000681{
hasso6452df02004-08-15 05:52:07 +0000682 struct ospf6_area *oa;
683
hasso508e53e2004-05-18 18:57:06 +0000684 char buffer[OSPF6_MAX_LSASIZE];
685 struct ospf6_lsa_header *lsa_header;
686 struct ospf6_lsa *old, *lsa;
687
688 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
689 struct ospf6_interface *oi;
690 struct ospf6_neighbor *on;
691 struct ospf6_route *route;
692 struct ospf6_prefix *op;
hasso52dc7ee2004-09-23 19:18:23 +0000693 struct listnode *i, *j;
hasso508e53e2004-05-18 18:57:06 +0000694 int full_count = 0;
695 unsigned short prefix_num = 0;
696 char buf[BUFSIZ];
697 struct ospf6_route_table *route_advertise;
698
hasso6452df02004-08-15 05:52:07 +0000699 oa = (struct ospf6_area *) THREAD_ARG (thread);
700 oa->thread_intra_prefix_lsa = NULL;
701
hasso508e53e2004-05-18 18:57:06 +0000702 /* find previous LSA */
703 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
704 htonl (0), oa->ospf6->router_id, oa->lsdb);
705
hasso6452df02004-08-15 05:52:07 +0000706 if (! IS_AREA_ENABLED (oa))
hasso508e53e2004-05-18 18:57:06 +0000707 {
708 if (old)
hasso6452df02004-08-15 05:52:07 +0000709 ospf6_lsa_purge (old);
710 return 0;
hasso508e53e2004-05-18 18:57:06 +0000711 }
712
hasso1e058382004-09-01 21:36:14 +0000713 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000714 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
hasso508e53e2004-05-18 18:57:06 +0000715 oa->name);
716
717 /* prepare buffer */
718 memset (buffer, 0, sizeof (buffer));
719 lsa_header = (struct ospf6_lsa_header *) buffer;
720 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
721 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
722
723 /* Fill Intra-Area-Prefix-LSA */
724 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
725 intra_prefix_lsa->ref_id = htonl (0);
726 intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
727
Paul Jakmacf1ce252006-05-15 10:46:07 +0000728 route_advertise = ospf6_route_table_create (0, 0);
hasso508e53e2004-05-18 18:57:06 +0000729
paul1eb8ef22005-04-07 07:30:20 +0000730 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
hasso508e53e2004-05-18 18:57:06 +0000731 {
hasso508e53e2004-05-18 18:57:06 +0000732 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;
paul1eb8ef22005-04-07 07:30:20 +0000740
741 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
742 if (on->state == OSPF6_NEIGHBOR_FULL)
743 full_count++;
744
hasso508e53e2004-05-18 18:57:06 +0000745 if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
746 oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
747 full_count != 0)
748 {
hasso1e058382004-09-01 21:36:14 +0000749 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000750 zlog_debug (" Interface %s is not stub, ignore",
hasso508e53e2004-05-18 18:57:06 +0000751 oi->interface->name);
752 continue;
753 }
754
hasso1e058382004-09-01 21:36:14 +0000755 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000756 zlog_debug (" Interface %s:", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000757
758 /* connected prefix to advertise */
759 for (route = ospf6_route_head (oi->route_connected); route;
760 route = ospf6_route_best_next (route))
761 {
hasso1e058382004-09-01 21:36:14 +0000762 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +0000763 {
764 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000765 zlog_debug (" include %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000766 }
767 ospf6_route_add (ospf6_route_copy (route), route_advertise);
768 }
769 }
770
771 if (route_advertise->count == 0)
772 {
773 if (old)
hasso6452df02004-08-15 05:52:07 +0000774 ospf6_lsa_purge (old);
hasso508e53e2004-05-18 18:57:06 +0000775 ospf6_route_table_delete (route_advertise);
hasso6452df02004-08-15 05:52:07 +0000776 return 0;
hasso508e53e2004-05-18 18:57:06 +0000777 }
778
779 /* put prefixes to advertise */
780 prefix_num = 0;
781 op = (struct ospf6_prefix *)
782 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
783 for (route = ospf6_route_head (route_advertise); route;
784 route = ospf6_route_best_next (route))
785 {
786 op->prefix_length = route->prefix.prefixlen;
787 op->prefix_options = route->path.prefix_options;
788 op->prefix_metric = htons (route->path.cost);
789 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
790 OSPF6_PREFIX_SPACE (op->prefix_length));
791 op = OSPF6_PREFIX_NEXT (op);
792 prefix_num++;
793 }
794
795 ospf6_route_table_delete (route_advertise);
796
797 if (prefix_num == 0)
798 {
hasso1e058382004-09-01 21:36:14 +0000799 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000800 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
hasso6452df02004-08-15 05:52:07 +0000801 return 0;
hasso508e53e2004-05-18 18:57:06 +0000802 }
803
804 intra_prefix_lsa->prefix_num = htons (prefix_num);
805
806 /* Fill LSA Header */
807 lsa_header->age = 0;
808 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
809 lsa_header->id = htonl (0);
810 lsa_header->adv_router = oa->ospf6->router_id;
811 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000812 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
813 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000814 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
815
816 /* LSA checksum */
817 ospf6_lsa_checksum (lsa_header);
818
819 /* create LSA */
820 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000821
822 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000823 ospf6_lsa_originate_area (lsa, oa);
824
825 return 0;
hasso508e53e2004-05-18 18:57:06 +0000826}
827
hasso6452df02004-08-15 05:52:07 +0000828
829int
830ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
hasso508e53e2004-05-18 18:57:06 +0000831{
hasso6452df02004-08-15 05:52:07 +0000832 struct ospf6_interface *oi;
833
hasso508e53e2004-05-18 18:57:06 +0000834 char buffer[OSPF6_MAX_LSASIZE];
835 struct ospf6_lsa_header *lsa_header;
836 struct ospf6_lsa *old, *lsa;
837
838 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
839 struct ospf6_neighbor *on;
840 struct ospf6_route *route;
841 struct ospf6_prefix *op;
hasso52dc7ee2004-09-23 19:18:23 +0000842 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000843 int full_count = 0;
844 unsigned short prefix_num = 0;
845 struct ospf6_route_table *route_advertise;
846 struct ospf6_link_lsa *link_lsa;
847 char *start, *end, *current;
848 u_int16_t type;
849 char buf[BUFSIZ];
850
hasso6452df02004-08-15 05:52:07 +0000851 oi = (struct ospf6_interface *) THREAD_ARG (thread);
852 oi->thread_intra_prefix_lsa = NULL;
853
854 assert (oi->area);
hasso508e53e2004-05-18 18:57:06 +0000855
856 /* find previous LSA */
857 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
858 htonl (oi->interface->ifindex),
859 oi->area->ospf6->router_id, oi->area->lsdb);
860
861 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
862 {
863 if (old)
hasso6452df02004-08-15 05:52:07 +0000864 ospf6_lsa_purge (old);
865 return 0;
hasso508e53e2004-05-18 18:57:06 +0000866 }
867
hasso1e058382004-09-01 21:36:14 +0000868 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000869 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
hasso508e53e2004-05-18 18:57:06 +0000870 oi->interface->name);
871
872 /* prepare buffer */
873 memset (buffer, 0, sizeof (buffer));
874 lsa_header = (struct ospf6_lsa_header *) buffer;
875 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
876 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
877
878 /* Fill Intra-Area-Prefix-LSA */
879 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
880 intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
881 intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
882
883 if (oi->state != OSPF6_INTERFACE_DR)
884 {
hasso1e058382004-09-01 21:36:14 +0000885 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000886 zlog_debug (" Interface is not DR");
hasso508e53e2004-05-18 18:57:06 +0000887 if (old)
hasso6452df02004-08-15 05:52:07 +0000888 ospf6_lsa_purge (old);
889 return 0;
hasso508e53e2004-05-18 18:57:06 +0000890 }
891
892 full_count = 0;
paul1eb8ef22005-04-07 07:30:20 +0000893 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
894 if (on->state == OSPF6_NEIGHBOR_FULL)
895 full_count++;
896
hasso508e53e2004-05-18 18:57:06 +0000897 if (full_count == 0)
898 {
hasso1e058382004-09-01 21:36:14 +0000899 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000900 zlog_debug (" Interface is stub");
hasso508e53e2004-05-18 18:57:06 +0000901 if (old)
hasso6452df02004-08-15 05:52:07 +0000902 ospf6_lsa_purge (old);
903 return 0;
hasso508e53e2004-05-18 18:57:06 +0000904 }
905
906 /* connected prefix to advertise */
Paul Jakmacf1ce252006-05-15 10:46:07 +0000907 route_advertise = ospf6_route_table_create (0, 0);
hasso508e53e2004-05-18 18:57:06 +0000908
909 type = ntohs (OSPF6_LSTYPE_LINK);
910 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
911 lsa = ospf6_lsdb_type_next (type, lsa))
912 {
913 if (OSPF6_LSA_IS_MAXAGE (lsa))
paul718e3742002-12-13 20:15:29 +0000914 continue;
915
hasso1e058382004-09-01 21:36:14 +0000916 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000917 zlog_debug (" include prefix from %s", lsa->name);
paul718e3742002-12-13 20:15:29 +0000918
hasso508e53e2004-05-18 18:57:06 +0000919 if (lsa->header->adv_router != oi->area->ospf6->router_id)
paul718e3742002-12-13 20:15:29 +0000920 {
hasso508e53e2004-05-18 18:57:06 +0000921 on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
922 if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
paul718e3742002-12-13 20:15:29 +0000923 {
hasso1e058382004-09-01 21:36:14 +0000924 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000925 zlog_debug (" Neighbor not found or not Full, ignore");
paul718e3742002-12-13 20:15:29 +0000926 continue;
927 }
928 }
929
hasso508e53e2004-05-18 18:57:06 +0000930 link_lsa = (struct ospf6_link_lsa *)
931 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +0000932
hasso508e53e2004-05-18 18:57:06 +0000933 prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
934 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
935 end = (char *) lsa->header + ntohs (lsa->header->length);
936 for (current = start; current < end && prefix_num;
937 current += OSPF6_PREFIX_SIZE (op))
paul718e3742002-12-13 20:15:29 +0000938 {
hasso508e53e2004-05-18 18:57:06 +0000939 op = (struct ospf6_prefix *) current;
940 if (op->prefix_length == 0 ||
941 current + OSPF6_PREFIX_SIZE (op) > end)
942 break;
paul718e3742002-12-13 20:15:29 +0000943
hasso508e53e2004-05-18 18:57:06 +0000944 route = ospf6_route_create ();
945
946 route->type = OSPF6_DEST_TYPE_NETWORK;
947 route->prefix.family = AF_INET6;
948 route->prefix.prefixlen = op->prefix_length;
949 memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
950 memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
951 OSPF6_PREFIX_SPACE (op->prefix_length));
952
953 route->path.origin.type = lsa->header->type;
954 route->path.origin.id = lsa->header->id;
955 route->path.origin.adv_router = lsa->header->adv_router;
956 route->path.options[0] = link_lsa->options[0];
957 route->path.options[1] = link_lsa->options[1];
958 route->path.options[2] = link_lsa->options[2];
959 route->path.prefix_options = op->prefix_options;
960 route->path.area_id = oi->area->area_id;
961 route->path.type = OSPF6_PATH_TYPE_INTRA;
962
hasso1e058382004-09-01 21:36:14 +0000963 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
paul718e3742002-12-13 20:15:29 +0000964 {
hasso508e53e2004-05-18 18:57:06 +0000965 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000966 zlog_debug (" include %s", buf);
paul718e3742002-12-13 20:15:29 +0000967 }
968
hasso508e53e2004-05-18 18:57:06 +0000969 ospf6_route_add (route, route_advertise);
970 prefix_num--;
paul718e3742002-12-13 20:15:29 +0000971 }
hasso1e058382004-09-01 21:36:14 +0000972 if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000973 zlog_debug ("Trailing garbage in %s", lsa->name);
paul718e3742002-12-13 20:15:29 +0000974 }
975
hasso508e53e2004-05-18 18:57:06 +0000976 op = (struct ospf6_prefix *)
977 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
978
979 prefix_num = 0;
980 for (route = ospf6_route_head (route_advertise); route;
981 route = ospf6_route_best_next (route))
paul718e3742002-12-13 20:15:29 +0000982 {
hasso508e53e2004-05-18 18:57:06 +0000983 op->prefix_length = route->prefix.prefixlen;
984 op->prefix_options = route->path.prefix_options;
985 op->prefix_metric = htons (0);
986 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
987 OSPF6_PREFIX_SPACE (op->prefix_length));
988 op = OSPF6_PREFIX_NEXT (op);
989 prefix_num++;
990 }
991
992 ospf6_route_table_delete (route_advertise);
993
994 if (prefix_num == 0)
995 {
hasso1e058382004-09-01 21:36:14 +0000996 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000997 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
hasso6452df02004-08-15 05:52:07 +0000998 return 0;
paul718e3742002-12-13 20:15:29 +0000999 }
1000
hasso508e53e2004-05-18 18:57:06 +00001001 intra_prefix_lsa->prefix_num = htons (prefix_num);
paul718e3742002-12-13 20:15:29 +00001002
hasso508e53e2004-05-18 18:57:06 +00001003 /* Fill LSA Header */
1004 lsa_header->age = 0;
1005 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1006 lsa_header->id = htonl (oi->interface->ifindex);
1007 lsa_header->adv_router = oi->area->ospf6->router_id;
1008 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +00001009 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
1010 lsa_header->adv_router, oi->area->lsdb);
hasso508e53e2004-05-18 18:57:06 +00001011 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
paul718e3742002-12-13 20:15:29 +00001012
hasso508e53e2004-05-18 18:57:06 +00001013 /* LSA checksum */
1014 ospf6_lsa_checksum (lsa_header);
paul718e3742002-12-13 20:15:29 +00001015
hasso508e53e2004-05-18 18:57:06 +00001016 /* create LSA */
1017 lsa = ospf6_lsa_create (lsa_header);
paul718e3742002-12-13 20:15:29 +00001018
hasso508e53e2004-05-18 18:57:06 +00001019 /* Originate */
hasso6452df02004-08-15 05:52:07 +00001020 ospf6_lsa_originate_area (lsa, oi->area);
paul718e3742002-12-13 20:15:29 +00001021
1022 return 0;
1023}
1024
1025void
hasso508e53e2004-05-18 18:57:06 +00001026ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001027{
hasso508e53e2004-05-18 18:57:06 +00001028 struct ospf6_area *oa;
1029 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1030 struct prefix ls_prefix;
1031 struct ospf6_route *route, *ls_entry;
1032 int i, prefix_num;
1033 struct ospf6_prefix *op;
1034 char *start, *current, *end;
1035 char buf[64];
paul718e3742002-12-13 20:15:29 +00001036
hassoccb59b12004-08-25 09:10:37 +00001037 if (OSPF6_LSA_IS_MAXAGE (lsa))
1038 return;
1039
hasso1e058382004-09-01 21:36:14 +00001040 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001041 zlog_debug ("%s found", lsa->name);
paul718e3742002-12-13 20:15:29 +00001042
hasso6452df02004-08-15 05:52:07 +00001043 oa = OSPF6_AREA (lsa->lsdb->data);
1044
hasso508e53e2004-05-18 18:57:06 +00001045 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1046 OSPF6_LSA_HEADER_END (lsa->header);
1047 if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
1048 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1049 htonl (0), &ls_prefix);
1050 else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
1051 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1052 intra_prefix_lsa->ref_id, &ls_prefix);
1053 else
1054 {
hasso1e058382004-09-01 21:36:14 +00001055 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001056 zlog_debug ("Unknown reference LS-type: %#hx",
1057 ntohs (intra_prefix_lsa->ref_type));
hasso508e53e2004-05-18 18:57:06 +00001058 return;
1059 }
paul718e3742002-12-13 20:15:29 +00001060
hasso508e53e2004-05-18 18:57:06 +00001061 ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
1062 if (ls_entry == NULL)
1063 {
hasso1e058382004-09-01 21:36:14 +00001064 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001065 {
1066 ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001067 zlog_debug ("LS entry does not exist: %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001068 }
1069 return;
1070 }
paul718e3742002-12-13 20:15:29 +00001071
hasso508e53e2004-05-18 18:57:06 +00001072 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1073 start = (caddr_t) intra_prefix_lsa +
1074 sizeof (struct ospf6_intra_prefix_lsa);
1075 end = OSPF6_LSA_END (lsa->header);
1076 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1077 {
1078 op = (struct ospf6_prefix *) current;
1079 if (prefix_num == 0)
1080 break;
1081 if (end < current + OSPF6_PREFIX_SIZE (op))
1082 break;
1083
1084 route = ospf6_route_create ();
hassoccb59b12004-08-25 09:10:37 +00001085
1086 memset (&route->prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001087 route->prefix.family = AF_INET6;
hassoccb59b12004-08-25 09:10:37 +00001088 route->prefix.prefixlen = op->prefix_length;
1089 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
1090
hasso508e53e2004-05-18 18:57:06 +00001091 route->type = OSPF6_DEST_TYPE_NETWORK;
1092 route->path.origin.type = lsa->header->type;
1093 route->path.origin.id = lsa->header->id;
1094 route->path.origin.adv_router = lsa->header->adv_router;
1095 route->path.prefix_options = op->prefix_options;
1096 route->path.area_id = oa->area_id;
1097 route->path.type = OSPF6_PATH_TYPE_INTRA;
1098 route->path.metric_type = 1;
1099 route->path.cost = ls_entry->path.cost +
1100 ntohs (op->prefix_metric);
1101
1102 for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
1103 i < OSPF6_MULTI_PATH_LIMIT; i++)
1104 ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
1105
hasso1e058382004-09-01 21:36:14 +00001106 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001107 {
1108 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001109 zlog_debug (" add %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001110 }
1111
1112 ospf6_route_add (route, oa->route_table);
1113 prefix_num--;
1114 }
1115
hasso1e058382004-09-01 21:36:14 +00001116 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001117 zlog_debug ("Trailing garbage ignored");
paul718e3742002-12-13 20:15:29 +00001118}
1119
1120void
hasso508e53e2004-05-18 18:57:06 +00001121ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001122{
hasso508e53e2004-05-18 18:57:06 +00001123 struct ospf6_area *oa;
1124 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1125 struct prefix prefix;
1126 struct ospf6_route *route;
1127 int prefix_num;
1128 struct ospf6_prefix *op;
1129 char *start, *current, *end;
1130 char buf[64];
1131
hasso1e058382004-09-01 21:36:14 +00001132 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001133 zlog_debug ("%s disappearing", lsa->name);
hasso508e53e2004-05-18 18:57:06 +00001134
hasso6452df02004-08-15 05:52:07 +00001135 oa = OSPF6_AREA (lsa->lsdb->data);
1136
hasso508e53e2004-05-18 18:57:06 +00001137 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1138 OSPF6_LSA_HEADER_END (lsa->header);
1139
1140 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1141 start = (caddr_t) intra_prefix_lsa +
1142 sizeof (struct ospf6_intra_prefix_lsa);
1143 end = OSPF6_LSA_END (lsa->header);
1144 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1145 {
1146 op = (struct ospf6_prefix *) current;
1147 if (prefix_num == 0)
1148 break;
1149 if (end < current + OSPF6_PREFIX_SIZE (op))
1150 break;
1151 prefix_num--;
1152
hassoccb59b12004-08-25 09:10:37 +00001153 memset (&prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001154 prefix.family = AF_INET6;
1155 prefix.prefixlen = op->prefix_length;
1156 ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
1157
1158 route = ospf6_route_lookup (&prefix, oa->route_table);
1159 if (route == NULL)
1160 continue;
1161
1162 for (ospf6_route_lock (route);
1163 route && ospf6_route_is_prefix (&prefix, route);
1164 route = ospf6_route_next (route))
1165 {
1166 if (route->type != OSPF6_DEST_TYPE_NETWORK)
1167 continue;
1168 if (route->path.area_id != oa->area_id)
1169 continue;
1170 if (route->path.type != OSPF6_PATH_TYPE_INTRA)
1171 continue;
1172 if (route->path.origin.type != lsa->header->type ||
1173 route->path.origin.id != lsa->header->id ||
1174 route->path.origin.adv_router != lsa->header->adv_router)
1175 continue;
1176
hasso1e058382004-09-01 21:36:14 +00001177 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001178 {
1179 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001180 zlog_debug ("remove %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001181 }
1182 ospf6_route_remove (route, oa->route_table);
1183 }
Tom Goffe7a6d802010-11-10 13:03:02 -08001184 if (route)
1185 ospf6_route_unlock (route);
hasso508e53e2004-05-18 18:57:06 +00001186 }
1187
hasso1e058382004-09-01 21:36:14 +00001188 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001189 zlog_debug ("Trailing garbage ignored");
paul718e3742002-12-13 20:15:29 +00001190}
1191
1192void
hasso508e53e2004-05-18 18:57:06 +00001193ospf6_intra_route_calculation (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +00001194{
hasso508e53e2004-05-18 18:57:06 +00001195 struct ospf6_route *route;
1196 u_int16_t type;
1197 struct ospf6_lsa *lsa;
1198 void (*hook_add) (struct ospf6_route *) = NULL;
1199 void (*hook_remove) (struct ospf6_route *) = NULL;
1200
hasso1e058382004-09-01 21:36:14 +00001201 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001202 zlog_debug ("Re-examin intra-routes for area %s", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001203
1204 hook_add = oa->route_table->hook_add;
1205 hook_remove = oa->route_table->hook_remove;
1206 oa->route_table->hook_add = NULL;
1207 oa->route_table->hook_remove = NULL;
1208
1209 for (route = ospf6_route_head (oa->route_table); route;
1210 route = ospf6_route_next (route))
1211 route->flag = OSPF6_ROUTE_REMOVE;
1212
1213 type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1214 for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
1215 lsa = ospf6_lsdb_type_next (type, lsa))
1216 ospf6_intra_prefix_lsa_add (lsa);
1217
1218 oa->route_table->hook_add = hook_add;
1219 oa->route_table->hook_remove = hook_remove;
1220
1221 for (route = ospf6_route_head (oa->route_table); route;
1222 route = ospf6_route_next (route))
1223 {
1224 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
1225 CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
1226 {
1227 UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
1228 UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
1229 }
1230
1231 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
1232 ospf6_route_remove (route, oa->route_table);
1233 else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
1234 CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
1235 {
1236 if (hook_add)
1237 (*hook_add) (route);
1238 }
1239
1240 route->flag = 0;
1241 }
1242
hasso1e058382004-09-01 21:36:14 +00001243 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001244 zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001245}
1246
Paul Jakma6ac29a52008-08-15 13:45:30 +01001247static void
Paul Jakmacf1ce252006-05-15 10:46:07 +00001248ospf6_brouter_debug_print (struct ospf6_route *brouter)
1249{
1250 u_int32_t brouter_id;
1251 char brouter_name[16];
1252 char area_name[16];
1253 char destination[64];
1254 char installed[16], changed[16];
1255 struct timeval now, res;
1256 char id[16], adv_router[16];
1257 char capa[16], options[16];
1258
1259 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1260 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1261 inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
1262 ospf6_linkstate_prefix2str (&brouter->prefix, destination,
1263 sizeof (destination));
1264
Takashi Sogabe86f72dc2009-06-22 13:07:02 +09001265 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001266 timersub (&now, &brouter->installed, &res);
1267 timerstring (&res, installed, sizeof (installed));
1268
Takashi Sogabe86f72dc2009-06-22 13:07:02 +09001269 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001270 timersub (&now, &brouter->changed, &res);
1271 timerstring (&res, changed, sizeof (changed));
1272
1273 inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
1274 inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
1275 sizeof (adv_router));
1276
1277 ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
1278 ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
1279
1280 zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
1281 zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
1282 brouter->prev, brouter, brouter->next, brouter->rnode);
1283 zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1284 brouter->type, destination, installed, changed);
1285 zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock,
1286 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
1287 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
1288 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
1289 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
1290 zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1291 OSPF6_PATH_TYPE_NAME (brouter->path.type),
1292 ospf6_lstype_name (brouter->path.origin.type),
1293 id, adv_router);
1294 zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1295 options, capa, brouter->path.metric_type,
1296 brouter->path.cost, brouter->path.cost_e2);
1297}
1298
1299void
hasso6452df02004-08-15 05:52:07 +00001300ospf6_intra_brouter_calculation (struct ospf6_area *oa)
hasso508e53e2004-05-18 18:57:06 +00001301{
Paul Jakmacb4b8842006-05-15 10:39:30 +00001302 struct ospf6_route *brouter, *copy;
hasso508e53e2004-05-18 18:57:06 +00001303 void (*hook_add) (struct ospf6_route *) = NULL;
1304 void (*hook_remove) (struct ospf6_route *) = NULL;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001305 u_int32_t brouter_id;
1306 char brouter_name[16];
1307
1308 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1309 zlog_info ("border-router calculation for area %s", oa->name);
1310
hasso6452df02004-08-15 05:52:07 +00001311 hook_add = oa->ospf6->brouter_table->hook_add;
1312 hook_remove = oa->ospf6->brouter_table->hook_remove;
1313 oa->ospf6->brouter_table->hook_add = NULL;
1314 oa->ospf6->brouter_table->hook_remove = NULL;
hasso508e53e2004-05-18 18:57:06 +00001315
hasso6452df02004-08-15 05:52:07 +00001316 /* withdraw the previous router entries for the area */
Paul Jakmacb4b8842006-05-15 10:39:30 +00001317 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1318 brouter = ospf6_route_next (brouter))
hasso508e53e2004-05-18 18:57:06 +00001319 {
Paul Jakmacf1ce252006-05-15 10:46:07 +00001320 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1321 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
Paul Jakmacb4b8842006-05-15 10:39:30 +00001322 if (brouter->path.area_id != oa->area_id)
hasso508e53e2004-05-18 18:57:06 +00001323 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001324 brouter->flag = OSPF6_ROUTE_REMOVE;
Paul Jakmacf1ce252006-05-15 10:46:07 +00001325
1326 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1327 IS_OSPF6_DEBUG_ROUTE (MEMORY))
1328 {
1329 zlog_info ("%p: mark as removing: area %s brouter %s",
1330 brouter, oa->name, brouter_name);
1331 ospf6_brouter_debug_print (brouter);
1332 }
hasso508e53e2004-05-18 18:57:06 +00001333 }
1334
Paul Jakmacb4b8842006-05-15 10:39:30 +00001335 for (brouter = ospf6_route_head (oa->spf_table); brouter;
1336 brouter = ospf6_route_next (brouter))
hasso508e53e2004-05-18 18:57:06 +00001337 {
Paul Jakmacf1ce252006-05-15 10:46:07 +00001338 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1339 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1340
Paul Jakmacb4b8842006-05-15 10:39:30 +00001341 if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
hasso508e53e2004-05-18 18:57:06 +00001342 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001343 if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
hasso508e53e2004-05-18 18:57:06 +00001344 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001345 if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
1346 ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
hasso508e53e2004-05-18 18:57:06 +00001347 continue;
1348
Paul Jakmacb4b8842006-05-15 10:39:30 +00001349 copy = ospf6_route_copy (brouter);
hasso508e53e2004-05-18 18:57:06 +00001350 copy->type = OSPF6_DEST_TYPE_ROUTER;
hassoccb59b12004-08-25 09:10:37 +00001351 copy->path.area_id = oa->area_id;
hasso6452df02004-08-15 05:52:07 +00001352 ospf6_route_add (copy, oa->ospf6->brouter_table);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001353
1354 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1355 IS_OSPF6_DEBUG_ROUTE (MEMORY))
1356 {
1357 zlog_info ("%p: transfer: area %s brouter %s",
1358 brouter, oa->name, brouter_name);
1359 ospf6_brouter_debug_print (brouter);
1360 }
hasso508e53e2004-05-18 18:57:06 +00001361 }
1362
hasso6452df02004-08-15 05:52:07 +00001363 oa->ospf6->brouter_table->hook_add = hook_add;
1364 oa->ospf6->brouter_table->hook_remove = hook_remove;
hasso508e53e2004-05-18 18:57:06 +00001365
Paul Jakmacb4b8842006-05-15 10:39:30 +00001366 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1367 brouter = ospf6_route_next (brouter))
hasso508e53e2004-05-18 18:57:06 +00001368 {
Paul Jakmacb4b8842006-05-15 10:39:30 +00001369 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1370 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1371
1372 if (brouter->path.area_id != oa->area_id)
hasso508e53e2004-05-18 18:57:06 +00001373 continue;
1374
Paul Jakmacb4b8842006-05-15 10:39:30 +00001375 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
hasso9428f2d2004-09-13 14:01:12 +00001376 continue;
1377
Paul Jakmacb4b8842006-05-15 10:39:30 +00001378 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
1379 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
hasso508e53e2004-05-18 18:57:06 +00001380 {
Paul Jakmacb4b8842006-05-15 10:39:30 +00001381 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
1382 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
hasso508e53e2004-05-18 18:57:06 +00001383 }
1384
Paul Jakmacb4b8842006-05-15 10:39:30 +00001385 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
hasso508e53e2004-05-18 18:57:06 +00001386 {
Paul Jakmacb4b8842006-05-15 10:39:30 +00001387 if (IS_OSPF6_DEBUG_BROUTER ||
1388 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1389 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1390 zlog_info ("brouter %s disappears via area %s",
1391 brouter_name, oa->name);
1392 ospf6_route_remove (brouter, oa->ospf6->brouter_table);
1393 }
1394 else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
1395 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
1396 {
1397 if (IS_OSPF6_DEBUG_BROUTER ||
1398 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1399 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1400 zlog_info ("brouter %s appears via area %s",
1401 brouter_name, oa->name);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001402
Paul Jakmacb4b8842006-05-15 10:39:30 +00001403 /* newly added */
hasso508e53e2004-05-18 18:57:06 +00001404 if (hook_add)
Paul Jakmacb4b8842006-05-15 10:39:30 +00001405 (*hook_add) (brouter);
1406 }
1407 else
1408 {
1409 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1410 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1411 zlog_info ("brouter %s still exists via area %s",
1412 brouter_name, oa->name);
hasso508e53e2004-05-18 18:57:06 +00001413 }
1414
Paul Jakmacb4b8842006-05-15 10:39:30 +00001415 brouter->flag = 0;
hasso508e53e2004-05-18 18:57:06 +00001416 }
1417
Paul Jakmacb4b8842006-05-15 10:39:30 +00001418 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1419 zlog_info ("border-router calculation for area %s: done", oa->name);
paul718e3742002-12-13 20:15:29 +00001420}
1421
hasso6452df02004-08-15 05:52:07 +00001422struct ospf6_lsa_handler router_handler =
1423{
1424 OSPF6_LSTYPE_ROUTER,
1425 "Router",
1426 ospf6_router_lsa_show
1427};
1428
1429struct ospf6_lsa_handler network_handler =
1430{
1431 OSPF6_LSTYPE_NETWORK,
1432 "Network",
1433 ospf6_network_lsa_show
1434};
1435
1436struct ospf6_lsa_handler link_handler =
1437{
1438 OSPF6_LSTYPE_LINK,
1439 "Link",
1440 ospf6_link_lsa_show
1441};
1442
1443struct ospf6_lsa_handler intra_prefix_handler =
1444{
1445 OSPF6_LSTYPE_INTRA_PREFIX,
1446 "Intra-Prefix",
1447 ospf6_intra_prefix_lsa_show
1448};
1449
paul718e3742002-12-13 20:15:29 +00001450void
Paul Jakmacb4b8842006-05-15 10:39:30 +00001451ospf6_intra_init (void)
paul718e3742002-12-13 20:15:29 +00001452{
hasso6452df02004-08-15 05:52:07 +00001453 ospf6_install_lsa_handler (&router_handler);
1454 ospf6_install_lsa_handler (&network_handler);
1455 ospf6_install_lsa_handler (&link_handler);
1456 ospf6_install_lsa_handler (&intra_prefix_handler);
paul718e3742002-12-13 20:15:29 +00001457}
1458
Paul Jakmacb4b8842006-05-15 10:39:30 +00001459DEFUN (debug_ospf6_brouter,
1460 debug_ospf6_brouter_cmd,
1461 "debug ospf6 border-routers",
1462 DEBUG_STR
1463 OSPF6_STR
1464 "Debug border router\n"
1465 )
1466{
1467 OSPF6_DEBUG_BROUTER_ON ();
1468 return CMD_SUCCESS;
1469}
1470
1471DEFUN (no_debug_ospf6_brouter,
1472 no_debug_ospf6_brouter_cmd,
1473 "no debug ospf6 border-routers",
1474 NO_STR
1475 DEBUG_STR
1476 OSPF6_STR
1477 "Debug border router\n"
1478 )
1479{
1480 OSPF6_DEBUG_BROUTER_OFF ();
1481 return CMD_SUCCESS;
1482}
1483
1484DEFUN (debug_ospf6_brouter_router,
1485 debug_ospf6_brouter_router_cmd,
1486 "debug ospf6 border-routers router-id A.B.C.D",
1487 DEBUG_STR
1488 OSPF6_STR
1489 "Debug border router\n"
1490 "Debug specific border router\n"
1491 "Specify border-router's router-id\n"
1492 )
1493{
1494 u_int32_t router_id;
1495 inet_pton (AF_INET, argv[0], &router_id);
1496 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
1497 return CMD_SUCCESS;
1498}
1499
1500DEFUN (no_debug_ospf6_brouter_router,
1501 no_debug_ospf6_brouter_router_cmd,
1502 "no debug ospf6 border-routers router-id",
1503 NO_STR
1504 DEBUG_STR
1505 OSPF6_STR
1506 "Debug border router\n"
1507 "Debug specific border router\n"
1508 )
1509{
1510 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1511 return CMD_SUCCESS;
1512}
1513
1514DEFUN (debug_ospf6_brouter_area,
1515 debug_ospf6_brouter_area_cmd,
1516 "debug ospf6 border-routers area-id A.B.C.D",
1517 DEBUG_STR
1518 OSPF6_STR
1519 "Debug border router\n"
1520 "Debug border routers in specific Area\n"
1521 "Specify Area-ID\n"
1522 )
1523{
1524 u_int32_t area_id;
1525 inet_pton (AF_INET, argv[0], &area_id);
1526 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
1527 return CMD_SUCCESS;
1528}
1529
1530DEFUN (no_debug_ospf6_brouter_area,
1531 no_debug_ospf6_brouter_area_cmd,
1532 "no debug ospf6 border-routers area-id",
1533 NO_STR
1534 DEBUG_STR
1535 OSPF6_STR
1536 "Debug border router\n"
1537 "Debug border routers in specific Area\n"
1538 )
1539{
1540 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1541 return CMD_SUCCESS;
1542}
1543
1544int
1545config_write_ospf6_debug_brouter (struct vty *vty)
1546{
1547 char buf[16];
1548 if (IS_OSPF6_DEBUG_BROUTER)
1549 vty_out (vty, "debug ospf6 border-routers%s", VNL);
1550 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
1551 {
1552 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
1553 buf, sizeof (buf));
1554 vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
1555 }
1556 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
1557 {
1558 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
1559 buf, sizeof (buf));
1560 vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
1561 }
1562 return 0;
1563}
1564
1565void
1566install_element_ospf6_debug_brouter (void)
1567{
1568 install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
1569 install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
1570 install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
1571 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
1572 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
1573 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
1574 install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
1575 install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
1576 install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
1577 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
1578 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
1579 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
1580}
1581
paul718e3742002-12-13 20:15:29 +00001582