ipv4: Make output route lookup return rtable directly.

Instead of on the stack.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2011-03-02 14:31:35 -08:00
parent 452edd598f
commit b23dd4fe42
36 changed files with 267 additions and 224 deletions

View File

@@ -118,9 +118,10 @@ 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 void rt_cache_flush_batch(struct net *net);
extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp);
extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp);
extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk);
extern struct rtable *__ip_route_output_key(struct net *, const struct flowi *flp);
extern struct rtable *ip_route_output_key(struct net *, struct flowi *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi *flp,
struct sock *sk);
extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig);
extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
@@ -166,10 +167,10 @@ static inline char rt_tos2priority(u8 tos)
return ip_tos2prio[IPTOS_TOS(tos)>>1];
}
static inline int ip_route_connect(struct rtable **rp, __be32 dst,
__be32 src, u32 tos, int oif, u8 protocol,
__be16 sport, __be16 dport, struct sock *sk,
bool can_sleep)
static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos,
int oif, u8 protocol,
__be16 sport, __be16 dport,
struct sock *sk, bool can_sleep)
{
struct flowi fl = { .oif = oif,
.mark = sk->sk_mark,
@@ -179,8 +180,8 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
.proto = protocol,
.fl_ip_sport = sport,
.fl_ip_dport = dport };
int err;
struct net *net = sock_net(sk);
struct rtable *rt;
if (inet_sk(sk)->transparent)
fl.flags |= FLOWI_FLAG_ANYSRC;
@@ -190,29 +191,29 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
fl.flags |= FLOWI_FLAG_CAN_SLEEP;
if (!dst || !src) {
err = __ip_route_output_key(net, rp, &fl);
if (err)
return err;
fl.fl4_dst = (*rp)->rt_dst;
fl.fl4_src = (*rp)->rt_src;
ip_rt_put(*rp);
*rp = NULL;
rt = __ip_route_output_key(net, &fl);
if (IS_ERR(rt))
return rt;
fl.fl4_dst = rt->rt_dst;
fl.fl4_src = rt->rt_src;
ip_rt_put(rt);
}
security_sk_classify_flow(sk, &fl);
return ip_route_output_flow(net, rp, &fl, sk);
return ip_route_output_flow(net, &fl, sk);
}
static inline int ip_route_newports(struct rtable **rp, u8 protocol,
__be16 orig_sport, __be16 orig_dport,
__be16 sport, __be16 dport, struct sock *sk)
static inline struct rtable *ip_route_newports(struct rtable *rt,
u8 protocol, __be16 orig_sport,
__be16 orig_dport, __be16 sport,
__be16 dport, struct sock *sk)
{
if (sport != orig_sport || dport != orig_dport) {
struct flowi fl = { .oif = (*rp)->fl.oif,
.mark = (*rp)->fl.mark,
.fl4_dst = (*rp)->fl.fl4_dst,
.fl4_src = (*rp)->fl.fl4_src,
.fl4_tos = (*rp)->fl.fl4_tos,
.proto = (*rp)->fl.proto,
struct flowi fl = { .oif = rt->fl.oif,
.mark = rt->fl.mark,
.fl4_dst = rt->fl.fl4_dst,
.fl4_src = rt->fl.fl4_src,
.fl4_tos = rt->fl.fl4_tos,
.proto = rt->fl.proto,
.fl_ip_sport = sport,
.fl_ip_dport = dport };
@@ -220,12 +221,11 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol,
fl.flags |= FLOWI_FLAG_ANYSRC;
if (protocol == IPPROTO_TCP)
fl.flags |= FLOWI_FLAG_PRECOW_METRICS;
ip_rt_put(*rp);
*rp = NULL;
ip_rt_put(rt);
security_sk_classify_flow(sk, &fl);
return ip_route_output_flow(sock_net(sk), rp, &fl, sk);
return ip_route_output_flow(sock_net(sk), &fl, sk);
}
return 0;
return rt;
}
extern void rt_bind_peer(struct rtable *rt, int create);