public inbox for netdev@vger.kernel.org 
 help / color / mirror / Atom feed
* [net-next 0/2] export SO_REUSEADDR and SO_REUSEPORT via sock_diag
@ 2023-09-12 14:31 Jason Baron
  2023-09-12 14:31 ` [net-next 1/2] inet_diag: export SO_REUSEADDR and SO_REUSEPORT sockopts Jason Baron
  2023-09-12 14:31 ` [net-next 2/2] sock: add SO_REUSEADDR values to include/uapi/linux/socket.h Jason Baron
  0 siblings, 2 replies; 5+ messages in thread
From: Jason Baron @ 2023-09-12 14:31 UTC (permalink / raw)
  To: davem, dsahern, edumazet, kuba, pabeni; +Cc: netdev

Hi,

We've found it useful to have SO_REUSEADDR and SO_REUSEPORT
available to understand when apps cannot bind() to specific
ports. I think this would be nice to have available as part
of monitoring tools as well. I can add this to 'ss' if this
series is accepted.

Thanks,

-Jason

Jason Baron (2):
  inet_diag: export SO_REUSEADDR and SO_REUSEPORT sockopts
  sock: add SO_REUSEADDR values to include/uapi/linux/socket.h

 drivers/block/drbd/drbd_receiver.c |  6 +++---
 drivers/scsi/iscsi_tcp.c           |  2 +-
 fs/ocfs2/cluster/tcp.c             |  2 +-
 include/linux/inet_diag.h          |  2 ++
 include/net/sock.h                 | 11 -----------
 include/uapi/linux/inet_diag.h     |  7 +++++++
 include/uapi/linux/socket.h        | 11 +++++++++++
 net/core/sock.c                    |  4 ++--
 net/ipv4/af_inet.c                 |  2 +-
 net/ipv4/inet_connection_sock.c    |  4 ++--
 net/ipv4/inet_diag.c               |  7 +++++++
 net/ipv4/tcp.c                     |  6 +++---
 net/ipv6/af_inet6.c                |  2 +-
 net/netfilter/ipvs/ip_vs_sync.c    |  2 +-
 net/rds/tcp_listen.c               |  2 +-
 net/sunrpc/svcsock.c               |  2 +-
 16 files changed, 44 insertions(+), 28 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [net-next 1/2] inet_diag: export SO_REUSEADDR and SO_REUSEPORT sockopts
  2023-09-12 14:31 [net-next 0/2] export SO_REUSEADDR and SO_REUSEPORT via sock_diag Jason Baron
@ 2023-09-12 14:31 ` Jason Baron
  2023-09-12 16:26   ` Kuniyuki Iwashima
  2023-09-12 14:31 ` [net-next 2/2] sock: add SO_REUSEADDR values to include/uapi/linux/socket.h Jason Baron
  1 sibling, 1 reply; 5+ messages in thread
From: Jason Baron @ 2023-09-12 14:31 UTC (permalink / raw)
  To: davem, dsahern, edumazet, kuba, pabeni; +Cc: netdev

Add the ability to monitor SO_REUSEADDR and SO_REUSEPORT for an inet
socket. These settings are currently readable via getsockopt().
We have an app that will sometimes fail to bind() and it's helpful to
understand what other apps are causing the bind() conflict.

Signed-off-by: Jason Baron <jbaron@akamai•com>
---
 include/linux/inet_diag.h      | 2 ++
 include/uapi/linux/inet_diag.h | 7 +++++++
 net/ipv4/inet_diag.c           | 7 +++++++
 3 files changed, 16 insertions(+)

diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index 84abb30a3fbb..d05a4c26b13d 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -77,6 +77,8 @@ static inline size_t inet_diag_msg_attrs_size(void)
 #endif
 		+ nla_total_size(sizeof(struct inet_diag_sockopt))
 						     /* INET_DIAG_SOCKOPT */
+		+ nla_total_size(sizeof(struct inet_diag_reuse))
+						    /* INET_DIAG_REUSE */
 		;
 }
 int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
index 50655de04c9b..f93eeea1faba 100644
--- a/include/uapi/linux/inet_diag.h
+++ b/include/uapi/linux/inet_diag.h
@@ -161,6 +161,7 @@ enum {
 	INET_DIAG_SK_BPF_STORAGES,
 	INET_DIAG_CGROUP_ID,
 	INET_DIAG_SOCKOPT,
+	INET_DIAG_REUSE,
 	__INET_DIAG_MAX,
 };
 
@@ -201,6 +202,12 @@ struct inet_diag_sockopt {
 		unused:5;
 };
 
+struct inet_diag_reuse {
+	__u8	reuse:4,
+		reuseport:1,
+		unused:3;
+};
+
 /* INET_DIAG_VEGASINFO */
 
 struct tcpvegas_info {
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index e13a84433413..d6ebb1e612fc 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -125,6 +125,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
 			     bool net_admin)
 {
 	const struct inet_sock *inet = inet_sk(sk);
+	struct inet_diag_reuse inet_reuse = {};
 	struct inet_diag_sockopt inet_sockopt;
 
 	if (nla_put_u8(skb, INET_DIAG_SHUTDOWN, sk->sk_shutdown))
@@ -197,6 +198,12 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
 		    &inet_sockopt))
 		goto errout;
 
+	inet_reuse.reuse = sk->sk_reuse;
+	inet_reuse.reuseport = sk->sk_reuseport;
+	if (nla_put(skb, INET_DIAG_REUSE, sizeof(inet_reuse),
+		    &inet_reuse))
+		goto errout;
+
 	return 0;
 errout:
 	return 1;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [net-next 2/2] sock: add SO_REUSEADDR values to include/uapi/linux/socket.h
  2023-09-12 14:31 [net-next 0/2] export SO_REUSEADDR and SO_REUSEPORT via sock_diag Jason Baron
  2023-09-12 14:31 ` [net-next 1/2] inet_diag: export SO_REUSEADDR and SO_REUSEPORT sockopts Jason Baron
