diff options
Diffstat (limited to 'isisd/isis_route.c')
| -rw-r--r-- | isisd/isis_route.c | 988 |
1 files changed, 484 insertions, 504 deletions
diff --git a/isisd/isis_route.c b/isisd/isis_route.c index bceb70ce03..afc4f65128 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -1,20 +1,20 @@ /* * IS-IS Rout(e)ing protocol - isis_route.c * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology + * Tampere University of Technology * Institute of Communications Engineering * * based on ../ospf6d/ospf6_route.[ch] * by Yasuhiro Ohara * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * This program is distributed in the hope that it will be useful,but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -49,502 +49,489 @@ #include "isis_route.h" #include "isis_zebra.h" -static struct isis_nexthop * -isis_nexthop_create (struct in_addr *ip, ifindex_t ifindex) +static struct isis_nexthop *isis_nexthop_create(struct in_addr *ip, + ifindex_t ifindex) { - struct listnode *node; - struct isis_nexthop *nexthop; + struct listnode *node; + struct isis_nexthop *nexthop; - for (ALL_LIST_ELEMENTS_RO (isis->nexthops, node, nexthop)) - { - if (nexthop->ifindex != ifindex) - continue; - if (ip && memcmp (&nexthop->ip, ip, sizeof (struct in_addr)) != 0) - continue; + for (ALL_LIST_ELEMENTS_RO(isis->nexthops, node, nexthop)) { + if (nexthop->ifindex != ifindex) + continue; + if (ip && memcmp(&nexthop->ip, ip, sizeof(struct in_addr)) != 0) + continue; - nexthop->lock++; - return nexthop; - } + nexthop->lock++; + return nexthop; + } - nexthop = XCALLOC (MTYPE_ISIS_NEXTHOP, sizeof (struct isis_nexthop)); + nexthop = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop)); - nexthop->ifindex = ifindex; - memcpy (&nexthop->ip, ip, sizeof (struct in_addr)); - listnode_add (isis->nexthops, nexthop); - nexthop->lock++; + nexthop->ifindex = ifindex; + memcpy(&nexthop->ip, ip, sizeof(struct in_addr)); + listnode_add(isis->nexthops, nexthop); + nexthop->lock++; - return nexthop; + return nexthop; } -static void -isis_nexthop_delete (struct isis_nexthop *nexthop) +static void isis_nexthop_delete(struct isis_nexthop *nexthop) { - nexthop->lock--; - if (nexthop->lock == 0) - { - listnode_delete (isis->nexthops, nexthop); - XFREE (MTYPE_ISIS_NEXTHOP, nexthop); - } - - return; + nexthop->lock--; + if (nexthop->lock == 0) { + listnode_delete(isis->nexthops, nexthop); + XFREE(MTYPE_ISIS_NEXTHOP, nexthop); + } + + return; } -static int -nexthoplookup (struct list *nexthops, struct in_addr *ip, - ifindex_t ifindex) +static int nexthoplookup(struct list *nexthops, struct in_addr *ip, + ifindex_t ifindex) { - struct listnode *node; - struct isis_nexthop *nh; + struct listnode *node; + struct isis_nexthop *nh; - for (ALL_LIST_ELEMENTS_RO (nexthops, node, nh)) - { - if (!(memcmp (ip, &nh->ip, sizeof (struct in_addr))) && - ifindex == nh->ifindex) - return 1; - } + for (ALL_LIST_ELEMENTS_RO(nexthops, node, nh)) { + if (!(memcmp(ip, &nh->ip, sizeof(struct in_addr))) + && ifindex == nh->ifindex) + return 1; + } - return 0; + return 0; } #ifdef EXTREME_DEBUG -static void -nexthop_print (struct isis_nexthop *nh) +static void nexthop_print(struct isis_nexthop *nh) { - u_char buf[BUFSIZ]; + u_char buf[BUFSIZ]; - inet_ntop (AF_INET, &nh->ip, (char *) buf, BUFSIZ); + inet_ntop(AF_INET, &nh->ip, (char *)buf, BUFSIZ); - zlog_debug (" %s %u", buf, nh->ifindex); + zlog_debug(" %s %u", buf, nh->ifindex); } -static void -nexthops_print (struct list *nhs) +static void nexthops_print(struct list *nhs) { - struct listnode *node; - struct isis_nexthop *nh; + struct listnode *node; + struct isis_nexthop *nh; - for (ALL_LIST_ELEMENTS_RO (nhs, node, nh)) - nexthop_print (nh); + for (ALL_LIST_ELEMENTS_RO(nhs, node, nh)) + nexthop_print(nh); } #endif /* EXTREME_DEBUG */ -static struct isis_nexthop6 * -isis_nexthop6_new (struct in6_addr *ip6, ifindex_t ifindex) +static struct isis_nexthop6 *isis_nexthop6_new(struct in6_addr *ip6, + ifindex_t ifindex) { - struct isis_nexthop6 *nexthop6; + struct isis_nexthop6 *nexthop6; - nexthop6 = XCALLOC (MTYPE_ISIS_NEXTHOP6, sizeof (struct isis_nexthop6)); + nexthop6 = XCALLOC(MTYPE_ISIS_NEXTHOP6, sizeof(struct isis_nexthop6)); - nexthop6->ifindex = ifindex; - memcpy (&nexthop6->ip6, ip6, sizeof (struct in6_addr)); - nexthop6->lock++; + nexthop6->ifindex = ifindex; + memcpy(&nexthop6->ip6, ip6, sizeof(struct in6_addr)); + nexthop6->lock++; - return nexthop6; + return nexthop6; } -static struct isis_nexthop6 * -isis_nexthop6_create (struct in6_addr *ip6, ifindex_t ifindex) +static struct isis_nexthop6 *isis_nexthop6_create(struct in6_addr *ip6, + ifindex_t ifindex) { - struct listnode *node; - struct isis_nexthop6 *nexthop6; - - for (ALL_LIST_ELEMENTS_RO (isis->nexthops6, node, nexthop6)) - { - if (nexthop6->ifindex != ifindex) - continue; - if (ip6 && memcmp (&nexthop6->ip6, ip6, sizeof (struct in6_addr)) != 0) - continue; - - nexthop6->lock++; - return nexthop6; - } + struct listnode *node; + struct isis_nexthop6 *nexthop6; + + for (ALL_LIST_ELEMENTS_RO(isis->nexthops6, node, nexthop6)) { + if (nexthop6->ifindex != ifindex) + continue; + if (ip6 + && memcmp(&nexthop6->ip6, ip6, sizeof(struct in6_addr)) + != 0) + continue; + + nexthop6->lock++; + return nexthop6; + } - nexthop6 = isis_nexthop6_new (ip6, ifindex); + nexthop6 = isis_nexthop6_new(ip6, ifindex); - return nexthop6; + return nexthop6; } -static void -isis_nexthop6_delete (struct isis_nexthop6 *nexthop6) +static void isis_nexthop6_delete(struct isis_nexthop6 *nexthop6) { - nexthop6->lock--; - if (nexthop6->lock == 0) - { - listnode_delete (isis->nexthops6, nexthop6); - XFREE (MTYPE_ISIS_NEXTHOP6, nexthop6); - } + nexthop6->lock--; + if (nexthop6->lock == 0) { + listnode_delete(isis->nexthops6, nexthop6); + XFREE(MTYPE_ISIS_NEXTHOP6, nexthop6); + } - return; + return; } -static int -nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6, - ifindex_t ifindex) +static int nexthop6lookup(struct list *nexthops6, struct in6_addr *ip6, + ifindex_t ifindex) { - struct listnode *node; - struct isis_nexthop6 *nh6; + struct listnode *node; + struct isis_nexthop6 *nh6; - for (ALL_LIST_ELEMENTS_RO (nexthops6, node, nh6)) - { - if (!(memcmp (ip6, &nh6->ip6, sizeof (struct in6_addr))) && - ifindex == nh6->ifindex) - return 1; - } + for (ALL_LIST_ELEMENTS_RO(nexthops6, node, nh6)) { + if (!(memcmp(ip6, &nh6->ip6, sizeof(struct in6_addr))) + && ifindex == nh6->ifindex) + return 1; + } - return 0; + return 0; } #ifdef EXTREME_DEBUG -static void -nexthop6_print (struct isis_nexthop6 *nh6) +static void nexthop6_print(struct isis_nexthop6 *nh6) { - u_char buf[BUFSIZ]; + u_char buf[BUFSIZ]; - inet_ntop (AF_INET6, &nh6->ip6, (char *) buf, BUFSIZ); + inet_ntop(AF_INET6, &nh6->ip6, (char *)buf, BUFSIZ); - zlog_debug (" %s %u", buf, nh6->ifindex); + zlog_debug(" %s %u", buf, nh6->ifindex); } -static void -nexthops6_print (struct list *nhs6) +static void nexthops6_print(struct list *nhs6) { - struct listnode *node; - struct isis_nexthop6 *nh6; + struct listnode *node; + struct isis_nexthop6 *nh6; - for (ALL_LIST_ELEMENTS_RO (nhs6, node, nh6)) - nexthop6_print (nh6); + for (ALL_LIST_ELEMENTS_RO(nhs6, node, nh6)) + nexthop6_print(nh6); } #endif /* EXTREME_DEBUG */ -static void -adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj) +static void adjinfo2nexthop(struct list *nexthops, struct isis_adjacency *adj) { - struct isis_nexthop *nh; - struct listnode *node; - struct in_addr *ipv4_addr; - - if (adj->ipv4_addrs == NULL) - return; - - for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr)) - { - if (!nexthoplookup (nexthops, ipv4_addr, - adj->circuit->interface->ifindex)) - { - nh = isis_nexthop_create (ipv4_addr, - adj->circuit->interface->ifindex); - nh->router_address = adj->router_address; - listnode_add (nexthops, nh); + struct isis_nexthop *nh; + struct listnode *node; + struct in_addr *ipv4_addr; + + if (adj->ipv4_addrs == NULL) + return; + + for (ALL_LIST_ELEMENTS_RO(adj->ipv4_addrs, node, ipv4_addr)) { + if (!nexthoplookup(nexthops, ipv4_addr, + adj->circuit->interface->ifindex)) { + nh = isis_nexthop_create( + ipv4_addr, adj->circuit->interface->ifindex); + nh->router_address = adj->router_address; + listnode_add(nexthops, nh); + } } - } } -static void -adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj) +static void adjinfo2nexthop6(struct list *nexthops6, struct isis_adjacency *adj) { - struct listnode *node; - struct in6_addr *ipv6_addr; - struct isis_nexthop6 *nh6; - - if (!adj->ipv6_addrs) - return; - - for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr)) - { - if (!nexthop6lookup (nexthops6, ipv6_addr, - adj->circuit->interface->ifindex)) - { - nh6 = isis_nexthop6_create (ipv6_addr, - adj->circuit->interface->ifindex); - nh6->router_address6 = adj->router_address6; - listnode_add (nexthops6, nh6); + struct listnode *node; + struct in6_addr *ipv6_addr; + struct isis_nexthop6 *nh6; + + if (!adj->ipv6_addrs) + return; + + for (ALL_LIST_ELEMENTS_RO(adj->ipv6_addrs, node, ipv6_addr)) { + if (!nexthop6lookup(nexthops6, ipv6_addr, + adj->circuit->interface->ifindex)) { + nh6 = isis_nexthop6_create( + ipv6_addr, adj->circuit->interface->ifindex); + nh6->router_address6 = adj->router_address6; + listnode_add(nexthops6, nh6); + } } - } } -static struct isis_route_info * -isis_route_info_new (struct prefix *prefix, uint32_t cost, uint32_t depth, - struct list *adjacencies) +static struct isis_route_info *isis_route_info_new(struct prefix *prefix, + uint32_t cost, + uint32_t depth, + struct list *adjacencies) { - struct isis_route_info *rinfo; - struct isis_adjacency *adj; - struct listnode *node; - - rinfo = XCALLOC (MTYPE_ISIS_ROUTE_INFO, sizeof (struct isis_route_info)); - - if (prefix->family == AF_INET) - { - rinfo->nexthops = list_new (); - for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj)) - { - /* check for force resync this route */ - if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) - SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); - /* update neighbor router address */ - if (depth == 2 && prefix->prefixlen == 32) - adj->router_address = prefix->u.prefix4; - adjinfo2nexthop (rinfo->nexthops, adj); - } - } - if (prefix->family == AF_INET6) - { - rinfo->nexthops6 = list_new (); - for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj)) - { - /* check for force resync this route */ - if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) - SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); - /* update neighbor router address */ - if (depth == 2 && prefix->prefixlen == 128) - adj->router_address6 = prefix->u.prefix6; - adjinfo2nexthop6 (rinfo->nexthops6, adj); - } - } - - rinfo->cost = cost; - rinfo->depth = depth; - - return rinfo; + struct isis_route_info *rinfo; + struct isis_adjacency *adj; + struct listnode *node; + + rinfo = XCALLOC(MTYPE_ISIS_ROUTE_INFO, sizeof(struct isis_route_info)); + + if (prefix->family == AF_INET) { + rinfo->nexthops = list_new(); + for (ALL_LIST_ELEMENTS_RO(adjacencies, node, adj)) { + /* check for force resync this route */ + if (CHECK_FLAG(adj->circuit->flags, + ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) + SET_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_RESYNC); + /* update neighbor router address */ + if (depth == 2 && prefix->prefixlen == 32) + adj->router_address = prefix->u.prefix4; + adjinfo2nexthop(rinfo->nexthops, adj); + } + } + if (prefix->family == AF_INET6) { + rinfo->nexthops6 = list_new(); + for (ALL_LIST_ELEMENTS_RO(adjacencies, node, adj)) { + /* check for force resync this route */ + if (CHECK_FLAG(adj->circuit->flags, + ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) + SET_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_RESYNC); + /* update neighbor router address */ + if (depth == 2 && prefix->prefixlen == 128) + adj->router_address6 = prefix->u.prefix6; + adjinfo2nexthop6(rinfo->nexthops6, adj); + } + } + + rinfo->cost = cost; + rinfo->depth = depth; + + return rinfo; } -static void -isis_route_info_delete (struct isis_route_info *route_info) +static void isis_route_info_delete(struct isis_route_info *route_info) { - if (route_info->nexthops) - { - route_info->nexthops->del = (void (*)(void *)) isis_nexthop_delete; - list_delete (route_info->nexthops); - } - - if (route_info->nexthops6) - { - route_info->nexthops6->del = (void (*)(void *)) isis_nexthop6_delete; - list_delete (route_info->nexthops6); - } - - XFREE (MTYPE_ISIS_ROUTE_INFO, route_info); + if (route_info->nexthops) { + route_info->nexthops->del = + (void (*)(void *))isis_nexthop_delete; + list_delete(route_info->nexthops); + } + + if (route_info->nexthops6) { + route_info->nexthops6->del = + (void (*)(void *))isis_nexthop6_delete; + list_delete(route_info->nexthops6); + } + + XFREE(MTYPE_ISIS_ROUTE_INFO, route_info); } -static int -isis_route_info_same_attrib (struct isis_route_info *new, - struct isis_route_info *old) +static int isis_route_info_same_attrib(struct isis_route_info *new, + struct isis_route_info *old) { - if (new->cost != old->cost) - return 0; - if (new->depth != old->depth) - return 0; + if (new->cost != old->cost) + return 0; + if (new->depth != old->depth) + return 0; - return 1; + return 1; } -static int -isis_route_info_same (struct isis_route_info *new, - struct isis_route_info *old, u_char family) +static int isis_route_info_same(struct isis_route_info *new, + struct isis_route_info *old, u_char family) { - struct listnode *node; - struct isis_nexthop *nexthop; - struct isis_nexthop6 *nexthop6; - - if (!CHECK_FLAG (old->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - return 0; - - if (CHECK_FLAG (new->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC)) - return 0; - - if (!isis_route_info_same_attrib (new, old)) - return 0; - - if (family == AF_INET) - { - for (ALL_LIST_ELEMENTS_RO (new->nexthops, node, nexthop)) - if (nexthoplookup (old->nexthops, &nexthop->ip, nexthop->ifindex) - == 0) - return 0; - - for (ALL_LIST_ELEMENTS_RO (old->nexthops, node, nexthop)) - if (nexthoplookup (new->nexthops, &nexthop->ip, nexthop->ifindex) - == 0) - return 0; - } - else if (family == AF_INET6) - { - for (ALL_LIST_ELEMENTS_RO (new->nexthops6, node, nexthop6)) - if (nexthop6lookup (old->nexthops6, &nexthop6->ip6, - nexthop6->ifindex) == 0) - return 0; - - for (ALL_LIST_ELEMENTS_RO (old->nexthops6, node, nexthop6)) - if (nexthop6lookup (new->nexthops6, &nexthop6->ip6, - nexthop6->ifindex) == 0) - return 0; - } - - return 1; + struct listnode *node; + struct isis_nexthop *nexthop; + struct isis_nexthop6 *nexthop6; + + if (!CHECK_FLAG(old->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) + return 0; + + if (CHECK_FLAG(new->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC)) + return 0; + + if (!isis_route_info_same_attrib(new, old)) + return 0; + + if (family == AF_INET) { + for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) + if (nexthoplookup(old->nexthops, &nexthop->ip, + nexthop->ifindex) + == 0) + return 0; + + for (ALL_LIST_ELEMENTS_RO(old->nexthops, node, nexthop)) + if (nexthoplookup(new->nexthops, &nexthop->ip, + nexthop->ifindex) + == 0) + return 0; + } else if (family == AF_INET6) { + for (ALL_LIST_ELEMENTS_RO(new->nexthops6, node, nexthop6)) + if (nexthop6lookup(old->nexthops6, &nexthop6->ip6, + nexthop6->ifindex) + == 0) + return 0; + + for (ALL_LIST_ELEMENTS_RO(old->nexthops6, node, nexthop6)) + if (nexthop6lookup(new->nexthops6, &nexthop6->ip6, + nexthop6->ifindex) + == 0) + return 0; + } + + return 1; } -struct isis_route_info * -isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth, - struct list *adjacencies, struct isis_area *area, - int level) +struct isis_route_info *isis_route_create(struct prefix *prefix, u_int32_t cost, + u_int32_t depth, + struct list *adjacencies, + struct isis_area *area, int level) { - struct route_node *route_node; - struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL; - char buff[PREFIX2STR_BUFFER]; - u_char family; - - family = prefix->family; - /* for debugs */ - prefix2str (prefix, buff, sizeof (buff)); - - rinfo_new = isis_route_info_new (prefix, cost, depth, adjacencies); - - if (family == AF_INET) - route_node = route_node_get (area->route_table[level - 1], prefix); - else if (family == AF_INET6) - route_node = route_node_get (area->route_table6[level - 1], prefix); - else - { - isis_route_info_delete (rinfo_new); - return NULL; - } - - rinfo_old = route_node->info; - if (!rinfo_old) - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte (%s) route created: %s", area->area_tag, buff); - route_info = rinfo_new; - UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - } - else - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte (%s) route already exists: %s", area->area_tag, - buff); - if (isis_route_info_same (rinfo_new, rinfo_old, family)) - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte (%s) route unchanged: %s", area->area_tag, - buff); - isis_route_info_delete (rinfo_new); - route_info = rinfo_old; - } - else - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte (%s) route changed: %s", area->area_tag, - buff); - isis_route_info_delete (rinfo_old); - route_info = rinfo_new; - UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - } - } - - SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE); - route_node->info = route_info; - - return route_info; + struct route_node *route_node; + struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL; + char buff[PREFIX2STR_BUFFER]; + u_char family; + + family = prefix->family; + /* for debugs */ + prefix2str(prefix, buff, sizeof(buff)); + + rinfo_new = isis_route_info_new(prefix, cost, depth, adjacencies); + + if (family == AF_INET) + route_node = + route_node_get(area->route_table[level - 1], prefix); + else if (family == AF_INET6) + route_node = + route_node_get(area->route_table6[level - 1], prefix); + else { + isis_route_info_delete(rinfo_new); + return NULL; + } + + rinfo_old = route_node->info; + if (!rinfo_old) { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte (%s) route created: %s", + area->area_tag, buff); + route_info = rinfo_new; + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } else { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte (%s) route already exists: %s", + area->area_tag, buff); + if (isis_route_info_same(rinfo_new, rinfo_old, family)) { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte (%s) route unchanged: %s", + area->area_tag, buff); + isis_route_info_delete(rinfo_new); + route_info = rinfo_old; + } else { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte (%s) route changed: %s", + area->area_tag, buff); + isis_route_info_delete(rinfo_old); + route_info = rinfo_new; + UNSET_FLAG(route_info->flag, + ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } + } + + SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE); + route_node->info = route_info; + + return route_info; } -static void -isis_route_delete (struct prefix *prefix, struct route_table *table) +static void isis_route_delete(struct prefix *prefix, struct route_table *table) { - struct route_node *rode; - struct isis_route_info *rinfo; - char buff[PREFIX2STR_BUFFER]; - - /* for log */ - prefix2str (prefix, buff, sizeof (buff)); - - - rode = route_node_get (table, prefix); - rinfo = rode->info; - - if (rinfo == NULL) - { - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte: tried to delete non-existant route %s", buff); - return; - } - - if (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - { - UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); - if (isis->debugs & DEBUG_RTE_EVENTS) - zlog_debug ("ISIS-Rte: route delete %s", buff); - isis_zebra_route_update (prefix, rinfo); - } - isis_route_info_delete (rinfo); - rode->info = NULL; - - return; + struct route_node *rode; + struct isis_route_info *rinfo; + char buff[PREFIX2STR_BUFFER]; + + /* for log */ + prefix2str(prefix, buff, sizeof(buff)); + + + rode = route_node_get(table, prefix); + rinfo = rode->info; + + if (rinfo == NULL) { + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug( + "ISIS-Rte: tried to delete non-existant route %s", + buff); + return; + } + + if (CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) { + UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); + if (isis->debugs & DEBUG_RTE_EVENTS) + zlog_debug("ISIS-Rte: route delete %s", buff); + isis_zebra_route_update(prefix, rinfo); + } + isis_route_info_delete(rinfo); + rode->info = NULL; + + return; } /* Validating routes in particular table. */ -static void -isis_route_validate_table (struct isis_area *area, struct route_table *table) +static void isis_route_validate_table(struct isis_area *area, + struct route_table *table) { - struct route_node *rnode, *drnode; - struct isis_route_info *rinfo; - char buff[PREFIX2STR_BUFFER]; - - for (rnode = route_top (table); rnode; rnode = route_next (rnode)) - { - if (rnode->info == NULL) - continue; - rinfo = rnode->info; - - if (isis->debugs & DEBUG_RTE_EVENTS) - { - prefix2str (&rnode->p, buff, sizeof (buff)); - zlog_debug ("ISIS-Rte (%s): route validate: %s %s %s %s", - area->area_tag, - (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED) ? - "synced" : "not-synced"), - (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC) ? - "resync" : "not-resync"), - (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) ? - "active" : "inactive"), buff); + struct route_node *rnode, *drnode; + struct isis_route_info *rinfo; + char buff[PREFIX2STR_BUFFER]; + + for (rnode = route_top(table); rnode; rnode = route_next(rnode)) { + if (rnode->info == NULL) + continue; + rinfo = rnode->info; + + if (isis->debugs & DEBUG_RTE_EVENTS) { + prefix2str(&rnode->p, buff, sizeof(buff)); + zlog_debug( + "ISIS-Rte (%s): route validate: %s %s %s %s", + area->area_tag, + (CHECK_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_SYNCED) + ? "synced" + : "not-synced"), + (CHECK_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_RESYNC) + ? "resync" + : "not-resync"), + (CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) + ? "active" + : "inactive"), + buff); + } + + isis_zebra_route_update(&rnode->p, rinfo); + if (!CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE)) { + /* Area is either L1 or L2 => we use level route tables + * directly for + * validating => no problems with deleting routes. */ + if (area->is_type != IS_LEVEL_1_AND_2) { + isis_route_delete(&rnode->p, table); + continue; + } + /* If area is L1L2, we work with merge table and + * therefore must + * delete node from level tables as well before deleting + * route info. + * FIXME: Is it performance problem? There has to be the + * better way. + * Like not to deal with it here at all (see the next + * comment)? */ + if (rnode->p.family == AF_INET) { + drnode = route_node_get(area->route_table[0], + &rnode->p); + if (drnode->info == rnode->info) + drnode->info = NULL; + drnode = route_node_get(area->route_table[1], + &rnode->p); + if (drnode->info == rnode->info) + drnode->info = NULL; + } + + if (rnode->p.family == AF_INET6) { + drnode = route_node_get(area->route_table6[0], + &rnode->p); + if (drnode->info == rnode->info) + drnode->info = NULL; + drnode = route_node_get(area->route_table6[1], + &rnode->p); + if (drnode->info == rnode->info) + drnode->info = NULL; + } + + isis_route_delete(&rnode->p, table); + } } - - isis_zebra_route_update (&rnode->p, rinfo); - if (!CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE)) - { - /* Area is either L1 or L2 => we use level route tables directly for - * validating => no problems with deleting routes. */ - if (area->is_type != IS_LEVEL_1_AND_2) - { - isis_route_delete (&rnode->p, table); - continue; - } - /* If area is L1L2, we work with merge table and therefore must - * delete node from level tables as well before deleting route info. - * FIXME: Is it performance problem? There has to be the better way. - * Like not to deal with it here at all (see the next comment)? */ - if (rnode->p.family == AF_INET) - { - drnode = route_node_get (area->route_table[0], &rnode->p); - if (drnode->info == rnode->info) - drnode->info = NULL; - drnode = route_node_get (area->route_table[1], &rnode->p); - if (drnode->info == rnode->info) - drnode->info = NULL; - } - - if (rnode->p.family == AF_INET6) - { - drnode = route_node_get (area->route_table6[0], &rnode->p); - if (drnode->info == rnode->info) - drnode->info = NULL; - drnode = route_node_get (area->route_table6[1], &rnode->p); - if (drnode->info == rnode->info) - drnode->info = NULL; - } - - isis_route_delete (&rnode->p, table); - } - } } /* Function to validate route tables for L1L2 areas. In this case we can't use @@ -557,106 +544,99 @@ isis_route_validate_table (struct isis_area *area, struct route_table *table) * * FIXME: Is it right place to do it at all? Maybe we should push both levels * to the RIB with different zebra route types and let RIB handle this? */ -static void -isis_route_validate_merge (struct isis_area *area, int family) +static void isis_route_validate_merge(struct isis_area *area, int family) { - struct route_table *table = NULL; - struct route_table *merge; - struct route_node *rnode, *mrnode; - - merge = route_table_init (); - - if (family == AF_INET) - table = area->route_table[0]; - else if (family == AF_INET6) - table = area->route_table6[0]; - else - { - zlog_warn ("ISIS-Rte (%s) %s called for unknown family %d", - area->area_tag, __func__, family); - route_table_finish(merge); - return; - } - - for (rnode = route_top (table); rnode; rnode = route_next (rnode)) - { - if (rnode->info == NULL) - continue; - mrnode = route_node_get (merge, &rnode->p); - mrnode->info = rnode->info; - } - - if (family == AF_INET) - table = area->route_table[1]; - else if (family == AF_INET6) - table = area->route_table6[1]; - - for (rnode = route_top (table); rnode; rnode = route_next (rnode)) - { - if (rnode->info == NULL) - continue; - mrnode = route_node_get (merge, &rnode->p); - if (mrnode->info != NULL) - continue; - mrnode->info = rnode->info; - } - - isis_route_validate_table (area, merge); - route_table_finish (merge); + struct route_table *table = NULL; + struct route_table *merge; + struct route_node *rnode, *mrnode; + + merge = route_table_init(); + + if (family == AF_INET) + table = area->route_table[0]; + else if (family == AF_INET6) + table = area->route_table6[0]; + else { + zlog_warn("ISIS-Rte (%s) %s called for unknown family %d", + area->area_tag, __func__, family); + route_table_finish(merge); + return; + } + + for (rnode = route_top(table); rnode; rnode = route_next(rnode)) { + if (rnode->info == NULL) + continue; + mrnode = route_node_get(merge, &rnode->p); + mrnode->info = rnode->info; + } + + if (family == AF_INET) + table = area->route_table[1]; + else if (family == AF_INET6) + table = area->route_table6[1]; + + for (rnode = route_top(table); rnode; rnode = route_next(rnode)) { + if (rnode->info == NULL) + continue; + mrnode = route_node_get(merge, &rnode->p); + if (mrnode->info != NULL) + continue; + mrnode->info = rnode->info; + } + + isis_route_validate_table(area, merge); + route_table_finish(merge); } /* Walk through route tables and propagate necessary changes into RIB. In case * of L1L2 area, level tables have to be merged at first. */ -void -isis_route_validate (struct isis_area *area) +void isis_route_validate(struct isis_area *area) { - struct listnode *node; - struct isis_circuit *circuit; - - if (area->is_type == IS_LEVEL_1) - isis_route_validate_table (area, area->route_table[0]); - else if (area->is_type == IS_LEVEL_2) - isis_route_validate_table (area, area->route_table[1]); - else - isis_route_validate_merge (area, AF_INET); - - if (area->is_type == IS_LEVEL_1) - isis_route_validate_table (area, area->route_table6[0]); - else if (area->is_type == IS_LEVEL_2) - isis_route_validate_table (area, area->route_table6[1]); - else - isis_route_validate_merge (area, AF_INET6); - - if (!area->circuit_list) { - return; - } - /* walk all circuits and reset any spf specific flags */ - for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit)) - UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF); - - return; + struct listnode *node; + struct isis_circuit *circuit; + + if (area->is_type == IS_LEVEL_1) + isis_route_validate_table(area, area->route_table[0]); + else if (area->is_type == IS_LEVEL_2) + isis_route_validate_table(area, area->route_table[1]); + else + isis_route_validate_merge(area, AF_INET); + + if (area->is_type == IS_LEVEL_1) + isis_route_validate_table(area, area->route_table6[0]); + else if (area->is_type == IS_LEVEL_2) + isis_route_validate_table(area, area->route_table6[1]); + else + isis_route_validate_merge(area, AF_INET6); + + if (!area->circuit_list) { + return; + } + /* walk all circuits and reset any spf specific flags */ + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) + UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF); + + return; } -void -isis_route_invalidate_table (struct isis_area *area, struct route_table *table) +void isis_route_invalidate_table(struct isis_area *area, + struct route_table *table) { - struct route_node *rode; - struct isis_route_info *rinfo; - for (rode = route_top (table); rode; rode = route_next (rode)) - { - if (rode->info == NULL) - continue; - rinfo = rode->info; - - UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); - } + struct route_node *rode; + struct isis_route_info *rinfo; + for (rode = route_top(table); rode; rode = route_next(rode)) { + if (rode->info == NULL) + continue; + rinfo = rode->info; + + UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); + } } -void -isis_route_invalidate (struct isis_area *area) +void isis_route_invalidate(struct isis_area *area) { - if (area->is_type & IS_LEVEL_1) - isis_route_invalidate_table (area, area->route_table[0]); - if (area->is_type & IS_LEVEL_2) - isis_route_invalidate_table (area, area->route_table[1]); + if (area->is_type & IS_LEVEL_1) + isis_route_invalidate_table(area, area->route_table[0]); + if (area->is_type & IS_LEVEL_2) + isis_route_invalidate_table(area, area->route_table[1]); } |
