Message ID | 20220324135753.25182-4-fw@strlen.de (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | mptcp: listen dump support | expand |
Context | Check | Description |
---|---|---|
matttbe/build | success | Build and static analysis OK |
matttbe/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 79 lines checked |
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);
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,
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(+)