summaryrefslogtreecommitdiff
path: root/zebra/rt_socket.c
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2013-07-05 15:35:37 +0000
committerDavid Lamparter <equinox@opensourcerouting.org>2013-09-19 18:04:40 +0200
commitfa713d9ee5ed30dedd0a290be9aaff780a2896be (patch)
tree1d263cce70c341f3f2a73a47d4b1cd5a38b09129 /zebra/rt_socket.c
parentbfac8dcd2fe7ed099a679b5c8245599c6d0312ed (diff)
zebra: rework recursive route resolution
Change the datastructure for recursive routes. This brings the following benefits: By using struct nexthop also to store nexthops obtained by recursive resolution, we can get rid of quite a bit of code duplication in the fib management. (rt_netlink, rt_socket, ...) With the new datastructure we can make use of all available paths when recursive routes are resolved with multipath routes. Signed-off-by: Christian Franke <chris@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'zebra/rt_socket.c')
-rw-r--r--zebra/rt_socket.c98
1 files changed, 36 insertions, 62 deletions
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index 1b8ded7e..5d175d84 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -71,7 +71,8 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
{
struct sockaddr_in *mask = NULL;
struct sockaddr_in sin_dest, sin_mask, sin_gate;
- struct nexthop *nexthop;
+ struct nexthop *nexthop, *tnexthop;
+ int recursing;
int nexthop_num = 0;
unsigned int ifindex = 0;
int gate = 0;
@@ -96,8 +97,11 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
/* Make gateway. */
- for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
+ for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
{
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ continue;
+
gate = 0;
char gate_buf[INET_ADDRSTRLEN] = "NULL";
@@ -112,38 +116,22 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
))
{
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
+ nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
{
- if (nexthop->rtype == NEXTHOP_TYPE_IPV4 ||
- nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
- {
- sin_gate.sin_addr = nexthop->rgate.ipv4;
- gate = 1;
- }
- if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
- || nexthop->rtype == NEXTHOP_TYPE_IFNAME
- || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
- ifindex = nexthop->rifindex;
+ sin_gate.sin_addr = nexthop->gate.ipv4;
+ gate = 1;
}
- else
+ if (nexthop->type == NEXTHOP_TYPE_IFINDEX
+ || nexthop->type == NEXTHOP_TYPE_IFNAME
+ || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
+ ifindex = nexthop->ifindex;
+ if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
{
- if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
- nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
- {
- sin_gate.sin_addr = nexthop->gate.ipv4;
- gate = 1;
- }
- if (nexthop->type == NEXTHOP_TYPE_IFINDEX
- || nexthop->type == NEXTHOP_TYPE_IFNAME
- || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
- ifindex = nexthop->ifindex;
- if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
- {
- struct in_addr loopback;
- loopback.s_addr = htonl (INADDR_LOOPBACK);
- sin_gate.sin_addr = loopback;
- gate = 1;
- }
+ struct in_addr loopback;
+ loopback.s_addr = htonl (INADDR_LOOPBACK);
+ sin_gate.sin_addr = loopback;
+ gate = 1;
}
if (gate && p->prefixlen == 32)
@@ -219,7 +207,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug ("%s: odd command %s for flags %d",
__func__, lookup (rtm_type_str, cmd), nexthop->flags);
- } /* for (nexthop = ... */
+ } /* for (ALL_NEXTHOPS_RO(...))*/
/* If there was no useful nexthop, then complain. */
if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)
@@ -354,7 +342,8 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
{
struct sockaddr_in6 *mask;
struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
- struct nexthop *nexthop;
+ struct nexthop *nexthop, *tnexthop;
+ int recursing;
int nexthop_num = 0;
unsigned int ifindex = 0;
int gate = 0;
@@ -376,8 +365,11 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
/* Make gateway. */
- for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
+ for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
{
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ continue;
+
gate = 0;
if ((cmd == RTM_ADD
@@ -388,36 +380,18 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
#endif
))
{
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
- {
- if (nexthop->rtype == NEXTHOP_TYPE_IPV6
- || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
- || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
- {
- sin_gate.sin6_addr = nexthop->rgate.ipv6;
- gate = 1;
- }
- if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
- || nexthop->rtype == NEXTHOP_TYPE_IFNAME
- || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
- || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
- ifindex = nexthop->rifindex;
- }
- else
+ if (nexthop->type == NEXTHOP_TYPE_IPV6
+ || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
+ || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
{
- if (nexthop->type == NEXTHOP_TYPE_IPV6
- || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
- || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
- {
- sin_gate.sin6_addr = nexthop->gate.ipv6;
- gate = 1;
- }
- if (nexthop->type == NEXTHOP_TYPE_IFINDEX
- || nexthop->type == NEXTHOP_TYPE_IFNAME
- || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
- || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
- ifindex = nexthop->ifindex;
+ sin_gate.sin6_addr = nexthop->gate.ipv6;
+ gate = 1;
}
+ if (nexthop->type == NEXTHOP_TYPE_IFINDEX
+ || nexthop->type == NEXTHOP_TYPE_IFNAME
+ || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
+ || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
+ ifindex = nexthop->ifindex;
if (cmd == RTM_ADD)
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);