diff options
author | Pavel Emelyanov <xemul@parallels.com> | 2012-08-13 01:57:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-14 19:56:33 -0400 |
commit | eea68e2f1a0061e09265992b91fdc0014930ae92 (patch) | |
tree | 2b8f78565a04701e49b271b670a67fcb362c8022 /net/packet | |
parent | 8a360be0c5f8fe2c46f0a524886fa56596534193 (diff) |
packet: Report socket mclist info via diag module
The info is reported as an array of packet_diag_mclist structures. Each
includes not only the directly configured values (index, type, etc), but
also the "count".
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet')
-rw-r--r-- | net/packet/diag.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/net/packet/diag.c b/net/packet/diag.c index d5bd0372d004..3dda4ecb9a46 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <linux/sock_diag.h> | 2 | #include <linux/sock_diag.h> |
3 | #include <linux/net.h> | 3 | #include <linux/net.h> |
4 | #include <linux/netdevice.h> | ||
4 | #include <linux/packet_diag.h> | 5 | #include <linux/packet_diag.h> |
5 | #include <net/net_namespace.h> | 6 | #include <net/net_namespace.h> |
6 | #include <net/sock.h> | 7 | #include <net/sock.h> |
@@ -32,6 +33,40 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb) | |||
32 | return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo); | 33 | return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo); |
33 | } | 34 | } |
34 | 35 | ||
36 | static int pdiag_put_mclist(const struct packet_sock *po, struct sk_buff *nlskb) | ||
37 | { | ||
38 | struct nlattr *mca; | ||
39 | struct packet_mclist *ml; | ||
40 | |||
41 | mca = nla_nest_start(nlskb, PACKET_DIAG_MCLIST); | ||
42 | if (!mca) | ||
43 | return -EMSGSIZE; | ||
44 | |||
45 | rtnl_lock(); | ||
46 | for (ml = po->mclist; ml; ml = ml->next) { | ||
47 | struct packet_diag_mclist *dml; | ||
48 | |||
49 | dml = nla_reserve_nohdr(nlskb, sizeof(*dml)); | ||
50 | if (!dml) { | ||
51 | rtnl_unlock(); | ||
52 | nla_nest_cancel(nlskb, mca); | ||
53 | return -EMSGSIZE; | ||
54 | } | ||
55 | |||
56 | dml->pdmc_index = ml->ifindex; | ||
57 | dml->pdmc_type = ml->type; | ||
58 | dml->pdmc_alen = ml->alen; | ||
59 | dml->pdmc_count = ml->count; | ||
60 | BUILD_BUG_ON(sizeof(dml->pdmc_addr) != sizeof(ml->addr)); | ||
61 | memcpy(dml->pdmc_addr, ml->addr, sizeof(ml->addr)); | ||
62 | } | ||
63 | |||
64 | rtnl_unlock(); | ||
65 | nla_nest_end(nlskb, mca); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
35 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req, | 70 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req, |
36 | u32 pid, u32 seq, u32 flags, int sk_ino) | 71 | u32 pid, u32 seq, u32 flags, int sk_ino) |
37 | { | 72 | { |
@@ -54,6 +89,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag | |||
54 | pdiag_put_info(po, skb)) | 89 | pdiag_put_info(po, skb)) |
55 | goto out_nlmsg_trim; | 90 | goto out_nlmsg_trim; |
56 | 91 | ||
92 | if ((req->pdiag_show & PACKET_SHOW_MCLIST) && | ||
93 | pdiag_put_mclist(po, skb)) | ||
94 | goto out_nlmsg_trim; | ||
95 | |||
57 | return nlmsg_end(skb, nlh); | 96 | return nlmsg_end(skb, nlh); |
58 | 97 | ||
59 | out_nlmsg_trim: | 98 | out_nlmsg_trim: |