Skip to content

Commit

Permalink
Merge branch 'listener-sock-const'
Browse files Browse the repository at this point in the history
Eric Dumazet says:

====================
dccp/tcp: constify listener sock

Another patch bomb to prepare lockless TCP/DCCP LISTEN handling.

SYNACK retransmits are built and sent without listener socket
being locked. Soon, initial SYNACK packets will have same property.

This series makes sure we did not something wrong with this model,
by adding a const qualifier in all the paths taken from synack building
and transmit, for IPv4/IPv6 and TCP/dccp.

The only potential problem was the rewrite of ecn bits for connections
with DCTCP as congestion module, but this was a very minor one.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Sep 25, 2015
2 parents 6ea29da + 1b70e97 commit 4d54d86
Show file tree
Hide file tree
Showing 24 changed files with 149 additions and 106 deletions.
9 changes: 5 additions & 4 deletions include/net/dst.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,8 @@ struct flowi;
#ifndef CONFIG_XFRM
static inline struct dst_entry *xfrm_lookup(struct net *net,
struct dst_entry *dst_orig,
const struct flowi *fl, struct sock *sk,
const struct flowi *fl,
const struct sock *sk,
int flags)
{
return dst_orig;
Expand All @@ -498,7 +499,7 @@ static inline struct dst_entry *xfrm_lookup(struct net *net,
static inline struct dst_entry *xfrm_lookup_route(struct net *net,
struct dst_entry *dst_orig,
const struct flowi *fl,
struct sock *sk,
const struct sock *sk,
int flags)
{
return dst_orig;
Expand All @@ -511,11 +512,11 @@ static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)

#else
struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
const struct flowi *fl, struct sock *sk,
const struct flowi *fl, const struct sock *sk,
int flags);

struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
const struct flowi *fl, struct sock *sk,
const struct flowi *fl, const struct sock *sk,
int flags);

/* skb attached with this dst needs transformation if dst->xfrm is valid */
Expand Down
2 changes: 1 addition & 1 deletion include/net/inet6_connection_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct sockaddr;
int inet6_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb, bool relax);

struct dst_entry *inet6_csk_route_req(struct sock *sk, struct flowi6 *fl6,
struct dst_entry *inet6_csk_route_req(const struct sock *sk, struct flowi6 *fl6,
const struct request_sock *req);

struct request_sock *inet6_csk_search_req(struct sock *sk,
Expand Down
2 changes: 1 addition & 1 deletion include/net/inet_connection_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ int inet_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb, bool relax);
int inet_csk_get_port(struct sock *sk, unsigned short snum);

struct dst_entry *inet_csk_route_req(struct sock *sk, struct flowi4 *fl4,
struct dst_entry *inet_csk_route_req(const struct sock *sk, struct flowi4 *fl4,
const struct request_sock *req);
struct dst_entry *inet_csk_route_child_sock(struct sock *sk, struct sock *newsk,
const struct request_sock *req);
Expand Down
10 changes: 6 additions & 4 deletions include/net/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ int igmp_mc_init(void);
* Functions provided by ip.c
*/

int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
__be32 saddr, __be32 daddr,
struct ip_options_rcu *opt);
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
Expand Down Expand Up @@ -282,10 +282,12 @@ int ip_decrease_ttl(struct iphdr *iph)
}

static inline
int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
{
return inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO ||
(inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT &&
u8 pmtudisc = READ_ONCE(inet_sk(sk)->pmtudisc);

return pmtudisc == IP_PMTUDISC_DO ||
(pmtudisc == IP_PMTUDISC_WANT &&
!(dst_metric_locked(dst, RTAX_MTU)));
}

Expand Down
4 changes: 2 additions & 2 deletions include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
/*
* upper-layer output functions
*/
int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
struct ipv6_txoptions *opt, int tclass);

int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
Expand Down Expand Up @@ -849,7 +849,7 @@ static inline struct sk_buff *ip6_finish_skb(struct sock *sk)

int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
struct flowi6 *fl6);
struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6,
const struct in6_addr *final_dst);
struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
const struct in6_addr *final_dst);
Expand Down
4 changes: 2 additions & 2 deletions include/net/request_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct request_sock_ops {
int obj_size;
struct kmem_cache *slab;
char *slab_name;
int (*rtx_syn_ack)(struct sock *sk,
int (*rtx_syn_ack)(const struct sock *sk,
struct request_sock *req);
void (*send_ack)(struct sock *sk, struct sk_buff *skb,
struct request_sock *req);
Expand All @@ -42,7 +42,7 @@ struct request_sock_ops {
void (*syn_ack_timeout)(const struct request_sock *req);
};

int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req);
int inet_rtx_syn_ack(const struct sock *parent, struct request_sock *req);

/* struct request_sock - mini sock to represent a connection request
*/
Expand Down
2 changes: 1 addition & 1 deletion include/net/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void rt_cache_flush(struct net *net);
void rt_flush_dev(struct net_device *dev);
struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
struct sock *sk);
const struct sock *sk);
struct dst_entry *ipv4_blackhole_route(struct net *net,
struct dst_entry *dst_orig);

Expand Down
22 changes: 12 additions & 10 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb);
int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
int tcp_connect(struct sock *sk);
struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
struct request_sock *req,
struct tcp_fastopen_cookie *foc);
int tcp_disconnect(struct sock *sk, int flags);
Expand Down Expand Up @@ -1207,7 +1207,8 @@ static inline int tcp_full_space(const struct sock *sk)
}

extern void tcp_openreq_init_rwin(struct request_sock *req,
struct sock *sk, struct dst_entry *dst);
const struct sock *sk_listener,
const struct dst_entry *dst);

void tcp_enter_memory_pressure(struct sock *sk);

Expand Down Expand Up @@ -1371,16 +1372,16 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
int family, const u8 *newkey, u8 newkeylen, gfp_t gfp);
int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr,
int family);
struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk,
struct tcp_md5sig_key *tcp_v4_md5_lookup(const struct sock *sk,
const struct sock *addr_sk);

#ifdef CONFIG_TCP_MD5SIG
struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk,
struct tcp_md5sig_key *tcp_md5_do_lookup(const struct sock *sk,
const union tcp_md5_addr *addr,
int family);
#define tcp_twsk_md5_key(twsk) ((twsk)->tw_md5_key)
#else
static inline struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk,
static inline struct tcp_md5sig_key *tcp_md5_do_lookup(const struct sock *sk,
const union tcp_md5_addr *addr,
int family)
{
Expand Down Expand Up @@ -1675,15 +1676,15 @@ int tcp4_proc_init(void);
void tcp4_proc_exit(void);
#endif

int tcp_rtx_synack(struct sock *sk, struct request_sock *req);
int tcp_rtx_synack(const struct sock *sk, struct request_sock *req);
int tcp_conn_request(struct request_sock_ops *rsk_ops,
const struct tcp_request_sock_ops *af_ops,
struct sock *sk, struct sk_buff *skb);

/* TCP af-specific functions */
struct tcp_sock_af_ops {
#ifdef CONFIG_TCP_MD5SIG
struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk,
struct tcp_md5sig_key *(*md5_lookup) (const struct sock *sk,
const struct sock *addr_sk);
int (*calc_md5_hash)(char *location,
const struct tcp_md5sig_key *md5,
Expand All @@ -1698,14 +1699,15 @@ struct tcp_sock_af_ops {
struct tcp_request_sock_ops {
u16 mss_clamp;
#ifdef CONFIG_TCP_MD5SIG
struct tcp_md5sig_key *(*req_md5_lookup)(struct sock *sk,
struct tcp_md5sig_key *(*req_md5_lookup)(const struct sock *sk,
const struct sock *addr_sk);
int (*calc_md5_hash) (char *location,
const struct tcp_md5sig_key *md5,
const struct sock *sk,
const struct sk_buff *skb);
#endif
void (*init_req)(struct request_sock *req, struct sock *sk,
void (*init_req)(struct request_sock *req,
const struct sock *sk_listener,
struct sk_buff *skb);
#ifdef CONFIG_SYN_COOKIES
__u32 (*cookie_init_seq)(struct sock *sk, const struct sk_buff *skb,
Expand All @@ -1715,7 +1717,7 @@ struct tcp_request_sock_ops {
const struct request_sock *req,
bool *strict);
__u32 (*init_seq)(const struct sk_buff *skb);
int (*send_synack)(struct sock *sk, struct dst_entry *dst,
int (*send_synack)(const struct sock *sk, struct dst_entry *dst,
struct flowi *fl, struct request_sock *req,
u16 queue_mapping, struct tcp_fastopen_cookie *foc);
void (*queue_hash_add)(struct sock *sk, struct request_sock *req,
Expand Down
2 changes: 1 addition & 1 deletion net/dccp/dccp.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized);
void dccp_destroy_sock(struct sock *sk);

void dccp_close(struct sock *sk, long timeout);
struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
struct sk_buff *dccp_make_response(const struct sock *sk, struct dst_entry *dst,
struct request_sock *req);

int dccp_connect(struct sock *sk);
Expand Down
2 changes: 1 addition & 1 deletion net/dccp/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
return &rt->dst;
}

static int dccp_v4_send_response(struct sock *sk, struct request_sock *req)
static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req)
{
int err = -1;
struct sk_buff *skb;
Expand Down
2 changes: 1 addition & 1 deletion net/dccp/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
}


static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req)
{
struct inet_request_sock *ireq = inet_rsk(req);
struct ipv6_pinfo *np = inet6_sk(sk);
Expand Down
17 changes: 11 additions & 6 deletions net/dccp/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,21 +390,26 @@ int dccp_retransmit_skb(struct sock *sk)
return dccp_transmit_skb(sk, skb_clone(sk->sk_send_head, GFP_ATOMIC));
}

struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
struct sk_buff *dccp_make_response(const struct sock *sk, struct dst_entry *dst,
struct request_sock *req)
{
struct dccp_hdr *dh;
struct dccp_request_sock *dreq;
const u32 dccp_header_size = sizeof(struct dccp_hdr) +
sizeof(struct dccp_hdr_ext) +
sizeof(struct dccp_hdr_response);
struct sk_buff *skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1,
GFP_ATOMIC);
if (skb == NULL)
struct sk_buff *skb;

/* sk is marked const to clearly express we dont hold socket lock.
* sock_wmalloc() will atomically change sk->sk_wmem_alloc,
* it is safe to promote sk to non const.
*/
skb = sock_wmalloc((struct sock *)sk, MAX_DCCP_HEADER, 1,
GFP_ATOMIC);
if (!skb)
return NULL;

/* Reserve space for headers. */
skb_reserve(skb, sk->sk_prot->max_header);
skb_reserve(skb, MAX_DCCP_HEADER);

skb_dst_set(skb, dst_clone(dst));

Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/inet_connection_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
}
EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);

struct dst_entry *inet_csk_route_req(struct sock *sk,
struct dst_entry *inet_csk_route_req(const struct sock *sk,
struct flowi4 *fl4,
const struct request_sock *req)
{
Expand Down Expand Up @@ -563,7 +563,7 @@ static inline void syn_ack_recalc(struct request_sock *req, const int thresh,
req->num_timeout >= rskq_defer_accept - 1;
}

int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req)
int inet_rtx_syn_ack(const struct sock *parent, struct request_sock *req)
{
int err = req->rsk_ops->rtx_syn_ack(parent, req);

Expand Down
14 changes: 8 additions & 6 deletions net/ipv4/ip_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
* Add an ip header to a skbuff and send it out.
*
*/
int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
__be32 saddr, __be32 daddr, struct ip_options_rcu *opt)
{
struct inet_sock *inet = inet_sk(sk);
Expand All @@ -151,15 +151,17 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
iph->version = 4;
iph->ihl = 5;
iph->tos = inet->tos;
if (ip_dont_fragment(sk, &rt->dst))
iph->frag_off = htons(IP_DF);
else
iph->frag_off = 0;
iph->ttl = ip_select_ttl(inet, &rt->dst);
iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
iph->saddr = saddr;
iph->protocol = sk->sk_protocol;
ip_select_ident(sock_net(sk), skb, sk);
if (ip_dont_fragment(sk, &rt->dst)) {
iph->frag_off = htons(IP_DF);
iph->id = 0;
} else {
iph->frag_off = 0;
__ip_select_ident(sock_net(sk), iph, 1);
}

if (opt && opt->opt.optlen) {
iph->ihl += opt->opt.optlen>>2;
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2291,7 +2291,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
}

struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
struct sock *sk)
const struct sock *sk)
{
struct rtable *rt = __ip_route_output_key(net, flp4);

Expand Down
12 changes: 10 additions & 2 deletions net/ipv4/tcp_cong.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ void tcp_assign_congestion_control(struct sock *sk)
*/
if (ca->get_info)
memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
if (ca->flags & TCP_CONG_NEEDS_ECN)
INET_ECN_xmit(sk);
else
INET_ECN_dontxmit(sk);
}

void tcp_init_congestion_control(struct sock *sk)
Expand All @@ -181,6 +185,10 @@ void tcp_init_congestion_control(struct sock *sk)

if (icsk->icsk_ca_ops->init)
icsk->icsk_ca_ops->init(sk);
if (tcp_ca_needs_ecn(sk))
INET_ECN_xmit(sk);
else
INET_ECN_dontxmit(sk);
}

static void tcp_reinit_congestion_control(struct sock *sk,
Expand All @@ -192,8 +200,8 @@ static void tcp_reinit_congestion_control(struct sock *sk,
icsk->icsk_ca_ops = ca;
icsk->icsk_ca_setsockopt = 1;

if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init)
icsk->icsk_ca_ops->init(sk);
if (sk->sk_state != TCP_CLOSE)
tcp_init_congestion_control(sk);
}

/* Manage refcounts on socket close. */
Expand Down
Loading

0 comments on commit 4d54d86

Please sign in to comment.