Skip to contentSkip to conversation

GRE over IPv6

PATCH Superseded Dmitry Kozlov 2 participants 4 messages Jul 29, 2012 – Jul 30, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH v3 1/1 GRE over IPv6

GRE over IPv6 implementation.

---
Changes:
Initialize nt->dev before calling ip6gre_tnl_link_config in ip6gre_newlink.
Add missing ip6gre.c

 include/linux/if_arp.h     |    1 +
 include/linux/if_tunnel.h  |    3 +
 include/linux/ip6_tunnel.h |   18 +
 include/net/ip6_tunnel.h   |   40 +-
 include/net/ipv6.h         |    1 +
 net/ipv6/Kconfig           |   16 +
 net/ipv6/Makefile          |    1 +
 net/ipv6/ip6_gre.c         | 1817 ++++++++++++++++++++++++++++++++++++++++++++
 net/ipv6/ip6_tunnel.c      |   86 ++-
 9 files changed, 1958 insertions(+), 25 deletions(-)
include/linux/if_arp.h +1 -0
index f0e69c6..9adcc29 100644
@@ -92,6 +92,7 @@
 #define ARPHRD_PHONET	820		/* PhoNet media type		*/
 #define ARPHRD_PHONET_PIPE 821		/* PhoNet pipe header		*/
 #define ARPHRD_CAIF	822		/* CAIF media type		*/
+#define ARPHRD_IP6GRE	823		/* GRE over IPv6		*/
 
 #define ARPHRD_VOID	  0xFFFF	/* Void type, nothing is known */
 #define ARPHRD_NONE	  0xFFFE	/* zero header length */
include/linux/if_tunnel.h +3 -0
index 5efff60..8c5035a 100644
@@ -75,6 +75,9 @@ enum {
 	IFLA_GRE_TTL,
 	IFLA_GRE_TOS,
 	IFLA_GRE_PMTUDISC,
+	IFLA_GRE_ENCAP_LIMIT,
+	IFLA_GRE_FLOWINFO,
+	IFLA_GRE_FLAGS,
 	__IFLA_GRE_MAX,
 };
 
include/linux/ip6_tunnel.h +18 -0
index bf22b03..1efe2e0 100644
@@ -31,4 +31,22 @@ struct ip6_tnl_parm {
 	struct in6_addr raddr;	/* remote tunnel end-point address */
 };
 
+struct ip6_tnl_parm2 {
+	char name[IFNAMSIZ];	/* name of tunnel device */
+	int link;		/* ifindex of underlying L2 interface */
+	__u8 proto;		/* tunnel protocol */
+	__u8 encap_limit;	/* encapsulation limit for tunnel */
+	__u8 hop_limit;		/* hop limit for tunnel */
+	__be32 flowinfo;	/* traffic class and flowlabel for tunnel */
+	__u32 flags;		/* tunnel flags */
+	struct in6_addr laddr;	/* local tunnel end-point address */
+	struct in6_addr raddr;	/* remote tunnel end-point address */
+
+	__be16			i_flags;
+	__be16			o_flags;
+	__be32			i_key;
+	__be32			o_key;
+};
+
+
 #endif
include/net/ip6_tunnel.h +39 -1
index 358fb86..8400ba0 100644
@@ -5,6 +5,8 @@
 #include <linux/netdevice.h>
 #include <linux/ip6_tunnel.h>
 
+#define IP6TUNNEL_ERR_TIMEO (30*HZ)
+
 /* capable of sending packets */
 #define IP6_TNL_F_CAP_XMIT 0x10000
 /* capable of receiving packets */
@@ -13,14 +15,40 @@
 #define IP6_TNL_F_CAP_PER_PACKET 0x40000
 
 /* IPv6 tunnel */
+struct __ip6_tnl_parm
+{
+	char name[IFNAMSIZ];	/* name of tunnel device */
+	int link;		/* ifindex of underlying L2 interface */
+	__u8 proto;		/* tunnel protocol */
+	__u8 encap_limit;	/* encapsulation limit for tunnel */
+	__u8 hop_limit;		/* hop limit for tunnel */
+	__be32 flowinfo;	/* traffic class and flowlabel for tunnel */
+	__u32 flags;		/* tunnel flags */
+	struct in6_addr laddr;	/* local tunnel end-point address */
+	struct in6_addr raddr;	/* remote tunnel end-point address */
+
+	__be16			i_flags;
+	__be16			o_flags;
+	__be32			i_key;
+	__be32			o_key;
+};
 
 struct ip6_tnl {
 	struct ip6_tnl __rcu *next;	/* next tunnel in list */
 	struct net_device *dev;	/* virtual device associated with tunnel */
-	struct ip6_tnl_parm parms;	/* tunnel configuration parameters */
+	struct __ip6_tnl_parm parms;	/* tunnel configuration parameters */
 	struct flowi fl;	/* flowi template for xmit */
 	struct dst_entry *dst_cache;    /* cached dst */
 	u32 dst_cookie;
+
+	int err_count;
+	unsigned long err_time;
+
+	/* These fields used only by GRE */
+	__u32			i_seqno;	/* The last seen seqno	*/
+	__u32			o_seqno;	/* The last output seqno */
+	int			hlen;		/* Precalculated GRE header length */
+	int mlink;
 };
 
 /* Tunnel encapsulation limit destination sub-option */
