aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTom Herbert <tom@herbertland.com>2016-12-14 19:54:16 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-17 11:13:19 -0500
commit0643ee4fd1b79c1af3bd7bc8968dbf5fd047f490 (patch)
treeddae48385faf13e6537d82b1f72cff8553456a9a /include
parent9af7e923fdd82dc25ad5ea75e24e92708947f961 (diff)
inet: Fix get port to handle zero port number with soreuseport set
A user may call listen with binding an explicit port with the intent that the kernel will assign an available port to the socket. In this case inet_csk_get_port does a port scan. For such sockets, the user may also set soreuseport with the intent a creating more sockets for the port that is selected. The problem is that the initial socket being opened could inadvertently choose an existing and unreleated port number that was already created with soreuseport. This patch adds a boolean parameter to inet_bind_conflict that indicates rather soreuseport is allowed for the check (in addition to sk->sk_reuseport). In calls to inet_bind_conflict from inet_csk_get_port the argument is set to true if an explicit port is being looked up (snum argument is nonzero), and is false if port scan is done. Signed-off-by: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/inet6_connection_sock.h3
-rw-r--r--include/net/inet_connection_sock.h6
2 files changed, 6 insertions, 3 deletions
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
index 954ad6bfb56a..3212b39b5bfc 100644
--- a/include/net/inet6_connection_sock.h
+++ b/include/net/inet6_connection_sock.h
@@ -22,7 +22,8 @@ struct sock;
22struct sockaddr; 22struct sockaddr;
23 23
24int inet6_csk_bind_conflict(const struct sock *sk, 24int inet6_csk_bind_conflict(const struct sock *sk,
25 const struct inet_bind_bucket *tb, bool relax); 25 const struct inet_bind_bucket *tb, bool relax,
26 bool soreuseport_ok);
26 27
27struct dst_entry *inet6_csk_route_req(const struct sock *sk, struct flowi6 *fl6, 28struct dst_entry *inet6_csk_route_req(const struct sock *sk, struct flowi6 *fl6,
28 const struct request_sock *req, u8 proto); 29 const struct request_sock *req, u8 proto);
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 146054ceea8e..85ee3879499e 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -63,7 +63,8 @@ struct inet_connection_sock_af_ops {
63#endif 63#endif
64 void (*addr2sockaddr)(struct sock *sk, struct sockaddr *); 64 void (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
65 int (*bind_conflict)(const struct sock *sk, 65 int (*bind_conflict)(const struct sock *sk,
66 const struct inet_bind_bucket *tb, bool relax); 66 const struct inet_bind_bucket *tb,
67 bool relax, bool soreuseport_ok);
67 void (*mtu_reduced)(struct sock *sk); 68 void (*mtu_reduced)(struct sock *sk);
68}; 69};
69 70
@@ -261,7 +262,8 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk,
261struct sock *inet_csk_accept(struct sock *sk, int flags, int *err); 262struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
262 263
263int inet_csk_bind_conflict(const struct sock *sk, 264int inet_csk_bind_conflict(const struct sock *sk,
264 const struct inet_bind_bucket *tb, bool relax); 265 const struct inet_bind_bucket *tb, bool relax,
266 bool soreuseport_ok);
265int inet_csk_get_port(struct sock *sk, unsigned short snum); 267int inet_csk_get_port(struct sock *sk, unsigned short snum);
266 268
267struct dst_entry *inet_csk_route_req(const struct sock *sk, struct flowi4 *fl4, 269struct dst_entry *inet_csk_route_req(const struct sock *sk, struct flowi4 *fl4,