@ 2023-09-12 14:31 ` Jason Baron
  1 sibling, 0 replies; 5+ messages in thread
From: Jason Baron @ 2023-09-12 14:31 UTC (permalink / raw)
  To: davem, dsahern, edumazet, kuba, pabeni; +Cc: netdev

The settings for SO_REUSEADDR are now available via sock_diag. To
help userspace understand it's meaning let's add the values to
include/uapi/linux/socket.h. Also, rename them from SK_* to SOCK_*
to match the convention. These can also be used to interpret the
getsockopt() return value from SO_REUSEADDR.

Signed-off-by: Jason Baron <jbaron@akamai•com>
---
 drivers/block/drbd/drbd_receiver.c |  6 +++---
 drivers/scsi/iscsi_tcp.c           |  2 +-
 fs/ocfs2/cluster/tcp.c             |  2 +-
 include/net/sock.h                 | 11 -----------
 include/uapi/linux/socket.h        | 11 +++++++++++
 net/core/sock.c                    |  4 ++--
 net/ipv4/af_inet.c                 |  2 +-
 net/ipv4/inet_connection_sock.c    |  4 ++--
 net/ipv4/tcp.c                     |  6 +++---
 net/ipv6/af_inet6.c                |  2 +-
 net/netfilter/ipvs/ip_vs_sync.c    |  2 +-
 net/rds/tcp_listen.c               |  2 +-
 net/sunrpc/svcsock.c               |  2 +-
 13 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 0c9f54197768..315c3a1de0ff 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -721,7 +721,7 @@ static int prepare_listen_socket(struct drbd_connection *connection, struct acce
 		goto out;
 	}
 
-	s_listen->sk->sk_reuse = SK_CAN_REUSE; /* SO_REUSEADDR */
+	s_listen->sk->sk_reuse = SOCK_CAN_REUSE; /* SO_REUSEADDR */
 	drbd_setbufsize(s_listen, sndbuf_size, rcvbuf_size);
 
 	what = "bind before listen";
@@ -1023,8 +1023,8 @@ static int conn_connect(struct drbd_connection *connection)
 	if (ad.s_listen)
 		sock_release(ad.s_listen);
 
-	sock.socket->sk->sk_reuse = SK_CAN_REUSE; /* SO_REUSEADDR */
-	msock.socket->sk->sk_reuse = SK_CAN_REUSE; /* SO_REUSEADDR */
+	sock.socket->sk->sk_reuse = SOCK_CAN_REUSE; /* SO_REUSEADDR */
+	msock.socket->sk->sk_reuse = SOCK_CAN_REUSE; /* SO_REUSEADDR */
 
 	sock.socket->sk->sk_allocation = GFP_NOIO;
 	msock.socket->sk->sk_allocation = GFP_NOIO;
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 9ab8555180a3..163964207fa2 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -735,7 +735,7 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,
 
 	/* setup Socket parameters */
 	sk = sock->sk;
-	sk->sk_reuse = SK_CAN_REUSE;
+	sk->sk_reuse = SOCK_CAN_REUSE;
 	sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
 	sk->sk_allocation = GFP_ATOMIC;
 	sk->sk_use_task_frag = false;
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 960080753d3b..f2a7da6ea48a 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -1997,7 +1997,7 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
 	o2net_listen_sock = sock;
 	INIT_WORK(&o2net_listen_work, o2net_accept_many);
 
-	sock->sk->sk_reuse = SK_CAN_REUSE;
+	sock->sk->sk_reuse = SOCK_CAN_REUSE;
 	ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
 	if (ret < 0) {
 		printk(KERN_ERR "o2net: Error %d while binding socket at "
diff --git a/include/net/sock.h b/include/net/sock.h
index b770261fbdaf..a3b760ebf3f8 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -657,17 +657,6 @@ void sock_net_set(struct sock *sk, struct net *net)
 	write_pnet(&sk->sk_net, net);
 }
 
-/*
- * SK_CAN_REUSE and SK_NO_REUSE on a socket mean that the socket is OK
- * or not whether his port will be reused by someone else. SK_FORCE_REUSE
- * on a socket means that the socket will reuse everybody else's port
- * without looking at the other's sk_reuse value.
- */
-
-#define SK_NO_REUSE	0
-#define SK_CAN_REUSE	1
-#define SK_FORCE_REUSE	2
-
 int sk_set_peek_off(struct sock *sk, int val);
 
 static inline int sk_peek_offset(const struct sock *sk, int flags)
diff --git a/include/uapi/linux/socket.h b/include/uapi/linux/socket.h
index d3fcd3b5ec53..635ceabefada 100644
--- a/include/uapi/linux/socket.h
+++ b/include/uapi/linux/socket.h
@@ -35,4 +35,15 @@ struct __kernel_sockaddr_storage {
 #define SOCK_TXREHASH_DISABLED	0
 #define SOCK_TXREHASH_ENABLED	1
 
+/*
+ * SOCK_CAN_REUSE and SOCK_NO_REUSE on a socket mean that the socket is OK
+ * or not whether his port will be reused by someone else. SOCK_FORCE_REUSE
+ * on a socket means that the socket will reuse everybody else's port
+ * without looking at the other's sk_reuse value.
+ */
+
+#define SOCK_NO_REUSE     0
+#define SOCK_CAN_REUSE    1
+#define SOCK_FORCE_REUSE  2
+
 #endif /* _UAPI_LINUX_SOCKET_H */
diff --git a/net/core/sock.c b/net/core/sock.c
index 16584e2dd648..2a14f29c8cac 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -782,7 +782,7 @@ EXPORT_SYMBOL(sk_mc_loop);
 void sock_set_reuseaddr(struct sock *sk)
 {
 	lock_sock(sk);
-	sk->sk_reuse = SK_CAN_REUSE;
+	sk->sk_reuse = SOCK_CAN_REUSE;
 	release_sock(sk);
 }
 EXPORT_SYMBOL(sock_set_reuseaddr);
@@ -1128,7 +1128,7 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
 			sock_valbool_flag(sk, SOCK_DBG, valbool);
 		break;
 	case SO_REUSEADDR:
-		sk->sk_reuse = (valbool ? SK_CAN_REUSE : SK_NO_REUSE);
+		sk->sk_reuse = (valbool ? SOCK_CAN_REUSE : SOCK_NO_REUSE);
 		break;
 	case SO_REUSEPORT:
 		sk->sk_reuseport = valbool;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 3d2e30e20473..1abce1f1d026 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -328,7 +328,7 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
 
 	err = 0;
 	if (INET_PROTOSW_REUSE & answer_flags)
-		sk->sk_reuse = SK_CAN_REUSE;
+		sk->sk_reuse = SOCK_CAN_REUSE;
 
 	inet = inet_sk(sk);
 	inet_assign_bit(IS_ICSK, sk, INET_PROTOSW_ICSK & answer_flags);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index aeebe8816689..70bcd996b2e6 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -335,7 +335,7 @@ inet_csk_find_open_port(const struct sock *sk, struct inet_bind_bucket **tb_ret,
 
 	l3mdev = inet_sk_bound_l3mdev(sk);
 ports_exhausted:
-	attempt_half = (sk->sk_reuse == SK_CAN_REUSE) ? 1 : 0;
+	attempt_half = (sk->sk_reuse == SOCK_CAN_REUSE) ? 1 : 0;
 other_half_scan:
 	inet_sk_get_local_port_range(sk, &low, &high);
 	high++; /* [32768, 60999] -> [32768, 61000[ */
@@ -548,7 +548,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
 
 	if (!found_port) {
 		if (!hlist_empty(&tb->owners)) {
-			if (sk->sk_reuse == SK_FORCE_REUSE ||
+			if (sk->sk_reuse == SOCK_FORCE_REUSE ||
 			    (tb->fastreuse > 0 && reuse) ||
 			    sk_reuseport_match(tb, sk))
 				check_bind_conflict = false;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0c3040a63ebd..fcf69377d4cd 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3522,15 +3522,15 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
 			err = -EPERM;
 		else if (val == TCP_REPAIR_ON) {
 			tp->repair = 1;
-			sk->sk_reuse = SK_FORCE_REUSE;
+			sk->sk_reuse = SOCK_FORCE_REUSE;
 			tp->repair_queue = TCP_NO_QUEUE;
 		} else if (val == TCP_REPAIR_OFF) {
 			tp->repair = 0;
-			sk->sk_reuse = SK_NO_REUSE;
+			sk->sk_reuse = SOCK_NO_REUSE;
 			tcp_send_window_probe(sk);
 		} else if (val == TCP_REPAIR_OFF_NO_WP) {
 			tp->repair = 0;
-			sk->sk_reuse = SK_NO_REUSE;
+			sk->sk_reuse = SOCK_NO_REUSE;
 		} else
 			err = -EINVAL;
 
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 368824fe9719..cf66fe3c35b0 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -197,7 +197,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
 
 	err = 0;
 	if (INET_PROTOSW_REUSE & answer_flags)
-		sk->sk_reuse = SK_CAN_REUSE;
+		sk->sk_reuse = SOCK_CAN_REUSE;
 
 	inet = inet_sk(sk);
 	inet_assign_bit(IS_ICSK, sk, INET_PROTOSW_ICSK & answer_flags);
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index da5af28ff57b..d3a2a88d1688 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -1539,7 +1539,7 @@ static int make_receive_sock(struct netns_ipvs *ipvs, int id,
 	}
 	*sock_ret = sock;
 	/* it is equivalent to the REUSEADDR option in user-space */
-	sock->sk->sk_reuse = SK_CAN_REUSE;
+	sock->sk->sk_reuse = SOCK_CAN_REUSE;
 	result = sysctl_sync_sock_size(ipvs);
 	if (result > 0)
 		set_sock_size(sock->sk, 0, result);
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 014fa24418c1..4f3c4d7936b4 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -282,7 +282,7 @@ struct socket *rds_tcp_listen_init(struct net *net, bool isv6)
 		goto out;
 	}
 
-	sock->sk->sk_reuse = SK_CAN_REUSE;
+	sock->sk->sk_reuse = SOCK_CAN_REUSE;
 	tcp_sock_set_nodelay(sock->sk);
 
 	write_lock_bh(&sock->sk->sk_callback_lock);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 998687421fa6..bd9580900ccf 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1559,7 +1559,7 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
 	if (family == PF_INET6)
 		ip6_sock_set_v6only(sock->sk);
 	if (type == SOCK_STREAM)
-		sock->sk->sk_reuse = SK_CAN_REUSE; /* allow address reuse */
+		sock->sk->sk_reuse = SOCK_CAN_REUSE; /* allow address reuse */
 	error = kernel_bind(sock, sin, len);
 	if (error < 0)
 		goto bummer;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [net-next 1/2] inet_diag: export SO_REUSEADDR and SO_REUSEPORT sockopts
  2023-09-12 14:31 ` [net-next 1/2] inet_diag: export SO_REUSEADDR and SO_REUSEPORT sockopts Jason Baron
