makes 'ss -Ml' show mptcp listen sockets.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/mptcp/mptcp_diag.c | 67 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/net/mptcp/mptcp_diag.c b/net/mptcp/mptcp_diag.c
index c4992eeb67d8..6a6dfc7eac33 100644
--- a/net/mptcp/mptcp_diag.c
+++ b/net/mptcp/mptcp_diag.c
@@ -69,6 +69,8 @@ static int mptcp_diag_dump_one(struct netlink_callback *cb,
struct mptcp_diag_ctx {
long s_slot;
long s_num;
+ unsigned int l_slot;
+ unsigned int l_num;
};
static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
@@ -114,6 +116,71 @@ static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
}
cond_resched();
}
+
+ if (r->idiag_states & TCPF_LISTEN) {
+ int i;
+
+ for (i = diag_ctx->l_slot; i < INET_LHTABLE_SIZE; i++) {
+ struct inet_listen_hashbucket *ilb;
+ struct hlist_nulls_node *node;
+ struct sock *sk;
+ int num = 0;
+
+ ilb = &tcp_hashinfo.listening_hash[i];
+
+ rcu_read_lock();
+ spin_lock(&ilb->lock);
+ sk_nulls_for_each(sk, node, &ilb->nulls_head) {
+ const struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(sk);
+ struct inet_sock *inet = inet_sk(sk);
+ int ret;
+
+ if (num < diag_ctx->l_num)
+ goto next_listen;
+
+ if (!ctx || strcmp(inet_csk(sk)->icsk_ulp_ops->name, "mptcp"))
+ goto next_listen;
+
+ sk = ctx->conn;
+ if (!sk || !net_eq(sock_net(sk), net))
+ goto next_listen;
+
+ if (r->sdiag_family != AF_UNSPEC &&
+ sk->sk_family != r->sdiag_family)
+ goto next_listen;
+
+ if (r->id.idiag_sport != inet->inet_sport &&
+ r->id.idiag_sport)
+ goto next_listen;
+
+ if (!refcount_inc_not_zero(&sk->sk_refcnt))
+ goto next_listen;
+
+ ret = sk_diag_dump(sk, skb, cb, r, bc, net_admin);
+ sock_put(sk);
+
+ if (ret < 0) {
+ spin_unlock(&ilb->lock);
+ rcu_read_unlock();
+ diag_ctx->l_slot = i;
+ diag_ctx->l_num = num;
+ return;
+ }
+ diag_ctx->l_num = num + 1;
+ num = 0;
+next_listen:
+ ++num;
+ }
+ spin_unlock(&ilb->lock);
+ rcu_read_unlock();
+
+ cond_resched();
+ diag_ctx->l_num = 0;
+ }
+
+ diag_ctx->l_num = 0;
+ diag_ctx->l_slot = i;
+ }
}
static void mptcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
--
2.34.1
On Thu, 2022-03-24 at 14:57 +0100, Florian Westphal wrote:
> makes 'ss -Ml' show mptcp listen sockets.
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> net/mptcp/mptcp_diag.c | 67 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 67 insertions(+)
>
> diff --git a/net/mptcp/mptcp_diag.c b/net/mptcp/mptcp_diag.c
> index c4992eeb67d8..6a6dfc7eac33 100644
> --- a/net/mptcp/mptcp_diag.c
> +++ b/net/mptcp/mptcp_diag.c
> @@ -69,6 +69,8 @@ static int mptcp_diag_dump_one(struct netlink_callback *cb,
> struct mptcp_diag_ctx {
> long s_slot;
> long s_num;
> + unsigned int l_slot;
> + unsigned int l_num;
> };
>
> static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> @@ -114,6 +116,71 @@ static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> }
> cond_resched();
> }
> +
> + if (r->idiag_states & TCPF_LISTEN) {
> + int i;
perhaps here we need to add something alike:
if (r->id.idiag_dport)
return;
???
Also, what about moving the following chunk in separate helper -
mptcp_diag_dump_listener()?
Thanks!
Paolo
Paolo Abeni <pabeni@redhat.com> wrote:
> On Thu, 2022-03-24 at 14:57 +0100, Florian Westphal wrote:
> > makes 'ss -Ml' show mptcp listen sockets.
> >
> > Signed-off-by: Florian Westphal <fw@strlen.de>
> > ---
> > net/mptcp/mptcp_diag.c | 67 ++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 67 insertions(+)
> >
> > diff --git a/net/mptcp/mptcp_diag.c b/net/mptcp/mptcp_diag.c
> > index c4992eeb67d8..6a6dfc7eac33 100644
> > --- a/net/mptcp/mptcp_diag.c
> > +++ b/net/mptcp/mptcp_diag.c
> > @@ -69,6 +69,8 @@ static int mptcp_diag_dump_one(struct netlink_callback *cb,
> > struct mptcp_diag_ctx {
> > long s_slot;
> > long s_num;
> > + unsigned int l_slot;
> > + unsigned int l_num;
> > };
> >
> > static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> > @@ -114,6 +116,71 @@ static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> > }
> > cond_resched();
> > }
> > +
> > + if (r->idiag_states & TCPF_LISTEN) {
> > + int i;
>
> perhaps here we need to add something alike:
>
> if (r->id.idiag_dport)
> return;
[..]
> Also, what about moving the following chunk in separate helper -
> mptcp_diag_dump_listener()?
Changed to:
if ((r->idiag_states & TCPF_LISTEN) && r->id.idiag_dport == 0)
mptcp_diag_dump_listeners(skb, cb, r, net_admin);
© 2016 - 2026 Red Hat, Inc.