summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2018-09-11 23:16:59 -0400
committerDavid S. Miller <davem@davemloft.net>2018-09-13 12:25:40 -0400
commite4a2a3048ed93f0c354ad837f1d45fc8d389d538 (patch)
treeca93825037b3a5cc93d3aa358aac755ff34f527f
parent9708d2b5b7c648e8e0a40d11e8cea12f6277f33c (diff)
net: sock: introduce SOCK_XDP
This patch introduces a new sock flag - SOCK_XDP. This will be used for notifying the upper layer that XDP program is attached on the lower socket, and requires for extra headroom. TUN will be the first user. Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tun.c19
-rw-r--r--include/net/sock.h1
2 files changed, 20 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
diff --git a/include/net/sock.h b/include/net/sock.h
index 433f45fc2d68..38cae35f6e16 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -800,6 +800,7 @@ enum sock_flags {
800 SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */ 800 SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
801 SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */ 801 SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */
802 SOCK_TXTIME, 802 SOCK_TXTIME,
803 SOCK_XDP, /* XDP is attached */
803}; 804};
804 805
805#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) 806#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))