@ 2023-09-12 16:26   ` Kuniyuki Iwashima
  2023-09-12 18:54     ` Jason Baron
  0 siblings, 1 reply; 5+ messages in thread
From: Kuniyuki Iwashima @ 2023-09-12 16:26 UTC (permalink / raw)
  To: jbaron; +Cc: davem, dsahern, edumazet, kuba, netdev, pabeni, kuniyu

From: Jason Baron <jbaron@akamai•com>
Date: Tue, 12 Sep 2023 10:31:48 -0400
> Add the ability to monitor SO_REUSEADDR and SO_REUSEPORT for an inet
> socket. These settings are currently readable via getsockopt().
> We have an app that will sometimes fail to bind() and it's helpful to
> understand what other apps are causing the bind() conflict.

If bind() fails with -EADDRINUSE, you can find the conflicting sockets
with just the failing 2-tuple, no ?

Also, BPF iterator and bpf_sk_getsockopt() has the same functionality
with more flexibility.  (See: sol_socket_sockopt() in net/core/filter.c)


> 
> Signed-off-by: Jason Baron <jbaron@akamai•com>
> ---
>  include/linux/inet_diag.h      | 2 ++
>  include/uapi/linux/inet_diag.h | 7 +++++++
>  net/ipv4/inet_diag.c           | 7 +++++++
>  3 files changed, 16 insertions(+)
> 
> diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
> index 84abb30a3fbb..d05a4c26b13d 100644
> --- a/include/linux/inet_diag.h
> +++ b/include/linux/inet_diag.h
> @@ -77,6 +77,8 @@ static inline size_t inet_diag_msg_attrs_size(void)
>  #endif
>  		+ nla_total_size(sizeof(struct inet_diag_sockopt))
>  						     /* INET_DIAG_SOCKOPT */
> +		+ nla_total_size(sizeof(struct inet_diag_reuse))
> +						    /* INET_DIAG_REUSE */
>  		;
>  }
>  int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
> diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
> index 50655de04c9b..f93eeea1faba 100644
> --- a/include/uapi/linux/inet_diag.h
> +++ b/include/uapi/linux/inet_diag.h
> @@ -161,6 +161,7 @@ enum {
>  	INET_DIAG_SK_BPF_STORAGES,
>  	INET_DIAG_CGROUP_ID,
>  	INET_DIAG_SOCKOPT,
> +	INET_DIAG_REUSE,
>  	__INET_DIAG_MAX,
>  };
>  
> @@ -201,6 +202,12 @@ struct inet_diag_sockopt {
>  		unused:5;
>  };
>  
> +struct inet_diag_reuse {
> +	__u8	reuse:4,
> +		reuseport:1,
> +		unused:3;
> +};
> +
>  /* INET_DIAG_VEGASINFO */
>  
>  struct tcpvegas_info {
> diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
> index e13a84433413..d6ebb1e612fc 100644
> --- a/net/ipv4/inet_diag.c
> +++ b/net/ipv4/inet_diag.c
> @@ -125,6 +125,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
>  			     bool net_admin)
>  {
>  	const struct inet_sock *inet = inet_sk(sk);
> +	struct inet_diag_reuse inet_reuse = {};
>  	struct inet_diag_sockopt inet_sockopt;
>  
>  	if (nla_put_u8(skb, INET_DIAG_SHUTDOWN, sk->sk_shutdown))
> @@ -197,6 +198,12 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
>  		    &inet_sockopt))
>  		goto errout;
>  
> +	inet_reuse.reuse = sk->sk_reuse;
> +	inet_reuse.reuseport = sk->sk_reuseport;
> +	if (nla_put(skb, INET_DIAG_REUSE, sizeof(inet_reuse),
> +		    &inet_reuse))
> +		goto errout;
> +
>  	return 0;
>  errout:
>  	return 1;
> -- 
> 2.25.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [net-next 1/2] inet_diag: export SO_REUSEADDR and SO_REUSEPORT sockopts
  2023-09-12 16:26   ` Kuniyuki Iwashima
@ 2023-09-12 18:54     ` Jason Baron
  0 siblings, 0 replies; 5+ messages in thread
