mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	tun: socket filter support
This patch adds Linux Socket Filter support to tun driver. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									5ff3f07367
								
							
						
					
					
						commit
						9940516259
					
				
					 2 changed files with 29 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -61,6 +61,7 @@
 | 
			
		|||
#include <linux/crc32.h>
 | 
			
		||||
#include <linux/nsproxy.h>
 | 
			
		||||
#include <linux/virtio_net.h>
 | 
			
		||||
#include <linux/rcupdate.h>
 | 
			
		||||
#include <net/net_namespace.h>
 | 
			
		||||
#include <net/netns/generic.h>
 | 
			
		||||
#include <net/rtnetlink.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -366,6 +367,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
			
		|||
	if (!check_filter(&tun->txflt, skb))
 | 
			
		||||
		goto drop;
 | 
			
		||||
 | 
			
		||||
	if (tun->socket.sk->sk_filter &&
 | 
			
		||||
	    sk_filter(tun->socket.sk, skb))
 | 
			
		||||
		goto drop;
 | 
			
		||||
 | 
			
		||||
	if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) {
 | 
			
		||||
		if (!(tun->flags & TUN_ONE_QUEUE)) {
 | 
			
		||||
			/* Normal queueing mode. */
 | 
			
		||||
| 
						 | 
				
			
			@ -1162,6 +1167,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 | 
			
		|||
	struct tun_file *tfile = file->private_data;
 | 
			
		||||
	struct tun_struct *tun;
 | 
			
		||||
	void __user* argp = (void __user*)arg;
 | 
			
		||||
	struct sock_fprog fprog;
 | 
			
		||||
	struct ifreq ifr;
 | 
			
		||||
	int sndbuf;
 | 
			
		||||
	int ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -1309,6 +1315,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 | 
			
		|||
		tun->socket.sk->sk_sndbuf = sndbuf;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case TUNATTACHFILTER:
 | 
			
		||||
		/* Can be set only for TAPs */
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
 | 
			
		||||
			break;
 | 
			
		||||
		ret = -EFAULT;
 | 
			
		||||
		if (copy_from_user(&fprog, argp, sizeof(fprog)))
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		ret = sk_attach_filter(&fprog, tun->socket.sk);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case TUNDETACHFILTER:
 | 
			
		||||
		/* Can be set only for TAPs */
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
 | 
			
		||||
			break;
 | 
			
		||||
		ret = sk_detach_filter(tun->socket.sk);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
 | 
			
		||||
#include <linux/types.h>
 | 
			
		||||
#include <linux/if_ether.h>
 | 
			
		||||
#include <linux/filter.h>
 | 
			
		||||
 | 
			
		||||
/* Read queue size */
 | 
			
		||||
#define TUN_READQ_SIZE	500
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +49,8 @@
 | 
			
		|||
#define TUNGETIFF      _IOR('T', 210, unsigned int)
 | 
			
		||||
#define TUNGETSNDBUF   _IOR('T', 211, int)
 | 
			
		||||
#define TUNSETSNDBUF   _IOW('T', 212, int)
 | 
			
		||||
#define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog)
 | 
			
		||||
#define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
 | 
			
		||||
 | 
			
		||||
/* TUNSETIFF ifr flags */
 | 
			
		||||
#define IFF_TUN		0x0001
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue