Skip to content

Commit a29ae44

Browse files
committed
Merge branch 'tun-allow-to-attach-eBPF-filter'
Jason Wang says: ==================== tun: allow to attach eBPF filter This series tries to implement eBPF socket filter for tun. This could be used for implementing efficient virtio-net receive filter for vhost-net. Changes from V2: - fix typo - remove unnecessary double check ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents ca46abd + aff3d70 commit a29ae44

File tree

2 files changed

+51
-20
lines changed

2 files changed

+51
-20
lines changed

drivers/net/tun.c

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ struct tun_flow_entry {
196196

197197
#define TUN_NUM_FLOW_ENTRIES 1024
198198

199-
struct tun_steering_prog {
199+
struct tun_prog {
200200
struct rcu_head rcu;
201201
struct bpf_prog *prog;
202202
};
@@ -238,7 +238,13 @@ struct tun_struct {
238238
u32 rx_batched;
239239
struct tun_pcpu_stats __percpu *pcpu_stats;
240240
struct bpf_prog __rcu *xdp_prog;
241-
struct tun_steering_prog __rcu *steering_prog;
241+
struct tun_prog __rcu *steering_prog;
242+
struct tun_prog __rcu *filter_prog;
243+
};
244+
245+
struct veth {
246+
__be16 h_vlan_proto;
247+
__be16 h_vlan_TCI;
242248
};
243249

244250
bool tun_is_xdp_buff(void *ptr)
@@ -590,7 +596,7 @@ static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff *skb)
590596

591597
static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *skb)
592598
{
593-
struct tun_steering_prog *prog;
599+
struct tun_prog *prog;
594600
u16 ret = 0;
595601

596602
prog = rcu_dereference(tun->steering_prog);
@@ -1036,12 +1042,25 @@ static void tun_automq_xmit(struct tun_struct *tun, struct sk_buff *skb)
10361042
#endif
10371043
}
10381044

1045+
static 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+
10391057
/* Net device start xmit */
10401058
static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
10411059
{
10421060
struct tun_struct *tun = netdev_priv(dev);
10431061
int txq = skb->queue_mapping;
10441062
struct tun_file *tfile;
1063+
int len = skb->len;
10451064

10461065
rcu_read_lock();
10471066
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)
10671086
sk_filter(tfile->socket.sk, skb))
10681087
goto drop;
10691088

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+
10701098
if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))
10711099
goto drop;
10721100

@@ -2054,10 +2082,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
20542082

20552083
if (vlan_hlen) {
20562084
int ret;
2057-
struct {
2058-
__be16 h_vlan_proto;
2059-
__be16 h_vlan_TCI;
2060-
} veth;
2085+
struct veth veth;
20612086

20622087
veth.h_vlan_proto = skb->vlan_proto;
20632088
veth.h_vlan_TCI = htons(skb_vlan_tag_get(skb));
@@ -2184,19 +2209,18 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to)
21842209
return ret;
21852210
}
21862211

2187-
static void tun_steering_prog_free(struct rcu_head *rcu)
2212+
static void tun_prog_free(struct rcu_head *rcu)
21882213
{
2189-
struct tun_steering_prog *prog = container_of(rcu,
2190-
struct tun_steering_prog, rcu);
2214+
struct tun_prog *prog = container_of(rcu, struct tun_prog, rcu);
21912215

21922216
bpf_prog_destroy(prog->prog);
21932217
kfree(prog);
21942218
}
21952219

2196-
static int __tun_set_steering_ebpf(struct tun_struct *tun,
2197-
struct bpf_prog *prog)
2220+
static int __tun_set_ebpf(struct tun_struct *tun, struct tun_prog **prog_p,
2221+
struct bpf_prog *prog)
21982222
{
2199-
struct tun_steering_prog *old, *new = NULL;
2223+
struct tun_prog *old, *new = NULL;
22002224

22012225
if (prog) {
22022226
new = kmalloc(sizeof(*new), GFP_KERNEL);
@@ -2206,13 +2230,13 @@ static int __tun_set_steering_ebpf(struct tun_struct *tun,
22062230
}
22072231

22082232
spin_lock_bh(&tun->lock);
2209-
old = rcu_dereference_protected(tun->steering_prog,
2233+
old = rcu_dereference_protected(*prog_p,
22102234
lockdep_is_held(&tun->lock));
2211-
rcu_assign_pointer(tun->steering_prog, new);
2235+
rcu_assign_pointer(*prog_p, new);
22122236
spin_unlock_bh(&tun->lock);
22132237

22142238
if (old)
2215-
call_rcu(&old->rcu, tun_steering_prog_free);
2239+
call_rcu(&old->rcu, tun_prog_free);
22162240

22172241
return 0;
22182242
}
@@ -2225,7 +2249,8 @@ static void tun_free_netdev(struct net_device *dev)
22252249
free_percpu(tun->pcpu_stats);
22262250
tun_flow_uninit(tun);
22272251
security_tun_dev_free_security(tun->security);
2228-
__tun_set_steering_ebpf(tun, NULL);
2252+
__tun_set_ebpf(tun, &tun->steering_prog, NULL);
2253+
__tun_set_ebpf(tun, &tun->filter_prog, NULL);
22292254
}
22302255

22312256
static void tun_setup(struct net_device *dev)
@@ -2720,7 +2745,8 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
27202745
return ret;
27212746
}
27222747

2723-
static int tun_set_steering_ebpf(struct tun_struct *tun, void __user *data)
2748+
static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog **prog_p,
2749+
void __user *data)
27242750
{
27252751
struct bpf_prog *prog;
27262752
int fd;
@@ -2736,7 +2762,7 @@ static int tun_set_steering_ebpf(struct tun_struct *tun, void __user *data)
27362762
return PTR_ERR(prog);
27372763
}
27382764

2739-
return __tun_set_steering_ebpf(tun, prog);
2765+
return __tun_set_ebpf(tun, prog_p, prog);
27402766
}
27412767

27422768
static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
@@ -3016,7 +3042,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
30163042
break;
30173043

30183044
case TUNSETSTEERINGEBPF:
3019-
ret = tun_set_steering_ebpf(tun, argp);
3045+
ret = tun_set_ebpf(tun, &tun->steering_prog, argp);
3046+
break;
3047+
3048+
case TUNSETFILTEREBPF:
3049+
ret = tun_set_ebpf(tun, &tun->filter_prog, argp);
30203050
break;
30213051

30223052
default:

include/uapi/linux/if_tun.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#define TUNSETVNETBE _IOW('T', 222, int)
5959
#define TUNGETVNETBE _IOR('T', 223, int)
6060
#define TUNSETSTEERINGEBPF _IOR('T', 224, int)
61+
#define TUNSETFILTEREBPF _IOR('T', 225, int)
6162

6263
/* TUNSETIFF ifr flags */
6364
#define IFF_TUN 0x0001

0 commit comments

Comments
 (0)