Skip to content

Commit

Permalink
ipv4: tcp: dont cache output dst for syncookies
Browse files Browse the repository at this point in the history
Don't cache output dst for syncookies, as this adds pressure on IP route
cache and rcu subsystem for no gain.

Signed-off-by: Eric Dumazet <[email protected]>
Cc: Hans Schillstrom <[email protected]>
Signed-off-by: Jesper Dangaard Brouer <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Eric Dumazet authored and davem330 committed Jun 23, 2012
1 parent 24ea818 commit 7586ece
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 10 deletions.
1 change: 1 addition & 0 deletions include/net/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct flowi_common {
#define FLOWI_FLAG_ANYSRC 0x01
#define FLOWI_FLAG_PRECOW_METRICS 0x02
#define FLOWI_FLAG_CAN_SLEEP 0x04
#define FLOWI_FLAG_RT_NOCACHE 0x08
__u32 flowic_secid;
};

Expand Down
3 changes: 2 additions & 1 deletion include/net/inet_connection_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ extern int inet_csk_get_port(struct sock *sk, unsigned short snum);

extern struct dst_entry* inet_csk_route_req(struct sock *sk,
struct flowi4 *fl4,
const struct request_sock *req);
const struct request_sock *req,
bool nocache);
extern struct dst_entry* inet_csk_route_child_sock(struct sock *sk,
struct sock *newsk,
const struct request_sock *req);
Expand Down
2 changes: 1 addition & 1 deletion net/dccp/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
struct dst_entry *dst;
struct flowi4 fl4;

dst = inet_csk_route_req(sk, &fl4, req);
dst = inet_csk_route_req(sk, &fl4, req, false);
if (dst == NULL)
goto out;

Expand Down
8 changes: 6 additions & 2 deletions net/ipv4/inet_connection_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,17 +368,21 @@ EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);

struct dst_entry *inet_csk_route_req(struct sock *sk,
struct flowi4 *fl4,
const struct request_sock *req)
const struct request_sock *req,
bool nocache)
{
struct rtable *rt;
const struct inet_request_sock *ireq = inet_rsk(req);
struct ip_options_rcu *opt = inet_rsk(req)->opt;
struct net *net = sock_net(sk);
int flags = inet_sk_flowi_flags(sk) & ~FLOWI_FLAG_PRECOW_METRICS;

if (nocache)
flags |= FLOWI_FLAG_RT_NOCACHE;
flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
sk->sk_protocol,
inet_sk_flowi_flags(sk) & ~FLOWI_FLAG_PRECOW_METRICS,
flags,
(opt && opt->opt.srr) ? opt->opt.faddr : ireq->rmt_addr,
ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport);
security_req_classify_flow(req, flowi4_to_flowi(fl4));
Expand Down
5 changes: 4 additions & 1 deletion net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,7 @@ static struct rtable *rt_intern_hash(unsigned int hash, struct rtable *rt,
candp = NULL;
now = jiffies;

if (!rt_caching(dev_net(rt->dst.dev))) {
if (!rt_caching(dev_net(rt->dst.dev)) || (rt->dst.flags & DST_NOCACHE)) {
/*
* If we're not caching, just tell the caller we
* were successful and don't touch the route. The
Expand Down Expand Up @@ -2582,6 +2582,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res,

rt_set_nexthop(rth, fl4, res, fi, type, 0);

if (fl4->flowi4_flags & FLOWI_FLAG_RT_NOCACHE)
rth->dst.flags |= DST_NOCACHE;

return rth;
}

Expand Down
12 changes: 7 additions & 5 deletions net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,15 +825,16 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst,
struct request_sock *req,
struct request_values *rvp,
u16 queue_mapping)
u16 queue_mapping,
bool nocache)
{
const struct inet_request_sock *ireq = inet_rsk(req);
struct flowi4 fl4;
int err = -1;
struct sk_buff * skb;

/* First, grab a route. */
if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL)
if (!dst && (dst = inet_csk_route_req(sk, &fl4, req, nocache)) == NULL)
return -1;

skb = tcp_make_synack(sk, dst, req, rvp);
Expand All @@ -855,7 +856,7 @@ static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req,
struct request_values *rvp)
{
TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
return tcp_v4_send_synack(sk, NULL, req, rvp, 0);
return tcp_v4_send_synack(sk, NULL, req, rvp, 0, false);
}

/*
Expand Down Expand Up @@ -1388,7 +1389,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
*/
if (tmp_opt.saw_tstamp &&
tcp_death_row.sysctl_tw_recycle &&
(dst = inet_csk_route_req(sk, &fl4, req)) != NULL &&
(dst = inet_csk_route_req(sk, &fl4, req, want_cookie)) != NULL &&
fl4.daddr == saddr &&
(peer = rt_get_peer((struct rtable *)dst, fl4.daddr)) != NULL) {
inet_peer_refcheck(peer);
Expand Down Expand Up @@ -1424,7 +1425,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)

if (tcp_v4_send_synack(sk, dst, req,
(struct request_values *)&tmp_ext,
skb_get_queue_mapping(skb)) ||
skb_get_queue_mapping(skb),
want_cookie) ||
want_cookie)
goto drop_and_free;

Expand Down

0 comments on commit 7586ece

Please sign in to comment.