summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2019-08-06 22:43:46 +0200
committerRenato Westphal <renato@opensourcerouting.org>2019-08-21 06:04:03 +0200
commit363be4dd90bd8c0b9f6f045f0cf2391f1e456229 (patch)
treeb5b6fc4952faa61fdc91bf964598a7681c6128dd
parentisisd: reuse the nexthop lookup functions to avoid code duplication (diff)
downloadfrr-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.c1
-rw-r--r--isisd/isis_memory.h1
-rw-r--r--isisd/isis_route.c238
-rw-r--r--isisd/isis_route.h10
-rw-r--r--isisd/isis_zebra.c60
-rw-r--r--isisd/isisd.c1
-rw-r--r--isisd/isisd.h3
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 */