From: Björn Töpel <bjorn.to...@intel.com>

Buildable skeleton. Move on, nothing to see.

Signed-off-by: Björn Töpel <bjorn.to...@intel.com>
---
 include/linux/socket.h              |   5 +-
 include/uapi/linux/if_xdp.h         |  32 +++++++++
 net/Kconfig                         |   1 +
 net/Makefile                        |   1 +
 net/core/sock.c                     |  12 ++--
 net/xdp/Kconfig                     |   7 ++
 net/xdp/Makefile                    |   1 +
 net/xdp/xsk.c                       | 133 ++++++++++++++++++++++++++++++++++++
 net/xdp/xsk.h                       |  18 +++++
 security/selinux/hooks.c            |   4 +-
 security/selinux/include/classmap.h |   4 +-
 11 files changed, 211 insertions(+), 7 deletions(-)
 create mode 100644 include/uapi/linux/if_xdp.h
 create mode 100644 net/xdp/Kconfig
 create mode 100644 net/xdp/Makefile
 create mode 100644 net/xdp/xsk.c
 create mode 100644 net/xdp/xsk.h

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 9286a5a8c60c..ada0102ff8db 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -207,8 +207,9 @@ struct ucred {
                                 * PF_SMC protocol family that
                                 * reuses AF_INET address family
                                 */
+#define AF_XDP         44      /* XDP sockets                  */
 
-#define AF_MAX         44      /* For now.. */
+#define AF_MAX         45      /* For now.. */
 
 /* Protocol families, same as address families. */
 #define PF_UNSPEC      AF_UNSPEC
@@ -257,6 +258,7 @@ struct ucred {
 #define PF_KCM         AF_KCM
 #define PF_QIPCRTR     AF_QIPCRTR
 #define PF_SMC         AF_SMC
+#define PF_XDP         AF_XDP
 #define PF_MAX         AF_MAX
 
 /* Maximum queue length specifiable by listen.  */
@@ -337,6 +339,7 @@ struct ucred {
 #define SOL_NFC                280
 #define SOL_KCM                281
 #define SOL_TLS                282
+#define SOL_XDP                283
 
 /* IPX options */
 #define IPX_TYPE       1
diff --git a/include/uapi/linux/if_xdp.h b/include/uapi/linux/if_xdp.h
new file mode 100644
index 000000000000..cd09232e16c1
--- /dev/null
+++ b/include/uapi/linux/if_xdp.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * if_xdp: XDP socket user-space interface
+ *
+ * Copyright(c) 2017 Intel Corporation.
+ *
+ * Author(s): Björn Töpel <bjorn.to...@intel.com>
+ *           Magnus Karlsson <magnus.karls...@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef _LINUX_IF_XDP_H
+#define _LINUX_IF_XDP_H
+
+#include <linux/types.h>
+
+struct sockaddr_xdp {
+       __u16   sxdp_family;
+       __u32   sxdp_ifindex;
+       __u32   sxdp_queue_id;
+};
+
+/* XDP socket options */
+#define XDP_MEM_REG    1
+#define XDP_RX_RING    2
+#define XDP_TX_RING    3
+
+#endif /* _LINUX_IF_XDP_H */
diff --git a/net/Kconfig b/net/Kconfig
index 37ec8e67af57..03e5c64b411d 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -59,6 +59,7 @@ source "net/tls/Kconfig"
 source "net/xfrm/Kconfig"
 source "net/iucv/Kconfig"
 source "net/smc/Kconfig"
+source "net/xdp/Kconfig"
 
 config INET
        bool "TCP/IP networking"
diff --git a/net/Makefile b/net/Makefile
index 14fede520840..9df8e6f827f8 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -86,3 +86,4 @@ obj-y                         += l3mdev/
 endif
 obj-$(CONFIG_QRTR)             += qrtr/
 obj-$(CONFIG_NET_NCSI)         += ncsi/
+obj-$(CONFIG_XDP_SOCKETS)      += xdp/
diff --git a/net/core/sock.c b/net/core/sock.c
index abf4cbff99b2..4d29430f4671 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -226,7 +226,8 @@ static struct lock_class_key 
af_family_kern_slock_keys[AF_MAX];
   x "AF_RXRPC" ,       x "AF_ISDN"     ,       x "AF_PHONET"   , \
   x "AF_IEEE802154",   x "AF_CAIF"     ,       x "AF_ALG"      , \
   x "AF_NFC"   ,       x "AF_VSOCK"    ,       x "AF_KCM"      , \
-  x "AF_QIPCRTR",      x "AF_SMC"      ,       x "AF_MAX"
+  x "AF_QIPCRTR",      x "AF_SMC"      ,       x "AF_XDP"      , \
+  x "AF_MAX"
 
 static const char *const af_family_key_strings[AF_MAX+1] = {
        _sock_locks("sk_lock-")
@@ -262,7 +263,8 @@ static const char *const 
af_family_rlock_key_strings[AF_MAX+1] = {
   "rlock-AF_RXRPC" , "rlock-AF_ISDN"     , "rlock-AF_PHONET"   ,
   "rlock-AF_IEEE802154", "rlock-AF_CAIF" , "rlock-AF_ALG"      ,
   "rlock-AF_NFC"   , "rlock-AF_VSOCK"    , "rlock-AF_KCM"      ,
-  "rlock-AF_QIPCRTR", "rlock-AF_SMC"     , "rlock-AF_MAX"
+  "rlock-AF_QIPCRTR", "rlock-AF_SMC"     , "rlock-AF_XDP"      ,
+  "rlock-AF_MAX"
 };
 static const char *const af_family_wlock_key_strings[AF_MAX+1] = {
   "wlock-AF_UNSPEC", "wlock-AF_UNIX"     , "wlock-AF_INET"     ,
@@ -279,7 +281,8 @@ static const char *const 
af_family_wlock_key_strings[AF_MAX+1] = {
   "wlock-AF_RXRPC" , "wlock-AF_ISDN"     , "wlock-AF_PHONET"   ,
   "wlock-AF_IEEE802154", "wlock-AF_CAIF" , "wlock-AF_ALG"      ,
   "wlock-AF_NFC"   , "wlock-AF_VSOCK"    , "wlock-AF_KCM"      ,
-  "wlock-AF_QIPCRTR", "wlock-AF_SMC"     , "wlock-AF_MAX"
+  "wlock-AF_QIPCRTR", "wlock-AF_SMC"     , "wlock-AF_XDP"      ,
+  "wlock-AF_MAX"
 };
 static const char *const af_family_elock_key_strings[AF_MAX+1] = {
   "elock-AF_UNSPEC", "elock-AF_UNIX"     , "elock-AF_INET"     ,
@@ -296,7 +299,8 @@ static const char *const 
af_family_elock_key_strings[AF_MAX+1] = {
   "elock-AF_RXRPC" , "elock-AF_ISDN"     , "elock-AF_PHONET"   ,
   "elock-AF_IEEE802154", "elock-AF_CAIF" , "elock-AF_ALG"      ,
   "elock-AF_NFC"   , "elock-AF_VSOCK"    , "elock-AF_KCM"      ,
-  "elock-AF_QIPCRTR", "elock-AF_SMC"     , "elock-AF_MAX"
+  "elock-AF_QIPCRTR", "elock-AF_SMC"     , "elock-AF_XDP"      ,
+  "elock-AF_MAX"
 };
 
 /*
diff --git a/net/xdp/Kconfig b/net/xdp/Kconfig
new file mode 100644
index 000000000000..90e4a7152854
--- /dev/null
+++ b/net/xdp/Kconfig
@@ -0,0 +1,7 @@
+config XDP_SOCKETS
+       bool "XDP sockets"
+       depends on BPF_SYSCALL
+       default n
+       help
+         XDP sockets allows a channel between XDP programs and
+         userspace applications.
diff --git a/net/xdp/Makefile b/net/xdp/Makefile
new file mode 100644
index 000000000000..0c7631f21586
--- /dev/null
+++ b/net/xdp/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_XDP_SOCKETS) += xsk.o
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
new file mode 100644
index 000000000000..2d7c08a50c60
--- /dev/null
+++ b/net/xdp/xsk.c
@@ -0,0 +1,133 @@
+/*
+ * XDP sockets
+ *
+ * AF_XDP sockets allows a channel between XDP programs and userspace
+ * applications.
+ *
+ * Copyright(c) 2017 Intel Corporation.
+ *
+ * Author(s): Björn Töpel <bjorn.to...@intel.com>
+ *           Magnus Karlsson <magnus.karls...@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#define pr_fmt(fmt) "AF_XDP: %s: " fmt, __func__
+
+#include <linux/if_xdp.h>
+#include <linux/init.h>
+#include <linux/socket.h>
+#include <net/sock.h>
+
+#include "xsk.h"
+
+struct xdp_sock {
+       /* struct sock must be the first member of struct xdp_sock */
+       struct sock sk;
+};
+
+static int xsk_release(struct socket *sock)
+{
+       return 0;
+}
+
+static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+{
+       return -EOPNOTSUPP;
+}
+
+static unsigned int xsk_poll(struct file *file, struct socket *sock,
+                            struct poll_table_struct *wait)
+{
+       return -EOPNOTSUPP;
+}
+
+static int xsk_setsockopt(struct socket *sock, int level, int optname,
+                         char __user *optval, unsigned int optlen)
+{
+       return -ENOPROTOOPT;
+}
+
+static int xsk_getsockopt(struct socket *sock, int level, int optname,
+                         char __user *optval, int __user *optlen)
+{
+       return -EOPNOTSUPP;
+}
+
+static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
+{
+       return -EOPNOTSUPP;
+}
+
+static int xsk_mmap(struct file *file, struct socket *sock,
+                   struct vm_area_struct *vma)
+{
+       return -EOPNOTSUPP;
+}
+
+static struct proto xsk_proto = {
+       .name =         "XDP",
+       .owner =        THIS_MODULE,
+       .obj_size =     sizeof(struct xdp_sock),
+};
+
+static const struct proto_ops xsk_proto_ops = {
+       .family =       PF_XDP,
+       .owner =        THIS_MODULE,
+       .release =      xsk_release,
+       .bind =         xsk_bind,
+       .connect =      sock_no_connect,
+       .socketpair =   sock_no_socketpair,
+       .accept =       sock_no_accept,
+       .getname =      sock_no_getname, /* XXX do we need this? */
+       .poll =         xsk_poll,
+       .ioctl =        sock_no_ioctl, /* XXX do we need this? */
+       .listen =       sock_no_listen,
+       .shutdown =     sock_no_shutdown,
+       .setsockopt =   xsk_setsockopt,
+       .getsockopt =   xsk_getsockopt,
+       /* XXX make sure we don't rely on any ioctl/{get,set}sockopt that would 
require CONFIG_COMPAT! */
+       .sendmsg =      xsk_sendmsg,
+       .recvmsg =      sock_no_recvmsg,
+       .mmap =         xsk_mmap,
+       .sendpage =     sock_no_sendpage,
+       /* the rest vvv, OK to be missing implementation -- checked against 
NULL. */
+};
+
+static int xsk_create(struct net *net, struct socket *sock, int protocol,
+                     int kern)
+{
+       return -EOPNOTSUPP;
+}
+
+static const struct net_proto_family xsk_family_ops = {
+       .family = PF_XDP,
+       .create = xsk_create,
+       .owner  = THIS_MODULE,
+};
+
+/* XXX Do we need any namespace support? _pernet_subsys and friends */
+static int __init xsk_init(void)
+{
+       int err;
+
+       err = proto_register(&xsk_proto, 0 /* no slab */);
+       if (err)
+               goto out;
+
+       err = sock_register(&xsk_family_ops);
+       if (err)
+               goto out_proto;
+
+       return 0;
+
+out_proto:
+       proto_unregister(&xsk_proto);
+out:
+       return err;
+}
+
+fs_initcall(xsk_init);
diff --git a/net/xdp/xsk.h b/net/xdp/xsk.h
new file mode 100644
index 000000000000..441f8d00a9d5
--- /dev/null
+++ b/net/xdp/xsk.h
@@ -0,0 +1,18 @@
+/*
+ *  XDP sockets
+ *  Copyright(c) 2017 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _LINUX_XDPSOCK_H
+#define _LINUX_XDPSOCK_H
+
+#endif /* _LINUX_XDPSOCK_H */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8644d864e3c1..b6b959c5efb3 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1436,7 +1436,9 @@ static inline u16 socket_type_to_security_class(int 
family, int type, int protoc
                        return SECCLASS_QIPCRTR_SOCKET;
                case PF_SMC:
                        return SECCLASS_SMC_SOCKET;
-#if PF_MAX > 44
+               case PF_XDP:
+                       return SECCLASS_XDP_SOCKET;
+#if PF_MAX > 45
 #error New address family defined, please update this function.
 #endif
                }
diff --git a/security/selinux/include/classmap.h 
b/security/selinux/include/classmap.h
index acdee7795297..e2044cd358bb 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -240,9 +240,11 @@ struct security_class_mapping secclass_map[] = {
          { "manage_subnet", NULL } },
        { "bpf",
          {"map_create", "map_read", "map_write", "prog_load", "prog_run"} },
+       { "xdp_socket",
+         { COMMON_SOCK_PERMS, NULL } },
        { NULL }
   };
 
-#if PF_MAX > 44
+#if PF_MAX > 45
 #error New address family defined, please update secclass_map.
 #endif
-- 
2.14.1

Reply via email to