mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									8a360be0c5
								
							
						
					
					
						commit
						eea68e2f1a
					
				
					 2 changed files with 49 additions and 0 deletions
				
			
		| 
						 | 
					@ -13,6 +13,7 @@ struct packet_diag_req {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PACKET_SHOW_INFO	0x00000001 /* Basic packet_sk information */
 | 
					#define PACKET_SHOW_INFO	0x00000001 /* Basic packet_sk information */
 | 
				
			||||||
 | 
					#define PACKET_SHOW_MCLIST	0x00000002 /* A set of packet_diag_mclist-s */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct packet_diag_msg {
 | 
					struct packet_diag_msg {
 | 
				
			||||||
	__u8	pdiag_family;
 | 
						__u8	pdiag_family;
 | 
				
			||||||
| 
						 | 
					@ -25,6 +26,7 @@ struct packet_diag_msg {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	PACKET_DIAG_INFO,
 | 
						PACKET_DIAG_INFO,
 | 
				
			||||||
 | 
						PACKET_DIAG_MCLIST,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PACKET_DIAG_MAX,
 | 
						PACKET_DIAG_MAX,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -44,4 +46,12 @@ struct packet_diag_info {
 | 
				
			||||||
#define PDI_LOSS	0x10
 | 
					#define PDI_LOSS	0x10
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct packet_diag_mclist {
 | 
				
			||||||
 | 
						__u32	pdmc_index;
 | 
				
			||||||
 | 
						__u32	pdmc_count;
 | 
				
			||||||
 | 
						__u16	pdmc_type;
 | 
				
			||||||
 | 
						__u16	pdmc_alen;
 | 
				
			||||||
 | 
						__u8	pdmc_addr[MAX_ADDR_LEN];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/sock_diag.h>
 | 
					#include <linux/sock_diag.h>
 | 
				
			||||||
#include <linux/net.h>
 | 
					#include <linux/net.h>
 | 
				
			||||||
 | 
					#include <linux/netdevice.h>
 | 
				
			||||||
#include <linux/packet_diag.h>
 | 
					#include <linux/packet_diag.h>
 | 
				
			||||||
#include <net/net_namespace.h>
 | 
					#include <net/net_namespace.h>
 | 
				
			||||||
#include <net/sock.h>
 | 
					#include <net/sock.h>
 | 
				
			||||||
| 
						 | 
					@ -32,6 +33,40 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
 | 
				
			||||||
	return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo);
 | 
						return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int pdiag_put_mclist(const struct packet_sock *po, struct sk_buff *nlskb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nlattr *mca;
 | 
				
			||||||
 | 
						struct packet_mclist *ml;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mca = nla_nest_start(nlskb, PACKET_DIAG_MCLIST);
 | 
				
			||||||
 | 
						if (!mca)
 | 
				
			||||||
 | 
							return -EMSGSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rtnl_lock();
 | 
				
			||||||
 | 
						for (ml = po->mclist; ml; ml = ml->next) {
 | 
				
			||||||
 | 
							struct packet_diag_mclist *dml;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dml = nla_reserve_nohdr(nlskb, sizeof(*dml));
 | 
				
			||||||
 | 
							if (!dml) {
 | 
				
			||||||
 | 
								rtnl_unlock();
 | 
				
			||||||
 | 
								nla_nest_cancel(nlskb, mca);
 | 
				
			||||||
 | 
								return -EMSGSIZE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dml->pdmc_index = ml->ifindex;
 | 
				
			||||||
 | 
							dml->pdmc_type = ml->type;
 | 
				
			||||||
 | 
							dml->pdmc_alen = ml->alen;
 | 
				
			||||||
 | 
							dml->pdmc_count = ml->count;
 | 
				
			||||||
 | 
							BUILD_BUG_ON(sizeof(dml->pdmc_addr) != sizeof(ml->addr));
 | 
				
			||||||
 | 
							memcpy(dml->pdmc_addr, ml->addr, sizeof(ml->addr));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rtnl_unlock();
 | 
				
			||||||
 | 
						nla_nest_end(nlskb, mca);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req,
 | 
					static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req,
 | 
				
			||||||
		u32 pid, u32 seq, u32 flags, int sk_ino)
 | 
							u32 pid, u32 seq, u32 flags, int sk_ino)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -54,6 +89,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag
 | 
				
			||||||
			pdiag_put_info(po, skb))
 | 
								pdiag_put_info(po, skb))
 | 
				
			||||||
		goto out_nlmsg_trim;
 | 
							goto out_nlmsg_trim;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((req->pdiag_show & PACKET_SHOW_MCLIST) &&
 | 
				
			||||||
 | 
								pdiag_put_mclist(po, skb))
 | 
				
			||||||
 | 
							goto out_nlmsg_trim;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nlmsg_end(skb, nlh);
 | 
						return nlmsg_end(skb, nlh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_nlmsg_trim:
 | 
					out_nlmsg_trim:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue