]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_route.c
* prefix.[hc]: Pass argument to the inet6_ntoa by value making it more
[mirror_frr.git] / isisd / isis_route.c
CommitLineData
eb5d44eb 1/*
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>
eb5d44eb 28
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
92365889 56static struct isis_nexthop *
eb5d44eb 57isis_nexthop_create (struct in_addr *ip, unsigned int ifindex)
eb5d44eb 58{
59 struct listnode *node;
60 struct isis_nexthop *nexthop;
f390d2c7 61
1eb8ef25 62 for (ALL_LIST_ELEMENTS_RO (isis->nexthops, node, nexthop))
f390d2c7 63 {
f390d2c7 64 if (nexthop->ifindex != ifindex)
65 continue;
66 if (ip && memcmp (&nexthop->ip, ip, sizeof (struct in_addr)) != 0)
67 continue;
68
69 nexthop->lock++;
70 return nexthop;
71 }
72
eb5d44eb 73 nexthop = XMALLOC (MTYPE_ISIS_NEXTHOP, sizeof (struct isis_nexthop));
f390d2c7 74 if (!nexthop)
75 {
76 zlog_err ("ISIS-Rte: isis_nexthop_create: out of memory!");
77 }
78
eb5d44eb 79 memset (nexthop, 0, sizeof (struct isis_nexthop));
80 nexthop->ifindex = ifindex;
81 memcpy (&nexthop->ip, ip, sizeof (struct in_addr));
82 listnode_add (isis->nexthops, nexthop);
83 nexthop->lock++;
84
85 return nexthop;
86}
87
92365889 88static void
eb5d44eb 89isis_nexthop_delete (struct isis_nexthop *nexthop)
90{
91 nexthop->lock--;
f390d2c7 92 if (nexthop->lock == 0)
93 {
94 listnode_delete (isis->nexthops, nexthop);
95 XFREE (MTYPE_ISIS_NEXTHOP, nexthop);
96 }
97
eb5d44eb 98 return;
99}
100
92365889 101static int
f390d2c7 102nexthoplookup (struct list *nexthops, struct in_addr *ip,
103 unsigned int ifindex)
eb5d44eb 104{
105 struct listnode *node;
106 struct isis_nexthop *nh;
107
1eb8ef25 108 for (ALL_LIST_ELEMENTS_RO (nexthops, node, nh))
f390d2c7 109 {
f390d2c7 110 if (!(memcmp (ip, &nh->ip, sizeof (struct in_addr))) &&
111 ifindex == nh->ifindex)
112 return 1;
113 }
eb5d44eb 114
115 return 0;
116}
117
92365889 118#if 0 /* Old or new code? */
119static void
eb5d44eb 120nexthop_print (struct isis_nexthop *nh)
121{
122 u_char buf[BUFSIZ];
f390d2c7 123
f7c43dcb 124 inet_ntop (AF_INET, &nh->ip, (char *) buf, BUFSIZ);
f390d2c7 125
529d65b3 126 zlog_debug (" %s %u", buf, nh->ifindex);
eb5d44eb 127}
128
92365889 129static void
eb5d44eb 130nexthops_print (struct list *nhs)
131{
132 struct listnode *node;
f390d2c7 133
1eb8ef25 134 for (ALL_LIST_ELEMENTS_RO (nhs, node, nh))
135 nexthop_print (nh);
eb5d44eb 136}
92365889 137#endif /* 0 */
eb5d44eb 138
139#ifdef HAVE_IPV6
92365889 140static struct isis_nexthop6 *
f390d2c7 141isis_nexthop6_new (struct in6_addr *ip6, unsigned int ifindex)
eb5d44eb 142{
f390d2c7 143
eb5d44eb 144 struct isis_nexthop6 *nexthop6;
f390d2c7 145
eb5d44eb 146 nexthop6 = XMALLOC (MTYPE_ISIS_NEXTHOP6, sizeof (struct isis_nexthop6));
f390d2c7 147 if (!nexthop6)
148 {
149 zlog_err ("ISIS-Rte: isis_nexthop_create6: out of memory!");
150 }
151
eb5d44eb 152 memset (nexthop6, 0, sizeof (struct isis_nexthop6));
153 nexthop6->ifindex = ifindex;
154 memcpy (&nexthop6->ip6, ip6, sizeof (struct in6_addr));
155 nexthop6->lock++;
156
157 return nexthop6;
158}
159
92365889 160static struct isis_nexthop6 *
eb5d44eb 161isis_nexthop6_create (struct in6_addr *ip6, unsigned int ifindex)
eb5d44eb 162{
163 struct listnode *node;
164 struct isis_nexthop6 *nexthop6;
f390d2c7 165
1eb8ef25 166 for (ALL_LIST_ELEMENTS_RO (isis->nexthops6, node, nexthop6))
f390d2c7 167 {
f390d2c7 168 if (nexthop6->ifindex != ifindex)
169 continue;
170 if (ip6 && memcmp (&nexthop6->ip6, ip6, sizeof (struct in6_addr)) != 0)
171 continue;
172
173 nexthop6->lock++;
174 return nexthop6;
175 }
176
eb5d44eb 177 nexthop6 = isis_nexthop6_new (ip6, ifindex);
178
179 return nexthop6;
180}
181
92365889 182static void
eb5d44eb 183isis_nexthop6_delete (struct isis_nexthop6 *nexthop6)
184{
185
186 nexthop6->lock--;
f390d2c7 187 if (nexthop6->lock == 0)
188 {
189 listnode_delete (isis->nexthops6, nexthop6);
190 XFREE (MTYPE_ISIS_NEXTHOP6, nexthop6);
191 }
192
eb5d44eb 193 return;
194}
195
92365889 196static int
f390d2c7 197nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6,
198 unsigned int ifindex)
eb5d44eb 199{
200 struct listnode *node;
201 struct isis_nexthop6 *nh6;
202
1eb8ef25 203 for (ALL_LIST_ELEMENTS_RO (nexthops6, node, nh6))
f390d2c7 204 {
f390d2c7 205 if (!(memcmp (ip6, &nh6->ip6, sizeof (struct in6_addr))) &&
206 ifindex == nh6->ifindex)
207 return 1;
208 }
eb5d44eb 209
210 return 0;
211}
212
92365889 213#ifdef EXTREME_DEBUG
214static void
eb5d44eb 215nexthop6_print (struct isis_nexthop6 *nh6)
216{
217 u_char buf[BUFSIZ];
f390d2c7 218
f7c43dcb 219 inet_ntop (AF_INET6, &nh6->ip6, (char *) buf, BUFSIZ);
f390d2c7 220
529d65b3 221 zlog_debug (" %s %u", buf, nh6->ifindex);
eb5d44eb 222}
223
92365889 224static void
eb5d44eb 225nexthops6_print (struct list *nhs6)
226{
227 struct listnode *node;
f390d2c7 228
1eb8ef25 229 for (ALL_LIST_ELEMENTS_RO (nhs6, node, nh6))
230 nexthop6_print (nh6);
eb5d44eb 231}
92365889 232#endif /* EXTREME_DEBUG */
eb5d44eb 233#endif /* HAVE_IPV6 */
234
92365889 235static void
eb5d44eb 236adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj)
237{
238 struct isis_nexthop *nh;
1eb8ef25 239 struct listnode *node, *nnode;
eb5d44eb 240 struct in_addr *ipv4_addr;
241
242 if (adj->ipv4_addrs == NULL)
243 return;
1eb8ef25 244
245 for (ALL_LIST_ELEMENTS (adj->ipv4_addrs, node, nnode, ipv4_addr))
f390d2c7 246 {
f390d2c7 247 if (!nexthoplookup (nexthops, ipv4_addr,
248 adj->circuit->interface->ifindex))
249 {
250 nh = isis_nexthop_create (ipv4_addr,
251 adj->circuit->interface->ifindex);
252 listnode_add (nexthops, nh);
253 }
eb5d44eb 254 }
eb5d44eb 255}
256
257#ifdef HAVE_IPV6
92365889 258static void
eb5d44eb 259adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
260{
1eb8ef25 261 struct listnode *node, *nnode;
eb5d44eb 262 struct in6_addr *ipv6_addr;
263 struct isis_nexthop6 *nh6;
f390d2c7 264
eb5d44eb 265 if (!adj->ipv6_addrs)
266 return;
267
1eb8ef25 268 for (ALL_LIST_ELEMENTS (adj->ipv6_addrs, node, nnode, ipv6_addr))
f390d2c7 269 {
f390d2c7 270 if (!nexthop6lookup (nexthops6, ipv6_addr,
271 adj->circuit->interface->ifindex))
272 {
273 nh6 = isis_nexthop6_create (ipv6_addr,
274 adj->circuit->interface->ifindex);
275 listnode_add (nexthops6, nh6);
276 }
eb5d44eb 277 }
eb5d44eb 278}
279#endif /* HAVE_IPV6 */
280
92365889 281static struct isis_route_info *
f390d2c7 282isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
283 struct list *adjacencies)
eb5d44eb 284{
285 struct isis_route_info *rinfo;
286 struct isis_adjacency *adj;
1eb8ef25 287 struct listnode *node, *nnode;
f390d2c7 288
eb5d44eb 289 rinfo = XMALLOC (MTYPE_ISIS_ROUTE_INFO, sizeof (struct isis_route_info));
f390d2c7 290 if (!rinfo)
291 {
292 zlog_err ("ISIS-Rte: isis_route_info_new: out of memory!");
293 return NULL;
294 }
eb5d44eb 295 memset (rinfo, 0, sizeof (struct isis_route_info));
296
f390d2c7 297 if (family == AF_INET)
298 {
299 rinfo->nexthops = list_new ();
1eb8ef25 300 for (ALL_LIST_ELEMENTS (adjacencies, node, nnode, adj))
301 adjinfo2nexthop (rinfo->nexthops, adj);
eb5d44eb 302 }
eb5d44eb 303#ifdef HAVE_IPV6
f390d2c7 304 if (family == AF_INET6)
305 {
306 rinfo->nexthops6 = list_new ();
1eb8ef25 307 for (ALL_LIST_ELEMENTS (adjacencies, node, nnode, adj))
308 adjinfo2nexthop6 (rinfo->nexthops6, adj);
eb5d44eb 309 }
f390d2c7 310
eb5d44eb 311#endif /* HAVE_IPV6 */
312
313 rinfo->cost = cost;
314 rinfo->depth = depth;
f390d2c7 315
eb5d44eb 316 return rinfo;
317}
318
92365889 319static void
eb5d44eb 320isis_route_info_delete (struct isis_route_info *route_info)
321{
f390d2c7 322 if (route_info->nexthops)
323 {
f7c43dcb 324 route_info->nexthops->del = (void (*)(void *)) isis_nexthop_delete;
f390d2c7 325 list_delete (route_info->nexthops);
326 }
327
eb5d44eb 328#ifdef HAVE_IPV6
f390d2c7 329 if (route_info->nexthops6)
330 {
f7c43dcb 331 route_info->nexthops6->del = (void (*)(void *)) isis_nexthop6_delete;
eb5d44eb 332 list_delete (route_info->nexthops6);
f390d2c7 333 }
eb5d44eb 334#endif /* HAVE_IPV6 */
f390d2c7 335
eb5d44eb 336 XFREE (MTYPE_ISIS_ROUTE_INFO, route_info);
337}
338
92365889 339static int
f390d2c7 340isis_route_info_same_attrib (struct isis_route_info *new,
341 struct isis_route_info *old)
eb5d44eb 342{
343 if (new->cost != old->cost)
344 return 0;
345 if (new->depth != old->depth)
346 return 0;
f390d2c7 347
eb5d44eb 348 return 1;
349}
350
92365889 351static int
f390d2c7 352isis_route_info_same (struct isis_route_info *new,
353 struct isis_route_info *old, u_char family)
eb5d44eb 354{
1eb8ef25 355 struct listnode *node, *nnode;
eb5d44eb 356 struct isis_nexthop *nexthop;
357#ifdef HAVE_IPV6
358 struct isis_nexthop6 *nexthop6;
359#endif /* HAVE_IPV6 */
360 if (!isis_route_info_same_attrib (new, old))
361 return 0;
f390d2c7 362
363 if (family == AF_INET)
364 {
1eb8ef25 365 for (ALL_LIST_ELEMENTS (new->nexthops, node, nnode, nexthop))
366 if (nexthoplookup (old->nexthops, &nexthop->ip, nexthop->ifindex)
367 == 0)
368 return 0;
369
370 for (ALL_LIST_ELEMENTS (old->nexthops, node, nnode, nexthop))
371 if (nexthoplookup (new->nexthops, &nexthop->ip, nexthop->ifindex)
372 == 0)
373 return 0;
eb5d44eb 374 }
eb5d44eb 375#ifdef HAVE_IPV6
f390d2c7 376 else if (family == AF_INET6)
377 {
1eb8ef25 378 for (ALL_LIST_ELEMENTS (new->nexthops6, node, nnode, nexthop6))
379 if (nexthop6lookup (old->nexthops6, &nexthop6->ip6,
380 nexthop6->ifindex) == 0)
381 return 0;
382
383 for (ALL_LIST_ELEMENTS (old->nexthops6, node, nnode, nexthop6))
384 if (nexthop6lookup (new->nexthops6, &nexthop6->ip6,
385 nexthop6->ifindex) == 0)
386 return 0;
eb5d44eb 387 }
eb5d44eb 388#endif /* HAVE_IPV6 */
389
390 return 1;
391}
392
92365889 393static void
eb5d44eb 394isis_nexthops_merge (struct list *new, struct list *old)
395{
1eb8ef25 396 struct listnode *node, *nnode;
eb5d44eb 397 struct isis_nexthop *nexthop;
398
1eb8ef25 399 for (ALL_LIST_ELEMENTS (new, node, nnode, nexthop))
f390d2c7 400 {
f390d2c7 401 if (nexthoplookup (old, &nexthop->ip, nexthop->ifindex))
402 continue;
403 listnode_add (old, nexthop);
404 nexthop->lock++;
405 }
eb5d44eb 406}
407
eb5d44eb 408#ifdef HAVE_IPV6
92365889 409static void
eb5d44eb 410isis_nexthops6_merge (struct list *new, struct list *old)
411{
1eb8ef25 412 struct listnode *node, *nnode;
eb5d44eb 413 struct isis_nexthop6 *nexthop6;
414
1eb8ef25 415 for (ALL_LIST_ELEMENTS (new, node, nnode, nexthop6))
f390d2c7 416 {
f390d2c7 417 if (nexthop6lookup (old, &nexthop6->ip6, nexthop6->ifindex))
418 continue;
419 listnode_add (old, nexthop6);
420 nexthop6->lock++;
421 }
eb5d44eb 422}
423#endif /* HAVE_IPV6 */
424
92365889 425static void
f390d2c7 426isis_route_info_merge (struct isis_route_info *new,
427 struct isis_route_info *old, u_char family)
eb5d44eb 428{
f390d2c7 429 if (family == AF_INET)
eb5d44eb 430 isis_nexthops_merge (new->nexthops, old->nexthops);
431#ifdef HAVE_IPV6
f390d2c7 432 else if (family == AF_INET6)
eb5d44eb 433 isis_nexthops6_merge (new->nexthops6, old->nexthops6);
434#endif /* HAVE_IPV6 */
f390d2c7 435
eb5d44eb 436 return;
437}
438
92365889 439static int
f390d2c7 440isis_route_info_prefer_new (struct isis_route_info *new,
441 struct isis_route_info *old)
eb5d44eb 442{
eb5d44eb 443 if (!CHECK_FLAG (old->flag, ISIS_ROUTE_FLAG_ACTIVE))
444 return 1;
445
446 if (new->cost < old->cost)
447 return 1;
f390d2c7 448
eb5d44eb 449 return 0;
450}
451
eb5d44eb 452struct isis_route_info *
453isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth,
f390d2c7 454 struct list *adjacencies, struct isis_area *area)
eb5d44eb 455{
456 struct route_node *route_node;
457 struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL;
458 u_char buff[BUFSIZ];
459 u_char family;
f390d2c7 460
eb5d44eb 461 family = prefix->family;
462 /* for debugs */
f7c43dcb 463 prefix2str (prefix, (char *) buff, BUFSIZ);
f390d2c7 464
eb5d44eb 465 rinfo_new = isis_route_info_new (cost, depth, family, adjacencies);
f390d2c7 466 if (!rinfo_new)
467 {
468 zlog_err ("ISIS-Rte (%s): isis_route_create: out of memory!",
469 area->area_tag);
470 return NULL;
471 }
472
eb5d44eb 473 if (family == AF_INET)
f390d2c7 474 route_node = route_node_get (area->route_table, prefix);
eb5d44eb 475#ifdef HAVE_IPV6
476 else if (family == AF_INET6)
f390d2c7 477 route_node = route_node_get (area->route_table6, prefix);
eb5d44eb 478#endif /* HAVE_IPV6 */
f390d2c7 479 else
eb5d44eb 480 return NULL;
f390d2c7 481 rinfo_old = route_node->info;
482 if (!rinfo_old)
483 {
484 if (isis->debugs & DEBUG_RTE_EVENTS)
529d65b3 485 zlog_debug ("ISIS-Rte (%s) route created: %s", area->area_tag, buff);
f390d2c7 486 SET_FLAG (rinfo_new->flag, ISIS_ROUTE_FLAG_ACTIVE);
487 route_node->info = rinfo_new;
488 return rinfo_new;
489 }
490
eb5d44eb 491 if (isis->debugs & DEBUG_RTE_EVENTS)
529d65b3 492 zlog_debug ("ISIS-Rte (%s) route already exists: %s", area->area_tag,
f390d2c7 493 buff);
494
495 if (isis_route_info_same (rinfo_new, rinfo_old, family))
496 {
eb5d44eb 497 if (isis->debugs & DEBUG_RTE_EVENTS)
529d65b3 498 zlog_debug ("ISIS-Rte (%s) route unchanged: %s", area->area_tag, buff);
f390d2c7 499 isis_route_info_delete (rinfo_new);
500 route_info = rinfo_old;
501 }
502 else if (isis_route_info_same_attrib (rinfo_new, rinfo_old))
503 {
504 /* merge the nexthop lists */
eb5d44eb 505 if (isis->debugs & DEBUG_RTE_EVENTS)
529d65b3 506 zlog_debug ("ISIS-Rte (%s) route changed (same attribs): %s",
f390d2c7 507 area->area_tag, buff);
508#ifdef EXTREME_DEBUG
529d65b3 509 zlog_debug ("Old nexthops");
f390d2c7 510 nexthops6_print (rinfo_old->nexthops6);
529d65b3 511 zlog_debug ("New nexthops");
f390d2c7 512 nexthops6_print (rinfo_new->nexthops6);
513#endif /* EXTREME_DEBUG */
514 isis_route_info_merge (rinfo_new, rinfo_old, family);
eb5d44eb 515 isis_route_info_delete (rinfo_new);
516 route_info = rinfo_old;
517 }
f390d2c7 518 else
519 {
520 if (isis_route_info_prefer_new (rinfo_new, rinfo_old))
521 {
522 if (isis->debugs & DEBUG_RTE_EVENTS)
529d65b3 523 zlog_debug ("ISIS-Rte (%s) route changed: %s", area->area_tag,
524 buff);
f390d2c7 525 isis_route_info_delete (rinfo_old);
526 route_info = rinfo_new;
527 }
528 else
529 {
530 if (isis->debugs & DEBUG_RTE_EVENTS)
529d65b3 531 zlog_debug ("ISIS-Rte (%s) route rejected: %s", area->area_tag,
532 buff);
f390d2c7 533 isis_route_info_delete (rinfo_new);
534 route_info = rinfo_old;
535 }
536 }
537
eb5d44eb 538 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE);
539 route_node->info = route_info;
f390d2c7 540
eb5d44eb 541 return route_info;
542}
543
92365889 544static void
eb5d44eb 545isis_route_delete (struct prefix *prefix, struct route_table *table)
546{
547 struct route_node *rode;
548 struct isis_route_info *rinfo;
549 char buff[BUFSIZ];
550
551 /* for log */
552 prefix2str (prefix, buff, BUFSIZ);
553
554
555 rode = route_node_get (table, prefix);
556 rinfo = rode->info;
557
f390d2c7 558 if (rinfo == NULL)
559 {
560 if (isis->debugs & DEBUG_RTE_EVENTS)
529d65b3 561 zlog_debug ("ISIS-Rte: tried to delete non-existant route %s", buff);
f390d2c7 562 return;
563 }
564
565 if (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
566 {
567 UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
568 if (isis->debugs & DEBUG_RTE_EVENTS)
529d65b3 569 zlog_debug ("ISIS-Rte: route delete %s", buff);
f390d2c7 570 isis_zebra_route_update (prefix, rinfo);
571 }
eb5d44eb 572 isis_route_info_delete (rinfo);
573 rode->info = NULL;
f390d2c7 574
eb5d44eb 575 return;
576}
577
578int
579isis_route_validate (struct thread *thread)
580{
581 struct isis_area *area;
582 struct route_table *table;
583 struct route_node *rode;
584 struct isis_route_info *rinfo;
585 u_char buff[BUFSIZ];
586#ifdef HAVE_IPV6
587 int v6done = 0;
588#endif
589 area = THREAD_ARG (thread);
590 table = area->route_table;
591#ifdef HAVE_IPV6
f390d2c7 592again:
eb5d44eb 593#endif
f390d2c7 594 for (rode = route_top (table); rode; rode = route_next (rode))
595 {
596 if (rode->info == NULL)
597 continue;
598 rinfo = rode->info;
599
600 if (isis->debugs & DEBUG_RTE_EVENTS)
601 {
f7c43dcb 602 prefix2str (&rode->p, (char *) buff, BUFSIZ);
529d65b3 603 zlog_debug ("ISIS-Rte (%s): route validate: %s %s %s",
604 area->area_tag,
605 (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC) ?
f390d2c7 606 "sync'ed" : "nosync"),
529d65b3 607 (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) ?
f390d2c7 608 "active" : "inactive"), buff);
609 }
610
611 isis_zebra_route_update (&rode->p, rinfo);
612 if (!CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
613 isis_route_delete (&rode->p, area->route_table);
eb5d44eb 614 }
eb5d44eb 615#ifdef HAVE_IPV6
616 if (v6done)
617 return ISIS_OK;
618 table = area->route_table6;
619 v6done = 1;
620 goto again;
621#endif
622
623 return ISIS_OK;
624}