blob: 1ef0b53550565361b9fb2dc5b77dae4107522aef [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"
Dinesh Dutta0edf672013-08-26 03:40:23 +000049#include "ospf6_spf.h"
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
Dinesh Dutte68a6762013-08-25 03:03:23 +000059static char *
60ospf6_router_lsa_get_nbr_id (struct ospf6_lsa *lsa, char *buf, int buflen,
61 int pos)
62{
63 struct ospf6_router_lsa *router_lsa;
64 struct ospf6_router_lsdesc *lsdesc;
65 char *start, *end;
66 char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN];
67
68 if (lsa)
69 {
70 router_lsa = (struct ospf6_router_lsa *)
71 ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
72 start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
73 end = (char *) lsa->header + ntohs (lsa->header->length);
74
75 lsdesc = (struct ospf6_router_lsdesc *)
76 (start + pos*(sizeof (struct ospf6_router_lsdesc)));
77 if ((char *)lsdesc < end)
78 {
79 if (buf && (buflen > INET_ADDRSTRLEN*2))
80 {
81 inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
82 buf1, sizeof(buf1));
83 inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
84 buf2, sizeof(buf2));
85 sprintf (buf, "%s/%s", buf2, buf1);
86 }
87 }
88 else
89 return NULL;
90 }
91
92 return buf;
93}
94
Paul Jakma6ac29a52008-08-15 13:45:30 +010095static int
hasso508e53e2004-05-18 18:57:06 +000096ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +000097{
hasso508e53e2004-05-18 18:57:06 +000098 char *start, *end, *current;
99 char buf[32], name[32], bits[16], options[32];
100 struct ospf6_router_lsa *router_lsa;
101 struct ospf6_router_lsdesc *lsdesc;
paul718e3742002-12-13 20:15:29 +0000102
hasso508e53e2004-05-18 18:57:06 +0000103 router_lsa = (struct ospf6_router_lsa *)
104 ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +0000105
hasso508e53e2004-05-18 18:57:06 +0000106 ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
107 ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
hasso049207c2004-08-04 20:02:13 +0000108 vty_out (vty, " Bits: %s Options: %s%s", bits, options, VNL);
paul718e3742002-12-13 20:15:29 +0000109
hasso508e53e2004-05-18 18:57:06 +0000110 start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
paul718e3742002-12-13 20:15:29 +0000111 end = (char *) lsa->header + ntohs (lsa->header->length);
hasso508e53e2004-05-18 18:57:06 +0000112 for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end;
113 current += sizeof (struct ospf6_router_lsdesc))
paul718e3742002-12-13 20:15:29 +0000114 {
hasso508e53e2004-05-18 18:57:06 +0000115 lsdesc = (struct ospf6_router_lsdesc *) current;
paul718e3742002-12-13 20:15:29 +0000116
hasso508e53e2004-05-18 18:57:06 +0000117 if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT)
118 snprintf (name, sizeof (name), "Point-To-Point");
119 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK)
120 snprintf (name, sizeof (name), "Transit-Network");
121 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK)
122 snprintf (name, sizeof (name), "Stub-Network");
123 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK)
124 snprintf (name, sizeof (name), "Virtual-Link");
paul718e3742002-12-13 20:15:29 +0000125 else
hasso508e53e2004-05-18 18:57:06 +0000126 snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
paul718e3742002-12-13 20:15:29 +0000127
hasso508e53e2004-05-18 18:57:06 +0000128 vty_out (vty, " Type: %s Metric: %d%s",
hasso049207c2004-08-04 20:02:13 +0000129 name, ntohs (lsdesc->metric), VNL);
hasso508e53e2004-05-18 18:57:06 +0000130 vty_out (vty, " Interface ID: %s%s",
131 inet_ntop (AF_INET, &lsdesc->interface_id,
hasso049207c2004-08-04 20:02:13 +0000132 buf, sizeof (buf)), VNL);
hasso508e53e2004-05-18 18:57:06 +0000133 vty_out (vty, " Neighbor Interface ID: %s%s",
134 inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
hasso049207c2004-08-04 20:02:13 +0000135 buf, sizeof (buf)), VNL);
hasso508e53e2004-05-18 18:57:06 +0000136 vty_out (vty, " Neighbor Router ID: %s%s",
137 inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
hasso049207c2004-08-04 20:02:13 +0000138 buf, sizeof (buf)), VNL);
paul718e3742002-12-13 20:15:29 +0000139 }
140 return 0;
141}
142
hasso6452df02004-08-15 05:52:07 +0000143int
Dinesh Duttf41b4a02013-08-24 08:00:37 +0000144ospf6_router_is_stub_router (struct ospf6_lsa *lsa)
145{
146 struct ospf6_router_lsa *rtr_lsa;
147
148 if (lsa != NULL && OSPF6_LSA_IS_TYPE (ROUTER, lsa))
149 {
150 rtr_lsa = (struct ospf6_router_lsa *)
151 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
152
153 if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_R))
154 {
155 return (OSPF6_IS_STUB_ROUTER);
156 }
157 else if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_V6))
158 {
159 return (OSPF6_IS_STUB_ROUTER_V6);
160 }
161 }
162
163 return (OSPF6_NOT_STUB_ROUTER);
164}
165
166int
hasso6452df02004-08-15 05:52:07 +0000167ospf6_router_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000168{
hasso6452df02004-08-15 05:52:07 +0000169 struct ospf6_area *oa;
170
hasso508e53e2004-05-18 18:57:06 +0000171 char buffer [OSPF6_MAX_LSASIZE];
172 struct ospf6_lsa_header *lsa_header;
173 struct ospf6_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000174
hasso508e53e2004-05-18 18:57:06 +0000175 u_int32_t link_state_id = 0;
paul1eb8ef22005-04-07 07:30:20 +0000176 struct listnode *node, *nnode;
177 struct listnode *j;
hasso508e53e2004-05-18 18:57:06 +0000178 struct ospf6_interface *oi;
179 struct ospf6_neighbor *on, *drouter = NULL;
180 struct ospf6_router_lsa *router_lsa;
181 struct ospf6_router_lsdesc *lsdesc;
182 u_int16_t type;
183 u_int32_t router;
184 int count;
paul718e3742002-12-13 20:15:29 +0000185
hasso6452df02004-08-15 05:52:07 +0000186 oa = (struct ospf6_area *) THREAD_ARG (thread);
187 oa->thread_router_lsa = NULL;
188
hasso1e058382004-09-01 21:36:14 +0000189 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
hassoc6487d62004-12-24 06:00:11 +0000190 zlog_debug ("Originate Router-LSA for Area %s", oa->name);
paul718e3742002-12-13 20:15:29 +0000191
hasso508e53e2004-05-18 18:57:06 +0000192 memset (buffer, 0, sizeof (buffer));
193 lsa_header = (struct ospf6_lsa_header *) buffer;
194 router_lsa = (struct ospf6_router_lsa *)
195 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
196
197 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
198 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
199 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
200 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
201 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
202 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
203
hasso6452df02004-08-15 05:52:07 +0000204 if (ospf6_is_router_abr (ospf6))
205 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
206 else
207 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
hasso508e53e2004-05-18 18:57:06 +0000208 if (ospf6_asbr_is_asbr (ospf6))
209 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
210 else
211 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
212 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
213 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
214
215 /* describe links for each interfaces */
216 lsdesc = (struct ospf6_router_lsdesc *)
217 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
218
paul1eb8ef22005-04-07 07:30:20 +0000219 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +0000220 {
hasso508e53e2004-05-18 18:57:06 +0000221 /* Interfaces in state Down or Loopback are not described */
222 if (oi->state == OSPF6_INTERFACE_DOWN ||
223 oi->state == OSPF6_INTERFACE_LOOPBACK)
paul718e3742002-12-13 20:15:29 +0000224 continue;
225
hasso508e53e2004-05-18 18:57:06 +0000226 /* Nor are interfaces without any full adjacencies described */
227 count = 0;
paul1eb8ef22005-04-07 07:30:20 +0000228 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
229 if (on->state == OSPF6_NEIGHBOR_FULL)
230 count++;
231
hasso508e53e2004-05-18 18:57:06 +0000232 if (count == 0)
233 continue;
234
235 /* Multiple Router-LSA instance according to size limit setting */
paul0c083ee2004-10-10 12:54:58 +0000236 if ( (oa->router_lsa_size_limit != 0)
237 && ((caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) -
gdt1686f932004-12-09 14:47:09 +0000238 /* XXX warning: comparison between signed and unsigned */
paul0c083ee2004-10-10 12:54:58 +0000239 (caddr_t) buffer > oa->router_lsa_size_limit))
hasso508e53e2004-05-18 18:57:06 +0000240 {
241 if ((caddr_t) lsdesc == (caddr_t) router_lsa +
242 sizeof (struct ospf6_router_lsa))
243 {
hasso1e058382004-09-01 21:36:14 +0000244 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
hassoc6487d62004-12-24 06:00:11 +0000245 zlog_debug ("Size limit setting for Router-LSA too short");
hasso6452df02004-08-15 05:52:07 +0000246 return 0;
hasso508e53e2004-05-18 18:57:06 +0000247 }
248
249 /* Fill LSA Header */
250 lsa_header->age = 0;
251 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
252 lsa_header->id = htonl (link_state_id);
253 lsa_header->adv_router = oa->ospf6->router_id;
254 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000255 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
256 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000257 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
258
259 /* LSA checksum */
260 ospf6_lsa_checksum (lsa_header);
261
262 /* create LSA */
263 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000264
265 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000266 ospf6_lsa_originate_area (lsa, oa);
hasso508e53e2004-05-18 18:57:06 +0000267
268 /* Reset setting for consecutive origination */
269 memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
270 0, (caddr_t) lsdesc - (caddr_t) router_lsa);
271 lsdesc = (struct ospf6_router_lsdesc *)
272 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
273 link_state_id ++;
paul718e3742002-12-13 20:15:29 +0000274 }
275
hasso508e53e2004-05-18 18:57:06 +0000276 /* Point-to-Point interfaces */
Dinesh Duttc5926a92013-08-24 07:55:00 +0000277 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
hasso508e53e2004-05-18 18:57:06 +0000278 {
paul1eb8ef22005-04-07 07:30:20 +0000279 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
hasso508e53e2004-05-18 18:57:06 +0000280 {
hasso508e53e2004-05-18 18:57:06 +0000281 if (on->state != OSPF6_NEIGHBOR_FULL)
282 continue;
paul718e3742002-12-13 20:15:29 +0000283
hasso508e53e2004-05-18 18:57:06 +0000284 lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
285 lsdesc->metric = htons (oi->cost);
286 lsdesc->interface_id = htonl (oi->interface->ifindex);
287 lsdesc->neighbor_interface_id = htonl (on->ifindex);
288 lsdesc->neighbor_router_id = on->router_id;
289
290 lsdesc++;
291 }
292 }
293
294 /* Broadcast and NBMA interfaces */
Dinesh Duttc5926a92013-08-24 07:55:00 +0000295 else if (oi->type == OSPF_IFTYPE_BROADCAST)
hasso508e53e2004-05-18 18:57:06 +0000296 {
297 /* If this router is not DR,
298 and If this router not fully adjacent with DR,
299 this interface is not transit yet: ignore. */
300 if (oi->state != OSPF6_INTERFACE_DR)
301 {
302 drouter = ospf6_neighbor_lookup (oi->drouter, oi);
303 if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
304 continue;
305 }
306
307 lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
308 lsdesc->metric = htons (oi->cost);
309 lsdesc->interface_id = htonl (oi->interface->ifindex);
310 if (oi->state != OSPF6_INTERFACE_DR)
311 {
312 lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
313 lsdesc->neighbor_router_id = drouter->router_id;
314 }
315 else
316 {
317 lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
318 lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
319 }
320
321 lsdesc++;
322 }
Dinesh Duttc5926a92013-08-24 07:55:00 +0000323 else
324 {
325 assert (0); /* Unknown interface type */
326 }
hasso508e53e2004-05-18 18:57:06 +0000327
328 /* Virtual links */
329 /* xxx */
330 /* Point-to-Multipoint interfaces */
331 /* xxx */
paul718e3742002-12-13 20:15:29 +0000332 }
hasso508e53e2004-05-18 18:57:06 +0000333
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000334 /* Fill LSA Header */
335 lsa_header->age = 0;
336 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
337 lsa_header->id = htonl (link_state_id);
338 lsa_header->adv_router = oa->ospf6->router_id;
339 lsa_header->seqnum =
340 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
341 lsa_header->adv_router, oa->lsdb);
342 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
hasso508e53e2004-05-18 18:57:06 +0000343
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000344 /* LSA checksum */
345 ospf6_lsa_checksum (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000346
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000347 /* create LSA */
348 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000349
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000350 /* Originate */
351 ospf6_lsa_originate_area (lsa, oa);
hasso508e53e2004-05-18 18:57:06 +0000352
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000353 link_state_id ++;
hasso508e53e2004-05-18 18:57:06 +0000354
355 /* Do premature-aging of rest, undesired Router-LSAs */
356 type = ntohs (OSPF6_LSTYPE_ROUTER);
357 router = oa->ospf6->router_id;
358 for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
359 lsa = ospf6_lsdb_type_router_next (type, router, lsa))
360 {
361 if (ntohl (lsa->header->id) < link_state_id)
362 continue;
hasso6452df02004-08-15 05:52:07 +0000363 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000364 }
hasso508e53e2004-05-18 18:57:06 +0000365
366 return 0;
367}
368
hasso508e53e2004-05-18 18:57:06 +0000369/*******************************/
370/* RFC2740 3.4.3.2 Network-LSA */
371/*******************************/
372
Dinesh Dutte68a6762013-08-25 03:03:23 +0000373static char *
374ospf6_network_lsa_get_ar_id (struct ospf6_lsa *lsa, char *buf, int buflen,
375 int pos)
376{
377 char *start, *end, *current;
378 struct ospf6_network_lsa *network_lsa;
379 struct ospf6_network_lsdesc *lsdesc;
380
381 if (lsa)
382 {
383 network_lsa = (struct ospf6_network_lsa *)
384 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
385
386 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
387 end = (char *) lsa->header + ntohs (lsa->header->length);
388 current = start + pos*(sizeof (struct ospf6_network_lsdesc));
389
390 if ((current + sizeof(struct ospf6_network_lsdesc)) <= end)
391 {
392 lsdesc = (struct ospf6_network_lsdesc *)current;
393 if (buf)
394 inet_ntop (AF_INET, &lsdesc->router_id, buf, buflen);
395 }
396 else
397 return NULL;
398 }
399
400 return (buf);
401}
402
Paul Jakma6ac29a52008-08-15 13:45:30 +0100403static int
hasso508e53e2004-05-18 18:57:06 +0000404ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
405{
406 char *start, *end, *current;
407 struct ospf6_network_lsa *network_lsa;
408 struct ospf6_network_lsdesc *lsdesc;
409 char buf[128], options[32];
410
411 network_lsa = (struct ospf6_network_lsa *)
412 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
413
414 ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
hasso049207c2004-08-04 20:02:13 +0000415 vty_out (vty, " Options: %s%s", options, VNL);
hasso508e53e2004-05-18 18:57:06 +0000416
417 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
418 end = (char *) lsa->header + ntohs (lsa->header->length);
419 for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
420 current += sizeof (struct ospf6_network_lsdesc))
421 {
422 lsdesc = (struct ospf6_network_lsdesc *) current;
423 inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +0000424 vty_out (vty, " Attached Router: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +0000425 }
426 return 0;
paul718e3742002-12-13 20:15:29 +0000427}
428
hasso6452df02004-08-15 05:52:07 +0000429int
430ospf6_network_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000431{
hasso6452df02004-08-15 05:52:07 +0000432 struct ospf6_interface *oi;
433
hasso508e53e2004-05-18 18:57:06 +0000434 char buffer [OSPF6_MAX_LSASIZE];
435 struct ospf6_lsa_header *lsa_header;
paul718e3742002-12-13 20:15:29 +0000436
hasso508e53e2004-05-18 18:57:06 +0000437 int count;
438 struct ospf6_lsa *old, *lsa;
439 struct ospf6_network_lsa *network_lsa;
440 struct ospf6_network_lsdesc *lsdesc;
441 struct ospf6_neighbor *on;
442 struct ospf6_link_lsa *link_lsa;
hasso52dc7ee2004-09-23 19:18:23 +0000443 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000444 u_int16_t type;
445
hasso6452df02004-08-15 05:52:07 +0000446 oi = (struct ospf6_interface *) THREAD_ARG (thread);
447 oi->thread_network_lsa = NULL;
448
449 /* The interface must be enabled until here. A Network-LSA of a
450 disabled interface (but was once enabled) should be flushed
451 by ospf6_lsa_refresh (), and does not come here. */
452 assert (oi->area);
paul718e3742002-12-13 20:15:29 +0000453
hasso508e53e2004-05-18 18:57:06 +0000454 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
455 htonl (oi->interface->ifindex),
456 oi->area->ospf6->router_id, oi->area->lsdb);
paul718e3742002-12-13 20:15:29 +0000457
hasso508e53e2004-05-18 18:57:06 +0000458 /* Do not originate Network-LSA if not DR */
459 if (oi->state != OSPF6_INTERFACE_DR)
paul718e3742002-12-13 20:15:29 +0000460 {
hasso508e53e2004-05-18 18:57:06 +0000461 if (old)
hasso6452df02004-08-15 05:52:07 +0000462 ospf6_lsa_purge (old);
463 return 0;
paul718e3742002-12-13 20:15:29 +0000464 }
hasso508e53e2004-05-18 18:57:06 +0000465
hasso1e058382004-09-01 21:36:14 +0000466 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
hassoc6487d62004-12-24 06:00:11 +0000467 zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000468
469 /* If none of neighbor is adjacent to us */
470 count = 0;
paul1eb8ef22005-04-07 07:30:20 +0000471
472 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
473 if (on->state == OSPF6_NEIGHBOR_FULL)
474 count++;
475
hasso508e53e2004-05-18 18:57:06 +0000476 if (count == 0)
477 {
hasso1e058382004-09-01 21:36:14 +0000478 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
hassoc6487d62004-12-24 06:00:11 +0000479 zlog_debug ("Interface stub, ignore");
hasso508e53e2004-05-18 18:57:06 +0000480 if (old)
hasso6452df02004-08-15 05:52:07 +0000481 ospf6_lsa_purge (old);
482 return 0;
hasso508e53e2004-05-18 18:57:06 +0000483 }
484
485 /* prepare buffer */
486 memset (buffer, 0, sizeof (buffer));
487 lsa_header = (struct ospf6_lsa_header *) buffer;
488 network_lsa = (struct ospf6_network_lsa *)
489 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
490
491 /* Collect the interface's Link-LSAs to describe
492 network's optional capabilities */
493 type = htons (OSPF6_LSTYPE_LINK);
494 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
495 lsa = ospf6_lsdb_type_next (type, lsa))
496 {
497 link_lsa = (struct ospf6_link_lsa *)
498 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
499 network_lsa->options[0] |= link_lsa->options[0];
500 network_lsa->options[1] |= link_lsa->options[1];
501 network_lsa->options[2] |= link_lsa->options[2];
502 }
503
504 lsdesc = (struct ospf6_network_lsdesc *)
505 ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
506
507 /* set Link Description to the router itself */
508 lsdesc->router_id = oi->area->ospf6->router_id;
509 lsdesc++;
510
511 /* Walk through the neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000512 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
hasso508e53e2004-05-18 18:57:06 +0000513 {
hasso508e53e2004-05-18 18:57:06 +0000514 if (on->state != OSPF6_NEIGHBOR_FULL)
515 continue;
516
517 /* set this neighbor's Router-ID to LSA */
518 lsdesc->router_id = on->router_id;
519 lsdesc++;
520 }
521
522 /* Fill LSA Header */
523 lsa_header->age = 0;
524 lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
525 lsa_header->id = htonl (oi->interface->ifindex);
526 lsa_header->adv_router = oi->area->ospf6->router_id;
527 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000528 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
529 lsa_header->adv_router, oi->area->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000530 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
531
532 /* LSA checksum */
533 ospf6_lsa_checksum (lsa_header);
534
535 /* create LSA */
536 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000537
538 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000539 ospf6_lsa_originate_area (lsa, oi->area);
hasso508e53e2004-05-18 18:57:06 +0000540
541 return 0;
542}
543
544
545/****************************/
546/* RFC2740 3.4.3.6 Link-LSA */
547/****************************/
548
Dinesh Dutte68a6762013-08-25 03:03:23 +0000549static char *
550ospf6_link_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, int buflen,
551 int pos)
552{
553 char *start, *end, *current;
554 struct ospf6_link_lsa *link_lsa;
555 struct in6_addr in6;
556 struct ospf6_prefix *prefix;
557 int cnt = 0, prefixnum;
558
559 if (lsa)
560 {
561 link_lsa = (struct ospf6_link_lsa *)
562 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
563
564 if (pos == 0) {
565 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, buflen);
566 return (buf);
567 }
568
569 prefixnum = ntohl (link_lsa->prefix_num);
570 if (pos > prefixnum)
571 return (NULL);
572
573 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
574 end = (char *) lsa->header + ntohs (lsa->header->length);
575 current = start;
576
577 do
578 {
579 prefix = (struct ospf6_prefix *) current;
580 if (prefix->prefix_length == 0 ||
581 current + OSPF6_PREFIX_SIZE (prefix) > end)
582 {
583 return (NULL);
584 }
585
586 if (cnt < pos)
587 {
588 current = start + pos*OSPF6_PREFIX_SIZE(prefix);
589 cnt++;
590 }
591 else
592 {
593 memset (&in6, 0, sizeof (in6));
594 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
595 OSPF6_PREFIX_SPACE (prefix->prefix_length));
596 inet_ntop (AF_INET6, &in6, buf, buflen);
597 return (buf);
598 }
599 } while (current <= end);
600 }
601 return (NULL);
602}
603
Paul Jakma6ac29a52008-08-15 13:45:30 +0100604static int
hasso508e53e2004-05-18 18:57:06 +0000605ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
606{
paul718e3742002-12-13 20:15:29 +0000607 char *start, *end, *current;
hasso508e53e2004-05-18 18:57:06 +0000608 struct ospf6_link_lsa *link_lsa;
609 int prefixnum;
610 char buf[128], options[32];
611 struct ospf6_prefix *prefix;
paul0c083ee2004-10-10 12:54:58 +0000612 const char *p, *mc, *la, *nu;
hasso508e53e2004-05-18 18:57:06 +0000613 struct in6_addr in6;
paul718e3742002-12-13 20:15:29 +0000614
hasso508e53e2004-05-18 18:57:06 +0000615 link_lsa = (struct ospf6_link_lsa *)
616 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +0000617
hasso508e53e2004-05-18 18:57:06 +0000618 ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
619 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
620 prefixnum = ntohl (link_lsa->prefix_num);
paul718e3742002-12-13 20:15:29 +0000621
hasso508e53e2004-05-18 18:57:06 +0000622 vty_out (vty, " Priority: %d Options: %s%s",
hasso049207c2004-08-04 20:02:13 +0000623 link_lsa->priority, options, VNL);
624 vty_out (vty, " LinkLocal Address: %s%s", buf, VNL);
625 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
paul718e3742002-12-13 20:15:29 +0000626
hasso508e53e2004-05-18 18:57:06 +0000627 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
628 end = (char *) lsa->header + ntohs (lsa->header->length);
paul718e3742002-12-13 20:15:29 +0000629 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
630 {
631 prefix = (struct ospf6_prefix *) current;
hasso508e53e2004-05-18 18:57:06 +0000632 if (prefix->prefix_length == 0 ||
633 current + OSPF6_PREFIX_SIZE (prefix) > end)
634 break;
paul718e3742002-12-13 20:15:29 +0000635
hasso508e53e2004-05-18 18:57:06 +0000636 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
637 "P" : "--");
638 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
639 "MC" : "--");
640 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
641 "LA" : "--");
642 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
643 "NU" : "--");
644 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
hasso049207c2004-08-04 20:02:13 +0000645 p, mc, la, nu, VNL);
paul718e3742002-12-13 20:15:29 +0000646
hasso508e53e2004-05-18 18:57:06 +0000647 memset (&in6, 0, sizeof (in6));
648 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
649 OSPF6_PREFIX_SPACE (prefix->prefix_length));
paul718e3742002-12-13 20:15:29 +0000650 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
651 vty_out (vty, " Prefix: %s/%d%s",
hasso049207c2004-08-04 20:02:13 +0000652 buf, prefix->prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +0000653 }
654
655 return 0;
656}
657
hasso6452df02004-08-15 05:52:07 +0000658int
659ospf6_link_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000660{
hasso6452df02004-08-15 05:52:07 +0000661 struct ospf6_interface *oi;
662
hasso508e53e2004-05-18 18:57:06 +0000663 char buffer[OSPF6_MAX_LSASIZE];
664 struct ospf6_lsa_header *lsa_header;
665 struct ospf6_lsa *old, *lsa;
paul718e3742002-12-13 20:15:29 +0000666
hasso508e53e2004-05-18 18:57:06 +0000667 struct ospf6_link_lsa *link_lsa;
668 struct ospf6_route *route;
669 struct ospf6_prefix *op;
paul718e3742002-12-13 20:15:29 +0000670
hasso6452df02004-08-15 05:52:07 +0000671 oi = (struct ospf6_interface *) THREAD_ARG (thread);
672 oi->thread_link_lsa = NULL;
673
674 assert (oi->area);
paul718e3742002-12-13 20:15:29 +0000675
676 /* find previous LSA */
hasso508e53e2004-05-18 18:57:06 +0000677 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
678 htonl (oi->interface->ifindex),
679 oi->area->ospf6->router_id, oi->lsdb);
paul718e3742002-12-13 20:15:29 +0000680
hasso508e53e2004-05-18 18:57:06 +0000681 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
paul718e3742002-12-13 20:15:29 +0000682 {
683 if (old)
hasso6452df02004-08-15 05:52:07 +0000684 ospf6_lsa_purge (old);
685 return 0;
paul718e3742002-12-13 20:15:29 +0000686 }
687
hasso1e058382004-09-01 21:36:14 +0000688 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
hassoc6487d62004-12-24 06:00:11 +0000689 zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
paul718e3742002-12-13 20:15:29 +0000690
hasso508e53e2004-05-18 18:57:06 +0000691 /* can't make Link-LSA if linklocal address not set */
692 if (oi->linklocal_addr == NULL)
paul718e3742002-12-13 20:15:29 +0000693 {
hasso1e058382004-09-01 21:36:14 +0000694 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
hassoc6487d62004-12-24 06:00:11 +0000695 zlog_debug ("No Linklocal address on %s, defer originating",
hasso508e53e2004-05-18 18:57:06 +0000696 oi->interface->name);
697 if (old)
hasso6452df02004-08-15 05:52:07 +0000698 ospf6_lsa_purge (old);
699 return 0;
hasso508e53e2004-05-18 18:57:06 +0000700 }
701
702 /* prepare buffer */
703 memset (buffer, 0, sizeof (buffer));
704 lsa_header = (struct ospf6_lsa_header *) buffer;
705 link_lsa = (struct ospf6_link_lsa *)
706 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
707
708 /* Fill Link-LSA */
709 link_lsa->priority = oi->priority;
710 memcpy (link_lsa->options, oi->area->options, 3);
711 memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
712 sizeof (struct in6_addr));
713 link_lsa->prefix_num = htonl (oi->route_connected->count);
714
715 op = (struct ospf6_prefix *)
716 ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
717
718 /* connected prefix to advertise */
719 for (route = ospf6_route_head (oi->route_connected); route;
720 route = ospf6_route_next (route))
721 {
722 op->prefix_length = route->prefix.prefixlen;
723 op->prefix_options = route->path.prefix_options;
724 op->prefix_metric = htons (0);
725 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
726 OSPF6_PREFIX_SPACE (op->prefix_length));
727 op = OSPF6_PREFIX_NEXT (op);
728 }
729
730 /* Fill LSA Header */
731 lsa_header->age = 0;
732 lsa_header->type = htons (OSPF6_LSTYPE_LINK);
733 lsa_header->id = htonl (oi->interface->ifindex);
734 lsa_header->adv_router = oi->area->ospf6->router_id;
735 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000736 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
737 lsa_header->adv_router, oi->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000738 lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
739
740 /* LSA checksum */
741 ospf6_lsa_checksum (lsa_header);
742
743 /* create LSA */
744 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000745
746 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000747 ospf6_lsa_originate_interface (lsa, oi);
hasso508e53e2004-05-18 18:57:06 +0000748
749 return 0;
750}
751
752
753/*****************************************/
754/* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
755/*****************************************/
Dinesh Dutte68a6762013-08-25 03:03:23 +0000756static char *
757ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
758 int buflen, int pos)
759{
760 char *start, *end, *current;
761 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
762 struct in6_addr in6;
763 int prefixnum, cnt = 0;
764 struct ospf6_prefix *prefix;
765
766 if (lsa)
767 {
768 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
769 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
770
771 prefixnum = ntohs (intra_prefix_lsa->prefix_num);
772 if (pos > prefixnum)
773 return (NULL);
774
775 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
776 end = (char *) lsa->header + ntohs (lsa->header->length);
777 current = start;
778
779 do
780 {
781 prefix = (struct ospf6_prefix *) current;
782 if (prefix->prefix_length == 0 ||
783 current + OSPF6_PREFIX_SIZE (prefix) > end)
784 {
785 return NULL;
786 }
787
788 if (cnt < pos)
789 {
790 current = start + pos*OSPF6_PREFIX_SIZE(prefix);
791 cnt++;
792 }
793 else
794 {
795 memset (&in6, 0, sizeof (in6));
796 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
797 OSPF6_PREFIX_SPACE (prefix->prefix_length));
798 inet_ntop (AF_INET6, &in6, buf, buflen);
799 sprintf(&buf[strlen(buf)], "/%d", prefix->prefix_length);
800 return (buf);
801 }
802 } while (current <= end);
803 }
804 return (buf);
805}
hasso508e53e2004-05-18 18:57:06 +0000806
Paul Jakma6ac29a52008-08-15 13:45:30 +0100807static int
hasso508e53e2004-05-18 18:57:06 +0000808ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
809{
810 char *start, *end, *current;
811 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
812 int prefixnum;
813 char buf[128];
814 struct ospf6_prefix *prefix;
815 char id[16], adv_router[16];
paul0c083ee2004-10-10 12:54:58 +0000816 const char *p, *mc, *la, *nu;
hasso508e53e2004-05-18 18:57:06 +0000817 struct in6_addr in6;
818
819 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
820 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
821
822 prefixnum = ntohs (intra_prefix_lsa->prefix_num);
823
hasso049207c2004-08-04 20:02:13 +0000824 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
hasso508e53e2004-05-18 18:57:06 +0000825
826 inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
827 inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
828 adv_router, sizeof (adv_router));
829 vty_out (vty, " Reference: %s Id: %s Adv: %s%s",
hasso1e058382004-09-01 21:36:14 +0000830 ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
hasso049207c2004-08-04 20:02:13 +0000831 VNL);
hasso508e53e2004-05-18 18:57:06 +0000832
833 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
834 end = (char *) lsa->header + ntohs (lsa->header->length);
835 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
836 {
837 prefix = (struct ospf6_prefix *) current;
838 if (prefix->prefix_length == 0 ||
839 current + OSPF6_PREFIX_SIZE (prefix) > end)
840 break;
841
842 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
843 "P" : "--");
844 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
845 "MC" : "--");
846 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
847 "LA" : "--");
848 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
849 "NU" : "--");
850 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
hasso049207c2004-08-04 20:02:13 +0000851 p, mc, la, nu, VNL);
hasso508e53e2004-05-18 18:57:06 +0000852
853 memset (&in6, 0, sizeof (in6));
854 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
855 OSPF6_PREFIX_SPACE (prefix->prefix_length));
856 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
857 vty_out (vty, " Prefix: %s/%d%s",
hasso049207c2004-08-04 20:02:13 +0000858 buf, prefix->prefix_length, VNL);
hasso508e53e2004-05-18 18:57:06 +0000859 }
860
861 return 0;
862}
863
hasso6452df02004-08-15 05:52:07 +0000864int
865ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
hasso508e53e2004-05-18 18:57:06 +0000866{
hasso6452df02004-08-15 05:52:07 +0000867 struct ospf6_area *oa;
868
hasso508e53e2004-05-18 18:57:06 +0000869 char buffer[OSPF6_MAX_LSASIZE];
870 struct ospf6_lsa_header *lsa_header;
871 struct ospf6_lsa *old, *lsa;
872
873 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
874 struct ospf6_interface *oi;
875 struct ospf6_neighbor *on;
876 struct ospf6_route *route;
877 struct ospf6_prefix *op;
hasso52dc7ee2004-09-23 19:18:23 +0000878 struct listnode *i, *j;
hasso508e53e2004-05-18 18:57:06 +0000879 int full_count = 0;
880 unsigned short prefix_num = 0;
881 char buf[BUFSIZ];
882 struct ospf6_route_table *route_advertise;
883
hasso6452df02004-08-15 05:52:07 +0000884 oa = (struct ospf6_area *) THREAD_ARG (thread);
885 oa->thread_intra_prefix_lsa = NULL;
886
hasso508e53e2004-05-18 18:57:06 +0000887 /* find previous LSA */
888 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
889 htonl (0), oa->ospf6->router_id, oa->lsdb);
890
hasso6452df02004-08-15 05:52:07 +0000891 if (! IS_AREA_ENABLED (oa))
hasso508e53e2004-05-18 18:57:06 +0000892 {
893 if (old)
hasso6452df02004-08-15 05:52:07 +0000894 ospf6_lsa_purge (old);
895 return 0;
hasso508e53e2004-05-18 18:57:06 +0000896 }
897
hasso1e058382004-09-01 21:36:14 +0000898 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000899 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
hasso508e53e2004-05-18 18:57:06 +0000900 oa->name);
901
902 /* prepare buffer */
903 memset (buffer, 0, sizeof (buffer));
904 lsa_header = (struct ospf6_lsa_header *) buffer;
905 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
906 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
907
908 /* Fill Intra-Area-Prefix-LSA */
909 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
910 intra_prefix_lsa->ref_id = htonl (0);
911 intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
912
Paul Jakmacf1ce252006-05-15 10:46:07 +0000913 route_advertise = ospf6_route_table_create (0, 0);
hasso508e53e2004-05-18 18:57:06 +0000914
paul1eb8ef22005-04-07 07:30:20 +0000915 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
hasso508e53e2004-05-18 18:57:06 +0000916 {
hasso508e53e2004-05-18 18:57:06 +0000917 if (oi->state == OSPF6_INTERFACE_DOWN)
918 {
hasso1e058382004-09-01 21:36:14 +0000919 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000920 zlog_debug (" Interface %s is down, ignore", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000921 continue;
922 }
923
924 full_count = 0;
paul1eb8ef22005-04-07 07:30:20 +0000925
926 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
927 if (on->state == OSPF6_NEIGHBOR_FULL)
928 full_count++;
929
hasso508e53e2004-05-18 18:57:06 +0000930 if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
931 oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
932 full_count != 0)
933 {
hasso1e058382004-09-01 21:36:14 +0000934 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000935 zlog_debug (" Interface %s is not stub, ignore",
hasso508e53e2004-05-18 18:57:06 +0000936 oi->interface->name);
937 continue;
938 }
939
hasso1e058382004-09-01 21:36:14 +0000940 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000941 zlog_debug (" Interface %s:", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000942
943 /* connected prefix to advertise */
944 for (route = ospf6_route_head (oi->route_connected); route;
945 route = ospf6_route_best_next (route))
946 {
hasso1e058382004-09-01 21:36:14 +0000947 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +0000948 {
949 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000950 zlog_debug (" include %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000951 }
952 ospf6_route_add (ospf6_route_copy (route), route_advertise);
953 }
954 }
955
956 if (route_advertise->count == 0)
957 {
958 if (old)
hasso6452df02004-08-15 05:52:07 +0000959 ospf6_lsa_purge (old);
hasso508e53e2004-05-18 18:57:06 +0000960 ospf6_route_table_delete (route_advertise);
hasso6452df02004-08-15 05:52:07 +0000961 return 0;
hasso508e53e2004-05-18 18:57:06 +0000962 }
963
964 /* put prefixes to advertise */
965 prefix_num = 0;
966 op = (struct ospf6_prefix *)
967 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
968 for (route = ospf6_route_head (route_advertise); route;
969 route = ospf6_route_best_next (route))
970 {
971 op->prefix_length = route->prefix.prefixlen;
972 op->prefix_options = route->path.prefix_options;
973 op->prefix_metric = htons (route->path.cost);
974 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
975 OSPF6_PREFIX_SPACE (op->prefix_length));
976 op = OSPF6_PREFIX_NEXT (op);
977 prefix_num++;
978 }
979
980 ospf6_route_table_delete (route_advertise);
981
982 if (prefix_num == 0)
983 {
hasso1e058382004-09-01 21:36:14 +0000984 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000985 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
hasso6452df02004-08-15 05:52:07 +0000986 return 0;
hasso508e53e2004-05-18 18:57:06 +0000987 }
988
989 intra_prefix_lsa->prefix_num = htons (prefix_num);
990
991 /* Fill LSA Header */
992 lsa_header->age = 0;
993 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
994 lsa_header->id = htonl (0);
995 lsa_header->adv_router = oa->ospf6->router_id;
996 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000997 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
998 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000999 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
1000
1001 /* LSA checksum */
1002 ospf6_lsa_checksum (lsa_header);
1003
1004 /* create LSA */
1005 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +00001006
1007 /* Originate */
hasso6452df02004-08-15 05:52:07 +00001008 ospf6_lsa_originate_area (lsa, oa);
1009
1010 return 0;
hasso508e53e2004-05-18 18:57:06 +00001011}
1012
hasso6452df02004-08-15 05:52:07 +00001013
1014int
1015ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
hasso508e53e2004-05-18 18:57:06 +00001016{
hasso6452df02004-08-15 05:52:07 +00001017 struct ospf6_interface *oi;
1018
hasso508e53e2004-05-18 18:57:06 +00001019 char buffer[OSPF6_MAX_LSASIZE];
1020 struct ospf6_lsa_header *lsa_header;
1021 struct ospf6_lsa *old, *lsa;
1022
1023 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1024 struct ospf6_neighbor *on;
1025 struct ospf6_route *route;
1026 struct ospf6_prefix *op;
hasso52dc7ee2004-09-23 19:18:23 +00001027 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +00001028 int full_count = 0;
1029 unsigned short prefix_num = 0;
1030 struct ospf6_route_table *route_advertise;
1031 struct ospf6_link_lsa *link_lsa;
1032 char *start, *end, *current;
1033 u_int16_t type;
1034 char buf[BUFSIZ];
1035
hasso6452df02004-08-15 05:52:07 +00001036 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1037 oi->thread_intra_prefix_lsa = NULL;
1038
1039 assert (oi->area);
hasso508e53e2004-05-18 18:57:06 +00001040
1041 /* find previous LSA */
1042 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
1043 htonl (oi->interface->ifindex),
1044 oi->area->ospf6->router_id, oi->area->lsdb);
1045
1046 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
1047 {
1048 if (old)
hasso6452df02004-08-15 05:52:07 +00001049 ospf6_lsa_purge (old);
1050 return 0;
hasso508e53e2004-05-18 18:57:06 +00001051 }
1052
hasso1e058382004-09-01 21:36:14 +00001053 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001054 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
hasso508e53e2004-05-18 18:57:06 +00001055 oi->interface->name);
1056
1057 /* prepare buffer */
1058 memset (buffer, 0, sizeof (buffer));
1059 lsa_header = (struct ospf6_lsa_header *) buffer;
1060 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1061 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
1062
1063 /* Fill Intra-Area-Prefix-LSA */
1064 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
1065 intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
1066 intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
1067
1068 if (oi->state != OSPF6_INTERFACE_DR)
1069 {
hasso1e058382004-09-01 21:36:14 +00001070 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001071 zlog_debug (" Interface is not DR");
hasso508e53e2004-05-18 18:57:06 +00001072 if (old)
hasso6452df02004-08-15 05:52:07 +00001073 ospf6_lsa_purge (old);
1074 return 0;
hasso508e53e2004-05-18 18:57:06 +00001075 }
1076
1077 full_count = 0;
paul1eb8ef22005-04-07 07:30:20 +00001078 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
1079 if (on->state == OSPF6_NEIGHBOR_FULL)
1080 full_count++;
1081
hasso508e53e2004-05-18 18:57:06 +00001082 if (full_count == 0)
1083 {
hasso1e058382004-09-01 21:36:14 +00001084 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001085 zlog_debug (" Interface is stub");
hasso508e53e2004-05-18 18:57:06 +00001086 if (old)
hasso6452df02004-08-15 05:52:07 +00001087 ospf6_lsa_purge (old);
1088 return 0;
hasso508e53e2004-05-18 18:57:06 +00001089 }
1090
1091 /* connected prefix to advertise */
Paul Jakmacf1ce252006-05-15 10:46:07 +00001092 route_advertise = ospf6_route_table_create (0, 0);
hasso508e53e2004-05-18 18:57:06 +00001093
1094 type = ntohs (OSPF6_LSTYPE_LINK);
1095 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
1096 lsa = ospf6_lsdb_type_next (type, lsa))
1097 {
1098 if (OSPF6_LSA_IS_MAXAGE (lsa))
paul718e3742002-12-13 20:15:29 +00001099 continue;
1100
hasso1e058382004-09-01 21:36:14 +00001101 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001102 zlog_debug (" include prefix from %s", lsa->name);
paul718e3742002-12-13 20:15:29 +00001103
hasso508e53e2004-05-18 18:57:06 +00001104 if (lsa->header->adv_router != oi->area->ospf6->router_id)
paul718e3742002-12-13 20:15:29 +00001105 {
hasso508e53e2004-05-18 18:57:06 +00001106 on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
1107 if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
paul718e3742002-12-13 20:15:29 +00001108 {
hasso1e058382004-09-01 21:36:14 +00001109 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001110 zlog_debug (" Neighbor not found or not Full, ignore");
paul718e3742002-12-13 20:15:29 +00001111 continue;
1112 }
1113 }
1114
hasso508e53e2004-05-18 18:57:06 +00001115 link_lsa = (struct ospf6_link_lsa *)
1116 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +00001117
hasso508e53e2004-05-18 18:57:06 +00001118 prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
1119 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
1120 end = (char *) lsa->header + ntohs (lsa->header->length);
1121 for (current = start; current < end && prefix_num;
1122 current += OSPF6_PREFIX_SIZE (op))
paul718e3742002-12-13 20:15:29 +00001123 {
hasso508e53e2004-05-18 18:57:06 +00001124 op = (struct ospf6_prefix *) current;
1125 if (op->prefix_length == 0 ||
1126 current + OSPF6_PREFIX_SIZE (op) > end)
1127 break;
paul718e3742002-12-13 20:15:29 +00001128
hasso508e53e2004-05-18 18:57:06 +00001129 route = ospf6_route_create ();
1130
1131 route->type = OSPF6_DEST_TYPE_NETWORK;
1132 route->prefix.family = AF_INET6;
1133 route->prefix.prefixlen = op->prefix_length;
1134 memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
1135 memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
1136 OSPF6_PREFIX_SPACE (op->prefix_length));
1137
1138 route->path.origin.type = lsa->header->type;
1139 route->path.origin.id = lsa->header->id;
1140 route->path.origin.adv_router = lsa->header->adv_router;
1141 route->path.options[0] = link_lsa->options[0];
1142 route->path.options[1] = link_lsa->options[1];
1143 route->path.options[2] = link_lsa->options[2];
1144 route->path.prefix_options = op->prefix_options;
1145 route->path.area_id = oi->area->area_id;
1146 route->path.type = OSPF6_PATH_TYPE_INTRA;
1147
hasso1e058382004-09-01 21:36:14 +00001148 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
paul718e3742002-12-13 20:15:29 +00001149 {
hasso508e53e2004-05-18 18:57:06 +00001150 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001151 zlog_debug (" include %s", buf);
paul718e3742002-12-13 20:15:29 +00001152 }
1153
hasso508e53e2004-05-18 18:57:06 +00001154 ospf6_route_add (route, route_advertise);
1155 prefix_num--;
paul718e3742002-12-13 20:15:29 +00001156 }
hasso1e058382004-09-01 21:36:14 +00001157 if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001158 zlog_debug ("Trailing garbage in %s", lsa->name);
paul718e3742002-12-13 20:15:29 +00001159 }
1160
hasso508e53e2004-05-18 18:57:06 +00001161 op = (struct ospf6_prefix *)
1162 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
1163
1164 prefix_num = 0;
1165 for (route = ospf6_route_head (route_advertise); route;
1166 route = ospf6_route_best_next (route))
paul718e3742002-12-13 20:15:29 +00001167 {
hasso508e53e2004-05-18 18:57:06 +00001168 op->prefix_length = route->prefix.prefixlen;
1169 op->prefix_options = route->path.prefix_options;
1170 op->prefix_metric = htons (0);
1171 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
1172 OSPF6_PREFIX_SPACE (op->prefix_length));
1173 op = OSPF6_PREFIX_NEXT (op);
1174 prefix_num++;
1175 }
1176
1177 ospf6_route_table_delete (route_advertise);
1178
1179 if (prefix_num == 0)
1180 {
hasso1e058382004-09-01 21:36:14 +00001181 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001182 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
hasso6452df02004-08-15 05:52:07 +00001183 return 0;
paul718e3742002-12-13 20:15:29 +00001184 }
1185
hasso508e53e2004-05-18 18:57:06 +00001186 intra_prefix_lsa->prefix_num = htons (prefix_num);
paul718e3742002-12-13 20:15:29 +00001187
hasso508e53e2004-05-18 18:57:06 +00001188 /* Fill LSA Header */
1189 lsa_header->age = 0;
1190 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1191 lsa_header->id = htonl (oi->interface->ifindex);
1192 lsa_header->adv_router = oi->area->ospf6->router_id;
1193 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +00001194 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
1195 lsa_header->adv_router, oi->area->lsdb);
hasso508e53e2004-05-18 18:57:06 +00001196 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
paul718e3742002-12-13 20:15:29 +00001197
hasso508e53e2004-05-18 18:57:06 +00001198 /* LSA checksum */
1199 ospf6_lsa_checksum (lsa_header);
paul718e3742002-12-13 20:15:29 +00001200
hasso508e53e2004-05-18 18:57:06 +00001201 /* create LSA */
1202 lsa = ospf6_lsa_create (lsa_header);
paul718e3742002-12-13 20:15:29 +00001203
hasso508e53e2004-05-18 18:57:06 +00001204 /* Originate */
hasso6452df02004-08-15 05:52:07 +00001205 ospf6_lsa_originate_area (lsa, oi->area);
paul718e3742002-12-13 20:15:29 +00001206
1207 return 0;
1208}
1209
1210void
hasso508e53e2004-05-18 18:57:06 +00001211ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001212{
hasso508e53e2004-05-18 18:57:06 +00001213 struct ospf6_area *oa;
1214 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1215 struct prefix ls_prefix;
1216 struct ospf6_route *route, *ls_entry;
1217 int i, prefix_num;
1218 struct ospf6_prefix *op;
1219 char *start, *current, *end;
1220 char buf[64];
Dinesh Duttb81e97a2013-08-24 07:55:50 +00001221 struct interface *ifp;
1222 int direct_connect = 0;
paul718e3742002-12-13 20:15:29 +00001223
hassoccb59b12004-08-25 09:10:37 +00001224 if (OSPF6_LSA_IS_MAXAGE (lsa))
1225 return;
1226
hasso1e058382004-09-01 21:36:14 +00001227 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001228 zlog_debug ("%s found", lsa->name);
paul718e3742002-12-13 20:15:29 +00001229
hasso6452df02004-08-15 05:52:07 +00001230 oa = OSPF6_AREA (lsa->lsdb->data);
1231
hasso508e53e2004-05-18 18:57:06 +00001232 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1233 OSPF6_LSA_HEADER_END (lsa->header);
1234 if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
1235 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1236 htonl (0), &ls_prefix);
1237 else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
1238 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1239 intra_prefix_lsa->ref_id, &ls_prefix);
1240 else
1241 {
hasso1e058382004-09-01 21:36:14 +00001242 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001243 zlog_debug ("Unknown reference LS-type: %#hx",
1244 ntohs (intra_prefix_lsa->ref_type));
hasso508e53e2004-05-18 18:57:06 +00001245 return;
1246 }
paul718e3742002-12-13 20:15:29 +00001247
hasso508e53e2004-05-18 18:57:06 +00001248 ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
1249 if (ls_entry == NULL)
1250 {
hasso1e058382004-09-01 21:36:14 +00001251 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001252 {
1253 ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001254 zlog_debug ("LS entry does not exist: %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001255 }
1256 return;
1257 }
paul718e3742002-12-13 20:15:29 +00001258
Dinesh Duttb81e97a2013-08-24 07:55:50 +00001259 if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id)
1260 {
1261 /* the intra-prefix are directly connected */
1262 direct_connect = 1;
1263 }
1264
hasso508e53e2004-05-18 18:57:06 +00001265 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1266 start = (caddr_t) intra_prefix_lsa +
1267 sizeof (struct ospf6_intra_prefix_lsa);
1268 end = OSPF6_LSA_END (lsa->header);
1269 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1270 {
1271 op = (struct ospf6_prefix *) current;
1272 if (prefix_num == 0)
1273 break;
1274 if (end < current + OSPF6_PREFIX_SIZE (op))
1275 break;
1276
Dinesh Dutte68a6762013-08-25 03:03:23 +00001277 /* Appendix A.4.1.1 */
1278 if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU) ||
1279 CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_LA))
1280 {
1281 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1282 {
1283 ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op),
1284 buf, sizeof (buf));
1285 zlog_debug ("%s: Skipping Prefix %s has NU/LA option set",
1286 __func__, buf);
1287 }
1288 continue;
1289 }
1290
hasso508e53e2004-05-18 18:57:06 +00001291 route = ospf6_route_create ();
hassoccb59b12004-08-25 09:10:37 +00001292
1293 memset (&route->prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001294 route->prefix.family = AF_INET6;
hassoccb59b12004-08-25 09:10:37 +00001295 route->prefix.prefixlen = op->prefix_length;
1296 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
1297
hasso508e53e2004-05-18 18:57:06 +00001298 route->type = OSPF6_DEST_TYPE_NETWORK;
1299 route->path.origin.type = lsa->header->type;
1300 route->path.origin.id = lsa->header->id;
1301 route->path.origin.adv_router = lsa->header->adv_router;
1302 route->path.prefix_options = op->prefix_options;
1303 route->path.area_id = oa->area_id;
1304 route->path.type = OSPF6_PATH_TYPE_INTRA;
1305 route->path.metric_type = 1;
1306 route->path.cost = ls_entry->path.cost +
1307 ntohs (op->prefix_metric);
1308
Dinesh Duttb81e97a2013-08-24 07:55:50 +00001309 if (direct_connect)
1310 {
1311 ifp = if_lookup_prefix(&route->prefix);
1312 if (ifp)
1313 route->nexthop[0].ifindex = ifp->ifindex;
1314 }
1315 else
1316 {
1317 for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
1318 i < OSPF6_MULTI_PATH_LIMIT; i++)
1319 ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
1320 }
hasso508e53e2004-05-18 18:57:06 +00001321
hasso1e058382004-09-01 21:36:14 +00001322 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001323 {
1324 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001325 zlog_debug (" add %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001326 }
1327
1328 ospf6_route_add (route, oa->route_table);
1329 prefix_num--;
1330 }
1331
hasso1e058382004-09-01 21:36:14 +00001332 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001333 zlog_debug ("Trailing garbage ignored");
paul718e3742002-12-13 20:15:29 +00001334}
1335
1336void
hasso508e53e2004-05-18 18:57:06 +00001337ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001338{
hasso508e53e2004-05-18 18:57:06 +00001339 struct ospf6_area *oa;
1340 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1341 struct prefix prefix;
1342 struct ospf6_route *route;
1343 int prefix_num;
1344 struct ospf6_prefix *op;
1345 char *start, *current, *end;
1346 char buf[64];
1347
hasso1e058382004-09-01 21:36:14 +00001348 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001349 zlog_debug ("%s disappearing", lsa->name);
hasso508e53e2004-05-18 18:57:06 +00001350
hasso6452df02004-08-15 05:52:07 +00001351 oa = OSPF6_AREA (lsa->lsdb->data);
1352
hasso508e53e2004-05-18 18:57:06 +00001353 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1354 OSPF6_LSA_HEADER_END (lsa->header);
1355
1356 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1357 start = (caddr_t) intra_prefix_lsa +
1358 sizeof (struct ospf6_intra_prefix_lsa);
1359 end = OSPF6_LSA_END (lsa->header);
1360 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1361 {
1362 op = (struct ospf6_prefix *) current;
1363 if (prefix_num == 0)
1364 break;
1365 if (end < current + OSPF6_PREFIX_SIZE (op))
1366 break;
1367 prefix_num--;
1368
hassoccb59b12004-08-25 09:10:37 +00001369 memset (&prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001370 prefix.family = AF_INET6;
1371 prefix.prefixlen = op->prefix_length;
1372 ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
1373
1374 route = ospf6_route_lookup (&prefix, oa->route_table);
1375 if (route == NULL)
1376 continue;
1377
1378 for (ospf6_route_lock (route);
1379 route && ospf6_route_is_prefix (&prefix, route);
1380 route = ospf6_route_next (route))
1381 {
1382 if (route->type != OSPF6_DEST_TYPE_NETWORK)
1383 continue;
1384 if (route->path.area_id != oa->area_id)
1385 continue;
1386 if (route->path.type != OSPF6_PATH_TYPE_INTRA)
1387 continue;
1388 if (route->path.origin.type != lsa->header->type ||
1389 route->path.origin.id != lsa->header->id ||
1390 route->path.origin.adv_router != lsa->header->adv_router)
1391 continue;
1392
hasso1e058382004-09-01 21:36:14 +00001393 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001394 {
1395 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001396 zlog_debug ("remove %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001397 }
1398 ospf6_route_remove (route, oa->route_table);
1399 }
Tom Goffe7a6d802010-11-10 13:03:02 -08001400 if (route)
1401 ospf6_route_unlock (route);
hasso508e53e2004-05-18 18:57:06 +00001402 }
1403
hasso1e058382004-09-01 21:36:14 +00001404 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001405 zlog_debug ("Trailing garbage ignored");
paul718e3742002-12-13 20:15:29 +00001406}
1407
1408void
hasso508e53e2004-05-18 18:57:06 +00001409ospf6_intra_route_calculation (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +00001410{
hasso508e53e2004-05-18 18:57:06 +00001411 struct ospf6_route *route;
1412 u_int16_t type;
1413 struct ospf6_lsa *lsa;
1414 void (*hook_add) (struct ospf6_route *) = NULL;
1415 void (*hook_remove) (struct ospf6_route *) = NULL;
1416
hasso1e058382004-09-01 21:36:14 +00001417 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001418 zlog_debug ("Re-examin intra-routes for area %s", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001419
1420 hook_add = oa->route_table->hook_add;
1421 hook_remove = oa->route_table->hook_remove;
1422 oa->route_table->hook_add = NULL;
1423 oa->route_table->hook_remove = NULL;
1424
1425 for (route = ospf6_route_head (oa->route_table); route;
1426 route = ospf6_route_next (route))
1427 route->flag = OSPF6_ROUTE_REMOVE;
1428
1429 type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1430 for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
1431 lsa = ospf6_lsdb_type_next (type, lsa))
1432 ospf6_intra_prefix_lsa_add (lsa);
1433
1434 oa->route_table->hook_add = hook_add;
1435 oa->route_table->hook_remove = hook_remove;
1436
1437 for (route = ospf6_route_head (oa->route_table); route;
1438 route = ospf6_route_next (route))
1439 {
1440 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
1441 CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
1442 {
1443 UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
1444 UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
1445 }
1446
1447 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
1448 ospf6_route_remove (route, oa->route_table);
1449 else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
1450 CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
1451 {
1452 if (hook_add)
1453 (*hook_add) (route);
1454 }
1455
1456 route->flag = 0;
1457 }
1458
hasso1e058382004-09-01 21:36:14 +00001459 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001460 zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001461}
1462
Paul Jakma6ac29a52008-08-15 13:45:30 +01001463static void
Paul Jakmacf1ce252006-05-15 10:46:07 +00001464ospf6_brouter_debug_print (struct ospf6_route *brouter)
1465{
1466 u_int32_t brouter_id;
1467 char brouter_name[16];
1468 char area_name[16];
1469 char destination[64];
1470 char installed[16], changed[16];
1471 struct timeval now, res;
1472 char id[16], adv_router[16];
1473 char capa[16], options[16];
1474
1475 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1476 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1477 inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
1478 ospf6_linkstate_prefix2str (&brouter->prefix, destination,
1479 sizeof (destination));
1480
Takashi Sogabe86f72dc2009-06-22 13:07:02 +09001481 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001482 timersub (&now, &brouter->installed, &res);
1483 timerstring (&res, installed, sizeof (installed));
1484
Takashi Sogabe86f72dc2009-06-22 13:07:02 +09001485 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001486 timersub (&now, &brouter->changed, &res);
1487 timerstring (&res, changed, sizeof (changed));
1488
1489 inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
1490 inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
1491 sizeof (adv_router));
1492
1493 ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
1494 ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
1495
1496 zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
1497 zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
David Lampartereed3c482015-03-03 08:51:53 +01001498 (void *)brouter->prev, (void *)brouter, (void *)brouter->next,
1499 (void *)brouter->rnode);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001500 zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1501 brouter->type, destination, installed, changed);
1502 zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock,
1503 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
1504 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
1505 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
1506 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
1507 zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1508 OSPF6_PATH_TYPE_NAME (brouter->path.type),
1509 ospf6_lstype_name (brouter->path.origin.type),
1510 id, adv_router);
1511 zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1512 options, capa, brouter->path.metric_type,
1513 brouter->path.cost, brouter->path.cost_e2);
1514}
1515
1516void
hasso6452df02004-08-15 05:52:07 +00001517ospf6_intra_brouter_calculation (struct ospf6_area *oa)
hasso508e53e2004-05-18 18:57:06 +00001518{
Paul Jakmacb4b8842006-05-15 10:39:30 +00001519 struct ospf6_route *brouter, *copy;
hasso508e53e2004-05-18 18:57:06 +00001520 void (*hook_add) (struct ospf6_route *) = NULL;
1521 void (*hook_remove) (struct ospf6_route *) = NULL;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001522 u_int32_t brouter_id;
1523 char brouter_name[16];
1524
1525 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1526 zlog_info ("border-router calculation for area %s", oa->name);
1527
hasso6452df02004-08-15 05:52:07 +00001528 hook_add = oa->ospf6->brouter_table->hook_add;
1529 hook_remove = oa->ospf6->brouter_table->hook_remove;
1530 oa->ospf6->brouter_table->hook_add = NULL;
1531 oa->ospf6->brouter_table->hook_remove = NULL;
hasso508e53e2004-05-18 18:57:06 +00001532
hasso6452df02004-08-15 05:52:07 +00001533 /* withdraw the previous router entries for the area */
Paul Jakmacb4b8842006-05-15 10:39:30 +00001534 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1535 brouter = ospf6_route_next (brouter))
hasso508e53e2004-05-18 18:57:06 +00001536 {
Paul Jakmacf1ce252006-05-15 10:46:07 +00001537 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1538 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
Paul Jakmacb4b8842006-05-15 10:39:30 +00001539 if (brouter->path.area_id != oa->area_id)
hasso508e53e2004-05-18 18:57:06 +00001540 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001541 brouter->flag = OSPF6_ROUTE_REMOVE;
Paul Jakmacf1ce252006-05-15 10:46:07 +00001542
1543 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1544 IS_OSPF6_DEBUG_ROUTE (MEMORY))
1545 {
1546 zlog_info ("%p: mark as removing: area %s brouter %s",
David Lampartereed3c482015-03-03 08:51:53 +01001547 (void *)brouter, oa->name, brouter_name);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001548 ospf6_brouter_debug_print (brouter);
1549 }
hasso508e53e2004-05-18 18:57:06 +00001550 }
1551
Paul Jakmacb4b8842006-05-15 10:39:30 +00001552 for (brouter = ospf6_route_head (oa->spf_table); brouter;
1553 brouter = ospf6_route_next (brouter))
hasso508e53e2004-05-18 18:57:06 +00001554 {
Paul Jakmacf1ce252006-05-15 10:46:07 +00001555 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1556 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1557
Paul Jakmacb4b8842006-05-15 10:39:30 +00001558 if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
hasso508e53e2004-05-18 18:57:06 +00001559 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001560 if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
hasso508e53e2004-05-18 18:57:06 +00001561 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001562 if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
1563 ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
hasso508e53e2004-05-18 18:57:06 +00001564 continue;
1565
Dinesh Dutt01879112013-08-25 03:03:31 +00001566 if (! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_V6) ||
1567 ! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_R))
1568 continue;
1569
Paul Jakmacb4b8842006-05-15 10:39:30 +00001570 copy = ospf6_route_copy (brouter);
hasso508e53e2004-05-18 18:57:06 +00001571 copy->type = OSPF6_DEST_TYPE_ROUTER;
hassoccb59b12004-08-25 09:10:37 +00001572 copy->path.area_id = oa->area_id;
hasso6452df02004-08-15 05:52:07 +00001573 ospf6_route_add (copy, oa->ospf6->brouter_table);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001574
1575 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1576 IS_OSPF6_DEBUG_ROUTE (MEMORY))
1577 {
1578 zlog_info ("%p: transfer: area %s brouter %s",
David Lampartereed3c482015-03-03 08:51:53 +01001579 (void *)brouter, oa->name, brouter_name);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001580 ospf6_brouter_debug_print (brouter);
1581 }
hasso508e53e2004-05-18 18:57:06 +00001582 }
1583
hasso6452df02004-08-15 05:52:07 +00001584 oa->ospf6->brouter_table->hook_add = hook_add;
1585 oa->ospf6->brouter_table->hook_remove = hook_remove;
hasso508e53e2004-05-18 18:57:06 +00001586
Paul Jakmacb4b8842006-05-15 10:39:30 +00001587 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1588 brouter = ospf6_route_next (brouter))
hasso508e53e2004-05-18 18:57:06 +00001589 {
Paul Jakmacb4b8842006-05-15 10:39:30 +00001590 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1591 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1592
1593 if (brouter->path.area_id != oa->area_id)
hasso508e53e2004-05-18 18:57:06 +00001594 continue;
1595
Paul Jakmacb4b8842006-05-15 10:39:30 +00001596 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
hasso9428f2d2004-09-13 14:01:12 +00001597 continue;
1598
Paul Jakmacb4b8842006-05-15 10:39:30 +00001599 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
1600 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
hasso508e53e2004-05-18 18:57:06 +00001601 {
Paul Jakmacb4b8842006-05-15 10:39:30 +00001602 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
1603 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
hasso508e53e2004-05-18 18:57:06 +00001604 }
1605
Paul Jakmacb4b8842006-05-15 10:39:30 +00001606 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
hasso508e53e2004-05-18 18:57:06 +00001607 {
Paul Jakmacb4b8842006-05-15 10:39:30 +00001608 if (IS_OSPF6_DEBUG_BROUTER ||
1609 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1610 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1611 zlog_info ("brouter %s disappears via area %s",
1612 brouter_name, oa->name);
1613 ospf6_route_remove (brouter, oa->ospf6->brouter_table);
1614 }
1615 else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
1616 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
1617 {
1618 if (IS_OSPF6_DEBUG_BROUTER ||
1619 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1620 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1621 zlog_info ("brouter %s appears via area %s",
1622 brouter_name, oa->name);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001623
Paul Jakmacb4b8842006-05-15 10:39:30 +00001624 /* newly added */
hasso508e53e2004-05-18 18:57:06 +00001625 if (hook_add)
Paul Jakmacb4b8842006-05-15 10:39:30 +00001626 (*hook_add) (brouter);
1627 }
1628 else
1629 {
1630 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1631 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1632 zlog_info ("brouter %s still exists via area %s",
1633 brouter_name, oa->name);
hasso508e53e2004-05-18 18:57:06 +00001634 }
1635
Paul Jakmacb4b8842006-05-15 10:39:30 +00001636 brouter->flag = 0;
hasso508e53e2004-05-18 18:57:06 +00001637 }
1638
Paul Jakmacb4b8842006-05-15 10:39:30 +00001639 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1640 zlog_info ("border-router calculation for area %s: done", oa->name);
paul718e3742002-12-13 20:15:29 +00001641}
1642
hasso6452df02004-08-15 05:52:07 +00001643struct ospf6_lsa_handler router_handler =
1644{
1645 OSPF6_LSTYPE_ROUTER,
1646 "Router",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001647 "Rtr",
1648 ospf6_router_lsa_show,
1649 ospf6_router_lsa_get_nbr_id
hasso6452df02004-08-15 05:52:07 +00001650};
1651
1652struct ospf6_lsa_handler network_handler =
1653{
1654 OSPF6_LSTYPE_NETWORK,
1655 "Network",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001656 "Net",
1657 ospf6_network_lsa_show,
1658 ospf6_network_lsa_get_ar_id
hasso6452df02004-08-15 05:52:07 +00001659};
1660
1661struct ospf6_lsa_handler link_handler =
1662{
1663 OSPF6_LSTYPE_LINK,
1664 "Link",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001665 "Lnk",
1666 ospf6_link_lsa_show,
1667 ospf6_link_lsa_get_prefix_str
hasso6452df02004-08-15 05:52:07 +00001668};
1669
1670struct ospf6_lsa_handler intra_prefix_handler =
1671{
1672 OSPF6_LSTYPE_INTRA_PREFIX,
1673 "Intra-Prefix",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001674 "INP",
1675 ospf6_intra_prefix_lsa_show,
1676 ospf6_intra_prefix_lsa_get_prefix_str
hasso6452df02004-08-15 05:52:07 +00001677};
1678
paul718e3742002-12-13 20:15:29 +00001679void
Paul Jakmacb4b8842006-05-15 10:39:30 +00001680ospf6_intra_init (void)
paul718e3742002-12-13 20:15:29 +00001681{
hasso6452df02004-08-15 05:52:07 +00001682 ospf6_install_lsa_handler (&router_handler);
1683 ospf6_install_lsa_handler (&network_handler);
1684 ospf6_install_lsa_handler (&link_handler);
1685 ospf6_install_lsa_handler (&intra_prefix_handler);
paul718e3742002-12-13 20:15:29 +00001686}
1687
Paul Jakmacb4b8842006-05-15 10:39:30 +00001688DEFUN (debug_ospf6_brouter,
1689 debug_ospf6_brouter_cmd,
1690 "debug ospf6 border-routers",
1691 DEBUG_STR
1692 OSPF6_STR
1693 "Debug border router\n"
1694 )
1695{
1696 OSPF6_DEBUG_BROUTER_ON ();
1697 return CMD_SUCCESS;
1698}
1699
1700DEFUN (no_debug_ospf6_brouter,
1701 no_debug_ospf6_brouter_cmd,
1702 "no debug ospf6 border-routers",
1703 NO_STR
1704 DEBUG_STR
1705 OSPF6_STR
1706 "Debug border router\n"
1707 )
1708{
1709 OSPF6_DEBUG_BROUTER_OFF ();
1710 return CMD_SUCCESS;
1711}
1712
1713DEFUN (debug_ospf6_brouter_router,
1714 debug_ospf6_brouter_router_cmd,
1715 "debug ospf6 border-routers router-id A.B.C.D",
1716 DEBUG_STR
1717 OSPF6_STR
1718 "Debug border router\n"
1719 "Debug specific border router\n"
1720 "Specify border-router's router-id\n"
1721 )
1722{
1723 u_int32_t router_id;
1724 inet_pton (AF_INET, argv[0], &router_id);
1725 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
1726 return CMD_SUCCESS;
1727}
1728
1729DEFUN (no_debug_ospf6_brouter_router,
1730 no_debug_ospf6_brouter_router_cmd,
1731 "no debug ospf6 border-routers router-id",
1732 NO_STR
1733 DEBUG_STR
1734 OSPF6_STR
1735 "Debug border router\n"
1736 "Debug specific border router\n"
1737 )
1738{
1739 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1740 return CMD_SUCCESS;
1741}
1742
1743DEFUN (debug_ospf6_brouter_area,
1744 debug_ospf6_brouter_area_cmd,
1745 "debug ospf6 border-routers area-id A.B.C.D",
1746 DEBUG_STR
1747 OSPF6_STR
1748 "Debug border router\n"
1749 "Debug border routers in specific Area\n"
1750 "Specify Area-ID\n"
1751 )
1752{
1753 u_int32_t area_id;
1754 inet_pton (AF_INET, argv[0], &area_id);
1755 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
1756 return CMD_SUCCESS;
1757}
1758
1759DEFUN (no_debug_ospf6_brouter_area,
1760 no_debug_ospf6_brouter_area_cmd,
1761 "no debug ospf6 border-routers area-id",
1762 NO_STR
1763 DEBUG_STR
1764 OSPF6_STR
1765 "Debug border router\n"
1766 "Debug border routers in specific Area\n"
1767 )
1768{
1769 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1770 return CMD_SUCCESS;
1771}
1772
1773int
1774config_write_ospf6_debug_brouter (struct vty *vty)
1775{
1776 char buf[16];
1777 if (IS_OSPF6_DEBUG_BROUTER)
1778 vty_out (vty, "debug ospf6 border-routers%s", VNL);
1779 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
1780 {
1781 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
1782 buf, sizeof (buf));
1783 vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
1784 }
1785 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
1786 {
1787 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
1788 buf, sizeof (buf));
1789 vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
1790 }
1791 return 0;
1792}
1793
1794void
1795install_element_ospf6_debug_brouter (void)
1796{
1797 install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
1798 install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
1799 install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
1800 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
1801 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
1802 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
1803 install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
1804 install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
1805 install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
1806 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
1807 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
1808 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
1809}
1810
paul718e3742002-12-13 20:15:29 +00001811