blob: 346b0753fc653694a0a0e219ba2e905ad8b5347f [file] [log] [blame]
jardineb5d44e2003-12-23 08:09:43 +00001/*
2 * IS-IS Rout(e)ing protocol - isis_route.c
3 * Copyright (C) 2001,2002 Sampo Saaristo
4 * Tampere University of Technology
5 * Institute of Communications Engineering
6 *
7 * based on ../ospf6d/ospf6_route.[ch]
8 * by Yasuhiro Ohara
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public Licenseas published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <zebra.h>
jardineb5d44e2003-12-23 08:09:43 +000028
29#include "thread.h"
30#include "linklist.h"
31#include "vty.h"
32#include "log.h"
33#include "memory.h"
34#include "prefix.h"
35#include "hash.h"
36#include "if.h"
37#include "table.h"
38
39#include "isis_constants.h"
40#include "isis_common.h"
41#include "dict.h"
42#include "isisd.h"
43#include "isis_misc.h"
44#include "isis_adjacency.h"
45#include "isis_circuit.h"
46#include "isis_tlv.h"
47#include "isis_pdu.h"
48#include "isis_lsp.h"
49#include "isis_spf.h"
50#include "isis_route.h"
51#include "isis_zebra.h"
52
53extern struct isis *isis;
54extern struct thread_master *master;
55
56struct isis_nexthop *
57isis_nexthop_create (struct in_addr *ip, unsigned int ifindex)
jardineb5d44e2003-12-23 08:09:43 +000058{
59 struct listnode *node;
60 struct isis_nexthop *nexthop;
jardineb5d44e2003-12-23 08:09:43 +000061
hassof390d2c2004-09-10 20:48:21 +000062 for (node = listhead (isis->nexthops); node; nextnode (node))
63 {
64 nexthop = getdata (node);
65 if (nexthop->ifindex != ifindex)
66 continue;
67 if (ip && memcmp (&nexthop->ip, ip, sizeof (struct in_addr)) != 0)
68 continue;
69
70 nexthop->lock++;
71 return nexthop;
72 }
73
jardineb5d44e2003-12-23 08:09:43 +000074 nexthop = XMALLOC (MTYPE_ISIS_NEXTHOP, sizeof (struct isis_nexthop));
hassof390d2c2004-09-10 20:48:21 +000075 if (!nexthop)
76 {
77 zlog_err ("ISIS-Rte: isis_nexthop_create: out of memory!");
78 }
79
jardineb5d44e2003-12-23 08:09:43 +000080 memset (nexthop, 0, sizeof (struct isis_nexthop));
81 nexthop->ifindex = ifindex;
82 memcpy (&nexthop->ip, ip, sizeof (struct in_addr));
83 listnode_add (isis->nexthops, nexthop);
84 nexthop->lock++;
85
86 return nexthop;
87}
88
jardineb5d44e2003-12-23 08:09:43 +000089void
90isis_nexthop_delete (struct isis_nexthop *nexthop)
91{
92 nexthop->lock--;
hassof390d2c2004-09-10 20:48:21 +000093 if (nexthop->lock == 0)
94 {
95 listnode_delete (isis->nexthops, nexthop);
96 XFREE (MTYPE_ISIS_NEXTHOP, nexthop);
97 }
98
jardineb5d44e2003-12-23 08:09:43 +000099 return;
100}
101
102int
hassof390d2c2004-09-10 20:48:21 +0000103nexthoplookup (struct list *nexthops, struct in_addr *ip,
104 unsigned int ifindex)
jardineb5d44e2003-12-23 08:09:43 +0000105{
106 struct listnode *node;
107 struct isis_nexthop *nh;
108
hassof390d2c2004-09-10 20:48:21 +0000109 for (node = listhead (nexthops); node; nextnode (node))
110 {
111 nh = getdata (node);
112 if (!(memcmp (ip, &nh->ip, sizeof (struct in_addr))) &&
113 ifindex == nh->ifindex)
114 return 1;
115 }
jardineb5d44e2003-12-23 08:09:43 +0000116
117 return 0;
118}
119
120void
121nexthop_print (struct isis_nexthop *nh)
122{
123 u_char buf[BUFSIZ];
hassof390d2c2004-09-10 20:48:21 +0000124
hassof7c43dc2004-09-26 16:24:14 +0000125 inet_ntop (AF_INET, &nh->ip, (char *) buf, BUFSIZ);
hassof390d2c2004-09-10 20:48:21 +0000126
hasso529d65b2004-12-24 00:14:50 +0000127 zlog_debug (" %s %u", buf, nh->ifindex);
jardineb5d44e2003-12-23 08:09:43 +0000128}
129
130void
131nexthops_print (struct list *nhs)
132{
133 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000134
135 for (node = listhead (nhs); node; nextnode (node))
jardineb5d44e2003-12-23 08:09:43 +0000136 nexthop_print (getdata (node));
137}
138
139#ifdef HAVE_IPV6
140
141struct isis_nexthop6 *
hassof390d2c2004-09-10 20:48:21 +0000142isis_nexthop6_new (struct in6_addr *ip6, unsigned int ifindex)
jardineb5d44e2003-12-23 08:09:43 +0000143{
hassof390d2c2004-09-10 20:48:21 +0000144
jardineb5d44e2003-12-23 08:09:43 +0000145 struct isis_nexthop6 *nexthop6;
hassof390d2c2004-09-10 20:48:21 +0000146
jardineb5d44e2003-12-23 08:09:43 +0000147 nexthop6 = XMALLOC (MTYPE_ISIS_NEXTHOP6, sizeof (struct isis_nexthop6));
hassof390d2c2004-09-10 20:48:21 +0000148 if (!nexthop6)
149 {
150 zlog_err ("ISIS-Rte: isis_nexthop_create6: out of memory!");
151 }
152
jardineb5d44e2003-12-23 08:09:43 +0000153 memset (nexthop6, 0, sizeof (struct isis_nexthop6));
154 nexthop6->ifindex = ifindex;
155 memcpy (&nexthop6->ip6, ip6, sizeof (struct in6_addr));
156 nexthop6->lock++;
157
158 return nexthop6;
159}
160
161struct isis_nexthop6 *
162isis_nexthop6_create (struct in6_addr *ip6, unsigned int ifindex)
jardineb5d44e2003-12-23 08:09:43 +0000163{
164 struct listnode *node;
165 struct isis_nexthop6 *nexthop6;
jardineb5d44e2003-12-23 08:09:43 +0000166
hassof390d2c2004-09-10 20:48:21 +0000167 for (node = listhead (isis->nexthops6); node; nextnode (node))
168 {
169 nexthop6 = getdata (node);
170 if (nexthop6->ifindex != ifindex)
171 continue;
172 if (ip6 && memcmp (&nexthop6->ip6, ip6, sizeof (struct in6_addr)) != 0)
173 continue;
174
175 nexthop6->lock++;
176 return nexthop6;
177 }
178
jardineb5d44e2003-12-23 08:09:43 +0000179 nexthop6 = isis_nexthop6_new (ip6, ifindex);
180
181 return nexthop6;
182}
183
jardineb5d44e2003-12-23 08:09:43 +0000184void
185isis_nexthop6_delete (struct isis_nexthop6 *nexthop6)
186{
187
188 nexthop6->lock--;
hassof390d2c2004-09-10 20:48:21 +0000189 if (nexthop6->lock == 0)
190 {
191 listnode_delete (isis->nexthops6, nexthop6);
192 XFREE (MTYPE_ISIS_NEXTHOP6, nexthop6);
193 }
194
jardineb5d44e2003-12-23 08:09:43 +0000195 return;
196}
197
198int
hassof390d2c2004-09-10 20:48:21 +0000199nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6,
200 unsigned int ifindex)
jardineb5d44e2003-12-23 08:09:43 +0000201{
202 struct listnode *node;
203 struct isis_nexthop6 *nh6;
204
hassof390d2c2004-09-10 20:48:21 +0000205 for (node = listhead (nexthops6); node; nextnode (node))
206 {
207 nh6 = getdata (node);
208 if (!(memcmp (ip6, &nh6->ip6, sizeof (struct in6_addr))) &&
209 ifindex == nh6->ifindex)
210 return 1;
211 }
jardineb5d44e2003-12-23 08:09:43 +0000212
213 return 0;
214}
215
216void
217nexthop6_print (struct isis_nexthop6 *nh6)
218{
219 u_char buf[BUFSIZ];
hassof390d2c2004-09-10 20:48:21 +0000220
hassof7c43dc2004-09-26 16:24:14 +0000221 inet_ntop (AF_INET6, &nh6->ip6, (char *) buf, BUFSIZ);
hassof390d2c2004-09-10 20:48:21 +0000222
hasso529d65b2004-12-24 00:14:50 +0000223 zlog_debug (" %s %u", buf, nh6->ifindex);
jardineb5d44e2003-12-23 08:09:43 +0000224}
225
226void
227nexthops6_print (struct list *nhs6)
228{
229 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000230
231 for (node = listhead (nhs6); node; nextnode (node))
jardineb5d44e2003-12-23 08:09:43 +0000232 nexthop6_print (getdata (node));
233}
234
235
236#endif /* HAVE_IPV6 */
237
238void
239adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj)
240{
241 struct isis_nexthop *nh;
242 struct listnode *node;
243 struct in_addr *ipv4_addr;
244
245 if (adj->ipv4_addrs == NULL)
246 return;
hassof390d2c2004-09-10 20:48:21 +0000247 for (node = listhead (adj->ipv4_addrs); node; nextnode (node))
248 {
249 ipv4_addr = getdata (node);
250 if (!nexthoplookup (nexthops, ipv4_addr,
251 adj->circuit->interface->ifindex))
252 {
253 nh = isis_nexthop_create (ipv4_addr,
254 adj->circuit->interface->ifindex);
255 listnode_add (nexthops, nh);
256 }
jardineb5d44e2003-12-23 08:09:43 +0000257 }
jardineb5d44e2003-12-23 08:09:43 +0000258}
259
260#ifdef HAVE_IPV6
261void
262adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
263{
264 struct listnode *node;
265 struct in6_addr *ipv6_addr;
266 struct isis_nexthop6 *nh6;
hassof390d2c2004-09-10 20:48:21 +0000267
jardineb5d44e2003-12-23 08:09:43 +0000268 if (!adj->ipv6_addrs)
269 return;
270
hassof390d2c2004-09-10 20:48:21 +0000271 for (node = listhead (adj->ipv6_addrs); node; nextnode (node))
272 {
273 ipv6_addr = getdata (node);
274 if (!nexthop6lookup (nexthops6, ipv6_addr,
275 adj->circuit->interface->ifindex))
276 {
277 nh6 = isis_nexthop6_create (ipv6_addr,
278 adj->circuit->interface->ifindex);
279 listnode_add (nexthops6, nh6);
280 }
jardineb5d44e2003-12-23 08:09:43 +0000281 }
jardineb5d44e2003-12-23 08:09:43 +0000282}
283#endif /* HAVE_IPV6 */
284
285struct isis_route_info *
hassof390d2c2004-09-10 20:48:21 +0000286isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
287 struct list *adjacencies)
jardineb5d44e2003-12-23 08:09:43 +0000288{
289 struct isis_route_info *rinfo;
290 struct isis_adjacency *adj;
291 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000292
jardineb5d44e2003-12-23 08:09:43 +0000293 rinfo = XMALLOC (MTYPE_ISIS_ROUTE_INFO, sizeof (struct isis_route_info));
hassof390d2c2004-09-10 20:48:21 +0000294 if (!rinfo)
295 {
296 zlog_err ("ISIS-Rte: isis_route_info_new: out of memory!");
297 return NULL;
298 }
jardineb5d44e2003-12-23 08:09:43 +0000299 memset (rinfo, 0, sizeof (struct isis_route_info));
300
hassof390d2c2004-09-10 20:48:21 +0000301 if (family == AF_INET)
302 {
303 rinfo->nexthops = list_new ();
304 for (node = listhead (adjacencies); node; nextnode (node))
305 {
306 adj = getdata (node);
307 adjinfo2nexthop (rinfo->nexthops, adj);
308 }
jardineb5d44e2003-12-23 08:09:43 +0000309 }
jardineb5d44e2003-12-23 08:09:43 +0000310#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000311 if (family == AF_INET6)
312 {
313 rinfo->nexthops6 = list_new ();
314 for (node = listhead (adjacencies); node; nextnode (node))
315 {
316 adj = getdata (node);
317 adjinfo2nexthop6 (rinfo->nexthops6, adj);
318 }
jardineb5d44e2003-12-23 08:09:43 +0000319 }
hassof390d2c2004-09-10 20:48:21 +0000320
jardineb5d44e2003-12-23 08:09:43 +0000321#endif /* HAVE_IPV6 */
322
323 rinfo->cost = cost;
324 rinfo->depth = depth;
hassof390d2c2004-09-10 20:48:21 +0000325
jardineb5d44e2003-12-23 08:09:43 +0000326 return rinfo;
327}
328
jardineb5d44e2003-12-23 08:09:43 +0000329void
330isis_route_info_delete (struct isis_route_info *route_info)
331{
hassof390d2c2004-09-10 20:48:21 +0000332 if (route_info->nexthops)
333 {
hassof7c43dc2004-09-26 16:24:14 +0000334 route_info->nexthops->del = (void (*)(void *)) isis_nexthop_delete;
hassof390d2c2004-09-10 20:48:21 +0000335 list_delete (route_info->nexthops);
336 }
337
jardineb5d44e2003-12-23 08:09:43 +0000338#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000339 if (route_info->nexthops6)
340 {
hassof7c43dc2004-09-26 16:24:14 +0000341 route_info->nexthops6->del = (void (*)(void *)) isis_nexthop6_delete;
jardineb5d44e2003-12-23 08:09:43 +0000342 list_delete (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000343 }
jardineb5d44e2003-12-23 08:09:43 +0000344#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000345
jardineb5d44e2003-12-23 08:09:43 +0000346 XFREE (MTYPE_ISIS_ROUTE_INFO, route_info);
347}
348
349int
hassof390d2c2004-09-10 20:48:21 +0000350isis_route_info_same_attrib (struct isis_route_info *new,
351 struct isis_route_info *old)
jardineb5d44e2003-12-23 08:09:43 +0000352{
353 if (new->cost != old->cost)
354 return 0;
355 if (new->depth != old->depth)
356 return 0;
hassof390d2c2004-09-10 20:48:21 +0000357
jardineb5d44e2003-12-23 08:09:43 +0000358 return 1;
359}
360
361int
hassof390d2c2004-09-10 20:48:21 +0000362isis_route_info_same (struct isis_route_info *new,
363 struct isis_route_info *old, u_char family)
jardineb5d44e2003-12-23 08:09:43 +0000364{
hassof390d2c2004-09-10 20:48:21 +0000365 struct listnode *node;
jardineb5d44e2003-12-23 08:09:43 +0000366 struct isis_nexthop *nexthop;
367#ifdef HAVE_IPV6
368 struct isis_nexthop6 *nexthop6;
369#endif /* HAVE_IPV6 */
370 if (!isis_route_info_same_attrib (new, old))
371 return 0;
hassof390d2c2004-09-10 20:48:21 +0000372
373 if (family == AF_INET)
374 {
375 for (node = listhead (new->nexthops); node; nextnode (node))
376 {
377 nexthop = (struct isis_nexthop *) getdata (node);
378 if (nexthoplookup (old->nexthops, &nexthop->ip, nexthop->ifindex) ==
379 0)
380 return 0;
381 }
382
383 for (node = listhead (old->nexthops); node; nextnode (node))
384 {
385 nexthop = (struct isis_nexthop *) getdata (node);
386 if (nexthoplookup (new->nexthops, &nexthop->ip, nexthop->ifindex) ==
387 0)
388 return 0;
389 }
jardineb5d44e2003-12-23 08:09:43 +0000390 }
jardineb5d44e2003-12-23 08:09:43 +0000391#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000392 else if (family == AF_INET6)
393 {
394 for (node = listhead (new->nexthops6); node; nextnode (node))
395 {
396 nexthop6 = (struct isis_nexthop6 *) getdata (node);
397 if (nexthop6lookup (old->nexthops6, &nexthop6->ip6,
398 nexthop6->ifindex) == 0)
399 return 0;
400 }
401
402 for (node = listhead (old->nexthops6); node; nextnode (node))
403 {
404 nexthop6 = (struct isis_nexthop6 *) getdata (node);
405 if (nexthop6lookup (new->nexthops6, &nexthop6->ip6,
406 nexthop6->ifindex) == 0)
407 return 0;
408 }
jardineb5d44e2003-12-23 08:09:43 +0000409 }
jardineb5d44e2003-12-23 08:09:43 +0000410#endif /* HAVE_IPV6 */
411
412 return 1;
413}
414
jardineb5d44e2003-12-23 08:09:43 +0000415void
416isis_nexthops_merge (struct list *new, struct list *old)
417{
418 struct listnode *node;
419 struct isis_nexthop *nexthop;
420
hassof390d2c2004-09-10 20:48:21 +0000421 for (node = listhead (new); node; nextnode (node))
422 {
423 nexthop = (struct isis_nexthop *) getdata (node);
424 if (nexthoplookup (old, &nexthop->ip, nexthop->ifindex))
425 continue;
426 listnode_add (old, nexthop);
427 nexthop->lock++;
428 }
jardineb5d44e2003-12-23 08:09:43 +0000429}
430
jardineb5d44e2003-12-23 08:09:43 +0000431#ifdef HAVE_IPV6
432void
433isis_nexthops6_merge (struct list *new, struct list *old)
434{
435 struct listnode *node;
436 struct isis_nexthop6 *nexthop6;
437
hassof390d2c2004-09-10 20:48:21 +0000438 for (node = listhead (new); node; nextnode (node))
439 {
440 nexthop6 = (struct isis_nexthop6 *) getdata (node);
441 if (nexthop6lookup (old, &nexthop6->ip6, nexthop6->ifindex))
442 continue;
443 listnode_add (old, nexthop6);
444 nexthop6->lock++;
445 }
jardineb5d44e2003-12-23 08:09:43 +0000446}
447#endif /* HAVE_IPV6 */
448
449void
hassof390d2c2004-09-10 20:48:21 +0000450isis_route_info_merge (struct isis_route_info *new,
451 struct isis_route_info *old, u_char family)
jardineb5d44e2003-12-23 08:09:43 +0000452{
hassof390d2c2004-09-10 20:48:21 +0000453 if (family == AF_INET)
jardineb5d44e2003-12-23 08:09:43 +0000454 isis_nexthops_merge (new->nexthops, old->nexthops);
455#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000456 else if (family == AF_INET6)
jardineb5d44e2003-12-23 08:09:43 +0000457 isis_nexthops6_merge (new->nexthops6, old->nexthops6);
458#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000459
jardineb5d44e2003-12-23 08:09:43 +0000460 return;
461}
462
jardineb5d44e2003-12-23 08:09:43 +0000463int
hassof390d2c2004-09-10 20:48:21 +0000464isis_route_info_prefer_new (struct isis_route_info *new,
465 struct isis_route_info *old)
jardineb5d44e2003-12-23 08:09:43 +0000466{
jardineb5d44e2003-12-23 08:09:43 +0000467 if (!CHECK_FLAG (old->flag, ISIS_ROUTE_FLAG_ACTIVE))
468 return 1;
469
470 if (new->cost < old->cost)
471 return 1;
hassof390d2c2004-09-10 20:48:21 +0000472
jardineb5d44e2003-12-23 08:09:43 +0000473 return 0;
474}
475
jardineb5d44e2003-12-23 08:09:43 +0000476struct isis_route_info *
477isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth,
hassof390d2c2004-09-10 20:48:21 +0000478 struct list *adjacencies, struct isis_area *area)
jardineb5d44e2003-12-23 08:09:43 +0000479{
480 struct route_node *route_node;
481 struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL;
482 u_char buff[BUFSIZ];
483 u_char family;
hassof390d2c2004-09-10 20:48:21 +0000484
jardineb5d44e2003-12-23 08:09:43 +0000485 family = prefix->family;
486 /* for debugs */
hassof7c43dc2004-09-26 16:24:14 +0000487 prefix2str (prefix, (char *) buff, BUFSIZ);
hassof390d2c2004-09-10 20:48:21 +0000488
jardineb5d44e2003-12-23 08:09:43 +0000489 rinfo_new = isis_route_info_new (cost, depth, family, adjacencies);
hassof390d2c2004-09-10 20:48:21 +0000490 if (!rinfo_new)
491 {
492 zlog_err ("ISIS-Rte (%s): isis_route_create: out of memory!",
493 area->area_tag);
494 return NULL;
495 }
496
jardineb5d44e2003-12-23 08:09:43 +0000497 if (family == AF_INET)
hassof390d2c2004-09-10 20:48:21 +0000498 route_node = route_node_get (area->route_table, prefix);
jardineb5d44e2003-12-23 08:09:43 +0000499#ifdef HAVE_IPV6
500 else if (family == AF_INET6)
hassof390d2c2004-09-10 20:48:21 +0000501 route_node = route_node_get (area->route_table6, prefix);
jardineb5d44e2003-12-23 08:09:43 +0000502#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000503 else
jardineb5d44e2003-12-23 08:09:43 +0000504 return NULL;
hassof390d2c2004-09-10 20:48:21 +0000505 rinfo_old = route_node->info;
506 if (!rinfo_old)
507 {
508 if (isis->debugs & DEBUG_RTE_EVENTS)
hasso529d65b2004-12-24 00:14:50 +0000509 zlog_debug ("ISIS-Rte (%s) route created: %s", area->area_tag, buff);
hassof390d2c2004-09-10 20:48:21 +0000510 SET_FLAG (rinfo_new->flag, ISIS_ROUTE_FLAG_ACTIVE);
511 route_node->info = rinfo_new;
512 return rinfo_new;
513 }
514
jardineb5d44e2003-12-23 08:09:43 +0000515 if (isis->debugs & DEBUG_RTE_EVENTS)
hasso529d65b2004-12-24 00:14:50 +0000516 zlog_debug ("ISIS-Rte (%s) route already exists: %s", area->area_tag,
hassof390d2c2004-09-10 20:48:21 +0000517 buff);
518
519 if (isis_route_info_same (rinfo_new, rinfo_old, family))
520 {
jardineb5d44e2003-12-23 08:09:43 +0000521 if (isis->debugs & DEBUG_RTE_EVENTS)
hasso529d65b2004-12-24 00:14:50 +0000522 zlog_debug ("ISIS-Rte (%s) route unchanged: %s", area->area_tag, buff);
jardineb5d44e2003-12-23 08:09:43 +0000523 isis_route_info_delete (rinfo_new);
524 route_info = rinfo_old;
525 }
hassof390d2c2004-09-10 20:48:21 +0000526 else if (isis_route_info_same_attrib (rinfo_new, rinfo_old))
527 {
528 /* merge the nexthop lists */
529 if (isis->debugs & DEBUG_RTE_EVENTS)
hasso529d65b2004-12-24 00:14:50 +0000530 zlog_debug ("ISIS-Rte (%s) route changed (same attribs): %s",
hassof390d2c2004-09-10 20:48:21 +0000531 area->area_tag, buff);
532#ifdef EXTREME_DEBUG
hasso529d65b2004-12-24 00:14:50 +0000533 zlog_debug ("Old nexthops");
hassof390d2c2004-09-10 20:48:21 +0000534 nexthops6_print (rinfo_old->nexthops6);
hasso529d65b2004-12-24 00:14:50 +0000535 zlog_debug ("New nexthops");
hassof390d2c2004-09-10 20:48:21 +0000536 nexthops6_print (rinfo_new->nexthops6);
537#endif /* EXTREME_DEBUG */
538 isis_route_info_merge (rinfo_new, rinfo_old, family);
539 isis_route_info_delete (rinfo_new);
540 route_info = rinfo_old;
541 }
542 else
543 {
544 if (isis_route_info_prefer_new (rinfo_new, rinfo_old))
545 {
546 if (isis->debugs & DEBUG_RTE_EVENTS)
hasso529d65b2004-12-24 00:14:50 +0000547 zlog_debug ("ISIS-Rte (%s) route changed: %s", area->area_tag,
548 buff);
hassof390d2c2004-09-10 20:48:21 +0000549 isis_route_info_delete (rinfo_old);
550 route_info = rinfo_new;
551 }
552 else
553 {
554 if (isis->debugs & DEBUG_RTE_EVENTS)
hasso529d65b2004-12-24 00:14:50 +0000555 zlog_debug ("ISIS-Rte (%s) route rejected: %s", area->area_tag,
556 buff);
hassof390d2c2004-09-10 20:48:21 +0000557 isis_route_info_delete (rinfo_new);
558 route_info = rinfo_old;
559 }
560 }
561
jardineb5d44e2003-12-23 08:09:43 +0000562 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE);
563 route_node->info = route_info;
hassof390d2c2004-09-10 20:48:21 +0000564
jardineb5d44e2003-12-23 08:09:43 +0000565 return route_info;
566}
567
568void
569isis_route_delete (struct prefix *prefix, struct route_table *table)
570{
571 struct route_node *rode;
572 struct isis_route_info *rinfo;
573 char buff[BUFSIZ];
574
575 /* for log */
576 prefix2str (prefix, buff, BUFSIZ);
577
578
579 rode = route_node_get (table, prefix);
580 rinfo = rode->info;
581
hassof390d2c2004-09-10 20:48:21 +0000582 if (rinfo == NULL)
583 {
584 if (isis->debugs & DEBUG_RTE_EVENTS)
hasso529d65b2004-12-24 00:14:50 +0000585 zlog_debug ("ISIS-Rte: tried to delete non-existant route %s", buff);
hassof390d2c2004-09-10 20:48:21 +0000586 return;
587 }
jardineb5d44e2003-12-23 08:09:43 +0000588
hassof390d2c2004-09-10 20:48:21 +0000589 if (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
590 {
591 UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
592 if (isis->debugs & DEBUG_RTE_EVENTS)
hasso529d65b2004-12-24 00:14:50 +0000593 zlog_debug ("ISIS-Rte: route delete %s", buff);
hassof390d2c2004-09-10 20:48:21 +0000594 isis_zebra_route_update (prefix, rinfo);
595 }
jardineb5d44e2003-12-23 08:09:43 +0000596 isis_route_info_delete (rinfo);
597 rode->info = NULL;
hassof390d2c2004-09-10 20:48:21 +0000598
jardineb5d44e2003-12-23 08:09:43 +0000599 return;
600}
601
602int
603isis_route_validate (struct thread *thread)
604{
605 struct isis_area *area;
606 struct route_table *table;
607 struct route_node *rode;
608 struct isis_route_info *rinfo;
609 u_char buff[BUFSIZ];
610#ifdef HAVE_IPV6
611 int v6done = 0;
612#endif
613 area = THREAD_ARG (thread);
614 table = area->route_table;
615#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000616again:
jardineb5d44e2003-12-23 08:09:43 +0000617#endif
hassof390d2c2004-09-10 20:48:21 +0000618 for (rode = route_top (table); rode; rode = route_next (rode))
619 {
620 if (rode->info == NULL)
621 continue;
622 rinfo = rode->info;
623
624 if (isis->debugs & DEBUG_RTE_EVENTS)
625 {
hassof7c43dc2004-09-26 16:24:14 +0000626 prefix2str (&rode->p, (char *) buff, BUFSIZ);
hasso529d65b2004-12-24 00:14:50 +0000627 zlog_debug ("ISIS-Rte (%s): route validate: %s %s %s",
628 area->area_tag,
629 (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC) ?
hassof390d2c2004-09-10 20:48:21 +0000630 "sync'ed" : "nosync"),
hasso529d65b2004-12-24 00:14:50 +0000631 (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) ?
hassof390d2c2004-09-10 20:48:21 +0000632 "active" : "inactive"), buff);
633 }
634
635 isis_zebra_route_update (&rode->p, rinfo);
636 if (!CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
637 isis_route_delete (&rode->p, area->route_table);
jardineb5d44e2003-12-23 08:09:43 +0000638 }
jardineb5d44e2003-12-23 08:09:43 +0000639#ifdef HAVE_IPV6
640 if (v6done)
641 return ISIS_OK;
642 table = area->route_table6;
643 v6done = 1;
644 goto again;
645#endif
646
647 return ISIS_OK;
648}