@@ -31,4 +59,14 @@ struct ipv6_tlv_tnl_enc_lim {
 	__u8 encap_limit;	/* tunnel encapsulation limit   */
 } __packed;
 
+struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t);
+void ip6_tnl_dst_reset(struct ip6_tnl *t);
+void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst);
+int ip6_tnl_rcv_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
+		const struct in6_addr *raddr);
+int ip6_tnl_xmit_ctl(struct ip6_tnl *t);
+__u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 * raw);
+__u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr,
+			     const struct in6_addr *raddr);
+
 #endif
include/net/ipv6.h +1 -0
index 01c34b3..6d01fb0 100644
@@ -34,6 +34,7 @@
 #define NEXTHDR_IPV6		41	/* IPv6 in IPv6 */
 #define NEXTHDR_ROUTING		43	/* Routing header. */
 #define NEXTHDR_FRAGMENT	44	/* Fragmentation/reassembly header. */
+#define NEXTHDR_GRE		47	/* GRE header. */
 #define NEXTHDR_ESP		50	/* Encapsulating security payload. */
 #define NEXTHDR_AUTH		51	/* Authentication header. */
 #define NEXTHDR_ICMP		58	/* ICMP for IPv6. */
net/ipv6/Kconfig +16 -0
index 5728695..4f7fe72 100644
@@ -201,6 +201,22 @@ config IPV6_TUNNEL
 
 	  If unsure, say N.
 
+config IPV6_GRE
+	tristate "IPv6: GRE tunnel"
+	select IPV6_TUNNEL
+	---help---
+	  Tunneling means encapsulating data of one protocol type within
+	  another protocol and sending it over a channel that understands the
+	  encapsulating protocol. This particular tunneling driver implements
+	  GRE (Generic Routing Encapsulation) and at this time allows
+	  encapsulating of IPv4 or IPv6 over existing IPv6 infrastructure.
+	  This driver is useful if the other endpoint is a Cisco router: Cisco
+	  likes GRE much better than the other Linux tunneling driver ("IP
+	  tunneling" above). In addition, GRE allows multicast redistribution
+	  through the tunnel.
+
+	  Saying M here will produce a module called ip6_gre. If unsure, say N.
+
 config IPV6_MULTIPLE_TABLES
 	bool "IPv6: Multiple Routing Tables"
 	depends on EXPERIMENTAL
net/ipv6/Makefile +1 -0
index 686934a..b6d3f79 100644
@@ -36,6 +36,7 @@ obj-$(CONFIG_NETFILTER)	+= netfilter/
 
 obj-$(CONFIG_IPV6_SIT) += sit.o
 obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
+obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
 
 obj-y += addrconf_core.o exthdrs_core.o
 
net/ipv6/ip6_gre.c new file +1817 -0

1,817 lines not on this page · raw message

net/ipv6/ip6_tunnel.c +62 -24

247 lines not on this page · raw message

#1 lore raw
Quoted 18 lines · On Sat, 28 Jul 2012 22:12:42 -0000 [email protected] wrote:

GRE over IPv6 implementation.

---
Changes:
Initialize nt->dev before calling ip6gre_tnl_link_config in ip6gre_newlink.
Add missing ip6gre.c

 include/linux/if_arp.h     |    1 +
 include/linux/if_tunnel.h  |    3 +
 include/linux/ip6_tunnel.h |   18 +
 include/net/ip6_tunnel.h   |   40 +-
 include/net/ipv6.h         |    1 +
 net/ipv6/Kconfig           |   16 +
 net/ipv6/Makefile          |    1 +
 net/ipv6/ip6_gre.c         | 1817
Quoted 3 lines

++++++++++++++++++++++++++++++++++++++++++++
net/ipv6/ip6_tunnel.c | 86 ++- 9 files changed, 1958
insertions(+), 25 deletions(-)

Would it be possible and/or feasible to instead modify ip_gre to support also ipv6 as outer protocol?

It already has ipv6 stuff in it for the inner protocol support. And it would avoid duplicating most of the code.

And I would especially love that approach, since I could then on per-target basis say if it should be contacted with IPv4 or IPv6. As in:

ip addr add 10.0.0.1/24 dev gre1
ip neigh add 10.0.0.2 lladdr 192.168.x.x dev gre1 nud permanent
ip neigh add 10.0.0.3 lladdr fe80::xxxx:xxxx:xxxx:xxxx/64 dev gre1 nud permanent

- Timo

#2 lore raw
Quoted 30 lines · On Monday 30 July 2012 14:38:06 Timo Teras wrote:
Quoted 19 lines · On Sat, 28 Jul 2012 22:12:42 -0000 [email protected] wrote:

GRE over IPv6 implementation.

---
Changes:
Initialize nt->dev before calling ip6gre_tnl_link_config in ip6gre_newlink.
Add missing ip6gre.c

 include/linux/if_arp.h     |    1 +
 include/linux/if_tunnel.h  |    3 +
 include/linux/ip6_tunnel.h |   18 +
 include/net/ip6_tunnel.h   |   40 +-
 include/net/ipv6.h         |    1 +
 net/ipv6/Kconfig           |   16 +
 net/ipv6/Makefile          |    1 +
 net/ipv6/ip6_gre.c         | 1817
Quoted 3 lines

++++++++++++++++++++++++++++++++++++++++++++
net/ipv6/ip6_tunnel.c | 86 ++- 9 files changed, 1958
insertions(+), 25 deletions(-)

Would it be possible and/or feasible to instead modify ip_gre to support also ipv6 as outer protocol?

It already has ipv6 stuff in it for the inner protocol support. And it would avoid duplicating most of the code.

Quoted 7 lines

And I would especially love that approach, since I could then on per-target basis say if it should be contacted with IPv4 or IPv6. As in:

ip addr add 10.0.0.1/24 dev gre1
ip neigh add 10.0.0.2 lladdr 192.168.x.x dev gre1 nud permanent ip neigh add 10.0.0.3 lladdr fe80::xxxx:xxxx:xxxx:xxxx/64 dev gre1 nud
permanent

Sounds good, but it involves too many if/else because there are much ipv4 and ipv6 specifics and code will be unreadable. I see only shared part is tunnel initialization and managing code.
Tunnel lookup, receive and transmit parts are mostly different.

#3 lore raw
Quoted 40 lines · On Mon, 30 Jul 2012 15:52:46 +0400 Kozlov Dmitry <[email protected]> wrote:
Quoted 30 lines · On Monday 30 July 2012 14:38:06 Timo Teras wrote:
Quoted 19 lines · On Sat, 28 Jul 2012 22:12:42 -0000 [email protected] wrote:

GRE over IPv6 implementation.

---
Changes:
Initialize nt->dev before calling ip6gre_tnl_link_config in ip6gre_newlink.
Add missing ip6gre.c

 include/linux/if_arp.h     |    1 +
 include/linux/if_tunnel.h  |    3 +
 include/linux/ip6_tunnel.h |   18 +
 include/net/ip6_tunnel.h   |   40 +-
 include/net/ipv6.h         |    1 +
 net/ipv6/Kconfig           |   16 +
 net/ipv6/Makefile          |    1 +
 net/ipv6/ip6_gre.c         | 1817
Quoted 3 lines

++++++++++++++++++++++++++++++++++++++++++++
net/ipv6/ip6_tunnel.c | 86 ++- 9 files changed, 1958
insertions(+), 25 deletions(-)

Would it be possible and/or feasible to instead modify ip_gre to support also ipv6 as outer protocol?

It already has ipv6 stuff in it for the inner protocol support. And it would avoid duplicating most of the code.

Quoted 8 lines

And I would especially love that approach, since I could then on per-target basis say if it should be contacted with IPv4 or IPv6. As in:

ip addr add 10.0.0.1/24 dev gre1
ip neigh add 10.0.0.2 lladdr 192.168.x.x dev gre1 nud permanent ip neigh add 10.0.0.3 lladdr fe80::xxxx:xxxx:xxxx:xxxx/64 dev
gre1 nud permanent

Quoted 4 lines

Sounds good, but it involves too many if/else because there are much ipv4 and ipv6 specifics and code will be unreadable. I see only shared part is tunnel initialization and managing code. Tunnel lookup, receive and transmit parts are mostly different.

Hmm... And thinking more, it looks like various other places need lot of tuning; e.g. tunnel might need multiple local address bindings which is not nice.

And now that I checked, seems Cisco also needs separate tunnel interfaces for "over IPv4" and "over IPv6" targets. That's rather inconvenient, but seems to be how things are.