From: Jason Baron @ 2023-09-12 18:54 UTC (permalink / raw)
  To: Kuniyuki Iwashima; +Cc: davem, dsahern, edumazet, kuba, netdev, pabeni



On 9/12/23 12:26 PM, Kuniyuki Iwashima wrote:
> From: Jason Baron <jbaron@akamai•com>
> Date: Tue, 12 Sep 2023 10:31:48 -0400
>> Add the ability to monitor SO_REUSEADDR and SO_REUSEPORT for an inet
>> socket. These settings are currently readable via getsockopt().
>> We have an app that will sometimes fail to bind() and it's helpful to
>> understand what other apps are causing the bind() conflict.
> 
> If bind() fails with -EADDRINUSE, you can find the conflicting sockets
> with just the failing 2-tuple, no ?

True, yes one can figure out the conflicting socket as is I agree, but 
then the next step is what went wrong. For so_reuseport, you also need 
to match uid for it to work. Or if the socket is bound to different 
devices it is ok, regardless of the reuse/reuseport setting (if I read 
the code correctly)...And these other factors are currently exposed via 
sock_diag. So maybe you can deduce these via process of elimination but 
I think it could be nice to be more explicit about it.

> 
> Also, BPF iterator and bpf_sk_getsockopt() has the same functionality
> with more flexibility.  (See: sol_socket_sockopt() in net/core/filter.c)
> 
> 

