History

tun: allow to attach ebpf socket filter

This patch allows userspace to attach eBPF filter to tun. This will allow to implement VM dataplane filtering in a more efficient way compared to cBPF filter by allowing either qemu or libvirt to attach eBPF filter to tun.

Jason Wang committed 8 years ago

Commit aff3d701 parent cd5681d2 files · +35 −4Browse files

Unified · Split

2 files
  1. drivers/net/tun.c +34 −4
  2. include/uapi/linux/if_tun.h +1 −0
drivers/net/tun.c+34−4
@@ -239,6 +239,12 @@ struct tun_struct { · 238 unmodified lines
239 struct tun_pcpu_stats __percpu *pcpu_stats;239 struct tun_pcpu_stats __percpu *pcpu_stats;
240 struct bpf_prog __rcu *xdp_prog;240 struct bpf_prog __rcu *xdp_prog;
241 struct tun_prog __rcu *steering_prog;241 struct tun_prog __rcu *steering_prog;
242 struct tun_prog __rcu *filter_prog;
243};
244
245struct veth {
246 __be16 h_vlan_proto;
247 __be16 h_vlan_TCI;
242};248};
243 249
244bool tun_is_xdp_buff(void *ptr)250bool tun_is_xdp_buff(void *ptr)
@@ -1036,12 +1042,25 @@ static void tun_automq_xmit(struct tun_struct *tun, struct sk_buff *skb) · 791 unmodified lines
1036#endif1042#endif
1037}1043}
1038 1044
1045static unsigned int run_ebpf_filter(struct tun_struct *tun,
1046 struct sk_buff *skb,
1047 int len)
1048{
1049 struct tun_prog *prog = rcu_dereference(tun->filter_prog);
1050
1051 if (prog)
1052 len = bpf_prog_run_clear_cb(prog->prog, skb);
1053
1054 return len;
1055}
1056
1039/* Net device start xmit */1057/* Net device start xmit */
1040static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)1058static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
1041{1059{
1042 struct tun_struct *tun = netdev_priv(dev);1060 struct tun_struct *tun = netdev_priv(dev);
1043 int txq = skb->queue_mapping;1061 int txq = skb->queue_mapping;
1044 struct tun_file *tfile;1062 struct tun_file *tfile;
1063 int len = skb->len;
1045 1064
1046 rcu_read_lock();1065 rcu_read_lock();
1047 tfile = rcu_dereference(tun->tfiles[txq]);1066 tfile = rcu_dereference(tun->tfiles[txq]);
@@ -1067,6 +1086,15 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) · 19 unmodified lines
1067 sk_filter(tfile->socket.sk, skb))1086 sk_filter(tfile->socket.sk, skb))
1068 goto drop;1087 goto drop;
1069 1088
1089 len = run_ebpf_filter(tun, skb, len);
1090
1091 /* Trim extra bytes since we may insert vlan proto & TCI
1092 * in tun_put_user().
1093 */
1094 len -= skb_vlan_tag_present(skb) ? sizeof(struct veth) : 0;
1095 if (len <= 0 || pskb_trim(skb, len))
1096 goto drop;
1097
1070 if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))1098 if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))
1071 goto drop;1099 goto drop;
1072 1100
@@ -2054,10 +2082,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, · 981 unmodified lines
2054 2082
2055 if (vlan_hlen) {2083 if (vlan_hlen) {
2056 int ret;2084 int ret;
2057 struct {2085 struct veth veth;
2058 __be16 h_vlan_proto;
2059 __be16 h_vlan_TCI;
2060 } veth;
2061 2086
2062 veth.h_vlan_proto = skb->vlan_proto;2087 veth.h_vlan_proto = skb->vlan_proto;
2063 veth.h_vlan_TCI = htons(skb_vlan_tag_get(skb));2088 veth.h_vlan_TCI = htons(skb_vlan_tag_get(skb));
@@ -2225,6 +2250,7 @@ static void tun_free_netdev(struct net_device *dev) · 161 unmodified lines
2225 tun_flow_uninit(tun);2250 tun_flow_uninit(tun);
2226 security_tun_dev_free_security(tun->security);2251 security_tun_dev_free_security(tun->security);
2227 __tun_set_ebpf(tun, &tun->steering_prog, NULL);2252 __tun_set_ebpf(tun, &tun->steering_prog, NULL);
2253 __tun_set_ebpf(tun, &tun->filter_prog, NULL);
2228}2254}
2229 2255
2230static void tun_setup(struct net_device *dev)2256static void tun_setup(struct net_device *dev)
@@ -3019,6 +3045,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, · 788 unmodified lines
3019 ret = tun_set_ebpf(tun, &tun->steering_prog, argp);3045 ret = tun_set_ebpf(tun, &tun->steering_prog, argp);
3020 break;3046 break;
3021 3047
3048 case TUNSETFILTEREBPF:
3049 ret = tun_set_ebpf(tun, &tun->filter_prog, argp);
3050 break;
3051
3022 default:3052 default:
3023 ret = -EINVAL;3053 ret = -EINVAL;
3024 break;3054 break;
include/uapi/linux/if_tun.h+1−0
@@ -58,6 +58,7 @@ · 57 unmodified lines
58#define TUNSETVNETBE _IOW('T', 222, int)58#define TUNSETVNETBE _IOW('T', 222, int)
59#define TUNGETVNETBE _IOR('T', 223, int)59#define TUNGETVNETBE _IOR('T', 223, int)
60#define TUNSETSTEERINGEBPF _IOR('T', 224, int)60#define TUNSETSTEERINGEBPF _IOR('T', 224, int)
61#define TUNSETFILTEREBPF _IOR('T', 225, int)
61 62
62/* TUNSETIFF ifr flags */63/* TUNSETIFF ifr flags */
63#define IFF_TUN 0x000164#define IFF_TUN 0x0001