blob: 591dab3269b130c20b7ca3f48c1909a083e7a63b [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)
David Lamparter3cf40532015-04-19 14:54:03 +0200237 && ((size_t)((char *)lsdesc - buffer)
238 + sizeof (struct ospf6_router_lsdesc)
239 > 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
hasso508e53e2004-05-18 18:57:06 +0000249 link_state_id ++;
paul718e3742002-12-13 20:15:29 +0000250 }
251
hasso508e53e2004-05-18 18:57:06 +0000252 /* Point-to-Point interfaces */
Dinesh Duttc5926a92013-08-24 07:55:00 +0000253 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
hasso508e53e2004-05-18 18:57:06 +0000254 {
paul1eb8ef22005-04-07 07:30:20 +0000255 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
hasso508e53e2004-05-18 18:57:06 +0000256 {
hasso508e53e2004-05-18 18:57:06 +0000257 if (on->state != OSPF6_NEIGHBOR_FULL)
258 continue;
paul718e3742002-12-13 20:15:29 +0000259
hasso508e53e2004-05-18 18:57:06 +0000260 lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
261 lsdesc->metric = htons (oi->cost);
262 lsdesc->interface_id = htonl (oi->interface->ifindex);
263 lsdesc->neighbor_interface_id = htonl (on->ifindex);
264 lsdesc->neighbor_router_id = on->router_id;
265
266 lsdesc++;
267 }
268 }
269
270 /* Broadcast and NBMA interfaces */
Dinesh Duttc5926a92013-08-24 07:55:00 +0000271 else if (oi->type == OSPF_IFTYPE_BROADCAST)
hasso508e53e2004-05-18 18:57:06 +0000272 {
273 /* If this router is not DR,
274 and If this router not fully adjacent with DR,
275 this interface is not transit yet: ignore. */
276 if (oi->state != OSPF6_INTERFACE_DR)
277 {
278 drouter = ospf6_neighbor_lookup (oi->drouter, oi);
279 if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
280 continue;
281 }
282
283 lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
284 lsdesc->metric = htons (oi->cost);
285 lsdesc->interface_id = htonl (oi->interface->ifindex);
286 if (oi->state != OSPF6_INTERFACE_DR)
287 {
288 lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
289 lsdesc->neighbor_router_id = drouter->router_id;
290 }
291 else
292 {
293 lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
294 lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
295 }
296
297 lsdesc++;
298 }
Dinesh Duttc5926a92013-08-24 07:55:00 +0000299 else
300 {
301 assert (0); /* Unknown interface type */
302 }
hasso508e53e2004-05-18 18:57:06 +0000303
304 /* Virtual links */
305 /* xxx */
306 /* Point-to-Multipoint interfaces */
307 /* xxx */
paul718e3742002-12-13 20:15:29 +0000308 }
hasso508e53e2004-05-18 18:57:06 +0000309
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000310 /* Fill LSA Header */
311 lsa_header->age = 0;
312 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
313 lsa_header->id = htonl (link_state_id);
314 lsa_header->adv_router = oa->ospf6->router_id;
315 lsa_header->seqnum =
316 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
Donald Sharpcb9ed1d2016-01-14 09:19:29 -0500317 lsa_header->adv_router, oa->lsdb);
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000318 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
hasso508e53e2004-05-18 18:57:06 +0000319
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000320 /* LSA checksum */
321 ospf6_lsa_checksum (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000322
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000323 /* create LSA */
324 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000325
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000326 /* Originate */
327 ospf6_lsa_originate_area (lsa, oa);
hasso508e53e2004-05-18 18:57:06 +0000328
Dinesh Dutt17d003d2013-08-24 07:55:43 +0000329 link_state_id ++;
hasso508e53e2004-05-18 18:57:06 +0000330
331 /* Do premature-aging of rest, undesired Router-LSAs */
332 type = ntohs (OSPF6_LSTYPE_ROUTER);
333 router = oa->ospf6->router_id;
334 for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
335 lsa = ospf6_lsdb_type_router_next (type, router, lsa))
336 {
337 if (ntohl (lsa->header->id) < link_state_id)
338 continue;
hasso6452df02004-08-15 05:52:07 +0000339 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000340 }
hasso508e53e2004-05-18 18:57:06 +0000341
342 return 0;
343}
344
hasso508e53e2004-05-18 18:57:06 +0000345/*******************************/
346/* RFC2740 3.4.3.2 Network-LSA */
347/*******************************/
348
Dinesh Dutte68a6762013-08-25 03:03:23 +0000349static char *
350ospf6_network_lsa_get_ar_id (struct ospf6_lsa *lsa, char *buf, int buflen,
351 int pos)
352{
353 char *start, *end, *current;
354 struct ospf6_network_lsa *network_lsa;
355 struct ospf6_network_lsdesc *lsdesc;
356
357 if (lsa)
358 {
359 network_lsa = (struct ospf6_network_lsa *)
360 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
361
362 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
363 end = (char *) lsa->header + ntohs (lsa->header->length);
364 current = start + pos*(sizeof (struct ospf6_network_lsdesc));
365
366 if ((current + sizeof(struct ospf6_network_lsdesc)) <= end)
367 {
368 lsdesc = (struct ospf6_network_lsdesc *)current;
369 if (buf)
370 inet_ntop (AF_INET, &lsdesc->router_id, buf, buflen);
371 }
372 else
373 return NULL;
374 }
375
376 return (buf);
377}
378
Paul Jakma6ac29a52008-08-15 13:45:30 +0100379static int
hasso508e53e2004-05-18 18:57:06 +0000380ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
381{
382 char *start, *end, *current;
383 struct ospf6_network_lsa *network_lsa;
384 struct ospf6_network_lsdesc *lsdesc;
385 char buf[128], options[32];
386
387 network_lsa = (struct ospf6_network_lsa *)
388 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
389
390 ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
hasso049207c2004-08-04 20:02:13 +0000391 vty_out (vty, " Options: %s%s", options, VNL);
hasso508e53e2004-05-18 18:57:06 +0000392
393 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
394 end = (char *) lsa->header + ntohs (lsa->header->length);
395 for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
396 current += sizeof (struct ospf6_network_lsdesc))
397 {
398 lsdesc = (struct ospf6_network_lsdesc *) current;
399 inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +0000400 vty_out (vty, " Attached Router: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +0000401 }
402 return 0;
paul718e3742002-12-13 20:15:29 +0000403}
404
hasso6452df02004-08-15 05:52:07 +0000405int
406ospf6_network_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000407{
hasso6452df02004-08-15 05:52:07 +0000408 struct ospf6_interface *oi;
409
hasso508e53e2004-05-18 18:57:06 +0000410 char buffer [OSPF6_MAX_LSASIZE];
411 struct ospf6_lsa_header *lsa_header;
paul718e3742002-12-13 20:15:29 +0000412
hasso508e53e2004-05-18 18:57:06 +0000413 int count;
414 struct ospf6_lsa *old, *lsa;
415 struct ospf6_network_lsa *network_lsa;
416 struct ospf6_network_lsdesc *lsdesc;
417 struct ospf6_neighbor *on;
418 struct ospf6_link_lsa *link_lsa;
hasso52dc7ee2004-09-23 19:18:23 +0000419 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000420 u_int16_t type;
421
hasso6452df02004-08-15 05:52:07 +0000422 oi = (struct ospf6_interface *) THREAD_ARG (thread);
423 oi->thread_network_lsa = NULL;
424
425 /* The interface must be enabled until here. A Network-LSA of a
426 disabled interface (but was once enabled) should be flushed
427 by ospf6_lsa_refresh (), and does not come here. */
428 assert (oi->area);
paul718e3742002-12-13 20:15:29 +0000429
hasso508e53e2004-05-18 18:57:06 +0000430 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
431 htonl (oi->interface->ifindex),
432 oi->area->ospf6->router_id, oi->area->lsdb);
paul718e3742002-12-13 20:15:29 +0000433
hasso508e53e2004-05-18 18:57:06 +0000434 /* Do not originate Network-LSA if not DR */
435 if (oi->state != OSPF6_INTERFACE_DR)
paul718e3742002-12-13 20:15:29 +0000436 {
hasso508e53e2004-05-18 18:57:06 +0000437 if (old)
hasso6452df02004-08-15 05:52:07 +0000438 ospf6_lsa_purge (old);
439 return 0;
paul718e3742002-12-13 20:15:29 +0000440 }
hasso508e53e2004-05-18 18:57:06 +0000441
hasso1e058382004-09-01 21:36:14 +0000442 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
hassoc6487d62004-12-24 06:00:11 +0000443 zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000444
445 /* If none of neighbor is adjacent to us */
446 count = 0;
paul1eb8ef22005-04-07 07:30:20 +0000447
448 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
449 if (on->state == OSPF6_NEIGHBOR_FULL)
450 count++;
451
hasso508e53e2004-05-18 18:57:06 +0000452 if (count == 0)
453 {
hasso1e058382004-09-01 21:36:14 +0000454 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
hassoc6487d62004-12-24 06:00:11 +0000455 zlog_debug ("Interface stub, ignore");
hasso508e53e2004-05-18 18:57:06 +0000456 if (old)
hasso6452df02004-08-15 05:52:07 +0000457 ospf6_lsa_purge (old);
458 return 0;
hasso508e53e2004-05-18 18:57:06 +0000459 }
460
461 /* prepare buffer */
462 memset (buffer, 0, sizeof (buffer));
463 lsa_header = (struct ospf6_lsa_header *) buffer;
464 network_lsa = (struct ospf6_network_lsa *)
465 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
466
467 /* Collect the interface's Link-LSAs to describe
468 network's optional capabilities */
469 type = htons (OSPF6_LSTYPE_LINK);
470 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
471 lsa = ospf6_lsdb_type_next (type, lsa))
472 {
473 link_lsa = (struct ospf6_link_lsa *)
474 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
475 network_lsa->options[0] |= link_lsa->options[0];
476 network_lsa->options[1] |= link_lsa->options[1];
477 network_lsa->options[2] |= link_lsa->options[2];
478 }
479
480 lsdesc = (struct ospf6_network_lsdesc *)
481 ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
482
483 /* set Link Description to the router itself */
484 lsdesc->router_id = oi->area->ospf6->router_id;
485 lsdesc++;
486
487 /* Walk through the neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000488 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
hasso508e53e2004-05-18 18:57:06 +0000489 {
hasso508e53e2004-05-18 18:57:06 +0000490 if (on->state != OSPF6_NEIGHBOR_FULL)
491 continue;
492
493 /* set this neighbor's Router-ID to LSA */
494 lsdesc->router_id = on->router_id;
495 lsdesc++;
496 }
497
498 /* Fill LSA Header */
499 lsa_header->age = 0;
500 lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
501 lsa_header->id = htonl (oi->interface->ifindex);
502 lsa_header->adv_router = oi->area->ospf6->router_id;
503 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000504 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
505 lsa_header->adv_router, oi->area->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000506 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
507
508 /* LSA checksum */
509 ospf6_lsa_checksum (lsa_header);
510
511 /* create LSA */
512 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000513
514 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000515 ospf6_lsa_originate_area (lsa, oi->area);
hasso508e53e2004-05-18 18:57:06 +0000516
517 return 0;
518}
519
520
521/****************************/
522/* RFC2740 3.4.3.6 Link-LSA */
523/****************************/
524
Dinesh Dutte68a6762013-08-25 03:03:23 +0000525static char *
526ospf6_link_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, int buflen,
527 int pos)
528{
529 char *start, *end, *current;
530 struct ospf6_link_lsa *link_lsa;
531 struct in6_addr in6;
532 struct ospf6_prefix *prefix;
533 int cnt = 0, prefixnum;
534
535 if (lsa)
536 {
537 link_lsa = (struct ospf6_link_lsa *)
538 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
539
540 if (pos == 0) {
541 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, buflen);
542 return (buf);
543 }
544
545 prefixnum = ntohl (link_lsa->prefix_num);
546 if (pos > prefixnum)
547 return (NULL);
548
549 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
550 end = (char *) lsa->header + ntohs (lsa->header->length);
551 current = start;
552
553 do
554 {
555 prefix = (struct ospf6_prefix *) current;
556 if (prefix->prefix_length == 0 ||
557 current + OSPF6_PREFIX_SIZE (prefix) > end)
558 {
559 return (NULL);
560 }
561
562 if (cnt < pos)
563 {
564 current = start + pos*OSPF6_PREFIX_SIZE(prefix);
565 cnt++;
566 }
567 else
568 {
569 memset (&in6, 0, sizeof (in6));
570 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
571 OSPF6_PREFIX_SPACE (prefix->prefix_length));
572 inet_ntop (AF_INET6, &in6, buf, buflen);
573 return (buf);
574 }
575 } while (current <= end);
576 }
577 return (NULL);
578}
579
Paul Jakma6ac29a52008-08-15 13:45:30 +0100580static int
hasso508e53e2004-05-18 18:57:06 +0000581ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
582{
paul718e3742002-12-13 20:15:29 +0000583 char *start, *end, *current;
hasso508e53e2004-05-18 18:57:06 +0000584 struct ospf6_link_lsa *link_lsa;
585 int prefixnum;
586 char buf[128], options[32];
587 struct ospf6_prefix *prefix;
paul0c083ee2004-10-10 12:54:58 +0000588 const char *p, *mc, *la, *nu;
hasso508e53e2004-05-18 18:57:06 +0000589 struct in6_addr in6;
paul718e3742002-12-13 20:15:29 +0000590
hasso508e53e2004-05-18 18:57:06 +0000591 link_lsa = (struct ospf6_link_lsa *)
592 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +0000593
hasso508e53e2004-05-18 18:57:06 +0000594 ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
595 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
596 prefixnum = ntohl (link_lsa->prefix_num);
paul718e3742002-12-13 20:15:29 +0000597
hasso508e53e2004-05-18 18:57:06 +0000598 vty_out (vty, " Priority: %d Options: %s%s",
hasso049207c2004-08-04 20:02:13 +0000599 link_lsa->priority, options, VNL);
600 vty_out (vty, " LinkLocal Address: %s%s", buf, VNL);
601 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
paul718e3742002-12-13 20:15:29 +0000602
hasso508e53e2004-05-18 18:57:06 +0000603 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
604 end = (char *) lsa->header + ntohs (lsa->header->length);
paul718e3742002-12-13 20:15:29 +0000605 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
606 {
607 prefix = (struct ospf6_prefix *) current;
hasso508e53e2004-05-18 18:57:06 +0000608 if (prefix->prefix_length == 0 ||
609 current + OSPF6_PREFIX_SIZE (prefix) > end)
610 break;
paul718e3742002-12-13 20:15:29 +0000611
hasso508e53e2004-05-18 18:57:06 +0000612 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
613 "P" : "--");
614 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
615 "MC" : "--");
616 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
617 "LA" : "--");
618 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
619 "NU" : "--");
620 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
hasso049207c2004-08-04 20:02:13 +0000621 p, mc, la, nu, VNL);
paul718e3742002-12-13 20:15:29 +0000622
hasso508e53e2004-05-18 18:57:06 +0000623 memset (&in6, 0, sizeof (in6));
624 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
625 OSPF6_PREFIX_SPACE (prefix->prefix_length));
paul718e3742002-12-13 20:15:29 +0000626 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
627 vty_out (vty, " Prefix: %s/%d%s",
hasso049207c2004-08-04 20:02:13 +0000628 buf, prefix->prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +0000629 }
630
631 return 0;
632}
633
hasso6452df02004-08-15 05:52:07 +0000634int
635ospf6_link_lsa_originate (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000636{
hasso6452df02004-08-15 05:52:07 +0000637 struct ospf6_interface *oi;
638
hasso508e53e2004-05-18 18:57:06 +0000639 char buffer[OSPF6_MAX_LSASIZE];
640 struct ospf6_lsa_header *lsa_header;
641 struct ospf6_lsa *old, *lsa;
paul718e3742002-12-13 20:15:29 +0000642
hasso508e53e2004-05-18 18:57:06 +0000643 struct ospf6_link_lsa *link_lsa;
644 struct ospf6_route *route;
645 struct ospf6_prefix *op;
paul718e3742002-12-13 20:15:29 +0000646
hasso6452df02004-08-15 05:52:07 +0000647 oi = (struct ospf6_interface *) THREAD_ARG (thread);
648 oi->thread_link_lsa = NULL;
649
650 assert (oi->area);
paul718e3742002-12-13 20:15:29 +0000651
652 /* find previous LSA */
hasso508e53e2004-05-18 18:57:06 +0000653 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
654 htonl (oi->interface->ifindex),
655 oi->area->ospf6->router_id, oi->lsdb);
paul718e3742002-12-13 20:15:29 +0000656
hasso508e53e2004-05-18 18:57:06 +0000657 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
paul718e3742002-12-13 20:15:29 +0000658 {
659 if (old)
hasso6452df02004-08-15 05:52:07 +0000660 ospf6_lsa_purge (old);
661 return 0;
paul718e3742002-12-13 20:15:29 +0000662 }
663
hasso1e058382004-09-01 21:36:14 +0000664 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
hassoc6487d62004-12-24 06:00:11 +0000665 zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
paul718e3742002-12-13 20:15:29 +0000666
hasso508e53e2004-05-18 18:57:06 +0000667 /* can't make Link-LSA if linklocal address not set */
668 if (oi->linklocal_addr == NULL)
paul718e3742002-12-13 20:15:29 +0000669 {
hasso1e058382004-09-01 21:36:14 +0000670 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
hassoc6487d62004-12-24 06:00:11 +0000671 zlog_debug ("No Linklocal address on %s, defer originating",
hasso508e53e2004-05-18 18:57:06 +0000672 oi->interface->name);
673 if (old)
hasso6452df02004-08-15 05:52:07 +0000674 ospf6_lsa_purge (old);
675 return 0;
hasso508e53e2004-05-18 18:57:06 +0000676 }
677
678 /* prepare buffer */
679 memset (buffer, 0, sizeof (buffer));
680 lsa_header = (struct ospf6_lsa_header *) buffer;
681 link_lsa = (struct ospf6_link_lsa *)
682 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
683
684 /* Fill Link-LSA */
685 link_lsa->priority = oi->priority;
686 memcpy (link_lsa->options, oi->area->options, 3);
687 memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
688 sizeof (struct in6_addr));
689 link_lsa->prefix_num = htonl (oi->route_connected->count);
690
691 op = (struct ospf6_prefix *)
692 ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
693
694 /* connected prefix to advertise */
695 for (route = ospf6_route_head (oi->route_connected); route;
696 route = ospf6_route_next (route))
697 {
698 op->prefix_length = route->prefix.prefixlen;
699 op->prefix_options = route->path.prefix_options;
700 op->prefix_metric = htons (0);
701 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
702 OSPF6_PREFIX_SPACE (op->prefix_length));
703 op = OSPF6_PREFIX_NEXT (op);
704 }
705
706 /* Fill LSA Header */
707 lsa_header->age = 0;
708 lsa_header->type = htons (OSPF6_LSTYPE_LINK);
709 lsa_header->id = htonl (oi->interface->ifindex);
710 lsa_header->adv_router = oi->area->ospf6->router_id;
711 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000712 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
713 lsa_header->adv_router, oi->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000714 lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
715
716 /* LSA checksum */
717 ospf6_lsa_checksum (lsa_header);
718
719 /* create LSA */
720 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000721
722 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000723 ospf6_lsa_originate_interface (lsa, oi);
hasso508e53e2004-05-18 18:57:06 +0000724
725 return 0;
726}
727
728
729/*****************************************/
730/* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
731/*****************************************/
Dinesh Dutte68a6762013-08-25 03:03:23 +0000732static char *
733ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
734 int buflen, int pos)
735{
736 char *start, *end, *current;
737 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
738 struct in6_addr in6;
739 int prefixnum, cnt = 0;
740 struct ospf6_prefix *prefix;
741
742 if (lsa)
743 {
744 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
745 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
746
747 prefixnum = ntohs (intra_prefix_lsa->prefix_num);
748 if (pos > prefixnum)
749 return (NULL);
750
751 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
752 end = (char *) lsa->header + ntohs (lsa->header->length);
753 current = start;
754
755 do
756 {
757 prefix = (struct ospf6_prefix *) current;
758 if (prefix->prefix_length == 0 ||
759 current + OSPF6_PREFIX_SIZE (prefix) > end)
760 {
761 return NULL;
762 }
763
764 if (cnt < pos)
765 {
766 current = start + pos*OSPF6_PREFIX_SIZE(prefix);
767 cnt++;
768 }
769 else
770 {
771 memset (&in6, 0, sizeof (in6));
772 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
773 OSPF6_PREFIX_SPACE (prefix->prefix_length));
774 inet_ntop (AF_INET6, &in6, buf, buflen);
775 sprintf(&buf[strlen(buf)], "/%d", prefix->prefix_length);
776 return (buf);
777 }
778 } while (current <= end);
779 }
780 return (buf);
781}
hasso508e53e2004-05-18 18:57:06 +0000782
Paul Jakma6ac29a52008-08-15 13:45:30 +0100783static int
hasso508e53e2004-05-18 18:57:06 +0000784ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
785{
786 char *start, *end, *current;
787 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
788 int prefixnum;
789 char buf[128];
790 struct ospf6_prefix *prefix;
791 char id[16], adv_router[16];
paul0c083ee2004-10-10 12:54:58 +0000792 const char *p, *mc, *la, *nu;
hasso508e53e2004-05-18 18:57:06 +0000793 struct in6_addr in6;
794
795 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
796 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
797
798 prefixnum = ntohs (intra_prefix_lsa->prefix_num);
799
hasso049207c2004-08-04 20:02:13 +0000800 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
hasso508e53e2004-05-18 18:57:06 +0000801
802 inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
803 inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
804 adv_router, sizeof (adv_router));
805 vty_out (vty, " Reference: %s Id: %s Adv: %s%s",
hasso1e058382004-09-01 21:36:14 +0000806 ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
hasso049207c2004-08-04 20:02:13 +0000807 VNL);
hasso508e53e2004-05-18 18:57:06 +0000808
809 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
810 end = (char *) lsa->header + ntohs (lsa->header->length);
811 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
812 {
813 prefix = (struct ospf6_prefix *) current;
814 if (prefix->prefix_length == 0 ||
815 current + OSPF6_PREFIX_SIZE (prefix) > end)
816 break;
817
818 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
819 "P" : "--");
820 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
821 "MC" : "--");
822 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
823 "LA" : "--");
824 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
825 "NU" : "--");
826 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
hasso049207c2004-08-04 20:02:13 +0000827 p, mc, la, nu, VNL);
hasso508e53e2004-05-18 18:57:06 +0000828
829 memset (&in6, 0, sizeof (in6));
830 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
831 OSPF6_PREFIX_SPACE (prefix->prefix_length));
832 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
833 vty_out (vty, " Prefix: %s/%d%s",
hasso049207c2004-08-04 20:02:13 +0000834 buf, prefix->prefix_length, VNL);
hasso508e53e2004-05-18 18:57:06 +0000835 }
836
837 return 0;
838}
839
hasso6452df02004-08-15 05:52:07 +0000840int
841ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
hasso508e53e2004-05-18 18:57:06 +0000842{
hasso6452df02004-08-15 05:52:07 +0000843 struct ospf6_area *oa;
844
hasso508e53e2004-05-18 18:57:06 +0000845 char buffer[OSPF6_MAX_LSASIZE];
846 struct ospf6_lsa_header *lsa_header;
847 struct ospf6_lsa *old, *lsa;
848
849 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
850 struct ospf6_interface *oi;
851 struct ospf6_neighbor *on;
852 struct ospf6_route *route;
853 struct ospf6_prefix *op;
hasso52dc7ee2004-09-23 19:18:23 +0000854 struct listnode *i, *j;
hasso508e53e2004-05-18 18:57:06 +0000855 int full_count = 0;
856 unsigned short prefix_num = 0;
857 char buf[BUFSIZ];
858 struct ospf6_route_table *route_advertise;
859
hasso6452df02004-08-15 05:52:07 +0000860 oa = (struct ospf6_area *) THREAD_ARG (thread);
861 oa->thread_intra_prefix_lsa = NULL;
862
hasso508e53e2004-05-18 18:57:06 +0000863 /* find previous LSA */
864 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
865 htonl (0), oa->ospf6->router_id, oa->lsdb);
866
hasso6452df02004-08-15 05:52:07 +0000867 if (! IS_AREA_ENABLED (oa))
hasso508e53e2004-05-18 18:57:06 +0000868 {
869 if (old)
hasso6452df02004-08-15 05:52:07 +0000870 ospf6_lsa_purge (old);
871 return 0;
hasso508e53e2004-05-18 18:57:06 +0000872 }
873
hasso1e058382004-09-01 21:36:14 +0000874 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000875 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
hasso508e53e2004-05-18 18:57:06 +0000876 oa->name);
877
878 /* prepare buffer */
879 memset (buffer, 0, sizeof (buffer));
880 lsa_header = (struct ospf6_lsa_header *) buffer;
881 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
882 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
883
884 /* Fill Intra-Area-Prefix-LSA */
885 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
886 intra_prefix_lsa->ref_id = htonl (0);
887 intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
888
Paul Jakmacf1ce252006-05-15 10:46:07 +0000889 route_advertise = ospf6_route_table_create (0, 0);
hasso508e53e2004-05-18 18:57:06 +0000890
paul1eb8ef22005-04-07 07:30:20 +0000891 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
hasso508e53e2004-05-18 18:57:06 +0000892 {
hasso508e53e2004-05-18 18:57:06 +0000893 if (oi->state == OSPF6_INTERFACE_DOWN)
894 {
hasso1e058382004-09-01 21:36:14 +0000895 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000896 zlog_debug (" Interface %s is down, ignore", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000897 continue;
898 }
899
900 full_count = 0;
paul1eb8ef22005-04-07 07:30:20 +0000901
902 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
903 if (on->state == OSPF6_NEIGHBOR_FULL)
904 full_count++;
905
hasso508e53e2004-05-18 18:57:06 +0000906 if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
907 oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
908 full_count != 0)
909 {
hasso1e058382004-09-01 21:36:14 +0000910 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000911 zlog_debug (" Interface %s is not stub, ignore",
hasso508e53e2004-05-18 18:57:06 +0000912 oi->interface->name);
913 continue;
914 }
915
hasso1e058382004-09-01 21:36:14 +0000916 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000917 zlog_debug (" Interface %s:", oi->interface->name);
hasso508e53e2004-05-18 18:57:06 +0000918
919 /* connected prefix to advertise */
920 for (route = ospf6_route_head (oi->route_connected); route;
921 route = ospf6_route_best_next (route))
922 {
hasso1e058382004-09-01 21:36:14 +0000923 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +0000924 {
925 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000926 zlog_debug (" include %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000927 }
928 ospf6_route_add (ospf6_route_copy (route), route_advertise);
929 }
930 }
931
932 if (route_advertise->count == 0)
933 {
934 if (old)
hasso6452df02004-08-15 05:52:07 +0000935 ospf6_lsa_purge (old);
hasso508e53e2004-05-18 18:57:06 +0000936 ospf6_route_table_delete (route_advertise);
hasso6452df02004-08-15 05:52:07 +0000937 return 0;
hasso508e53e2004-05-18 18:57:06 +0000938 }
939
940 /* put prefixes to advertise */
941 prefix_num = 0;
942 op = (struct ospf6_prefix *)
943 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
944 for (route = ospf6_route_head (route_advertise); route;
945 route = ospf6_route_best_next (route))
946 {
947 op->prefix_length = route->prefix.prefixlen;
948 op->prefix_options = route->path.prefix_options;
949 op->prefix_metric = htons (route->path.cost);
950 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
951 OSPF6_PREFIX_SPACE (op->prefix_length));
952 op = OSPF6_PREFIX_NEXT (op);
953 prefix_num++;
954 }
955
956 ospf6_route_table_delete (route_advertise);
957
958 if (prefix_num == 0)
959 {
hasso1e058382004-09-01 21:36:14 +0000960 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +0000961 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
hasso6452df02004-08-15 05:52:07 +0000962 return 0;
hasso508e53e2004-05-18 18:57:06 +0000963 }
964
965 intra_prefix_lsa->prefix_num = htons (prefix_num);
966
967 /* Fill LSA Header */
968 lsa_header->age = 0;
969 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
970 lsa_header->id = htonl (0);
971 lsa_header->adv_router = oa->ospf6->router_id;
972 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000973 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
974 lsa_header->adv_router, oa->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000975 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
976
977 /* LSA checksum */
978 ospf6_lsa_checksum (lsa_header);
979
980 /* create LSA */
981 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000982
983 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000984 ospf6_lsa_originate_area (lsa, oa);
985
986 return 0;
hasso508e53e2004-05-18 18:57:06 +0000987}
988
hasso6452df02004-08-15 05:52:07 +0000989
990int
991ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
hasso508e53e2004-05-18 18:57:06 +0000992{
hasso6452df02004-08-15 05:52:07 +0000993 struct ospf6_interface *oi;
994
hasso508e53e2004-05-18 18:57:06 +0000995 char buffer[OSPF6_MAX_LSASIZE];
996 struct ospf6_lsa_header *lsa_header;
997 struct ospf6_lsa *old, *lsa;
998
999 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1000 struct ospf6_neighbor *on;
1001 struct ospf6_route *route;
1002 struct ospf6_prefix *op;
hasso52dc7ee2004-09-23 19:18:23 +00001003 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +00001004 int full_count = 0;
1005 unsigned short prefix_num = 0;
1006 struct ospf6_route_table *route_advertise;
1007 struct ospf6_link_lsa *link_lsa;
1008 char *start, *end, *current;
1009 u_int16_t type;
1010 char buf[BUFSIZ];
1011
hasso6452df02004-08-15 05:52:07 +00001012 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1013 oi->thread_intra_prefix_lsa = NULL;
1014
1015 assert (oi->area);
hasso508e53e2004-05-18 18:57:06 +00001016
1017 /* find previous LSA */
1018 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
1019 htonl (oi->interface->ifindex),
1020 oi->area->ospf6->router_id, oi->area->lsdb);
1021
1022 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
1023 {
1024 if (old)
hasso6452df02004-08-15 05:52:07 +00001025 ospf6_lsa_purge (old);
1026 return 0;
hasso508e53e2004-05-18 18:57:06 +00001027 }
1028
hasso1e058382004-09-01 21:36:14 +00001029 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001030 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
hasso508e53e2004-05-18 18:57:06 +00001031 oi->interface->name);
1032
1033 /* prepare buffer */
1034 memset (buffer, 0, sizeof (buffer));
1035 lsa_header = (struct ospf6_lsa_header *) buffer;
1036 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1037 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
1038
1039 /* Fill Intra-Area-Prefix-LSA */
1040 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
1041 intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
1042 intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
1043
1044 if (oi->state != OSPF6_INTERFACE_DR)
1045 {
hasso1e058382004-09-01 21:36:14 +00001046 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001047 zlog_debug (" Interface is not DR");
hasso508e53e2004-05-18 18:57:06 +00001048 if (old)
hasso6452df02004-08-15 05:52:07 +00001049 ospf6_lsa_purge (old);
1050 return 0;
hasso508e53e2004-05-18 18:57:06 +00001051 }
1052
1053 full_count = 0;
paul1eb8ef22005-04-07 07:30:20 +00001054 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
1055 if (on->state == OSPF6_NEIGHBOR_FULL)
1056 full_count++;
1057
hasso508e53e2004-05-18 18:57:06 +00001058 if (full_count == 0)
1059 {
hasso1e058382004-09-01 21:36:14 +00001060 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001061 zlog_debug (" Interface is stub");
hasso508e53e2004-05-18 18:57:06 +00001062 if (old)
hasso6452df02004-08-15 05:52:07 +00001063 ospf6_lsa_purge (old);
1064 return 0;
hasso508e53e2004-05-18 18:57:06 +00001065 }
1066
1067 /* connected prefix to advertise */
Paul Jakmacf1ce252006-05-15 10:46:07 +00001068 route_advertise = ospf6_route_table_create (0, 0);
hasso508e53e2004-05-18 18:57:06 +00001069
1070 type = ntohs (OSPF6_LSTYPE_LINK);
1071 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
1072 lsa = ospf6_lsdb_type_next (type, lsa))
1073 {
1074 if (OSPF6_LSA_IS_MAXAGE (lsa))
paul718e3742002-12-13 20:15:29 +00001075 continue;
1076
hasso1e058382004-09-01 21:36:14 +00001077 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001078 zlog_debug (" include prefix from %s", lsa->name);
paul718e3742002-12-13 20:15:29 +00001079
hasso508e53e2004-05-18 18:57:06 +00001080 if (lsa->header->adv_router != oi->area->ospf6->router_id)
paul718e3742002-12-13 20:15:29 +00001081 {
hasso508e53e2004-05-18 18:57:06 +00001082 on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
1083 if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
paul718e3742002-12-13 20:15:29 +00001084 {
hasso1e058382004-09-01 21:36:14 +00001085 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001086 zlog_debug (" Neighbor not found or not Full, ignore");
paul718e3742002-12-13 20:15:29 +00001087 continue;
1088 }
1089 }
1090
hasso508e53e2004-05-18 18:57:06 +00001091 link_lsa = (struct ospf6_link_lsa *)
1092 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
paul718e3742002-12-13 20:15:29 +00001093
hasso508e53e2004-05-18 18:57:06 +00001094 prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
1095 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
1096 end = (char *) lsa->header + ntohs (lsa->header->length);
1097 for (current = start; current < end && prefix_num;
1098 current += OSPF6_PREFIX_SIZE (op))
paul718e3742002-12-13 20:15:29 +00001099 {
hasso508e53e2004-05-18 18:57:06 +00001100 op = (struct ospf6_prefix *) current;
1101 if (op->prefix_length == 0 ||
1102 current + OSPF6_PREFIX_SIZE (op) > end)
1103 break;
paul718e3742002-12-13 20:15:29 +00001104
hasso508e53e2004-05-18 18:57:06 +00001105 route = ospf6_route_create ();
1106
1107 route->type = OSPF6_DEST_TYPE_NETWORK;
1108 route->prefix.family = AF_INET6;
1109 route->prefix.prefixlen = op->prefix_length;
1110 memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
1111 memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
1112 OSPF6_PREFIX_SPACE (op->prefix_length));
1113
1114 route->path.origin.type = lsa->header->type;
1115 route->path.origin.id = lsa->header->id;
1116 route->path.origin.adv_router = lsa->header->adv_router;
1117 route->path.options[0] = link_lsa->options[0];
1118 route->path.options[1] = link_lsa->options[1];
1119 route->path.options[2] = link_lsa->options[2];
1120 route->path.prefix_options = op->prefix_options;
1121 route->path.area_id = oi->area->area_id;
1122 route->path.type = OSPF6_PATH_TYPE_INTRA;
1123
hasso1e058382004-09-01 21:36:14 +00001124 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
paul718e3742002-12-13 20:15:29 +00001125 {
hasso508e53e2004-05-18 18:57:06 +00001126 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001127 zlog_debug (" include %s", buf);
paul718e3742002-12-13 20:15:29 +00001128 }
1129
hasso508e53e2004-05-18 18:57:06 +00001130 ospf6_route_add (route, route_advertise);
1131 prefix_num--;
paul718e3742002-12-13 20:15:29 +00001132 }
hasso1e058382004-09-01 21:36:14 +00001133 if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001134 zlog_debug ("Trailing garbage in %s", lsa->name);
paul718e3742002-12-13 20:15:29 +00001135 }
1136
hasso508e53e2004-05-18 18:57:06 +00001137 op = (struct ospf6_prefix *)
1138 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
1139
1140 prefix_num = 0;
1141 for (route = ospf6_route_head (route_advertise); route;
1142 route = ospf6_route_best_next (route))
paul718e3742002-12-13 20:15:29 +00001143 {
hasso508e53e2004-05-18 18:57:06 +00001144 op->prefix_length = route->prefix.prefixlen;
1145 op->prefix_options = route->path.prefix_options;
1146 op->prefix_metric = htons (0);
1147 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
1148 OSPF6_PREFIX_SPACE (op->prefix_length));
1149 op = OSPF6_PREFIX_NEXT (op);
1150 prefix_num++;
1151 }
1152
1153 ospf6_route_table_delete (route_advertise);
1154
1155 if (prefix_num == 0)
1156 {
hasso1e058382004-09-01 21:36:14 +00001157 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001158 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
hasso6452df02004-08-15 05:52:07 +00001159 return 0;
paul718e3742002-12-13 20:15:29 +00001160 }
1161
hasso508e53e2004-05-18 18:57:06 +00001162 intra_prefix_lsa->prefix_num = htons (prefix_num);
paul718e3742002-12-13 20:15:29 +00001163
hasso508e53e2004-05-18 18:57:06 +00001164 /* Fill LSA Header */
1165 lsa_header->age = 0;
1166 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1167 lsa_header->id = htonl (oi->interface->ifindex);
1168 lsa_header->adv_router = oi->area->ospf6->router_id;
1169 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +00001170 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
1171 lsa_header->adv_router, oi->area->lsdb);
hasso508e53e2004-05-18 18:57:06 +00001172 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
paul718e3742002-12-13 20:15:29 +00001173
hasso508e53e2004-05-18 18:57:06 +00001174 /* LSA checksum */
1175 ospf6_lsa_checksum (lsa_header);
paul718e3742002-12-13 20:15:29 +00001176
hasso508e53e2004-05-18 18:57:06 +00001177 /* create LSA */
1178 lsa = ospf6_lsa_create (lsa_header);
paul718e3742002-12-13 20:15:29 +00001179
hasso508e53e2004-05-18 18:57:06 +00001180 /* Originate */
hasso6452df02004-08-15 05:52:07 +00001181 ospf6_lsa_originate_area (lsa, oi->area);
paul718e3742002-12-13 20:15:29 +00001182
1183 return 0;
1184}
1185
1186void
hasso508e53e2004-05-18 18:57:06 +00001187ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001188{
hasso508e53e2004-05-18 18:57:06 +00001189 struct ospf6_area *oa;
1190 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1191 struct prefix ls_prefix;
1192 struct ospf6_route *route, *ls_entry;
1193 int i, prefix_num;
1194 struct ospf6_prefix *op;
1195 char *start, *current, *end;
1196 char buf[64];
Dinesh Duttb81e97a2013-08-24 07:55:50 +00001197 struct interface *ifp;
1198 int direct_connect = 0;
paul718e3742002-12-13 20:15:29 +00001199
hassoccb59b12004-08-25 09:10:37 +00001200 if (OSPF6_LSA_IS_MAXAGE (lsa))
1201 return;
1202
hasso1e058382004-09-01 21:36:14 +00001203 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001204 zlog_debug ("%s found", lsa->name);
paul718e3742002-12-13 20:15:29 +00001205
hasso6452df02004-08-15 05:52:07 +00001206 oa = OSPF6_AREA (lsa->lsdb->data);
1207
hasso508e53e2004-05-18 18:57:06 +00001208 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1209 OSPF6_LSA_HEADER_END (lsa->header);
1210 if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
1211 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1212 htonl (0), &ls_prefix);
1213 else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
1214 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1215 intra_prefix_lsa->ref_id, &ls_prefix);
1216 else
1217 {
hasso1e058382004-09-01 21:36:14 +00001218 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001219 zlog_debug ("Unknown reference LS-type: %#hx",
1220 ntohs (intra_prefix_lsa->ref_type));
hasso508e53e2004-05-18 18:57:06 +00001221 return;
1222 }
paul718e3742002-12-13 20:15:29 +00001223
hasso508e53e2004-05-18 18:57:06 +00001224 ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
1225 if (ls_entry == NULL)
1226 {
hasso1e058382004-09-01 21:36:14 +00001227 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001228 {
1229 ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001230 zlog_debug ("LS entry does not exist: %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001231 }
1232 return;
1233 }
paul718e3742002-12-13 20:15:29 +00001234
Dinesh Duttb81e97a2013-08-24 07:55:50 +00001235 if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id)
1236 {
1237 /* the intra-prefix are directly connected */
1238 direct_connect = 1;
1239 }
1240
hasso508e53e2004-05-18 18:57:06 +00001241 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1242 start = (caddr_t) intra_prefix_lsa +
1243 sizeof (struct ospf6_intra_prefix_lsa);
1244 end = OSPF6_LSA_END (lsa->header);
1245 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1246 {
1247 op = (struct ospf6_prefix *) current;
1248 if (prefix_num == 0)
1249 break;
1250 if (end < current + OSPF6_PREFIX_SIZE (op))
1251 break;
1252
Dinesh Dutte68a6762013-08-25 03:03:23 +00001253 /* Appendix A.4.1.1 */
Vipin Kumarf1b96112015-05-19 18:03:51 -07001254 if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU))
Dinesh Dutte68a6762013-08-25 03:03:23 +00001255 {
1256 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1257 {
1258 ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op),
1259 buf, sizeof (buf));
Vipin Kumarf1b96112015-05-19 18:03:51 -07001260 zlog_debug ("%s: Skipping Prefix %s has NU option set",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001261 __func__, buf);
1262 }
1263 continue;
1264 }
1265
hasso508e53e2004-05-18 18:57:06 +00001266 route = ospf6_route_create ();
hassoccb59b12004-08-25 09:10:37 +00001267
1268 memset (&route->prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001269 route->prefix.family = AF_INET6;
hassoccb59b12004-08-25 09:10:37 +00001270 route->prefix.prefixlen = op->prefix_length;
1271 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
1272
hasso508e53e2004-05-18 18:57:06 +00001273 route->type = OSPF6_DEST_TYPE_NETWORK;
1274 route->path.origin.type = lsa->header->type;
1275 route->path.origin.id = lsa->header->id;
1276 route->path.origin.adv_router = lsa->header->adv_router;
1277 route->path.prefix_options = op->prefix_options;
1278 route->path.area_id = oa->area_id;
1279 route->path.type = OSPF6_PATH_TYPE_INTRA;
1280 route->path.metric_type = 1;
1281 route->path.cost = ls_entry->path.cost +
1282 ntohs (op->prefix_metric);
1283
Dinesh Duttb81e97a2013-08-24 07:55:50 +00001284 if (direct_connect)
1285 {
1286 ifp = if_lookup_prefix(&route->prefix);
1287 if (ifp)
1288 route->nexthop[0].ifindex = ifp->ifindex;
1289 }
1290 else
1291 {
Christian Franke7fca43f2016-06-14 20:07:03 +02001292 for (i = 0; i < OSPF6_MULTI_PATH_LIMIT &&
1293 ospf6_nexthop_is_set (&ls_entry->nexthop[i]); i++)
Dinesh Duttb81e97a2013-08-24 07:55:50 +00001294 ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
1295 }
hasso508e53e2004-05-18 18:57:06 +00001296
hasso1e058382004-09-01 21:36:14 +00001297 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001298 {
1299 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001300 zlog_debug (" add %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001301 }
1302
1303 ospf6_route_add (route, oa->route_table);
1304 prefix_num--;
1305 }
1306
hasso1e058382004-09-01 21:36:14 +00001307 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001308 zlog_debug ("Trailing garbage ignored");
paul718e3742002-12-13 20:15:29 +00001309}
1310
1311void
hasso508e53e2004-05-18 18:57:06 +00001312ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001313{
hasso508e53e2004-05-18 18:57:06 +00001314 struct ospf6_area *oa;
1315 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1316 struct prefix prefix;
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001317 struct ospf6_route *route, *nroute;
hasso508e53e2004-05-18 18:57:06 +00001318 int prefix_num;
1319 struct ospf6_prefix *op;
1320 char *start, *current, *end;
1321 char buf[64];
1322
hasso1e058382004-09-01 21:36:14 +00001323 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001324 zlog_debug ("%s disappearing", lsa->name);
hasso508e53e2004-05-18 18:57:06 +00001325
hasso6452df02004-08-15 05:52:07 +00001326 oa = OSPF6_AREA (lsa->lsdb->data);
1327
hasso508e53e2004-05-18 18:57:06 +00001328 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1329 OSPF6_LSA_HEADER_END (lsa->header);
1330
1331 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1332 start = (caddr_t) intra_prefix_lsa +
1333 sizeof (struct ospf6_intra_prefix_lsa);
1334 end = OSPF6_LSA_END (lsa->header);
1335 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1336 {
1337 op = (struct ospf6_prefix *) current;
1338 if (prefix_num == 0)
1339 break;
1340 if (end < current + OSPF6_PREFIX_SIZE (op))
1341 break;
1342 prefix_num--;
1343
hassoccb59b12004-08-25 09:10:37 +00001344 memset (&prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001345 prefix.family = AF_INET6;
1346 prefix.prefixlen = op->prefix_length;
1347 ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
1348
1349 route = ospf6_route_lookup (&prefix, oa->route_table);
1350 if (route == NULL)
1351 continue;
1352
1353 for (ospf6_route_lock (route);
1354 route && ospf6_route_is_prefix (&prefix, route);
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001355 route = nroute)
hasso508e53e2004-05-18 18:57:06 +00001356 {
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001357 nroute = ospf6_route_next (route);
hasso508e53e2004-05-18 18:57:06 +00001358 if (route->type != OSPF6_DEST_TYPE_NETWORK)
1359 continue;
1360 if (route->path.area_id != oa->area_id)
1361 continue;
1362 if (route->path.type != OSPF6_PATH_TYPE_INTRA)
1363 continue;
1364 if (route->path.origin.type != lsa->header->type ||
1365 route->path.origin.id != lsa->header->id ||
1366 route->path.origin.adv_router != lsa->header->adv_router)
1367 continue;
1368
hasso1e058382004-09-01 21:36:14 +00001369 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hasso508e53e2004-05-18 18:57:06 +00001370 {
1371 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +00001372 zlog_debug ("remove %s", buf);
hasso508e53e2004-05-18 18:57:06 +00001373 }
1374 ospf6_route_remove (route, oa->route_table);
1375 }
Tom Goffe7a6d802010-11-10 13:03:02 -08001376 if (route)
1377 ospf6_route_unlock (route);
hasso508e53e2004-05-18 18:57:06 +00001378 }
1379
hasso1e058382004-09-01 21:36:14 +00001380 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001381 zlog_debug ("Trailing garbage ignored");
paul718e3742002-12-13 20:15:29 +00001382}
1383
1384void
hasso508e53e2004-05-18 18:57:06 +00001385ospf6_intra_route_calculation (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +00001386{
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001387 struct ospf6_route *route, *nroute;
hasso508e53e2004-05-18 18:57:06 +00001388 u_int16_t type;
1389 struct ospf6_lsa *lsa;
1390 void (*hook_add) (struct ospf6_route *) = NULL;
1391 void (*hook_remove) (struct ospf6_route *) = NULL;
1392
hasso1e058382004-09-01 21:36:14 +00001393 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001394 zlog_debug ("Re-examin intra-routes for area %s", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001395
1396 hook_add = oa->route_table->hook_add;
1397 hook_remove = oa->route_table->hook_remove;
1398 oa->route_table->hook_add = NULL;
1399 oa->route_table->hook_remove = NULL;
1400
1401 for (route = ospf6_route_head (oa->route_table); route;
1402 route = ospf6_route_next (route))
1403 route->flag = OSPF6_ROUTE_REMOVE;
1404
1405 type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1406 for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
1407 lsa = ospf6_lsdb_type_next (type, lsa))
1408 ospf6_intra_prefix_lsa_add (lsa);
1409
1410 oa->route_table->hook_add = hook_add;
1411 oa->route_table->hook_remove = hook_remove;
1412
1413 for (route = ospf6_route_head (oa->route_table); route;
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001414 route = nroute)
hasso508e53e2004-05-18 18:57:06 +00001415 {
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001416 nroute = ospf6_route_next (route);
hasso508e53e2004-05-18 18:57:06 +00001417 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
1418 CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
1419 {
1420 UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
1421 UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
1422 }
1423
1424 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
1425 ospf6_route_remove (route, oa->route_table);
1426 else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
1427 CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
1428 {
1429 if (hook_add)
1430 (*hook_add) (route);
1431 }
1432
1433 route->flag = 0;
1434 }
1435
hasso1e058382004-09-01 21:36:14 +00001436 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
hassoc6487d62004-12-24 06:00:11 +00001437 zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
hasso508e53e2004-05-18 18:57:06 +00001438}
1439
Paul Jakma6ac29a52008-08-15 13:45:30 +01001440static void
Paul Jakmacf1ce252006-05-15 10:46:07 +00001441ospf6_brouter_debug_print (struct ospf6_route *brouter)
1442{
1443 u_int32_t brouter_id;
1444 char brouter_name[16];
1445 char area_name[16];
1446 char destination[64];
1447 char installed[16], changed[16];
1448 struct timeval now, res;
1449 char id[16], adv_router[16];
1450 char capa[16], options[16];
1451
1452 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1453 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1454 inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
1455 ospf6_linkstate_prefix2str (&brouter->prefix, destination,
1456 sizeof (destination));
1457
Takashi Sogabe86f72dc2009-06-22 13:07:02 +09001458 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001459 timersub (&now, &brouter->installed, &res);
1460 timerstring (&res, installed, sizeof (installed));
1461
Takashi Sogabe86f72dc2009-06-22 13:07:02 +09001462 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001463 timersub (&now, &brouter->changed, &res);
1464 timerstring (&res, changed, sizeof (changed));
1465
1466 inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
1467 inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
1468 sizeof (adv_router));
1469
1470 ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
1471 ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
1472
1473 zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
1474 zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
David Lampartereed3c482015-03-03 08:51:53 +01001475 (void *)brouter->prev, (void *)brouter, (void *)brouter->next,
1476 (void *)brouter->rnode);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001477 zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1478 brouter->type, destination, installed, changed);
1479 zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock,
1480 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
1481 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
1482 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
1483 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
1484 zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1485 OSPF6_PATH_TYPE_NAME (brouter->path.type),
1486 ospf6_lstype_name (brouter->path.origin.type),
1487 id, adv_router);
1488 zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1489 options, capa, brouter->path.metric_type,
1490 brouter->path.cost, brouter->path.cost_e2);
1491}
1492
1493void
hasso6452df02004-08-15 05:52:07 +00001494ospf6_intra_brouter_calculation (struct ospf6_area *oa)
hasso508e53e2004-05-18 18:57:06 +00001495{
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001496 struct ospf6_route *brouter, *nbrouter, *copy;
hasso508e53e2004-05-18 18:57:06 +00001497 void (*hook_add) (struct ospf6_route *) = NULL;
1498 void (*hook_remove) (struct ospf6_route *) = NULL;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001499 u_int32_t brouter_id;
1500 char brouter_name[16];
1501
1502 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1503 zlog_info ("border-router calculation for area %s", oa->name);
1504
hasso6452df02004-08-15 05:52:07 +00001505 hook_add = oa->ospf6->brouter_table->hook_add;
1506 hook_remove = oa->ospf6->brouter_table->hook_remove;
1507 oa->ospf6->brouter_table->hook_add = NULL;
1508 oa->ospf6->brouter_table->hook_remove = NULL;
hasso508e53e2004-05-18 18:57:06 +00001509
hasso6452df02004-08-15 05:52:07 +00001510 /* withdraw the previous router entries for the area */
Paul Jakmacb4b8842006-05-15 10:39:30 +00001511 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1512 brouter = ospf6_route_next (brouter))
hasso508e53e2004-05-18 18:57:06 +00001513 {
Paul Jakmacf1ce252006-05-15 10:46:07 +00001514 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1515 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
Paul Jakmacb4b8842006-05-15 10:39:30 +00001516 if (brouter->path.area_id != oa->area_id)
hasso508e53e2004-05-18 18:57:06 +00001517 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001518 brouter->flag = OSPF6_ROUTE_REMOVE;
Paul Jakmacf1ce252006-05-15 10:46:07 +00001519
1520 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1521 IS_OSPF6_DEBUG_ROUTE (MEMORY))
1522 {
1523 zlog_info ("%p: mark as removing: area %s brouter %s",
David Lampartereed3c482015-03-03 08:51:53 +01001524 (void *)brouter, oa->name, brouter_name);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001525 ospf6_brouter_debug_print (brouter);
1526 }
hasso508e53e2004-05-18 18:57:06 +00001527 }
1528
Paul Jakmacb4b8842006-05-15 10:39:30 +00001529 for (brouter = ospf6_route_head (oa->spf_table); brouter;
1530 brouter = ospf6_route_next (brouter))
hasso508e53e2004-05-18 18:57:06 +00001531 {
Paul Jakmacf1ce252006-05-15 10:46:07 +00001532 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1533 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1534
Paul Jakmacb4b8842006-05-15 10:39:30 +00001535 if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
hasso508e53e2004-05-18 18:57:06 +00001536 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001537 if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
hasso508e53e2004-05-18 18:57:06 +00001538 continue;
Paul Jakmacb4b8842006-05-15 10:39:30 +00001539 if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
1540 ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
hasso508e53e2004-05-18 18:57:06 +00001541 continue;
1542
Dinesh Dutt01879112013-08-25 03:03:31 +00001543 if (! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_V6) ||
1544 ! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_R))
1545 continue;
1546
Paul Jakmacb4b8842006-05-15 10:39:30 +00001547 copy = ospf6_route_copy (brouter);
hasso508e53e2004-05-18 18:57:06 +00001548 copy->type = OSPF6_DEST_TYPE_ROUTER;
hassoccb59b12004-08-25 09:10:37 +00001549 copy->path.area_id = oa->area_id;
hasso6452df02004-08-15 05:52:07 +00001550 ospf6_route_add (copy, oa->ospf6->brouter_table);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001551
1552 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1553 IS_OSPF6_DEBUG_ROUTE (MEMORY))
1554 {
1555 zlog_info ("%p: transfer: area %s brouter %s",
David Lampartereed3c482015-03-03 08:51:53 +01001556 (void *)brouter, oa->name, brouter_name);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001557 ospf6_brouter_debug_print (brouter);
1558 }
hasso508e53e2004-05-18 18:57:06 +00001559 }
1560
hasso6452df02004-08-15 05:52:07 +00001561 oa->ospf6->brouter_table->hook_add = hook_add;
1562 oa->ospf6->brouter_table->hook_remove = hook_remove;
hasso508e53e2004-05-18 18:57:06 +00001563
Paul Jakmacb4b8842006-05-15 10:39:30 +00001564 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001565 brouter = nbrouter)
hasso508e53e2004-05-18 18:57:06 +00001566 {
Vipin Kumar8c075ef2015-05-19 18:03:53 -07001567 nbrouter = ospf6_route_next (brouter);
Paul Jakmacb4b8842006-05-15 10:39:30 +00001568 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1569 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1570
1571 if (brouter->path.area_id != oa->area_id)
hasso508e53e2004-05-18 18:57:06 +00001572 continue;
1573
Paul Jakmacb4b8842006-05-15 10:39:30 +00001574 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
hasso9428f2d2004-09-13 14:01:12 +00001575 continue;
1576
Paul Jakmacb4b8842006-05-15 10:39:30 +00001577 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
1578 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
hasso508e53e2004-05-18 18:57:06 +00001579 {
Paul Jakmacb4b8842006-05-15 10:39:30 +00001580 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
1581 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
hasso508e53e2004-05-18 18:57:06 +00001582 }
1583
Paul Jakmacb4b8842006-05-15 10:39:30 +00001584 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
hasso508e53e2004-05-18 18:57:06 +00001585 {
Paul Jakmacb4b8842006-05-15 10:39:30 +00001586 if (IS_OSPF6_DEBUG_BROUTER ||
1587 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1588 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1589 zlog_info ("brouter %s disappears via area %s",
1590 brouter_name, oa->name);
1591 ospf6_route_remove (brouter, oa->ospf6->brouter_table);
1592 }
1593 else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
1594 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
1595 {
1596 if (IS_OSPF6_DEBUG_BROUTER ||
1597 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1598 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1599 zlog_info ("brouter %s appears via area %s",
1600 brouter_name, oa->name);
Paul Jakmacf1ce252006-05-15 10:46:07 +00001601
Paul Jakmacb4b8842006-05-15 10:39:30 +00001602 /* newly added */
hasso508e53e2004-05-18 18:57:06 +00001603 if (hook_add)
Paul Jakmacb4b8842006-05-15 10:39:30 +00001604 (*hook_add) (brouter);
1605 }
1606 else
1607 {
1608 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1609 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1610 zlog_info ("brouter %s still exists via area %s",
1611 brouter_name, oa->name);
hasso508e53e2004-05-18 18:57:06 +00001612 }
1613
Paul Jakmacb4b8842006-05-15 10:39:30 +00001614 brouter->flag = 0;
hasso508e53e2004-05-18 18:57:06 +00001615 }
1616
Paul Jakmacb4b8842006-05-15 10:39:30 +00001617 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1618 zlog_info ("border-router calculation for area %s: done", oa->name);
paul718e3742002-12-13 20:15:29 +00001619}
1620
hasso6452df02004-08-15 05:52:07 +00001621struct ospf6_lsa_handler router_handler =
1622{
1623 OSPF6_LSTYPE_ROUTER,
1624 "Router",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001625 "Rtr",
1626 ospf6_router_lsa_show,
1627 ospf6_router_lsa_get_nbr_id
hasso6452df02004-08-15 05:52:07 +00001628};
1629
1630struct ospf6_lsa_handler network_handler =
1631{
1632 OSPF6_LSTYPE_NETWORK,
1633 "Network",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001634 "Net",
1635 ospf6_network_lsa_show,
1636 ospf6_network_lsa_get_ar_id
hasso6452df02004-08-15 05:52:07 +00001637};
1638
1639struct ospf6_lsa_handler link_handler =
1640{
1641 OSPF6_LSTYPE_LINK,
1642 "Link",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001643 "Lnk",
1644 ospf6_link_lsa_show,
1645 ospf6_link_lsa_get_prefix_str
hasso6452df02004-08-15 05:52:07 +00001646};
1647
1648struct ospf6_lsa_handler intra_prefix_handler =
1649{
1650 OSPF6_LSTYPE_INTRA_PREFIX,
1651 "Intra-Prefix",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001652 "INP",
1653 ospf6_intra_prefix_lsa_show,
1654 ospf6_intra_prefix_lsa_get_prefix_str
hasso6452df02004-08-15 05:52:07 +00001655};
1656
paul718e3742002-12-13 20:15:29 +00001657void
Paul Jakmacb4b8842006-05-15 10:39:30 +00001658ospf6_intra_init (void)
paul718e3742002-12-13 20:15:29 +00001659{
hasso6452df02004-08-15 05:52:07 +00001660 ospf6_install_lsa_handler (&router_handler);
1661 ospf6_install_lsa_handler (&network_handler);
1662 ospf6_install_lsa_handler (&link_handler);
1663 ospf6_install_lsa_handler (&intra_prefix_handler);
paul718e3742002-12-13 20:15:29 +00001664}
1665
Paul Jakmacb4b8842006-05-15 10:39:30 +00001666DEFUN (debug_ospf6_brouter,
1667 debug_ospf6_brouter_cmd,
1668 "debug ospf6 border-routers",
1669 DEBUG_STR
1670 OSPF6_STR
1671 "Debug border router\n"
1672 )
1673{
1674 OSPF6_DEBUG_BROUTER_ON ();
1675 return CMD_SUCCESS;
1676}
1677
1678DEFUN (no_debug_ospf6_brouter,
1679 no_debug_ospf6_brouter_cmd,
1680 "no debug ospf6 border-routers",
1681 NO_STR
1682 DEBUG_STR
1683 OSPF6_STR
1684 "Debug border router\n"
1685 )
1686{
1687 OSPF6_DEBUG_BROUTER_OFF ();
1688 return CMD_SUCCESS;
1689}
1690
1691DEFUN (debug_ospf6_brouter_router,
1692 debug_ospf6_brouter_router_cmd,
1693 "debug ospf6 border-routers router-id A.B.C.D",
1694 DEBUG_STR
1695 OSPF6_STR
1696 "Debug border router\n"
1697 "Debug specific border router\n"
1698 "Specify border-router's router-id\n"
1699 )
1700{
1701 u_int32_t router_id;
1702 inet_pton (AF_INET, argv[0], &router_id);
1703 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
1704 return CMD_SUCCESS;
1705}
1706
1707DEFUN (no_debug_ospf6_brouter_router,
1708 no_debug_ospf6_brouter_router_cmd,
1709 "no debug ospf6 border-routers router-id",
1710 NO_STR
1711 DEBUG_STR
1712 OSPF6_STR
1713 "Debug border router\n"
1714 "Debug specific border router\n"
1715 )
1716{
1717 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1718 return CMD_SUCCESS;
1719}
1720
1721DEFUN (debug_ospf6_brouter_area,
1722 debug_ospf6_brouter_area_cmd,
1723 "debug ospf6 border-routers area-id A.B.C.D",
1724 DEBUG_STR
1725 OSPF6_STR
1726 "Debug border router\n"
1727 "Debug border routers in specific Area\n"
1728 "Specify Area-ID\n"
1729 )
1730{
1731 u_int32_t area_id;
1732 inet_pton (AF_INET, argv[0], &area_id);
1733 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
1734 return CMD_SUCCESS;
1735}
1736
1737DEFUN (no_debug_ospf6_brouter_area,
1738 no_debug_ospf6_brouter_area_cmd,
1739 "no debug ospf6 border-routers area-id",
1740 NO_STR
1741 DEBUG_STR
1742 OSPF6_STR
1743 "Debug border router\n"
1744 "Debug border routers in specific Area\n"
1745 )
1746{
1747 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1748 return CMD_SUCCESS;
1749}
1750
1751int
1752config_write_ospf6_debug_brouter (struct vty *vty)
1753{
1754 char buf[16];
1755 if (IS_OSPF6_DEBUG_BROUTER)
1756 vty_out (vty, "debug ospf6 border-routers%s", VNL);
1757 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
1758 {
1759 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
1760 buf, sizeof (buf));
1761 vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
1762 }
1763 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
1764 {
1765 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
1766 buf, sizeof (buf));
1767 vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
1768 }
1769 return 0;
1770}
1771
1772void
1773install_element_ospf6_debug_brouter (void)
1774{
1775 install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
1776 install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
1777 install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
1778 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
1779 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
1780 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
1781 install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
1782 install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
1783 install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
1784 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
1785 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
1786 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
1787}
1788
paul718e3742002-12-13 20:15:29 +00001789