summaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index ebd07ad82431..2c548bd20393 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -869,6 +869,9 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
869 tun_napi_init(tun, tfile, napi); 869 tun_napi_init(tun, tfile, napi);
870 } 870 }
871 871
872 if (rtnl_dereference(tun->xdp_prog))
873 sock_set_flag(&tfile->sk, SOCK_XDP);
874
872 tun_set_real_num_queues(tun); 875 tun_set_real_num_queues(tun);
873 876
874 /* device is allowed to go away first, so no need to hold extra 877 /* device is allowed to go away first, so no need to hold extra
@@ -1241,13 +1244,29 @@ static int tun_xdp_set(struct net_device *dev, struct bpf_prog *prog,
1241 struct netlink_ext_ack *extack) 1244 struct netlink_ext_ack *extack)
1242{ 1245{
1243 struct tun_struct *tun = netdev_priv(dev); 1246 struct tun_struct *tun = netdev_priv(dev);
1247 struct tun_file *tfile;
1244 struct bpf_prog *old_prog; 1248 struct bpf_prog *old_prog;
1249 int i;
1245 1250
1246 old_prog = rtnl_dereference(tun->xdp_prog); 1251 old_prog = rtnl_dereference(tun->xdp_prog);
1247 rcu_assign_pointer(tun->xdp_prog, prog); 1252 rcu_assign_pointer(tun->xdp_prog, prog);
1248 if (old_prog) 1253 if (old_prog)
1249 bpf_prog_put(old_prog); 1254 bpf_prog_put(old_prog);
1250 1255
1256 for (i = 0; i < tun->numqueues; i++) {
1257 tfile = rtnl_dereference(tun->tfiles[i]);
1258 if (prog)
1259 sock_set_flag(&tfile->sk, SOCK_XDP);
1260 else
1261 sock_reset_flag(&tfile->sk, SOCK_XDP);
1262 }
1263 list_for_each_entry(tfile, &tun->disabled, next) {
1264 if (prog)
1265 sock_set_flag(&tfile->sk, SOCK_XDP);
1266 else
1267 sock_reset_flag(&tfile->sk, SOCK_XDP);
1268 }
1269
1251 return 0; 1270 return 0;
1252} 1271}
1253 1272