Commit 4fab9071 authored by Neal Cardwell's avatar Neal Cardwell Committed by David S. Miller

tcp: fix tcp_release_cb() to dispatch via address family for mtu_reduced()

Make sure we use the correct address-family-specific function for
handling MTU reductions from within tcp_release_cb().

Previously AF_INET6 sockets were incorrectly always using the IPv6
code path when sometimes they were handling IPv4 traffic and thus had
an IPv4 dst.
Signed-off-by: default avatarNeal Cardwell <ncardwell@google.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Diagnosed-by: default avatarWillem de Bruijn <willemb@google.com>
Fixes: 563d34d0 ("tcp: dont drop MTU reduction indications")
Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bc8fc7b8
...@@ -62,6 +62,7 @@ struct inet_connection_sock_af_ops { ...@@ -62,6 +62,7 @@ struct inet_connection_sock_af_ops {
void (*addr2sockaddr)(struct sock *sk, struct sockaddr *); void (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
int (*bind_conflict)(const struct sock *sk, int (*bind_conflict)(const struct sock *sk,
const struct inet_bind_bucket *tb, bool relax); const struct inet_bind_bucket *tb, bool relax);
void (*mtu_reduced)(struct sock *sk);
}; };
/** inet_connection_sock - INET connection oriented sock /** inet_connection_sock - INET connection oriented sock
......
...@@ -987,7 +987,6 @@ struct proto { ...@@ -987,7 +987,6 @@ struct proto {
struct sk_buff *skb); struct sk_buff *skb);
void (*release_cb)(struct sock *sk); void (*release_cb)(struct sock *sk);
void (*mtu_reduced)(struct sock *sk);
/* Keeping track of sk's, looking them up, and port selection methods. */ /* Keeping track of sk's, looking them up, and port selection methods. */
void (*hash)(struct sock *sk); void (*hash)(struct sock *sk);
......
...@@ -448,6 +448,7 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); ...@@ -448,6 +448,7 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th);
*/ */
void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb);
void tcp_v4_mtu_reduced(struct sock *sk);
int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
struct sock *tcp_create_openreq_child(struct sock *sk, struct sock *tcp_create_openreq_child(struct sock *sk,
struct request_sock *req, struct request_sock *req,
......
...@@ -271,7 +271,7 @@ EXPORT_SYMBOL(tcp_v4_connect); ...@@ -271,7 +271,7 @@ EXPORT_SYMBOL(tcp_v4_connect);
* It can be called through tcp_release_cb() if socket was owned by user * It can be called through tcp_release_cb() if socket was owned by user
* at the time tcp_v4_err() was called to handle ICMP message. * at the time tcp_v4_err() was called to handle ICMP message.
*/ */
static void tcp_v4_mtu_reduced(struct sock *sk) void tcp_v4_mtu_reduced(struct sock *sk)
{ {
struct dst_entry *dst; struct dst_entry *dst;
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
...@@ -302,6 +302,7 @@ static void tcp_v4_mtu_reduced(struct sock *sk) ...@@ -302,6 +302,7 @@ static void tcp_v4_mtu_reduced(struct sock *sk)
tcp_simple_retransmit(sk); tcp_simple_retransmit(sk);
} /* else let the usual retransmit timer handle it */ } /* else let the usual retransmit timer handle it */
} }
EXPORT_SYMBOL(tcp_v4_mtu_reduced);
static void do_redirect(struct sk_buff *skb, struct sock *sk) static void do_redirect(struct sk_buff *skb, struct sock *sk)
{ {
...@@ -1787,6 +1788,7 @@ const struct inet_connection_sock_af_ops ipv4_specific = { ...@@ -1787,6 +1788,7 @@ const struct inet_connection_sock_af_ops ipv4_specific = {
.compat_setsockopt = compat_ip_setsockopt, .compat_setsockopt = compat_ip_setsockopt,
.compat_getsockopt = compat_ip_getsockopt, .compat_getsockopt = compat_ip_getsockopt,
#endif #endif
.mtu_reduced = tcp_v4_mtu_reduced,
}; };
EXPORT_SYMBOL(ipv4_specific); EXPORT_SYMBOL(ipv4_specific);
...@@ -2406,7 +2408,6 @@ struct proto tcp_prot = { ...@@ -2406,7 +2408,6 @@ struct proto tcp_prot = {
.sendpage = tcp_sendpage, .sendpage = tcp_sendpage,
.backlog_rcv = tcp_v4_do_rcv, .backlog_rcv = tcp_v4_do_rcv,
.release_cb = tcp_release_cb, .release_cb = tcp_release_cb,
.mtu_reduced = tcp_v4_mtu_reduced,
.hash = inet_hash, .hash = inet_hash,
.unhash = inet_unhash, .unhash = inet_unhash,
.get_port = inet_csk_get_port, .get_port = inet_csk_get_port,
......
...@@ -800,7 +800,7 @@ void tcp_release_cb(struct sock *sk) ...@@ -800,7 +800,7 @@ void tcp_release_cb(struct sock *sk)
__sock_put(sk); __sock_put(sk);
} }
if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) { if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) {
sk->sk_prot->mtu_reduced(sk); inet_csk(sk)->icsk_af_ops->mtu_reduced(sk);
__sock_put(sk); __sock_put(sk);
} }
} }
......
...@@ -1595,6 +1595,7 @@ static const struct inet_connection_sock_af_ops ipv6_specific = { ...@@ -1595,6 +1595,7 @@ static const struct inet_connection_sock_af_ops ipv6_specific = {
.compat_setsockopt = compat_ipv6_setsockopt, .compat_setsockopt = compat_ipv6_setsockopt,
.compat_getsockopt = compat_ipv6_getsockopt, .compat_getsockopt = compat_ipv6_getsockopt,
#endif #endif
.mtu_reduced = tcp_v6_mtu_reduced,
}; };
#ifdef CONFIG_TCP_MD5SIG #ifdef CONFIG_TCP_MD5SIG
...@@ -1625,6 +1626,7 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = { ...@@ -1625,6 +1626,7 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = {
.compat_setsockopt = compat_ipv6_setsockopt, .compat_setsockopt = compat_ipv6_setsockopt,
.compat_getsockopt = compat_ipv6_getsockopt, .compat_getsockopt = compat_ipv6_getsockopt,
#endif #endif
.mtu_reduced = tcp_v4_mtu_reduced,
}; };
#ifdef CONFIG_TCP_MD5SIG #ifdef CONFIG_TCP_MD5SIG
...@@ -1864,7 +1866,6 @@ struct proto tcpv6_prot = { ...@@ -1864,7 +1866,6 @@ struct proto tcpv6_prot = {
.sendpage = tcp_sendpage, .sendpage = tcp_sendpage,
.backlog_rcv = tcp_v6_do_rcv, .backlog_rcv = tcp_v6_do_rcv,
.release_cb = tcp_release_cb, .release_cb = tcp_release_cb,
.mtu_reduced = tcp_v6_mtu_reduced,
.hash = tcp_v6_hash, .hash = tcp_v6_hash,
.unhash = inet_unhash, .unhash = inet_unhash,
.get_port = inet_csk_get_port, .get_port = inet_csk_get_port,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment