net: sock: introduce SOCK_XDP
authorJason Wang <jasowang@redhat.com>
Wed, 12 Sep 2018 03:16:59 +0000 (11:16 +0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 13 Sep 2018 16:25:40 +0000 (09:25 -0700)
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>
drivers/net/tun.c
include/net/sock.h

index ebd07ad..2c548bd 100644 (file)
@@ -869,6 +869,9 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
                tun_napi_init(tun, tfile, napi);
        }
 
+       if (rtnl_dereference(tun->xdp_prog))
+               sock_set_flag(&tfile->sk, SOCK_XDP);
+
        tun_set_real_num_queues(tun);
 
        /* 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,
                       struct netlink_ext_ack *extack)
 {
        struct tun_struct *tun = netdev_priv(dev);
+       struct tun_file *tfile;
        struct bpf_prog *old_prog;
+       int i;
 
        old_prog = rtnl_dereference(tun->xdp_prog);
        rcu_assign_pointer(tun->xdp_prog, prog);
        if (old_prog)
                bpf_prog_put(old_prog);
 
+       for (i = 0; i < tun->numqueues; i++) {
+               tfile = rtnl_dereference(tun->tfiles[i]);
+               if (prog)
+                       sock_set_flag(&tfile->sk, SOCK_XDP);
+               else
+                       sock_reset_flag(&tfile->sk, SOCK_XDP);
+       }
+       list_for_each_entry(tfile, &tun->disabled, next) {
+               if (prog)
+                       sock_set_flag(&tfile->sk, SOCK_XDP);
+               else
+                       sock_reset_flag(&tfile->sk, SOCK_XDP);
+       }
+
        return 0;
 }
 
index 433f45f..38cae35 100644 (file)
@@ -800,6 +800,7 @@ enum sock_flags {
        SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
        SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */
        SOCK_TXTIME,
+       SOCK_XDP, /* XDP is attached */
 };
 
 #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))