diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2010-02-13 20:01:10 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-17 19:35:17 -0500 |
commit | 99405162598176e830d17ae6d4f3d9e070ad900c (patch) | |
tree | 41a23acd64d3f18de729c2abadc98f7c4687aa45 | |
parent | 5ff3f073670b544a9c0547cc6fef1f7eed5762ed (diff) |
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>
-rw-r--r-- | drivers/net/tun.c | 26 | ||||
-rw-r--r-- | include/linux/if_tun.h | 3 |
2 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 5adb3d150552..ce1efa4c0b0d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <linux/crc32.h> | 61 | #include <linux/crc32.h> |
62 | #include <linux/nsproxy.h> | 62 | #include <linux/nsproxy.h> |
63 | #include <linux/virtio_net.h> | 63 | #include <linux/virtio_net.h> |
64 | #include <linux/rcupdate.h> | ||
64 | #include <net/net_namespace.h> | 65 | #include <net/net_namespace.h> |
65 | #include <net/netns/generic.h> | 66 | #include <net/netns/generic.h> |
66 | #include <net/rtnetlink.h> | 67 | #include <net/rtnetlink.h> |
@@ -366,6 +367,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | |||
366 | if (!check_filter(&tun->txflt, skb)) | 367 | if (!check_filter(&tun->txflt, skb)) |
367 | goto drop; | 368 | goto drop; |
368 | 369 | ||
370 | if (tun->socket.sk->sk_filter && | ||
371 | sk_filter(tun->socket.sk, skb)) | ||
372 | goto drop; | ||
373 | |||
369 | if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) { | 374 | if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) { |
370 | if (!(tun->flags & TUN_ONE_QUEUE)) { | 375 | if (!(tun->flags & TUN_ONE_QUEUE)) { |
371 | /* Normal queueing mode. */ | 376 | /* Normal queueing mode. */ |
@@ -1162,6 +1167,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1162 | struct tun_file *tfile = file->private_data; | 1167 | struct tun_file *tfile = file->private_data; |
1163 | struct tun_struct *tun; | 1168 | struct tun_struct *tun; |
1164 | void __user* argp = (void __user*)arg; | 1169 | void __user* argp = (void __user*)arg; |
1170 | struct sock_fprog fprog; | ||
1165 | struct ifreq ifr; | 1171 | struct ifreq ifr; |
1166 | int sndbuf; | 1172 | int sndbuf; |
1167 | int ret; | 1173 | int ret; |
@@ -1309,6 +1315,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1309 | tun->socket.sk->sk_sndbuf = sndbuf; | 1315 | tun->socket.sk->sk_sndbuf = sndbuf; |
1310 | break; | 1316 | break; |
1311 | 1317 | ||
1318 | case TUNATTACHFILTER: | ||
1319 | /* Can be set only for TAPs */ | ||
1320 | ret = -EINVAL; | ||
1321 | if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) | ||
1322 | break; | ||
1323 | ret = -EFAULT; | ||
1324 | if (copy_from_user(&fprog, argp, sizeof(fprog))) | ||
1325 | break; | ||
1326 | |||
1327 | ret = sk_attach_filter(&fprog, tun->socket.sk); | ||
1328 | break; | ||
1329 | |||
1330 | case TUNDETACHFILTER: | ||
1331 | /* Can be set only for TAPs */ | ||
1332 | ret = -EINVAL; | ||
1333 | if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) | ||
1334 | break; | ||
1335 | ret = sk_detach_filter(tun->socket.sk); | ||
1336 | break; | ||
1337 | |||
1312 | default: | 1338 | default: |
1313 | ret = -EINVAL; | 1339 | ret = -EINVAL; |
1314 | break; | 1340 | break; |
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index 404abe00162c..1350a246893a 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/if_ether.h> | 20 | #include <linux/if_ether.h> |
21 | #include <linux/filter.h> | ||
21 | 22 | ||
22 | /* Read queue size */ | 23 | /* Read queue size */ |
23 | #define TUN_READQ_SIZE 500 | 24 | #define TUN_READQ_SIZE 500 |
@@ -48,6 +49,8 @@ | |||
48 | #define TUNGETIFF _IOR('T', 210, unsigned int) | 49 | #define TUNGETIFF _IOR('T', 210, unsigned int) |
49 | #define TUNGETSNDBUF _IOR('T', 211, int) | 50 | #define TUNGETSNDBUF _IOR('T', 211, int) |
50 | #define TUNSETSNDBUF _IOW('T', 212, int) | 51 | #define TUNSETSNDBUF _IOW('T', 212, int) |
52 | #define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog) | ||
53 | #define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog) | ||
51 | 54 | ||
52 | /* TUNSETIFF ifr flags */ | 55 | /* TUNSETIFF ifr flags */ |
53 | #define IFF_TUN 0x0001 | 56 | #define IFF_TUN 0x0001 |