True, yeah on one hand the fact that reuseport/reuseaddr are exposed via 
bpf means they are useful and reasonable to expose. On the other hand 
yeah there's an existing interface if you want to hook up bpf code. In 
the use case I had, we have a C++ application that wants to print debug 
information about the conflicting socket when the -EADDRINUSE happens 
and not necessarily have to invoke a bpf program.

Thanks,

-Jason


>>
>> Signed-off-by: Jason Baron <jbaron@akamai•com>
>> ---
>>   include/linux/inet_diag.h      | 2 ++
>>   include/uapi/linux/inet_diag.h | 7 +++++++
>>   net/ipv4/inet_diag.c           | 7 +++++++
>>   3 files changed, 16 insertions(+)
>>
>> diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
>> index 84abb30a3fbb..d05a4c26b13d 100644
>> --- a/include/linux/inet_diag.h
>> +++ b/include/linux/inet_diag.h
>> @@ -77,6 +77,8 @@ static inline size_t inet_diag_msg_attrs_size(void)
>>   #endif
>>   		+ nla_total_size(sizeof(struct inet_diag_sockopt))
>>   						     /* INET_DIAG_SOCKOPT */
>> +		+ nla_total_size(sizeof(struct inet_diag_reuse))
>> +						    /* INET_DIAG_REUSE */
>>   		;
>>   }
>>   int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
>> diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
>> index 50655de04c9b..f93eeea1faba 100644
>> --- a/include/uapi/linux/inet_diag.h
>> +++ b/include/uapi/linux/inet_diag.h
>> @@ -161,6 +161,7 @@ enum {
>>   	INET_DIAG_SK_BPF_STORAGES,
>>   	INET_DIAG_CGROUP_ID,
>>   	INET_DIAG_SOCKOPT,
>> +	INET_DIAG_REUSE,
>>   	__INET_DIAG_MAX,
>>   };
>>   
>> @@ -201,6 +202,12 @@ struct inet_diag_sockopt {
>>   		unused:5;
>>   };
>>   
>> +struct inet_diag_reuse {
>> +	__u8	reuse:4,
>> +		reuseport:1,
>> +		unused:3;
>> +};
>> +
>>   /* INET_DIAG_VEGASINFO */
>>   
>>   struct tcpvegas_info {
>> diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
>> index e13a84433413..d6ebb1e612fc 100644
>> --- a/net/ipv4/inet_diag.c
>> +++ b/net/ipv4/inet_diag.c
>> @@ -125,6 +125,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
>>   			     bool net_admin)
>>   {
>>   	const struct inet_sock *inet = inet_sk(sk);
>> +	struct inet_diag_reuse inet_reuse = {};
>>   	struct inet_diag_sockopt inet_sockopt;
>>   
>>   	if (nla_put_u8(skb, INET_DIAG_SHUTDOWN, sk->sk_shutdown))
>> @@ -197,6 +198,12 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
>>   		    &inet_sockopt))
>>   		goto errout;
>>   
>> +	inet_reuse.reuse = sk->sk_reuse;
>> +	inet_reuse.reuseport = sk->sk_reuseport;
>> +	if (nla_put(skb, INET_DIAG_REUSE, sizeof(inet_reuse),
>> +		    &inet_reuse))
>> +		goto errout;
>> +
>>   	return 0;
>>   errout:
>>   	return 1;
>> -- 
>> 2.25.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-09-12 18:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-12 14:31 [net-next 0/2] export SO_REUSEADDR and SO_REUSEPORT via sock_diag Jason Baron
2023-09-12 14:31 ` [net-next 1/2] inet_diag: export SO_REUSEADDR and SO_REUSEPORT sockopts Jason Baron
2023-09-12 16:26   ` Kuniyuki Iwashima
2023-09-12 18:54     ` Jason Baron
2023-09-12 14:31 ` [net-next 2/2] sock: add SO_REUSEADDR values to include/uapi/linux/socket.h Jason Baron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox