From: Tom Herbert <tom@herbertland.com>
To: <davem@davemloft.net>, <netdev@vger.kernel.org>
Cc: <kernel-team@fb.com>
Subject: [PATCH net-next 3/8] tou: Base infrastructure for Transport over UDP
Date: Thu, 16 Jun 2016 10:51:57 -0700 [thread overview]
Message-ID: <1466099522-690741-4-git-send-email-tom@herbertland.com> (raw)
In-Reply-To: <1466099522-690741-1-git-send-email-tom@herbertland.com>
Add tou.c that implements common setsockopt functionality. This includes
initialization and argument structure for the setsockopt.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/inet_sock.h | 2 +
include/net/ip_tunnels.h | 1 +
include/uapi/linux/if_tunnel.h | 10 +++
net/ipv4/Makefile | 3 +-
net/ipv4/af_inet.c | 4 ++
net/ipv4/tou.c | 140 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 159 insertions(+), 1 deletion(-)
create mode 100644 net/ipv4/tou.c
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 012b1f9..d39f383 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -167,6 +167,7 @@ struct rtable;
* @uc_index - Unicast outgoing device index
* @mc_index - Multicast device index
* @mc_list - Group array
+ * @tou_encap - Transports over UDP encapsulation
* @cork - info to build ip hdr on each ip frag while socket is corked
*/
struct inet_sock {
@@ -209,6 +210,7 @@ struct inet_sock {
__be32 mc_addr;
struct ip_mc_socklist __rcu *mc_list;
struct inet_cork_full cork;
+ struct ip_tunnel_encap *tou_encap;
};
#define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 7594132..e7ec9eb 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -88,6 +88,7 @@ struct ip_tunnel_encap {
u16 flags;
__be16 sport;
__be16 dport;
+ struct rcu_head rcu_head;
};
struct ip_tunnel_prl_entry {
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index 1046f55..d0415ae 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -71,6 +71,16 @@ enum tunnel_encap_types {
#define TUNNEL_ENCAP_FLAG_CSUM6 (1<<1)
#define TUNNEL_ENCAP_FLAG_REMCSUM (1<<2)
+/* Structure for Transport Over UDP (TOU) encapsulation. This is used in
+ * setsockopt of inet sockets.
+ */
+struct tou_encap {
+ u16 type; /* enum tunnel_encap_types */
+ u16 flags;
+ __be16 sport;
+ __be16 dport;
+};
+
/* SIT-mode i_flags */
#define SIT_ISATAP 0x0001
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 24629b6..c4349e2 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -12,7 +12,8 @@ obj-y := route.o inetpeer.o protocol.o \
tcp_offload.o datagram.o raw.o udp.o udplite.o \
udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \
fib_frontend.o fib_semantics.o fib_trie.o \
- inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o
+ inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o \
+ tou.o
obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d39e9e4..9a49376 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -120,6 +120,7 @@
#include <linux/mroute.h>
#endif
#include <net/l3mdev.h>
+#include <net/tou.h>
/* The inetsw table contains everything that inet_create needs to
@@ -1830,6 +1831,9 @@ static int __init inet_init(void)
/* Add UDP-Lite (RFC 3828) */
udplite4_register();
+ /* Set TOU slab cache (Transport layer encapsulation over UDP) */
+ tou_init();
+
ping_init();
/*
diff --git a/net/ipv4/tou.c b/net/ipv4/tou.c
new file mode 100644
index 0000000..ef9999f
--- /dev/null
+++ b/net/ipv4/tou.c
@@ -0,0 +1,140 @@
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <net/genetlink.h>
+#include <net/gue.h>
+#include <net/ip.h>
+#include <net/protocol.h>
+#include <net/udp.h>
+#include <net/udp_tunnel.h>
+#include <net/xfrm.h>
+#include <net/tou.h>
+#include <net/ip6_tunnel.h>
+#include <uapi/linux/fou.h>
+#include <uapi/linux/genetlink.h>
+
+static struct kmem_cache *tou_cachep __read_mostly;
+
+static void tou_encap_rcu_free(struct rcu_head *head)
+{
+ struct ip_tunnel_encap *e = container_of(head, struct ip_tunnel_encap,
+ rcu_head);
+
+ kmem_cache_free(tou_cachep, e);
+}
+
+int tou_encap_setsockopt(struct sock *sk, char __user *optval, int optlen,
+ bool is_ipv6)
+{
+ struct tou_encap te;
+ struct ip_tunnel_encap encap;
+ struct inet_sock *inet = inet_sk(sk);
+ struct ip_tunnel_encap *e = inet->tou_encap;
+ int hlen = 0, old_hlen = 0;
+
+ if (optlen < sizeof(te))
+ return -EINVAL;
+
+ if (copy_from_user(&te, optval, sizeof(te)))
+ return -EFAULT;
+
+ if (e) {
+ old_hlen = is_ipv6 ? ip6_encap_hlen(e) : ip_encap_hlen(e);
+ if (unlikely(old_hlen < 0))
+ return -EINVAL;
+ }
+
+ if (te.type == TUNNEL_ENCAP_NONE) {
+ if (e) {
+ if (unlikely(old_hlen < 0))
+ return -EINVAL;
+
+ rcu_assign_pointer(inet->tou_encap, NULL);
+ call_rcu(&e->rcu_head, tou_encap_rcu_free);
+
+ goto adjust_ext_hdr;
+ } else {
+ return 0;
+ }
+ }
+
+ memset(&encap, 0, sizeof(encap));
+ encap.type = te.type;
+ encap.sport = te.sport;
+ encap.dport = te.dport;
+ encap.flags = te.flags;
+
+ hlen = is_ipv6 ? ip6_encap_hlen(e) : ip_encap_hlen(e);
+ if (hlen < 0)
+ return hlen;
+
+ if (!e) {
+ e = kmem_cache_alloc(tou_cachep, GFP_KERNEL);
+ if (!e)
+ return -ENOMEM;
+ rcu_assign_pointer(inet->tou_encap, e);
+ }
+
+ *e = encap;
+
+adjust_ext_hdr:
+ if (inet->is_icsk) {
+ struct inet_connection_sock *icsk = inet_csk(sk);
+
+ /* For a connected socket add the overhead of encapsulation
+ * (specifically the difference between the new encapsulation
+ * and the old one it present) into the extrenal header length
+ * and adjust the mss.
+ */
+ icsk->icsk_ext_hdr_len += (hlen - old_hlen);
+ icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(tou_encap_setsockopt);
+
+int tou_encap_getsockopt(struct sock *sk, char __user *optval,
+ int len, int __user *optlen, bool is_ipv6)
+{
+ struct tou_encap te;
+ struct inet_sock *inet = inet_sk(sk);
+ struct ip_tunnel_encap *e = inet->tou_encap;
+
+ if (len < sizeof(te))
+ return -EINVAL;
+
+ len = sizeof(te);
+
+ memset(&te, 0, sizeof(te));
+
+ if (!e) {
+ te.type = TUNNEL_ENCAP_NONE;
+ } else {
+ te.type = e->type;
+ te.sport = e->sport;
+ te.dport = e->dport;
+ te.flags = e->flags;
+ }
+
+ if (put_user(len, optlen))
+ return -EFAULT;
+
+ if (copy_to_user(optval, &te, len))
+ return -EFAULT;
+
+ return 0;
+}
+EXPORT_SYMBOL(tou_encap_getsockopt);
+
+void __init tou_init(void)
+{
+ tou_cachep = kmem_cache_create("tou_cache",
+ sizeof(struct ip_tunnel_encap), 0,
+ SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
+}
--
2.8.0.rc2
next prev parent reply other threads:[~2016-06-16 17:52 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-16 17:51 [PATCH net-next 0/8] tou: Transports over UDP - part I Tom Herbert
2016-06-16 17:51 ` [PATCH net-next 1/8] net: Change SKB_GSO_DODGY to be a tx_flag Tom Herbert
2016-06-16 18:58 ` Alexander Duyck
2016-06-16 20:18 ` Tom Herbert
2016-06-16 20:33 ` Alexander Duyck
2016-06-17 22:33 ` Tom Herbert
2016-06-16 17:51 ` [PATCH net-next 2/8] fou: Change ip_tunnel_encap to take net argument Tom Herbert
2016-06-16 17:51 ` Tom Herbert [this message]
2016-06-16 17:51 ` [PATCH net-next 4/8] ipv4: Support TOU Tom Herbert
2016-06-16 17:51 ` [PATCH net-next 5/8] tcp: Support for TOU Tom Herbert
2016-06-16 17:52 ` [PATCH net-next 6/8] ipv6: Support TOU Tom Herbert
2016-06-16 17:52 ` [PATCH net-next 7/8] tcp6: Support for TOU Tom Herbert
2016-06-16 17:52 ` [PATCH net-next 8/8] tou: Support for GSO Tom Herbert
2016-06-16 18:10 ` [PATCH net-next 0/8] tou: Transports over UDP - part I Rick Jones
2016-06-16 23:15 ` Hannes Frederic Sowa
2016-06-17 16:51 ` Tom Herbert
2016-06-21 16:56 ` Hannes Frederic Sowa
2016-06-18 3:09 ` David Miller
2016-06-18 3:52 ` Tom Herbert
2016-06-19 20:15 ` Hajime Tazaki
2016-06-20 3:07 ` David Miller
2016-06-20 15:13 ` Tom Herbert
2016-06-21 8:29 ` David Miller
2016-06-22 3:42 ` Jerry Chu
2016-06-22 4:06 ` David Ahern
2016-06-22 19:24 ` David Miller
2016-06-22 17:40 ` Tom Herbert
2016-06-22 19:23 ` David Miller
2016-06-25 15:56 ` Tom Herbert
2016-06-21 17:11 ` Hannes Frederic Sowa
2016-06-21 17:23 ` Tom Herbert
2016-06-22 22:15 ` Richard Weinberger
2016-06-22 22:56 ` Tom Herbert
2016-06-23 7:40 ` David Miller
2016-06-23 7:50 ` Richard Weinberger
2016-06-24 21:12 ` Tom Herbert
2016-06-24 21:36 ` Rick Jones
2016-06-24 21:46 ` Tom Herbert
2016-06-24 22:06 ` Rick Jones
2016-06-24 23:43 ` Tom Herbert
2016-06-25 0:01 ` Rick Jones
2016-06-25 16:22 ` Tom Herbert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1466099522-690741-4-git-send-email-tom@herbertland.com \
--to=tom@herbertland.com \
--cc=davem@davemloft.net \
--cc=kernel-team@fb.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).