fix reuseaddr regression
Subsystems (4)
cover fix reuseaddr regression
I introduced a regression when reworking the fastreuse port stuff that allows bind conflicts to occur once a reuseaddr socket successfully opens on an existing tb. The root cause is I reversed an if statement which caused us to set the tb as if there were no owners on the socket if there were, which obviously is not correct.
Dave I have follow up patches that will add a selftest for this case and I ran the other reuseport related tests as well. These need to go in pretty quickly as it breaks kvm, I've marked them for stable. Sorry for the regression,
Josef
PATCH 1/3 net: set tb->fast_sk_family
From: Josef Bacik <[email protected]>
We need to set the tb->fast_sk_family properly so we can use the proper comparison function for all subsequent reuseport bind requests.
--- net/ipv4/inet_connection_sock.c | 2 ++ 1 file changed, 2 insertions(+)
net/ipv4/inet_connection_sock.c +2 -0
@@ -328,6 +328,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) tb->fastuid = uid; tb->fast_rcv_saddr = sk->sk_rcv_saddr; tb->fast_ipv6_only =ipv6_only_sock (sk); + tb->fast_sk_family = sk->sk_family;#if IS_ENABLED (CONFIG_IPV6 ) tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr;#endif
@@ -354,6 +355,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) tb->fastuid = uid; tb->fast_rcv_saddr = sk->sk_rcv_saddr; tb->fast_ipv6_only =ipv6_only_sock (sk); + tb->fast_sk_family = sk->sk_family;#if IS_ENABLED (CONFIG_IPV6 ) tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr;#endif
Signature · 1 line
2.7.4
PATCH 2/3 net: use inet6_rcv_saddr to compare sockets
In reply to [email protected]From: Josef Bacik <[email protected]>
In ipv6_rcv_saddr_equal() we need to use inet6_rcv_saddr(sk) for the ipv6 compare with the fast socket information to make sure we're doing the proper comparisons.
--- net/ipv4/inet_connection_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/inet_connection_sock.c +1 -1
@@ -266,7 +266,7 @@ static inline int sk_reuseport_match(struct inet_bind_bucket *tb,#if IS_ENABLED (CONFIG_IPV6 )if (tb->fast_sk_family ==AF_INET6 ) return ipv6_rcv_saddr_equal(&tb->fast_v6_rcv_saddr, - &sk->sk_v6_rcv_saddr, + inet6_rcv_saddr(sk), tb->fast_rcv_saddr, sk->sk_rcv_saddr, tb->fast_ipv6_only,
Signature · 1 line
2.7.4
PATCH 3/3 inet: fix improper empty comparison
In reply to [email protected]From: Josef Bacik <[email protected]>
When doing my reuseport rework I screwed up and changed a
if (hlist_empty(&tb->owners))
to
if (!hlist_empty(&tb->owners))
This is obviously bad as all of the reuseport/reuse logic was reversed, which caused weird problems like allowing an ipv4 bind conflict if we opened an ipv4 only socket on a port followed by an ipv6 only socket on the same port.
--- net/ipv4/inet_connection_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/inet_connection_sock.c +1 -1
@@ -321,7 +321,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) goto fail_unlock; } success: -if (!hlist_empty (&tb->owners)) { +if (hlist_empty (&tb->owners)) { tb->fastreuse = reuse;if (sk->sk_reuseport) { tb->fastreuseport =FASTREUSEPORT_ANY ;
Signature · 1 line
2.7.4
Quoted 10 lines · On 09/18/2017 12:28 PM, [email protected] wrote:
I introduced a regression when reworking the fastreuse port stuff that allows bind conflicts to occur once a reuseaddr socket successfully opens on an existing tb. The root cause is I reversed an if statement which caused us to set the tb as if there were no owners on the socket if there were, which obviously is not correct.
Dave I have follow up patches that will add a selftest for this case and I ran the other reuseport related tests as well. These need to go in pretty quickly as it breaks kvm, I've marked them for stable. Sorry for the regression,
To clarify, it doesn't really break KVM specifically, but it breaks a port collision detection idiom that libvirt depends on to successfully launch qemu/xen/... VMs in certain cases.
Thanks,
Cole
David Miller
maintainerFrom: [email protected]
Date: Mon, 18 Sep 2017 12:28:54 -0400
Quoted 9 lines
I introduced a regression when reworking the fastreuse port stuff that allows bind conflicts to occur once a reuseaddr socket successfully opens on an existing tb. The root cause is I reversed an if statement which caused us to set the tb as if there were no owners on the socket if there were, which obviously is not correct.
Dave I have follow up patches that will add a selftest for this case and I ran the other reuseport related tests as well. These need to go in pretty quickly as it breaks kvm, I've marked them for stable. Sorry for the regression,
First, please fix your "From: " field so that it actually has your full name rather than just your email address. This matter when I apply your patches.
Second, remove the stable CC:. For networking changes, you simply ask me to queue the changes up for -stable.
Thanks.
Quoted 13 lines · David Miller
From: [email protected]
Date: Mon, 18 Sep 2017 12:28:54 -0400Quoted 9 lines
I introduced a regression when reworking the fastreuse port stuff that allows bind conflicts to occur once a reuseaddr socket successfully opens on an existing tb. The root cause is I reversed an if statement which caused us to set the tb as if there were no owners on the socket if there were, which obviously is not correct.
Dave I have follow up patches that will add a selftest for this case and I ran the other reuseport related tests as well. These need to go in pretty quickly as it breaks kvm, I've marked them for stable. Sorry for the regression,
Quoted 7 lines
First, please fix your "From: " field so that it actually has your full name rather than just your email address. This matter when I apply your patches.
Second, remove the stable CC:. For networking changes, you simply ask me to queue the changes up for -stable.
Sorry Dave, I've fixed my git email settings and I droped the stable cc and sent a new round. Didn't see this until just now, my bad.
Josef