All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/4] tunnels: fix incorrect IPv4/v6 headers interpretation
@ 2015-08-28 14:27 Jiri Benc
  2015-08-28 14:27 ` [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags Jiri Benc
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Jiri Benc @ 2015-08-28 14:27 UTC (permalink / raw)
  To: netdev; +Cc: Thomas Graf

With tunneling, it is currently possible to get an IPv6 header and interpret
it as an IPv4 header, or to interpret an IPv6 address as an IPv4 address
(and vice versa). This leads to things like sending packets to incorrect
address, IPv6 flow label being interpreted as IP packet length, etc.

Fix several places where this can happen.

Most of this is net-next only. The third patch affects net, too, but it
doesn't seem there's anything in user space that sets the attribute at all
currently, thus net-next is fine.

Jiri Benc (4):
  ip_tunnels: convert the mode field of ip_tunnel_info to flags
  ip_tunnels: record IP version in tunnel info
  fou: reject IPv6 config
  vxlan: do not receive IPv4 packets on IPv6 socket

 drivers/net/geneve.c       |  3 +++
 drivers/net/vxlan.c        |  5 ++++-
 include/net/dst_metadata.h |  2 +-
 include/net/ip_tunnels.h   | 19 ++++++++++++-------
 include/net/udp_tunnel.h   |  3 ++-
 net/core/filter.c          |  2 ++
 net/ipv4/fou.c             |  2 +-
 net/ipv4/ip_gre.c          |  3 ++-
 net/ipv4/ip_tunnel_core.c  |  2 +-
 net/ipv4/route.c           |  2 +-
 net/ipv6/ip6_udp_tunnel.c  |  9 +++++++++
 net/ipv6/route.c           |  2 +-
 net/openvswitch/flow.c     |  2 ++
 net/openvswitch/vport.c    |  2 ++
 14 files changed, 43 insertions(+), 15 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags
  2015-08-28 14:27 [PATCH net-next 0/4] tunnels: fix incorrect IPv4/v6 headers interpretation Jiri Benc
@ 2015-08-28 14:27 ` Jiri Benc
  2015-08-28 16:32   ` Alexei Starovoitov
  2015-08-28 17:29   ` Pravin Shelar
  2015-08-28 14:27 ` [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info Jiri Benc
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Jiri Benc @ 2015-08-28 14:27 UTC (permalink / raw)
  To: netdev; +Cc: Thomas Graf

The mode field holds a single bit of information only (whether the
ip_tunnel_info struct is for rx or tx). Change the mode field to bit flags.
This allows more mode flags to be added.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
 drivers/net/vxlan.c        | 2 +-
 include/net/dst_metadata.h | 1 -
 include/net/ip_tunnels.h   | 9 ++-------
 net/ipv4/ip_gre.c          | 2 +-
 net/ipv4/route.c           | 2 +-
 net/ipv6/route.c           | 2 +-
 6 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 30e56cb58884..bd1b8cdf2bf6 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2113,7 +2113,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	if (vxlan->flags & VXLAN_F_COLLECT_METADATA &&
-	    info && info->mode == IP_TUNNEL_INFO_TX) {
+	    info && info->mode & IP_TUNNEL_INFO_TX) {
 		vxlan_xmit_one(skb, dev, NULL, false);
 		return NETDEV_TX_OK;
 	}
diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index 60c03326c087..2b83f0d232e0 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -59,7 +59,6 @@ static inline struct metadata_dst *tun_rx_dst(__be16 flags,
 		return NULL;
 
 	info = &tun_dst->u.tun_info;
-	info->mode = IP_TUNNEL_INFO_RX;
 	info->key.tun_flags = flags;
 	info->key.tun_id = tunnel_id;
 	info->key.tp_src = 0;
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 224e4ecec91b..9bdb3948798f 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -50,13 +50,8 @@ struct ip_tunnel_key {
 	__be16			tp_dst;
 };
 
-/* Indicates whether the tunnel info structure represents receive
- * or transmit tunnel parameters.
- */
-enum {
-	IP_TUNNEL_INFO_RX,
-	IP_TUNNEL_INFO_TX,
-};
+/* Flags for ip_tunnel_info mode. */
+#define IP_TUNNEL_INFO_TX	0x01	/* represents tx tunnel parameters */
 
 struct ip_tunnel_info {
 	struct ip_tunnel_key	key;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index faf1cde6f8da..1e813a9f9378 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -511,7 +511,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 	int err;
 
 	tun_info = skb_tunnel_info(skb);
-	if (unlikely(!tun_info || tun_info->mode != IP_TUNNEL_INFO_TX))
+	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX)))
 		goto err_free_skb;
 
 	key = &tun_info->key;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index f3087aaa6dd8..3d9e70c804a9 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1693,7 +1693,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 	 */
 
 	tun_info = skb_tunnel_info(skb);
-	if (tun_info && tun_info->mode == IP_TUNNEL_INFO_RX)
+	if (tun_info && !(tun_info->mode & IP_TUNNEL_INFO_TX))
 		fl4.flowi4_tun_key.tun_id = tun_info->key.tun_id;
 	else
 		fl4.flowi4_tun_key.tun_id = 0;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index df3e353a012d..308dd5f9158f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1174,7 +1174,7 @@ void ip6_route_input(struct sk_buff *skb)
 	};
 
 	tun_info = skb_tunnel_info(skb);
-	if (tun_info && tun_info->mode == IP_TUNNEL_INFO_RX)
+	if (tun_info && !(tun_info->mode & IP_TUNNEL_INFO_TX))
 		fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id;
 	skb_dst_drop(skb);
 	skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags));
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info
  2015-08-28 14:27 [PATCH net-next 0/4] tunnels: fix incorrect IPv4/v6 headers interpretation Jiri Benc
  2015-08-28 14:27 ` [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags Jiri Benc
@ 2015-08-28 14:27 ` Jiri Benc
  2015-08-28 16:33   ` Alexei Starovoitov
  2015-08-28 17:32   ` Pravin Shelar
  2015-08-28 14:27 ` [PATCH net-next 3/4] fou: reject IPv6 config Jiri Benc
  2015-08-28 14:27 ` [PATCH net-next 4/4] vxlan: do not receive IPv4 packets on IPv6 socket Jiri Benc
  3 siblings, 2 replies; 11+ messages in thread
From: Jiri Benc @ 2015-08-28 14:27 UTC (permalink / raw)
  To: netdev; +Cc: Thomas Graf

There's currently nothing preventing directing packets with IPv6
encapsulation data to IPv4 tunnels (and vice versa). If this happens,
IPv6 addresses are incorrectly interpreted as IPv4 ones.

Track whether the given ip_tunnel_key contains IPv4 or IPv6 data. Store this
in ip_tunnel_info. Reject packets at appropriate places if they are supposed
to be encapsulated into an incompatible protocol.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
 drivers/net/geneve.c       |  3 +++
 drivers/net/vxlan.c        |  2 ++
 include/net/dst_metadata.h |  1 +
 include/net/ip_tunnels.h   | 10 ++++++++++
 net/core/filter.c          |  2 ++
 net/ipv4/ip_gre.c          |  3 ++-
 net/ipv4/ip_tunnel_core.c  |  2 +-
 net/openvswitch/flow.c     |  2 ++
 net/openvswitch/vport.c    |  2 ++
 9 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 4357bae732d7..d4882d7904f6 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -644,6 +644,9 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
 		u8 *opts = NULL;
 		u8 vni[3];
 
+		if (ip_tunnel_info_af(info) != AF_INET)
+			goto err;
+
 		tunnel_id_to_vni(key->tun_id, vni);
 		if (key->tun_flags & TUNNEL_GENEVE_OPT)
 			opts = ip_tunnel_info_opts(info, info->options_len);
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index bd1b8cdf2bf6..e3adfe0ef66b 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1903,6 +1903,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 				  dev->name);
 			goto drop;
 		}
+		if (family != ip_tunnel_info_af(info))
+			goto drop;
 
 		dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
 		vni = be64_to_cpu(info->key.tun_id);
diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index 2b83f0d232e0..d32f49cc621d 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -105,6 +105,7 @@ static inline struct metadata_dst *ipv6_tun_rx_dst(struct sk_buff *skb,
 	info->key.u.ipv6.dst = ip6h->daddr;
 	info->key.tos = ipv6_get_dsfield(ip6h);
 	info->key.ttl = ip6h->hop_limit;
+	info->mode = IP_TUNNEL_INFO_IPV6;
 	return tun_dst;
 }
 
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 9bdb3948798f..2b4fa06e91bd 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -4,6 +4,7 @@
 #include <linux/if_tunnel.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/socket.h>
 #include <linux/types.h>
 #include <linux/u64_stats_sync.h>
 #include <net/dsfield.h>
@@ -52,6 +53,7 @@ struct ip_tunnel_key {
 
 /* Flags for ip_tunnel_info mode. */
 #define IP_TUNNEL_INFO_TX	0x01	/* represents tx tunnel parameters */
+#define IP_TUNNEL_INFO_IPV6	0x02	/* key contains IPv6 addresses */
 
 struct ip_tunnel_info {
 	struct ip_tunnel_key	key;
@@ -208,6 +210,8 @@ static inline void __ip_tunnel_info_init(struct ip_tunnel_info *tun_info,
 
 	tun_info->options = opts;
 	tun_info->options_len = opts_len;
+
+	tun_info->mode = 0;
 }
 
 static inline void ip_tunnel_info_init(struct ip_tunnel_info *tun_info,
@@ -221,6 +225,12 @@ static inline void ip_tunnel_info_init(struct ip_tunnel_info *tun_info,
 			      tun_id, tun_flags, opts, opts_len);
 }
 
+static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
+					       *tun_info)
+{
+	return tun_info->mode & IP_TUNNEL_INFO_IPV6 ? AF_INET6 : AF_INET;
+}
+
 #ifdef CONFIG_INET
 
 int ip_tunnel_init(struct net_device *dev);
diff --git a/net/core/filter.c b/net/core/filter.c
index 66500d490995..13079f03902e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1493,6 +1493,8 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)
 
 	if (unlikely(size != sizeof(struct bpf_tunnel_key) || flags || !info))
 		return -EINVAL;
+	if (ip_tunnel_info_af(info) != AF_INET)
+		return -EINVAL;
 
 	to->tunnel_id = be64_to_cpu(info->key.tun_id);
 	to->remote_ipv4 = be32_to_cpu(info->key.u.ipv4.src);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 1e813a9f9378..bd0679d90519 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -511,7 +511,8 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 	int err;
 
 	tun_info = skb_tunnel_info(skb);
-	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX)))
+	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
+		     ip_tunnel_info_af(tun_info) != AF_INET))
 		goto err_free_skb;
 
 	key = &tun_info->key;
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 934f2ac8ad61..0c756ade1cf7 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -356,7 +356,7 @@ static int ip6_tun_build_state(struct net_device *dev, struct nlattr *attr,
 	if (tb[LWTUNNEL_IP6_FLAGS])
 		tun_info->key.tun_flags = nla_get_u16(tb[LWTUNNEL_IP6_FLAGS]);
 
-	tun_info->mode = IP_TUNNEL_INFO_TX;
+	tun_info->mode = IP_TUNNEL_INFO_TX | IP_TUNNEL_INFO_IPV6;
 	tun_info->options = NULL;
 	tun_info->options_len = 0;
 
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 5a3195e538ce..9760dc43bdb9 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -688,6 +688,8 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
 {
 	/* Extract metadata from packet. */
 	if (tun_info) {
+		if (ip_tunnel_info_af(tun_info) != AF_INET)
+			return -EINVAL;
 		memcpy(&key->tun_key, &tun_info->key, sizeof(key->tun_key));
 
 		if (tun_info->options) {
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index e2dc9dac59e6..40164037928e 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -587,6 +587,8 @@ int ovs_tunnel_get_egress_info(struct ip_tunnel_info *egress_tun_info,
 
 	if (unlikely(!tun_info))
 		return -EINVAL;
+	if (ip_tunnel_info_af(tun_info) != AF_INET)
+		return -EINVAL;
 
 	tun_key = &tun_info->key;
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 3/4] fou: reject IPv6 config
  2015-08-28 14:27 [PATCH net-next 0/4] tunnels: fix incorrect IPv4/v6 headers interpretation Jiri Benc
  2015-08-28 14:27 ` [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags Jiri Benc
  2015-08-28 14:27 ` [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info Jiri Benc
@ 2015-08-28 14:27 ` Jiri Benc
  2015-08-28 14:27 ` [PATCH net-next 4/4] vxlan: do not receive IPv4 packets on IPv6 socket Jiri Benc
  3 siblings, 0 replies; 11+ messages in thread
From: Jiri Benc @ 2015-08-28 14:27 UTC (permalink / raw)
  To: netdev; +Cc: Thomas Graf, Tom Herbert

fou does not really support IPv6 encapsulation. After an UDP socket is
created in fou_create, the encap_rcv callback is set either to fou_udp_recv
or to gue_udp_recv. Both of those unconditionally assume that the received
packet has an IPv4 header and access the data at network_header as it was an
IPv4 header. This leads to IPv6 flow label being interpreted as IP packet
length, etc.

Disallow fou tunnel to be configured as IPv6 until real IPv6 support is
added to fou.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
 net/ipv4/fou.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 2d1646cff057..e0fcbbbcfe54 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -566,7 +566,7 @@ static int parse_nl_config(struct genl_info *info,
 	if (info->attrs[FOU_ATTR_AF]) {
 		u8 family = nla_get_u8(info->attrs[FOU_ATTR_AF]);
 
-		if (family != AF_INET && family != AF_INET6)
+		if (family != AF_INET)
 			return -EINVAL;
 
 		cfg->udp_config.family = family;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 4/4] vxlan: do not receive IPv4 packets on IPv6 socket
  2015-08-28 14:27 [PATCH net-next 0/4] tunnels: fix incorrect IPv4/v6 headers interpretation Jiri Benc
                   ` (2 preceding siblings ...)
  2015-08-28 14:27 ` [PATCH net-next 3/4] fou: reject IPv6 config Jiri Benc
@ 2015-08-28 14:27 ` Jiri Benc
  3 siblings, 0 replies; 11+ messages in thread
From: Jiri Benc @ 2015-08-28 14:27 UTC (permalink / raw)
  To: netdev; +Cc: Thomas Graf

By default (subject to the sysctl settings), IPv6 sockets listen also for
IPv4 traffic. Vxlan is not prepared for that and expects IPv6 header in
packets received through an IPv6 socket.

In addition, it's currently not possible to have both IPv4 and IPv6 vxlan
tunnel on the same port (unless bindv6only sysctl is enabled), as it's not
possible to create and bind both IPv4 and IPv6 vxlan interfaces and there's
no way to specify both IPv4 and IPv6 remote/group IP addresses.

Set IPV6_V6ONLY on vxlan sockets to fix both of these issues. This is not
done globally in udp_tunnel, as l2tp and tipc seems to work okay when
receiving IPv4 packets on IPv6 socket and people may rely on this behavior.
The other tunnels (geneve and fou) do not support IPv6.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
 drivers/net/vxlan.c       | 1 +
 include/net/udp_tunnel.h  | 3 ++-
 net/ipv6/ip6_udp_tunnel.c | 9 +++++++++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index e3adfe0ef66b..6c5269aea544 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2530,6 +2530,7 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
 		udp_conf.family = AF_INET6;
 		udp_conf.use_udp6_rx_checksums =
 		    !(flags & VXLAN_F_UDP_ZERO_CSUM6_RX);
+		udp_conf.ipv6_v6only = 1;
 	} else {
 		udp_conf.family = AF_INET;
 	}
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 35041d0fc21e..cb2f89f20f5c 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -31,7 +31,8 @@ struct udp_port_cfg {
 	__be16			peer_udp_port;
 	unsigned int		use_udp_checksums:1,
 				use_udp6_tx_checksums:1,
-				use_udp6_rx_checksums:1;
+				use_udp6_rx_checksums:1,
+				ipv6_v6only:1;
 };
 
 int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c
index e1a1136bda7c..14dacf1df529 100644
--- a/net/ipv6/ip6_udp_tunnel.c
+++ b/net/ipv6/ip6_udp_tunnel.c
@@ -23,6 +23,15 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
 	if (err < 0)
 		goto error;
 
+	if (cfg->ipv6_v6only) {
+		int val = 1;
+
+		err = kernel_setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+					(char *) &val, sizeof(val));
+		if (err < 0)
+			goto error;
+	}
+
 	udp6_addr.sin6_family = AF_INET6;
 	memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
 	       sizeof(udp6_addr.sin6_addr));
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags
  2015-08-28 14:27 ` [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags Jiri Benc
@ 2015-08-28 16:32   ` Alexei Starovoitov
  2015-08-28 17:29   ` Pravin Shelar
  1 sibling, 0 replies; 11+ messages in thread
From: Alexei Starovoitov @ 2015-08-28 16:32 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, Thomas Graf

On Fri, Aug 28, 2015 at 04:27:25PM +0200, Jiri Benc wrote:
> The mode field holds a single bit of information only (whether the
> ip_tunnel_info struct is for rx or tx). Change the mode field to bit flags.
> This allows more mode flags to be added.
> 
> Signed-off-by: Jiri Benc <jbenc@redhat.com>

Acked-by: Alexei Starovoitov <ast@plumgrid.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info
  2015-08-28 14:27 ` [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info Jiri Benc
@ 2015-08-28 16:33   ` Alexei Starovoitov
  2015-08-28 17:32   ` Pravin Shelar
  1 sibling, 0 replies; 11+ messages in thread
From: Alexei Starovoitov @ 2015-08-28 16:33 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, Thomas Graf

On Fri, Aug 28, 2015 at 04:27:26PM +0200, Jiri Benc wrote:
> There's currently nothing preventing directing packets with IPv6
> encapsulation data to IPv4 tunnels (and vice versa). If this happens,
> IPv6 addresses are incorrectly interpreted as IPv4 ones.
> 
> Track whether the given ip_tunnel_key contains IPv4 or IPv6 data. Store this
> in ip_tunnel_info. Reject packets at appropriate places if they are supposed
> to be encapsulated into an incompatible protocol.
> 
> Signed-off-by: Jiri Benc <jbenc@redhat.com>

Acked-by: Alexei Starovoitov <ast@plumgrid.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags
  2015-08-28 14:27 ` [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags Jiri Benc
  2015-08-28 16:32   ` Alexei Starovoitov
@ 2015-08-28 17:29   ` Pravin Shelar
  2015-08-28 18:08     ` Jiri Benc
  1 sibling, 1 reply; 11+ messages in thread
From: Pravin Shelar @ 2015-08-28 17:29 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, Thomas Graf

On Fri, Aug 28, 2015 at 7:27 AM, Jiri Benc <jbenc@redhat.com> wrote:
> The mode field holds a single bit of information only (whether the
> ip_tunnel_info struct is for rx or tx). Change the mode field to bit flags.
> This allows more mode flags to be added.
>
> Signed-off-by: Jiri Benc <jbenc@redhat.com>
> ---
>  drivers/net/vxlan.c        | 2 +-
>  include/net/dst_metadata.h | 1 -
>  include/net/ip_tunnels.h   | 9 ++-------
>  net/ipv4/ip_gre.c          | 2 +-
>  net/ipv4/route.c           | 2 +-
>  net/ipv6/route.c           | 2 +-

geneve module also needs to be updated.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info
  2015-08-28 14:27 ` [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info Jiri Benc
  2015-08-28 16:33   ` Alexei Starovoitov
@ 2015-08-28 17:32   ` Pravin Shelar
  2015-08-28 18:16     ` Jiri Benc
  1 sibling, 1 reply; 11+ messages in thread
From: Pravin Shelar @ 2015-08-28 17:32 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, Thomas Graf

On Fri, Aug 28, 2015 at 7:27 AM, Jiri Benc <jbenc@redhat.com> wrote:
> There's currently nothing preventing directing packets with IPv6
> encapsulation data to IPv4 tunnels (and vice versa). If this happens,
> IPv6 addresses are incorrectly interpreted as IPv4 ones.
>
> Track whether the given ip_tunnel_key contains IPv4 or IPv6 data. Store this
> in ip_tunnel_info. Reject packets at appropriate places if they are supposed
> to be encapsulated into an incompatible protocol.
>
> Signed-off-by: Jiri Benc <jbenc@redhat.com>
> ---
>  drivers/net/geneve.c       |  3 +++
>  drivers/net/vxlan.c        |  2 ++
>  include/net/dst_metadata.h |  1 +
>  include/net/ip_tunnels.h   | 10 ++++++++++
>  net/core/filter.c          |  2 ++
>  net/ipv4/ip_gre.c          |  3 ++-
>  net/ipv4/ip_tunnel_core.c  |  2 +-
>  net/openvswitch/flow.c     |  2 ++
>  net/openvswitch/vport.c    |  2 ++
>  9 files changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
> index 4357bae732d7..d4882d7904f6 100644
> --- a/drivers/net/geneve.c
> +++ b/drivers/net/geneve.c
> @@ -644,6 +644,9 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
>                 u8 *opts = NULL;
>                 u8 vni[3];
>
> +               if (ip_tunnel_info_af(info) != AF_INET)
> +                       goto err;
> +
geneve_get_rt() already interpreted the info as ipv4 tunnel info.

We can avoid such bugs by introducing separate API to retrieve ipv4
and ipv6 tunnel info. Something like
skb_tunnel_info_v4()/skb_tunnel_info_v6() for ipv4 and ipv6.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags
  2015-08-28 17:29   ` Pravin Shelar
@ 2015-08-28 18:08     ` Jiri Benc
  0 siblings, 0 replies; 11+ messages in thread
From: Jiri Benc @ 2015-08-28 18:08 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: netdev, Thomas Graf

On Fri, 28 Aug 2015 10:29:55 -0700, Pravin Shelar wrote:
> geneve module also needs to be updated.

Right, the rebase on top of your patches is not complete. I'll send v2.

Thanks,

 Jiri

-- 
Jiri Benc

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info
  2015-08-28 17:32   ` Pravin Shelar
@ 2015-08-28 18:16     ` Jiri Benc
  0 siblings, 0 replies; 11+ messages in thread
From: Jiri Benc @ 2015-08-28 18:16 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: netdev, Thomas Graf

On Fri, 28 Aug 2015 10:32:15 -0700, Pravin Shelar wrote:
> > --- a/drivers/net/geneve.c
> > +++ b/drivers/net/geneve.c
> > @@ -644,6 +644,9 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
> >                 u8 *opts = NULL;
> >                 u8 vni[3];
> >
> > +               if (ip_tunnel_info_af(info) != AF_INET)
> > +                       goto err;
> > +
> geneve_get_rt() already interpreted the info as ipv4 tunnel info.

Hmm, okay. I'll move the check. The geneve module changed more than
I thought.

Thanks for noticing this.

> We can avoid such bugs by introducing separate API to retrieve ipv4
> and ipv6 tunnel info. Something like
> skb_tunnel_info_v4()/skb_tunnel_info_v6() for ipv4 and ipv6.

I don't think we want that. Ideally, the xmit function should work with
both and use the protocol information to choose the correct output
path. I intend to try this with the metadata based vxlan which would
use the correct socket (IPv4 or IPv6) appropriately. That way, we won't
need a separate vxlan interface for IPv4 and IPv6 traffic. Will be much
more user friendly and most likely easier to use from ovs, too.

 Jiri

-- 
Jiri Benc

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-08-28 18:16 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-28 14:27 [PATCH net-next 0/4] tunnels: fix incorrect IPv4/v6 headers interpretation Jiri Benc
2015-08-28 14:27 ` [PATCH net-next 1/4] ip_tunnels: convert the mode field of ip_tunnel_info to flags Jiri Benc
2015-08-28 16:32   ` Alexei Starovoitov
2015-08-28 17:29   ` Pravin Shelar
2015-08-28 18:08     ` Jiri Benc
2015-08-28 14:27 ` [PATCH net-next 2/4] ip_tunnels: record IP version in tunnel info Jiri Benc
2015-08-28 16:33   ` Alexei Starovoitov
2015-08-28 17:32   ` Pravin Shelar
2015-08-28 18:16     ` Jiri Benc
2015-08-28 14:27 ` [PATCH net-next 3/4] fou: reject IPv6 config Jiri Benc
2015-08-28 14:27 ` [PATCH net-next 4/4] vxlan: do not receive IPv4 packets on IPv6 socket Jiri Benc

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.