.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Shared Memory Communications over RDMA (SMC-R) and RoCE |
---|
3 | 4 | * |
---|
.. | .. |
---|
20 | 21 | |
---|
21 | 22 | #include "smc.h" |
---|
22 | 23 | #include "smc_core.h" |
---|
| 24 | + |
---|
| 25 | +struct smc_diag_dump_ctx { |
---|
| 26 | + int pos[2]; |
---|
| 27 | +}; |
---|
| 28 | + |
---|
| 29 | +static struct smc_diag_dump_ctx *smc_dump_context(struct netlink_callback *cb) |
---|
| 30 | +{ |
---|
| 31 | + return (struct smc_diag_dump_ctx *)cb->ctx; |
---|
| 32 | +} |
---|
23 | 33 | |
---|
24 | 34 | static void smc_gid_be16_convert(__u8 *buf, u8 *gid_raw) |
---|
25 | 35 | { |
---|
.. | .. |
---|
192 | 202 | } |
---|
193 | 203 | |
---|
194 | 204 | static int smc_diag_dump_proto(struct proto *prot, struct sk_buff *skb, |
---|
195 | | - struct netlink_callback *cb) |
---|
| 205 | + struct netlink_callback *cb, int p_type) |
---|
196 | 206 | { |
---|
| 207 | + struct smc_diag_dump_ctx *cb_ctx = smc_dump_context(cb); |
---|
197 | 208 | struct net *net = sock_net(skb->sk); |
---|
| 209 | + int snum = cb_ctx->pos[p_type]; |
---|
198 | 210 | struct nlattr *bc = NULL; |
---|
199 | 211 | struct hlist_head *head; |
---|
| 212 | + int rc = 0, num = 0; |
---|
200 | 213 | struct sock *sk; |
---|
201 | | - int rc = 0; |
---|
202 | 214 | |
---|
203 | 215 | read_lock(&prot->h.smc_hash->lock); |
---|
204 | 216 | head = &prot->h.smc_hash->ht; |
---|
.. | .. |
---|
208 | 220 | sk_for_each(sk, head) { |
---|
209 | 221 | if (!net_eq(sock_net(sk), net)) |
---|
210 | 222 | continue; |
---|
| 223 | + if (num < snum) |
---|
| 224 | + goto next; |
---|
211 | 225 | rc = __smc_diag_dump(sk, skb, cb, nlmsg_data(cb->nlh), bc); |
---|
212 | | - if (rc) |
---|
213 | | - break; |
---|
| 226 | + if (rc < 0) |
---|
| 227 | + goto out; |
---|
| 228 | +next: |
---|
| 229 | + num++; |
---|
214 | 230 | } |
---|
215 | 231 | |
---|
216 | 232 | out: |
---|
217 | 233 | read_unlock(&prot->h.smc_hash->lock); |
---|
| 234 | + cb_ctx->pos[p_type] = num; |
---|
218 | 235 | return rc; |
---|
219 | 236 | } |
---|
220 | 237 | |
---|
.. | .. |
---|
222 | 239 | { |
---|
223 | 240 | int rc = 0; |
---|
224 | 241 | |
---|
225 | | - rc = smc_diag_dump_proto(&smc_proto, skb, cb); |
---|
| 242 | + rc = smc_diag_dump_proto(&smc_proto, skb, cb, SMCPROTO_SMC); |
---|
226 | 243 | if (!rc) |
---|
227 | | - rc = smc_diag_dump_proto(&smc_proto6, skb, cb); |
---|
228 | | - return rc; |
---|
| 244 | + smc_diag_dump_proto(&smc_proto6, skb, cb, SMCPROTO_SMC6); |
---|
| 245 | + return skb->len; |
---|
229 | 246 | } |
---|
230 | 247 | |
---|
231 | 248 | static int smc_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) |
---|