ipv4: Rearrange how ip_route_newports() gets port keys.
ip_route_newports() is the only place in the entire kernel that cares about the port members in the routing cache entry's lookup flow key. Therefore the only reason we store an entire flow inside of the struct rtentry is for this one special case. Rewrite ip_route_newports() such that: 1) The caller passes in the original port values, so we don't need to use the rth->fl.fl_ip_{s,d}port values to remember them. 2) The lookup flow is constructed by hand instead of being copied from the routing cache entry's flow. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
33765d0603
commit
dca8b089c9
|
@ -200,16 +200,19 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
|
|||
}
|
||||
|
||||
static inline int ip_route_newports(struct rtable **rp, u8 protocol,
|
||||
__be16 orig_sport, __be16 orig_dport,
|
||||
__be16 sport, __be16 dport, struct sock *sk)
|
||||
{
|
||||
if (sport != (*rp)->fl.fl_ip_sport ||
|
||||
dport != (*rp)->fl.fl_ip_dport) {
|
||||
struct flowi fl;
|
||||
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,
|
||||
.fl_ip_sport = sport,
|
||||
.fl_ip_dport = dport };
|
||||
|
||||
memcpy(&fl, &(*rp)->fl, sizeof(fl));
|
||||
fl.fl_ip_sport = sport;
|
||||
fl.fl_ip_dport = dport;
|
||||
fl.proto = protocol;
|
||||
if (inet_sk(sk)->transparent)
|
||||
fl.flags |= FLOWI_FLAG_ANYSRC;
|
||||
if (protocol == IPPROTO_TCP)
|
||||
|
|
|
@ -43,6 +43,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
|||
struct inet_sock *inet = inet_sk(sk);
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
|
||||
__be16 orig_sport, orig_dport;
|
||||
struct rtable *rt;
|
||||
__be32 daddr, nexthop;
|
||||
int tmp;
|
||||
|
@ -63,10 +64,12 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
|||
nexthop = inet->opt->faddr;
|
||||
}
|
||||
|
||||
orig_sport = inet->inet_sport;
|
||||
orig_dport = usin->sin_port;
|
||||
tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr,
|
||||
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
|
||||
IPPROTO_DCCP,
|
||||
inet->inet_sport, usin->sin_port, sk, 1);
|
||||
orig_sport, orig_dport, sk, 1);
|
||||
if (tmp < 0)
|
||||
return tmp;
|
||||
|
||||
|
@ -99,8 +102,9 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
|||
if (err != 0)
|
||||
goto failure;
|
||||
|
||||
err = ip_route_newports(&rt, IPPROTO_DCCP, inet->inet_sport,
|
||||
inet->inet_dport, sk);
|
||||
err = ip_route_newports(&rt, IPPROTO_DCCP,
|
||||
orig_sport, orig_dport,
|
||||
inet->inet_sport, inet->inet_dport, sk);
|
||||
if (err != 0)
|
||||
goto failure;
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
|||
struct inet_sock *inet = inet_sk(sk);
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
|
||||
__be16 orig_sport, orig_dport;
|
||||
struct rtable *rt;
|
||||
__be32 daddr, nexthop;
|
||||
int tmp;
|
||||
|
@ -167,10 +168,12 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
|||
nexthop = inet->opt->faddr;
|
||||
}
|
||||
|
||||
orig_sport = inet->inet_sport;
|
||||
orig_dport = usin->sin_port;
|
||||
tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr,
|
||||
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
|
||||
IPPROTO_TCP,
|
||||
inet->inet_sport, usin->sin_port, sk, 1);
|
||||
orig_sport, orig_dport, sk, 1);
|
||||
if (tmp < 0) {
|
||||
if (tmp == -ENETUNREACH)
|
||||
IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
|
||||
|
@ -234,6 +237,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
|||
goto failure;
|
||||
|
||||
err = ip_route_newports(&rt, IPPROTO_TCP,
|
||||
orig_sport, orig_dport,
|
||||
inet->inet_sport, inet->inet_dport, sk);
|
||||
if (err)
|
||||
goto failure;
|
||||
|
|
Loading…
Reference in a new issue