[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20110312.163803.58428227.davem@davemloft.net>
Date: Sat, 12 Mar 2011 16:38:03 -0800 (PST)
From: David Miller <davem@...emloft.net>
To: netdev@...r.kernel.org
Subject: [PATCH v4 RFC 8/8] ipv4: Use caller's on-stack flowi as-is in
output route lookups.
Signed-off-by: David S. Miller <davem@...emloft.net>
---
include/net/route.h | 2 +-
net/ipv4/route.c | 134 ++++++++++++++++++++++++--------------------------
2 files changed, 65 insertions(+), 71 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 154e589..304cd6c 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -117,7 +117,7 @@ extern int ip_rt_init(void);
extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how);
-extern struct rtable *__ip_route_output_key(struct net *, const struct flowi4 *flp);
+extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
struct sock *sk);
extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 21fb343..ab0053b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1037,7 +1037,7 @@ static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
return mtu;
}
-static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
+static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
struct fib_info *fi)
{
struct inet_peer *peer;
@@ -1046,7 +1046,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
/* If a peer entry exists for this destination, we must hook
* it up in order to get at cached metrics.
*/
- if (oldflp4 && (oldflp4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS))
+ if (fl4 && (fl4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS))
create = 1;
rt->peer = peer = inet_getpeer_v4(rt->rt_dst, create);
@@ -1073,7 +1073,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
}
}
-static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
+static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *fl4,
const struct fib_result *res,
struct fib_info *fi, u16 type, u32 itag)
{
@@ -1083,7 +1083,7 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
if (FIB_RES_GW(*res) &&
FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
rt->rt_gateway = FIB_RES_GW(*res);
- rt_init_metrics(rt, oldflp4, fi);
+ rt_init_metrics(rt, fl4, fi);
#ifdef CONFIG_IP_ROUTE_CLASSID
dst->tclassid = FIB_RES_NH(*res).nh_tclassid;
#endif
@@ -1571,12 +1571,11 @@ EXPORT_SYMBOL(ip_route_input);
/* called with rcu_read_lock() */
static struct rtable *__mkroute_output(const struct fib_result *res,
const struct flowi4 *fl4,
- const struct flowi4 *oldflp4,
struct net_device *dev_out,
unsigned int flags)
{
struct fib_info *fi = res->fi;
- u32 tos = RT_FL_TOS(oldflp4);
+ u32 tos = RT_FL_TOS(fl4);
struct in_device *in_dev;
u16 type = res->type;
struct rtable *rth;
@@ -1603,8 +1602,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
fi = NULL;
} else if (type == RTN_MULTICAST) {
flags |= RTCF_MULTICAST | RTCF_LOCAL;
- if (!ip_check_mc_rcu(in_dev, oldflp4->daddr, oldflp4->saddr,
- oldflp4->flowi4_proto))
+ if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr,
+ fl4->flowi4_proto))
flags &= ~RTCF_LOCAL;
/* If multicast route do not exist use
* default one, but do not gateway in this case.
@@ -1629,8 +1628,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
rth->rt_dst = fl4->daddr;
rth->rt_src = fl4->saddr;
rth->rt_iif = 0;
- rth->rt_oif = oldflp4->flowi4_oif;
- rth->rt_mark = oldflp4->flowi4_mark;
+ rth->rt_oif = fl4->flowi4_oif;
+ rth->rt_mark = fl4->flowi4_mark;
rth->rt_gateway = fl4->daddr;
rth->rt_spec_dst= fl4->saddr;
rth->rt_peer_genid = 0;
@@ -1653,7 +1652,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
#ifdef CONFIG_IP_MROUTE
if (type == RTN_MULTICAST) {
if (IN_DEV_MFORWARD(in_dev) &&
- !ipv4_is_local_multicast(oldflp4->daddr)) {
+ !ipv4_is_local_multicast(fl4->daddr)) {
rth->dst.input = ip_mr_input;
rth->dst.output = ip_mc_output;
}
@@ -1661,7 +1660,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
#endif
}
- rt_set_nexthop(rth, oldflp4, res, fi, type, 0);
+ rt_set_nexthop(rth, fl4, res, fi, type, 0);
return rth;
}
@@ -1670,13 +1669,12 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
* Major route resolver routine.
*/
-struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldflp4)
+struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
{
- u32 tos = RT_FL_TOS(oldflp4);
- struct flowi4 fl4;
- struct fib_result res;
- unsigned int flags = 0;
struct net_device *dev_out = NULL;
+ u32 tos = RT_FL_TOS(fl4);
+ unsigned int flags = 0;
+ struct fib_result res;
struct rtable *rth;
res.fi = NULL;
@@ -1684,21 +1682,17 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
res.r = NULL;
#endif
- fl4.flowi4_oif = oldflp4->flowi4_oif;
- fl4.flowi4_iif = net->loopback_dev->ifindex;
- fl4.flowi4_mark = oldflp4->flowi4_mark;
- fl4.daddr = oldflp4->daddr;
- fl4.saddr = oldflp4->saddr;
- fl4.flowi4_tos = tos & IPTOS_RT_MASK;
- fl4.flowi4_scope = ((tos & RTO_ONLINK) ?
- RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
+ fl4->flowi4_iif = net->loopback_dev->ifindex;
+ fl4->flowi4_tos = tos & IPTOS_RT_MASK;
+ fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
+ RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
rcu_read_lock();
- if (oldflp4->saddr) {
+ if (fl4->saddr) {
rth = ERR_PTR(-EINVAL);
- if (ipv4_is_multicast(oldflp4->saddr) ||
- ipv4_is_lbcast(oldflp4->saddr) ||
- ipv4_is_zeronet(oldflp4->saddr))
+ if (ipv4_is_multicast(fl4->saddr) ||
+ ipv4_is_lbcast(fl4->saddr) ||
+ ipv4_is_zeronet(fl4->saddr))
goto out;
/* I removed check for oif == dev_out->oif here.
@@ -1709,11 +1703,11 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
of another iface. --ANK
*/
- if (oldflp4->flowi4_oif == 0 &&
- (ipv4_is_multicast(oldflp4->daddr) ||
- ipv4_is_lbcast(oldflp4->daddr))) {
+ if (fl4->flowi4_oif == 0 &&
+ (ipv4_is_multicast(fl4->daddr) ||
+ ipv4_is_lbcast(fl4->daddr))) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- dev_out = __ip_dev_find(net, oldflp4->saddr, false);
+ dev_out = __ip_dev_find(net, fl4->saddr, false);
if (dev_out == NULL)
goto out;
@@ -1732,20 +1726,20 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
Luckily, this hack is good workaround.
*/
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
goto make_route;
}
- if (!(oldflp4->flowi4_flags & FLOWI_FLAG_ANYSRC)) {
+ if (!(fl4->flowi4_flags & FLOWI_FLAG_ANYSRC)) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- if (!__ip_dev_find(net, oldflp4->saddr, false))
+ if (!__ip_dev_find(net, fl4->saddr, false))
goto out;
}
}
- if (oldflp4->flowi4_oif) {
- dev_out = dev_get_by_index_rcu(net, oldflp4->flowi4_oif);
+ if (fl4->flowi4_oif) {
+ dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
rth = ERR_PTR(-ENODEV);
if (dev_out == NULL)
goto out;
@@ -1755,37 +1749,37 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
rth = ERR_PTR(-ENETUNREACH);
goto out;
}
- if (ipv4_is_local_multicast(oldflp4->daddr) ||
- ipv4_is_lbcast(oldflp4->daddr)) {
- if (!fl4.saddr)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_LINK);
+ if (ipv4_is_local_multicast(fl4->daddr) ||
+ ipv4_is_lbcast(fl4->daddr)) {
+ if (!fl4->saddr)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_LINK);
goto make_route;
}
- if (!fl4.saddr) {
- if (ipv4_is_multicast(oldflp4->daddr))
- fl4.saddr = inet_select_addr(dev_out, 0,
- fl4.flowi4_scope);
- else if (!oldflp4->daddr)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_HOST);
+ if (fl4->saddr) {
+ if (ipv4_is_multicast(fl4->daddr))
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ fl4->flowi4_scope);
+ else if (!fl4->daddr)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_HOST);
}
}
- if (!fl4.daddr) {
- fl4.daddr = fl4.saddr;
- if (!fl4.daddr)
- fl4.daddr = fl4.saddr = htonl(INADDR_LOOPBACK);
+ if (!fl4->daddr) {
+ fl4->daddr = fl4->saddr;
+ if (!fl4->daddr)
+ fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
dev_out = net->loopback_dev;
- fl4.flowi4_oif = net->loopback_dev->ifindex;
+ fl4->flowi4_oif = net->loopback_dev->ifindex;
res.type = RTN_LOCAL;
flags |= RTCF_LOCAL;
goto make_route;
}
- if (fib_lookup(net, &fl4, &res)) {
+ if (fib_lookup(net, fl4, &res)) {
res.fi = NULL;
- if (oldflp4->flowi4_oif) {
+ if (fl4->flowi4_oif) {
/* Apparently, routing tables are wrong. Assume,
that the destination is on link.
@@ -1804,9 +1798,9 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
likely IPv6, but we do not.
*/
- if (fl4.saddr == 0)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_LINK);
+ if (fl4->saddr == 0)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_LINK);
res.type = RTN_UNICAST;
goto make_route;
}
@@ -1815,36 +1809,36 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
}
if (res.type == RTN_LOCAL) {
- if (!fl4.saddr) {
+ if (!fl4->saddr) {
if (res.fi->fib_prefsrc)
- fl4.saddr = res.fi->fib_prefsrc;
+ fl4->saddr = res.fi->fib_prefsrc;
else
- fl4.saddr = fl4.daddr;
+ fl4->saddr = fl4->daddr;
}
dev_out = net->loopback_dev;
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
res.fi = NULL;
flags |= RTCF_LOCAL;
goto make_route;
}
#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (res.fi->fib_nhs > 1 && fl4.flowi4_oif == 0)
+ if (res.fi->fib_nhs > 1 && fl4->flowi4_oif == 0)
fib_select_multipath(&res);
else
#endif
- if (!res.prefixlen && res.type == RTN_UNICAST && !fl4.flowi4_oif)
+ if (!res.prefixlen && res.type == RTN_UNICAST && !fl4->flowi4_oif)
fib_select_default(&res);
- if (!fl4.saddr)
- fl4.saddr = FIB_RES_PREFSRC(res);
+ if (!fl4->saddr)
+ fl4->saddr = FIB_RES_PREFSRC(res);
dev_out = FIB_RES_DEV(res);
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
make_route:
- rth = __mkroute_output(&res, &fl4, oldflp4, dev_out, flags);
+ rth = __mkroute_output(&res, fl4, dev_out, flags);
if (!IS_ERR(rth))
rth = rt_finalize(rth, NULL);
--
1.7.4.1
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists