diff options
author | Jason Wang <jasowang@redhat.com> | 2018-09-11 23:16:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-09-13 12:25:40 -0400 |
commit | e4a2a3048ed93f0c354ad837f1d45fc8d389d538 (patch) | |
tree | ca93825037b3a5cc93d3aa358aac755ff34f527f | |
parent | 9708d2b5b7c648e8e0a40d11e8cea12f6277f33c (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.c | 19 | ||||
-rw-r--r-- | include/net/sock.h | 1 |
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)) |