diff options
author | Renato Westphal <renato@opensourcerouting.org> | 2019-08-06 22:43:46 +0200 |
---|---|---|
committer | Renato Westphal <renato@opensourcerouting.org> | 2019-08-21 06:04:03 +0200 |
commit | 363be4dd90bd8c0b9f6f045f0cf2391f1e456229 (patch) | |
tree | b5b6fc4952faa61fdc91bf964598a7681c6128dd | |
parent | isisd: reuse the nexthop lookup functions to avoid code duplication (diff) | |
download | frr-363be4dd90bd8c0b9f6f045f0cf2391f1e456229.tar.xz frr-363be4dd90bd8c0b9f6f045f0cf2391f1e456229.zip |
isisd: unify isis_nexthop and isis_nexthop6 into a single struct
This unification allows us to write code that works for both IPv4 and
IPv6, reducing duplication.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
-rw-r--r-- | isisd/isis_memory.c | 1 | ||||
-rw-r--r-- | isisd/isis_memory.h | 1 | ||||
-rw-r--r-- | isisd/isis_route.c | 238 | ||||
-rw-r--r-- | isisd/isis_route.h | 10 | ||||
-rw-r--r-- | isisd/isis_zebra.c | 60 | ||||
-rw-r--r-- | isisd/isisd.c | 1 | ||||
-rw-r--r-- | isisd/isisd.h | 3 |
7 files changed, 123 insertions, 191 deletions
diff --git a/isisd/isis_memory.c b/isisd/isis_memory.c index 7d1ad6b04..272545976 100644 --- a/isisd/isis_memory.c +++ b/isisd/isis_memory.c @@ -39,7 +39,6 @@ DEFINE_MTYPE(ISISD, ISIS_SPFTREE, "ISIS SPFtree") DEFINE_MTYPE(ISISD, ISIS_VERTEX, "ISIS vertex") DEFINE_MTYPE(ISISD, ISIS_ROUTE_INFO, "ISIS route info") DEFINE_MTYPE(ISISD, ISIS_NEXTHOP, "ISIS nexthop") -DEFINE_MTYPE(ISISD, ISIS_NEXTHOP6, "ISIS nexthop6") DEFINE_MTYPE(ISISD, ISIS_DICT, "ISIS dictionary") DEFINE_MTYPE(ISISD, ISIS_DICT_NODE, "ISIS dictionary node") DEFINE_MTYPE(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route") diff --git a/isisd/isis_memory.h b/isisd/isis_memory.h index 4078c7a67..e672340e8 100644 --- a/isisd/isis_memory.h +++ b/isisd/isis_memory.h @@ -38,7 +38,6 @@ DECLARE_MTYPE(ISIS_SPFTREE) DECLARE_MTYPE(ISIS_VERTEX) DECLARE_MTYPE(ISIS_ROUTE_INFO) DECLARE_MTYPE(ISIS_NEXTHOP) -DECLARE_MTYPE(ISIS_NEXTHOP6) DECLARE_MTYPE(ISIS_DICT) DECLARE_MTYPE(ISIS_DICT_NODE) DECLARE_MTYPE(ISIS_EXT_ROUTE) diff --git a/isisd/isis_route.c b/isisd/isis_route.c index 399e5ddb9..636a63e29 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -28,6 +28,7 @@ #include "linklist.h" #include "vty.h" #include "log.h" +#include "lib_errors.h" #include "memory.h" #include "prefix.h" #include "hash.h" @@ -48,17 +49,15 @@ #include "isis_route.h" #include "isis_zebra.h" -static struct isis_nexthop * -nexthoplookup(struct list *nexthops, struct in_addr *ip, ifindex_t ifindex); -static struct isis_nexthop6 * -nexthop6lookup(struct list *nexthops6, struct in6_addr *ip6, ifindex_t ifindex); +static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family, + union g_addr *ip, ifindex_t ifindex); -static struct isis_nexthop *isis_nexthop_create(struct in_addr *ip, +static struct isis_nexthop *isis_nexthop_create(int family, union g_addr *ip, ifindex_t ifindex) { struct isis_nexthop *nexthop; - nexthop = nexthoplookup(isis->nexthops, ip, ifindex); + nexthop = nexthoplookup(isis->nexthops, family, ip, ifindex); if (nexthop) { nexthop->lock++; return nexthop; @@ -66,8 +65,9 @@ static struct isis_nexthop *isis_nexthop_create(struct in_addr *ip, nexthop = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop)); + nexthop->family = family; nexthop->ifindex = ifindex; - memcpy(&nexthop->ip, ip, sizeof(struct in_addr)); + nexthop->ip = *ip; listnode_add(isis->nexthops, nexthop); nexthop->lock++; @@ -85,107 +85,79 @@ static void isis_nexthop_delete(struct isis_nexthop *nexthop) return; } -static struct isis_nexthop *nexthoplookup(struct list *nexthops, - struct in_addr *ip, ifindex_t ifindex) +static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family, + union g_addr *ip, ifindex_t ifindex) { 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 nh; - } - - return NULL; -} - -static struct isis_nexthop6 *isis_nexthop6_new(struct in6_addr *ip6, - ifindex_t ifindex) -{ - struct isis_nexthop6 *nexthop6; - - nexthop6 = XCALLOC(MTYPE_ISIS_NEXTHOP6, sizeof(struct isis_nexthop6)); - - nexthop6->ifindex = ifindex; - memcpy(&nexthop6->ip6, ip6, sizeof(struct in6_addr)); - nexthop6->lock++; - - return nexthop6; -} - -static struct isis_nexthop6 *isis_nexthop6_create(struct in6_addr *ip6, - ifindex_t ifindex) -{ - struct isis_nexthop6 *nexthop6; - - nexthop6 = nexthop6lookup(isis->nexthops6, ip6, ifindex); - if (nexthop6) { - nexthop6->lock++; - return nexthop6; - } - - nexthop6 = isis_nexthop6_new(ip6, ifindex); - - return 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); - } - - return; -} + if (nh->family != family) + continue; + if (nh->ifindex != ifindex) + continue; -static struct isis_nexthop6 * -nexthop6lookup(struct list *nexthops6, struct in6_addr *ip6, ifindex_t ifindex) -{ - struct listnode *node; - struct isis_nexthop6 *nh6; + switch (family) { + case AF_INET: + if (IPV4_ADDR_CMP(&nh->ip.ipv4, &ip->ipv4)) + continue; + break; + case AF_INET6: + if (IPV6_ADDR_CMP(&nh->ip.ipv6, &ip->ipv6)) + continue; + break; + default: + flog_err(EC_LIB_DEVELOPMENT, + "%s: unknown address family [%d]", __func__, + family); + exit(1); + } - for (ALL_LIST_ELEMENTS_RO(nexthops6, node, nh6)) { - if (!(memcmp(ip6, &nh6->ip6, sizeof(struct in6_addr))) - && ifindex == nh6->ifindex) - return nh6; + return nh; } return NULL; } -static void adjinfo2nexthop(struct list *nexthops, struct isis_adjacency *adj) +static void adjinfo2nexthop(int family, struct list *nexthops, + struct isis_adjacency *adj) { struct isis_nexthop *nh; - - for (unsigned int i = 0; i < adj->ipv4_address_count; i++) { - struct in_addr *ipv4_addr = &adj->ipv4_addresses[i]; - if (!nexthoplookup(nexthops, ipv4_addr, - adj->circuit->interface->ifindex)) { - nh = isis_nexthop_create( - ipv4_addr, adj->circuit->interface->ifindex); - listnode_add(nexthops, nh); - return; + union g_addr ip = {}; + + switch (family) { + case AF_INET: + for (unsigned int i = 0; i < adj->ipv4_address_count; i++) { + ip.ipv4 = adj->ipv4_addresses[i]; + + if (!nexthoplookup(nexthops, AF_INET, &ip, + adj->circuit->interface->ifindex)) { + nh = isis_nexthop_create( + AF_INET, &ip, + adj->circuit->interface->ifindex); + listnode_add(nexthops, nh); + break; + } } - } -} - -static void adjinfo2nexthop6(struct list *nexthops6, struct isis_adjacency *adj) -{ - struct isis_nexthop6 *nh6; - - for (unsigned int i = 0; i < adj->ipv6_address_count; i++) { - struct in6_addr *ipv6_addr = &adj->ipv6_addresses[i]; - if (!nexthop6lookup(nexthops6, ipv6_addr, - adj->circuit->interface->ifindex)) { - nh6 = isis_nexthop6_create( - ipv6_addr, adj->circuit->interface->ifindex); - listnode_add(nexthops6, nh6); - return; + break; + case AF_INET6: + for (unsigned int i = 0; i < adj->ipv6_address_count; i++) { + ip.ipv6 = adj->ipv6_addresses[i]; + + if (!nexthoplookup(nexthops, AF_INET6, &ip, + adj->circuit->interface->ifindex)) { + nh = isis_nexthop_create( + AF_INET6, &ip, + adj->circuit->interface->ifindex); + listnode_add(nexthops, nh); + break; + } } + break; + default: + flog_err(EC_LIB_DEVELOPMENT, "%s: unknown address family [%d]", + __func__, family); + exit(1); } } @@ -201,35 +173,32 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix, 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 */ + 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 */ + switch (prefix->family) { + case AF_INET: 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 */ + break; + case AF_INET6: if (depth == 2 && prefix->prefixlen == 128 && (!src_p || !src_p->prefixlen)) { adj->router_address6 = prefix->u.prefix6; } - adjinfo2nexthop6(rinfo->nexthops6, adj); + break; + default: + flog_err(EC_LIB_DEVELOPMENT, + "%s: unknown address family [%d]", __func__, + prefix->family); + exit(1); } + adjinfo2nexthop(prefix->family, rinfo->nexthops, adj); } rinfo->cost = cost; @@ -246,12 +215,6 @@ static void isis_route_info_delete(struct isis_route_info *route_info) 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); } @@ -271,7 +234,6 @@ static int isis_route_info_same(struct isis_route_info *new, { struct listnode *node; struct isis_nexthop *nexthop; - struct isis_nexthop6 *nexthop6; if (!CHECK_FLAG(old->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return 0; @@ -282,31 +244,15 @@ static int isis_route_info_same(struct isis_route_info *new, 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) - == NULL) - return 0; - - for (ALL_LIST_ELEMENTS_RO(old->nexthops, node, nexthop)) - if (nexthoplookup(new->nexthops, &nexthop->ip, - nexthop->ifindex) - == NULL) - 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; - } + for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) + if (!nexthoplookup(old->nexthops, nexthop->family, &nexthop->ip, + nexthop->ifindex)) + return 0; + + for (ALL_LIST_ELEMENTS_RO(old->nexthops, node, nexthop)) + if (!nexthoplookup(new->nexthops, nexthop->family, &nexthop->ip, + nexthop->ifindex)) + return 0; return 1; } diff --git a/isisd/isis_route.h b/isisd/isis_route.h index bb6313ad2..a20a7e038 100644 --- a/isisd/isis_route.h +++ b/isisd/isis_route.h @@ -25,15 +25,12 @@ #ifndef _ZEBRA_ISIS_ROUTE_H #define _ZEBRA_ISIS_ROUTE_H -struct isis_nexthop6 { - ifindex_t ifindex; - struct in6_addr ip6; - unsigned int lock; -}; +#include "lib/nexthop.h" struct isis_nexthop { ifindex_t ifindex; - struct in_addr ip; + int family; + union g_addr ip; unsigned int lock; }; @@ -45,7 +42,6 @@ struct isis_route_info { uint32_t cost; uint32_t depth; struct list *nexthops; - struct list *nexthops6; }; struct isis_route_info *isis_route_create(struct prefix *prefix, diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index e2ef93469..e8481a558 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -27,6 +27,7 @@ #include "command.h" #include "memory.h" #include "log.h" +#include "lib_errors.h" #include "if.h" #include "network.h" #include "prefix.h" @@ -225,7 +226,6 @@ static void isis_zebra_route_add_route(struct prefix *prefix, struct zapi_route api; struct zapi_nexthop *api_nh; struct isis_nexthop *nexthop; - struct isis_nexthop6 *nexthop6; struct listnode *node; int count = 0; @@ -250,47 +250,41 @@ static void isis_zebra_route_add_route(struct prefix *prefix, #endif /* Nexthops */ - switch (prefix->family) { - case AF_INET: - for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, - nexthop)) { - if (count >= MULTIPATH_NUM) - break; - api_nh = &api.nexthops[count]; - if (fabricd) - api_nh->onlink = true; - api_nh->vrf_id = VRF_DEFAULT; + for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, nexthop)) { + if (count >= MULTIPATH_NUM) + break; + api_nh = &api.nexthops[count]; + if (fabricd) + api_nh->onlink = true; + api_nh->vrf_id = VRF_DEFAULT; + + switch (nexthop->family) { + case AF_INET: /* FIXME: can it be ? */ - if (nexthop->ip.s_addr != INADDR_ANY) { + if (nexthop->ip.ipv4.s_addr != INADDR_ANY) { api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; - api_nh->gate.ipv4 = nexthop->ip; + api_nh->gate.ipv4 = nexthop->ip.ipv4; } else { api_nh->type = NEXTHOP_TYPE_IFINDEX; } - api_nh->ifindex = nexthop->ifindex; - count++; - } - break; - case AF_INET6: - for (ALL_LIST_ELEMENTS_RO(route_info->nexthops6, node, - nexthop6)) { - if (count >= MULTIPATH_NUM) - break; - if (!IN6_IS_ADDR_LINKLOCAL(&nexthop6->ip6) - && !IN6_IS_ADDR_UNSPECIFIED(&nexthop6->ip6)) { + break; + case AF_INET6: + if (!IN6_IS_ADDR_LINKLOCAL(&nexthop->ip.ipv6) + && !IN6_IS_ADDR_UNSPECIFIED(&nexthop->ip.ipv6)) { continue; } - - api_nh = &api.nexthops[count]; - if (fabricd) - api_nh->onlink = true; - api_nh->vrf_id = VRF_DEFAULT; - api_nh->gate.ipv6 = nexthop6->ip6; - api_nh->ifindex = nexthop6->ifindex; + api_nh->gate.ipv6 = nexthop->ip.ipv6; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; - count++; + break; + default: + flog_err(EC_LIB_DEVELOPMENT, + "%s: unknown address family [%d]", __func__, + nexthop->family); + exit(1); } - break; + + api_nh->ifindex = nexthop->ifindex; + count++; } if (!count) return; diff --git a/isisd/isisd.c b/isisd/isisd.c index bee3b6deb..67f557ab5 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -88,7 +88,6 @@ void isis_new(unsigned long process_id) isis->init_circ_list = list_new(); isis->uptime = time(NULL); isis->nexthops = list_new(); - isis->nexthops6 = list_new(); dyn_cache_init(); /* * uncomment the next line for full debugs diff --git a/isisd/isisd.h b/isisd/isisd.h index f8486ae0d..393b1d67c 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -69,8 +69,7 @@ struct isis { uint32_t router_id; /* Router ID from zebra */ struct list *area_list; /* list of IS-IS areas */ struct list *init_circ_list; - struct list *nexthops; /* IPv4 next hops from this IS */ - struct list *nexthops6; /* IPv6 next hops from this IS */ + struct list *nexthops; /* IP next hops from this IS */ uint8_t max_area_addrs; /* maximumAreaAdresses */ struct area_addr *man_area_addrs; /* manualAreaAddresses */ uint32_t debugs; /* bitmap for debug */ |