diff mbox

[net-next] ipip: Add room for user-specified custom header

Message ID 1376296778-1983-1-git-send-email-kristian.evensen@gmail.com
State Rejected, archived
Delegated to: David Miller
Headers show

Commit Message

Kristian Evensen Aug. 12, 2013, 8:39 a.m. UTC
This patch adds support for specifying the size of a custom header to be
inserted between the two IP headers. The actual content will be inserted later,
for example by a module that is attached to a hook.

A use-case for the feature provided by this patch is to ease the implementation
of custom tunneling protocols. Instead of implementing them directly in the
kernel and having to look out for changes in the kernel behavior/APIs, a
tunneling protocol can be implemented as an independent module.

To avoid breaking user space (by updating ip_tunnel_params), it is only possible
to specify the custom header length when an IPIP-tunnel is created using
netlink-messages.

Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
---
 include/uapi/linux/if_tunnel.h |  1 +
 net/ipv4/ipip.c                | 20 ++++++++++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

Comments

David Miller Aug. 14, 2013, 8:39 p.m. UTC | #1
From: Kristian Evensen <kristian.evensen@gmail.com>
Date: Mon, 12 Aug 2013 10:39:38 +0200

> This patch adds support for specifying the size of a custom header to be
> inserted between the two IP headers. The actual content will be inserted later,
> for example by a module that is attached to a hook.
> 
> A use-case for the feature provided by this patch is to ease the implementation
> of custom tunneling protocols. Instead of implementing them directly in the
> kernel and having to look out for changes in the kernel behavior/APIs, a
> tunneling protocol can be implemented as an independent module.
> 
> To avoid breaking user space (by updating ip_tunnel_params), it is only possible
> to specify the custom header length when an IPIP-tunnel is created using
> netlink-messages.
> 
> Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>

Sorry I'm not even going to consider applying this until you post
use-cases for this feature, because right now it just looks like a
random way to facilitate some third party proprietary kernel module
or similar.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kristian Evensen Aug. 15, 2013, 6:11 a.m. UTC | #2
On Wed, Aug 14, 2013 at 10:39 PM, David Miller <davem@davemloft.net> wrote:
>
> Sorry I'm not even going to consider applying this until you post
> use-cases for this feature, because right now it just looks like a
> random way to facilitate some third party proprietary kernel module
> or similar.

Thank you for your feedback and I agree, one challenge with this patch
is that it easy facilitates proprietary code.

My use-case when creating this patch was to simplify the
implementation of IP-in-UDP tunneling. I initially started out by
cloning IP-in-IP and managing a set of UDP-sockets (for the incoming
packets), but it seemed like overkill for something so simple.
Especially since UDP source ports are used on something that does not
need to be UDP sockets. So instead I made space between the IP headers
for the UDP header, and the UDP header was inserted using an xtables
extension. I was planning to post the xtables-module at the same time,
but some other things came in the way. There are only a few features
missing, so it will be out soon. I am aware that all of this could be
implemented in the xtables-module directly, but the additional
memmove() required has an impact on performance on the devices I am
working with.

Another, and perhaps more interesting, use-case is to ease development
and prototyping of new transport protocols on slower devices (for
example typical consumer routers). In the research lab I belong to, we
are currently looking into new protocols designed for mobile broadband
networks. In order to have the largest possible selection of test
applications and to avoid modifying client devices, we use existing
applications (or applications using existing protocols) and tunnel the
traffic through tunnels using our protocol. The devices we have are
too slow for user-space tunneling and the links are all connected to
the public internet. The protocol logic and header insertion is kept
in a separate xtables-module. Using this approach has improved the
speed at which we are able to prototype for example new flow or
congestion control algorithms, and given us sufficient networking
performance.

What is the recommended way forward for getting this patch considered?
Shall I focus on finishing the xtables example-module, or abandon this
patch and implement IP in UDP as a new tunneling protocol in the
kernel?

(Sorry about sending two emails, it was too early in the morning and I
forgot to enable plain-text)

-Kristian
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index aee73d0..a8ef1d3 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -44,6 +44,7 @@  enum {
 	IFLA_IPTUN_REMOTE,
 	IFLA_IPTUN_TTL,
 	IFLA_IPTUN_TOS,
+	IFLA_IPTUN_HLEN,
 	IFLA_IPTUN_ENCAP_LIMIT,
 	IFLA_IPTUN_FLOWINFO,
 	IFLA_IPTUN_FLAGS,
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 51fc2a1..1e5bd85 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -190,13 +190,14 @@  static int ipip_rcv(struct sk_buff *skb)
 	struct ip_tunnel *tunnel;
 	const struct iphdr *iph;
 
-	if (iptunnel_pull_header(skb, 0, tpi.proto))
-		goto drop;
-
 	iph = ip_hdr(skb);
 	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
 			iph->saddr, iph->daddr, 0);
+
 	if (tunnel) {
+		if (iptunnel_pull_header(skb, tunnel->hlen, tpi.proto))
+			goto drop;
+
 		if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
 			goto drop;
 		return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error);
@@ -226,6 +227,9 @@  static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb->encapsulation = 1;
 	}
 
+	if (tunnel->hlen > 0)
+		skb_push(skb, tunnel->hlen);
+
 	ip_tunnel_xmit(skb, dev, tiph, tiph->protocol);
 	return NETDEV_TX_OK;
 
@@ -302,7 +306,6 @@  static int ipip_tunnel_init(struct net_device *dev)
 	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
 	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
 
-	tunnel->hlen = 0;
 	tunnel->parms.iph.protocol = IPPROTO_IPIP;
 	return ip_tunnel_init(dev);
 }
@@ -345,8 +348,13 @@  static int ipip_newlink(struct net *src_net, struct net_device *dev,
 			struct nlattr *tb[], struct nlattr *data[])
 {
 	struct ip_tunnel_parm p;
+	struct ip_tunnel *tunnel = netdev_priv(dev);
 
 	ipip_netlink_parms(data, &p);
+
+	if (data[IFLA_IPTUN_HLEN])
+		tunnel->hlen = nla_get_u32(data[IFLA_IPTUN_HLEN]);
+
 	return ip_tunnel_newlink(dev, tb, &p);
 }
 
@@ -373,6 +381,8 @@  static size_t ipip_get_size(const struct net_device *dev)
 		nla_total_size(4) +
 		/* IFLA_IPTUN_REMOTE */
 		nla_total_size(4) +
+		/* IFLA_IPTUN_HLEN */
+		nla_total_size(4) +
 		/* IFLA_IPTUN_TTL */
 		nla_total_size(1) +
 		/* IFLA_IPTUN_TOS */
@@ -390,6 +400,7 @@  static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
 	    nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) ||
 	    nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) ||
+	    nla_put_u32(skb, IFLA_IPTUN_HLEN, tunnel->hlen) ||
 	    nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) ||
 	    nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) ||
 	    nla_put_u8(skb, IFLA_IPTUN_PMTUDISC,
@@ -405,6 +416,7 @@  static const struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = {
 	[IFLA_IPTUN_LINK]		= { .type = NLA_U32 },
 	[IFLA_IPTUN_LOCAL]		= { .type = NLA_U32 },
 	[IFLA_IPTUN_REMOTE]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_HLEN]		= { .type = NLA_U32 },
 	[IFLA_IPTUN_TTL]		= { .type = NLA_U8 },
 	[IFLA_IPTUN_TOS]		= { .type = NLA_U8 },
 	[IFLA_IPTUN_PMTUDISC]		= { .type = NLA_U8 },