All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/4] openvswitch: add IPv6 tunneling support
@ 2015-10-01 14:44 Jiri Benc
  2015-10-01 14:44 ` [PATCH net-next v2 1/4] openvswitch: add tunnel protocol to sw_flow_key Jiri Benc
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Jiri Benc @ 2015-10-01 14:44 UTC (permalink / raw)
  To: netdev; +Cc: dev, Pravin Shelar, Jesse Gross

This builds on the previous work that added IPv6 support to lwtunnels and
adds IPv6 tunneling support to ovs.

To use IPv6 tunneling, there needs to be a metadata based tunnel net_device
created and added to the ovs bridge. Currently, only vxlan is supported by
the kernel, with geneve to follow shortly. There's no need nor intent to add
a support for this into the vport-vxlan (etc.) compat layer.

Jiri Benc (4):
  openvswitch: add tunnel protocol to sw_flow_key
  openvswitch: netlink attributes for IPv6 tunneling
  ip_tunnels: introduce ip6_tunnel_key_init
  openvswitch: IPv6 support for ovs_tunnel_get_egress_info

 include/net/dst_metadata.h       |  18 ++----
 include/net/ip_tunnels.h         |  40 +++++++++---
 include/uapi/linux/openvswitch.h |   2 +
 net/openvswitch/flow.c           |   4 +-
 net/openvswitch/flow.h           |   1 +
 net/openvswitch/flow_netlink.c   | 129 +++++++++++++++++++++++++++------------
 net/openvswitch/flow_table.c     |   2 +-
 net/openvswitch/vport-geneve.c   |   4 +-
 net/openvswitch/vport-gre.c      |   4 +-
 net/openvswitch/vport-vxlan.c    |   6 +-
 net/openvswitch/vport.c          |  62 +++++++++++++------
 net/openvswitch/vport.h          |  26 ++++++++
 12 files changed, 211 insertions(+), 87 deletions(-)

-- 
1.8.3.1

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

* [PATCH net-next v2 1/4] openvswitch: add tunnel protocol to sw_flow_key
  2015-10-01 14:44 [PATCH net-next v2 0/4] openvswitch: add IPv6 tunneling support Jiri Benc
@ 2015-10-01 14:44 ` Jiri Benc
  2015-10-02  0:10   ` Pravin Shelar
  2015-10-01 14:44 ` [PATCH net-next v2 2/4] openvswitch: netlink attributes for IPv6 tunneling Jiri Benc
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Jiri Benc @ 2015-10-01 14:44 UTC (permalink / raw)
  To: netdev; +Cc: dev, Pravin Shelar, Jesse Gross

Store tunnel protocol (AF_INET or AF_INET6) in sw_flow_key. This field now
also acts as an indicator whether the flow contains tunnel data (this was
previously indicated by tun_key.u.ipv4.dst being set but with IPv6 addresses
in an union with IPv4 ones this won't work anymore).

The new field was added to a hole in sw_flow_key.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
v2: Set the tun_proto mask to 0xff in ip_tun_from_nlattr.
---
 net/openvswitch/flow.c         |  4 ++--
 net/openvswitch/flow.h         |  1 +
 net/openvswitch/flow_netlink.c | 10 ++++++++--
 net/openvswitch/flow_table.c   |  2 +-
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index c8db44ab2ee7..0ea128eeeab2 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -698,8 +698,7 @@ 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;
+		key->tun_proto = ip_tunnel_info_af(tun_info);
 		memcpy(&key->tun_key, &tun_info->key, sizeof(key->tun_key));
 
 		if (tun_info->options_len) {
@@ -714,6 +713,7 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
 			key->tun_opts_len = 0;
 		}
 	} else  {
+		key->tun_proto = 0;
 		key->tun_opts_len = 0;
 		memset(&key->tun_key, 0, sizeof(key->tun_key));
 	}
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index fe527d2dd4b7..5688e33e2de6 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -63,6 +63,7 @@ struct sw_flow_key {
 		u32	skb_mark;	/* SKB mark. */
 		u16	in_port;	/* Input switch port (or DP_MAX_PORTS). */
 	} __packed phy; /* Safe when right after 'tun_key'. */
+	u8 tun_proto;			/* Protocol of encapsulating tunnel. */
 	u32 ovs_flow_hash;		/* Datapath computed hash value.  */
 	u32 recirc_id;			/* Recirculation ID.  */
 	struct {
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 5c030a4d7338..6be701f6b31b 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -643,6 +643,10 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
 	}
 
 	SW_FLOW_KEY_PUT(match, tun_key.tun_flags, tun_flags, is_mask);
+	if (is_mask)
+		SW_FLOW_KEY_MEMSET_FIELD(match, tun_proto, 0xff, true);
+	else
+		SW_FLOW_KEY_PUT(match, tun_proto, AF_INET, false);
 
 	if (rem > 0) {
 		OVS_NLERR(log, "IPv4 tunnel attribute has %d unknown bytes.",
@@ -1194,7 +1198,7 @@ int ovs_nla_get_match(struct net *net, struct sw_flow_match *match,
 			/* The userspace does not send tunnel attributes that
 			 * are 0, but we should not wildcard them nonetheless.
 			 */
-			if (match->key->tun_key.u.ipv4.dst)
+			if (match->key->tun_proto)
 				SW_FLOW_KEY_MEMSET_FIELD(match, tun_key,
 							 0xff, true);
 
@@ -1367,7 +1371,7 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
 	if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority))
 		goto nla_put_failure;
 
-	if ((swkey->tun_key.u.ipv4.dst || is_mask)) {
+	if ((swkey->tun_proto || is_mask)) {
 		const void *opts = NULL;
 
 		if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT)
@@ -1913,6 +1917,8 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
 
 	tun_info = &tun_dst->u.tun_info;
 	tun_info->mode = IP_TUNNEL_INFO_TX;
+	if (key.tun_proto == AF_INET6)
+		tun_info->mode |= IP_TUNNEL_INFO_IPV6;
 	tun_info->key = key.tun_key;
 
 	/* We need to store the options in the action itself since
diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c
index f2ea83ba4763..95dbcedf0bd4 100644
--- a/net/openvswitch/flow_table.c
+++ b/net/openvswitch/flow_table.c
@@ -427,7 +427,7 @@ static u32 flow_hash(const struct sw_flow_key *key,
 
 static int flow_key_start(const struct sw_flow_key *key)
 {
-	if (key->tun_key.u.ipv4.dst)
+	if (key->tun_proto)
 		return 0;
 	else
 		return rounddown(offsetof(struct sw_flow_key, phy),
-- 
1.8.3.1

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

* [PATCH net-next v2 2/4] openvswitch: netlink attributes for IPv6 tunneling
  2015-10-01 14:44 [PATCH net-next v2 0/4] openvswitch: add IPv6 tunneling support Jiri Benc
  2015-10-01 14:44 ` [PATCH net-next v2 1/4] openvswitch: add tunnel protocol to sw_flow_key Jiri Benc
@ 2015-10-01 14:44 ` Jiri Benc
  2015-10-02  0:10   ` Pravin Shelar
  2015-10-01 14:44 ` [PATCH net-next v2 3/4] ip_tunnels: introduce ip6_tunnel_key_init Jiri Benc
  2015-10-01 14:44 ` [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info Jiri Benc
  3 siblings, 1 reply; 14+ messages in thread
From: Jiri Benc @ 2015-10-01 14:44 UTC (permalink / raw)
  To: netdev; +Cc: dev, Pravin Shelar, Jesse Gross

Add netlink attributes for IPv6 tunnel addresses. This enables IPv6 support
for tunnels.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
v2: Changed description. Rebased tun_proto assignment in ip_tun_from_nlattr
    to accomodate changes in the previous patch.
---
 include/uapi/linux/openvswitch.h |   2 +
 net/openvswitch/flow_netlink.c   | 121 +++++++++++++++++++++++++++------------
 2 files changed, 86 insertions(+), 37 deletions(-)

diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index 32e07d8cbaf4..4036e1b1980f 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -349,6 +349,8 @@ enum ovs_tunnel_key_attr {
 	OVS_TUNNEL_KEY_ATTR_TP_SRC,		/* be16 src Transport Port. */
 	OVS_TUNNEL_KEY_ATTR_TP_DST,		/* be16 dst Transport Port. */
 	OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS,		/* Nested OVS_VXLAN_EXT_* */
+	OVS_TUNNEL_KEY_ATTR_IPV6_SRC,		/* struct in6_addr src IPv6 address. */
+	OVS_TUNNEL_KEY_ATTR_IPV6_DST,		/* struct in6_addr dst IPv6 address. */
 	__OVS_TUNNEL_KEY_ATTR_MAX
 };
 
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 6be701f6b31b..77850f177a47 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -262,8 +262,8 @@ size_t ovs_tun_key_attr_size(void)
 	 * updating this function.
 	 */
 	return    nla_total_size(8)    /* OVS_TUNNEL_KEY_ATTR_ID */
-		+ nla_total_size(4)    /* OVS_TUNNEL_KEY_ATTR_IPV4_SRC */
-		+ nla_total_size(4)    /* OVS_TUNNEL_KEY_ATTR_IPV4_DST */
+		+ nla_total_size(16)   /* OVS_TUNNEL_KEY_ATTR_IPV[46]_SRC */
+		+ nla_total_size(16)   /* OVS_TUNNEL_KEY_ATTR_IPV[46]_DST */
 		+ nla_total_size(1)    /* OVS_TUNNEL_KEY_ATTR_TOS */
 		+ nla_total_size(1)    /* OVS_TUNNEL_KEY_ATTR_TTL */
 		+ nla_total_size(0)    /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
@@ -323,6 +323,8 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
 	[OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS]   = { .len = OVS_ATTR_VARIABLE },
 	[OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS]    = { .len = OVS_ATTR_NESTED,
 						.next = ovs_vxlan_ext_key_lens },
+	[OVS_TUNNEL_KEY_ATTR_IPV6_SRC]      = { .len = sizeof(struct in6_addr) },
+	[OVS_TUNNEL_KEY_ATTR_IPV6_DST]      = { .len = sizeof(struct in6_addr) },
 };
 
 /* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute.  */
@@ -542,14 +544,14 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr,
 	return 0;
 }
 
-static int ipv4_tun_from_nlattr(const struct nlattr *attr,
-				struct sw_flow_match *match, bool is_mask,
-				bool log)
+static int ip_tun_from_nlattr(const struct nlattr *attr,
+			      struct sw_flow_match *match, bool is_mask,
+			      bool log)
 {
 	struct nlattr *a;
 	int rem;
 	bool ttl = false;
-	__be16 tun_flags = 0;
+	__be16 tun_flags = 0, ipv4 = false, ipv6 = false;
 	int opts_type = 0;
 
 	nla_for_each_nested(a, attr, rem) {
@@ -578,10 +580,22 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
 		case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
 			SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.src,
 					nla_get_in_addr(a), is_mask);
+			ipv4 = true;
 			break;
 		case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
 			SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.dst,
 					nla_get_in_addr(a), is_mask);
+			ipv4 = true;
+			break;
+		case OVS_TUNNEL_KEY_ATTR_IPV6_SRC:
+			SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst,
+					nla_get_in6_addr(a), is_mask);
+			ipv6 = true;
+			break;
+		case OVS_TUNNEL_KEY_ATTR_IPV6_DST:
+			SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst,
+					nla_get_in6_addr(a), is_mask);
+			ipv6 = true;
 			break;
 		case OVS_TUNNEL_KEY_ATTR_TOS:
 			SW_FLOW_KEY_PUT(match, tun_key.tos,
@@ -636,7 +650,7 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
 			opts_type = type;
 			break;
 		default:
-			OVS_NLERR(log, "Unknown IPv4 tunnel attribute %d",
+			OVS_NLERR(log, "Unknown IP tunnel attribute %d",
 				  type);
 			return -EINVAL;
 		}
@@ -646,22 +660,36 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
 	if (is_mask)
 		SW_FLOW_KEY_MEMSET_FIELD(match, tun_proto, 0xff, true);
 	else
-		SW_FLOW_KEY_PUT(match, tun_proto, AF_INET, false);
+		SW_FLOW_KEY_PUT(match, tun_proto, ipv6 ? AF_INET6 : AF_INET,
+				false);
 
 	if (rem > 0) {
-		OVS_NLERR(log, "IPv4 tunnel attribute has %d unknown bytes.",
+		OVS_NLERR(log, "IP tunnel attribute has %d unknown bytes.",
 			  rem);
 		return -EINVAL;
 	}
 
+	if (ipv4 && ipv6) {
+		OVS_NLERR(log, "Mixed IPv4 and IPv6 tunnel attributes");
+		return -EINVAL;
+	}
+
 	if (!is_mask) {
-		if (!match->key->tun_key.u.ipv4.dst) {
+		if (!ipv4 && !ipv6) {
+			OVS_NLERR(log, "IP tunnel dst address not specified");
+			return -EINVAL;
+		}
+		if (ipv4 && !match->key->tun_key.u.ipv4.dst) {
 			OVS_NLERR(log, "IPv4 tunnel dst address is zero");
 			return -EINVAL;
 		}
+		if (ipv6 && ipv6_addr_any(&match->key->tun_key.u.ipv6.dst)) {
+			OVS_NLERR(log, "IPv6 tunnel dst address is zero");
+			return -EINVAL;
+		}
 
 		if (!ttl) {
-			OVS_NLERR(log, "IPv4 tunnel TTL not specified.");
+			OVS_NLERR(log, "IP tunnel TTL not specified.");
 			return -EINVAL;
 		}
 	}
@@ -686,21 +714,36 @@ static int vxlan_opt_to_nlattr(struct sk_buff *skb,
 	return 0;
 }
 
-static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
-				const struct ip_tunnel_key *output,
-				const void *tun_opts, int swkey_tun_opts_len)
+static int __ip_tun_to_nlattr(struct sk_buff *skb,
+			      const struct ip_tunnel_key *output,
+			      const void *tun_opts, int swkey_tun_opts_len,
+			      unsigned short tun_proto)
 {
 	if (output->tun_flags & TUNNEL_KEY &&
 	    nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id))
 		return -EMSGSIZE;
-	if (output->u.ipv4.src &&
-	    nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
-			    output->u.ipv4.src))
-		return -EMSGSIZE;
-	if (output->u.ipv4.dst &&
-	    nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_DST,
-			    output->u.ipv4.dst))
-		return -EMSGSIZE;
+	switch (tun_proto) {
+	case AF_INET:
+		if (output->u.ipv4.src &&
+		    nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
+				    output->u.ipv4.src))
+			return -EMSGSIZE;
+		if (output->u.ipv4.dst &&
+		    nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_DST,
+				    output->u.ipv4.dst))
+			return -EMSGSIZE;
+		break;
+	case AF_INET6:
+		if (!ipv6_addr_any(&output->u.ipv6.src) &&
+		    nla_put_in6_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV6_SRC,
+				     &output->u.ipv6.src))
+			return -EMSGSIZE;
+		if (!ipv6_addr_any(&output->u.ipv6.dst) &&
+		    nla_put_in6_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV6_DST,
+				     &output->u.ipv6.dst))
+			return -EMSGSIZE;
+		break;
+	}
 	if (output->tos &&
 	    nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TOS, output->tos))
 		return -EMSGSIZE;
@@ -734,9 +777,10 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
 	return 0;
 }
 
-static int ipv4_tun_to_nlattr(struct sk_buff *skb,
-			      const struct ip_tunnel_key *output,
-			      const void *tun_opts, int swkey_tun_opts_len)
+static int ip_tun_to_nlattr(struct sk_buff *skb,
+			    const struct ip_tunnel_key *output,
+			    const void *tun_opts, int swkey_tun_opts_len,
+			    unsigned short tun_proto)
 {
 	struct nlattr *nla;
 	int err;
@@ -745,7 +789,8 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
 	if (!nla)
 		return -EMSGSIZE;
 
-	err = __ipv4_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len);
+	err = __ip_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len,
+				 tun_proto);
 	if (err)
 		return err;
 
@@ -757,9 +802,10 @@ int ovs_nla_put_egress_tunnel_key(struct sk_buff *skb,
 				  const struct ip_tunnel_info *egress_tun_info,
 				  const void *egress_tun_opts)
 {
-	return __ipv4_tun_to_nlattr(skb, &egress_tun_info->key,
-				    egress_tun_opts,
-				    egress_tun_info->options_len);
+	return __ip_tun_to_nlattr(skb, &egress_tun_info->key,
+				  egress_tun_opts,
+				  egress_tun_info->options_len,
+				  ip_tunnel_info_af(egress_tun_info));
 }
 
 static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
@@ -810,8 +856,8 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
 		*attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
 	}
 	if (*attrs & (1 << OVS_KEY_ATTR_TUNNEL)) {
-		if (ipv4_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match,
-					 is_mask, log) < 0)
+		if (ip_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match,
+				       is_mask, log) < 0)
 			return -EINVAL;
 		*attrs &= ~(1 << OVS_KEY_ATTR_TUNNEL);
 	}
@@ -1377,8 +1423,8 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
 		if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT)
 			opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len);
 
-		if (ipv4_tun_to_nlattr(skb, &output->tun_key, opts,
-				       swkey->tun_opts_len))
+		if (ip_tun_to_nlattr(skb, &output->tun_key, opts,
+				     swkey->tun_opts_len, swkey->tun_proto))
 			goto nla_put_failure;
 	}
 
@@ -1881,7 +1927,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
 	int err = 0, start, opts_type;
 
 	ovs_match_init(&match, &key, NULL);
-	opts_type = ipv4_tun_from_nlattr(nla_data(attr), &match, false, log);
+	opts_type = ip_tun_from_nlattr(nla_data(attr), &match, false, log);
 	if (opts_type < 0)
 		return opts_type;
 
@@ -2380,10 +2426,11 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
 		if (!start)
 			return -EMSGSIZE;
 
-		err = ipv4_tun_to_nlattr(skb, &tun_info->key,
-					 tun_info->options_len ?
+		err = ip_tun_to_nlattr(skb, &tun_info->key,
+				       tun_info->options_len ?
 					     ip_tunnel_info_opts(tun_info) : NULL,
-					 tun_info->options_len);
+				       tun_info->options_len,
+				       ip_tunnel_info_af(tun_info));
 		if (err)
 			return err;
 		nla_nest_end(skb, start);
-- 
1.8.3.1

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

* [PATCH net-next v2 3/4] ip_tunnels: introduce ip6_tunnel_key_init
  2015-10-01 14:44 [PATCH net-next v2 0/4] openvswitch: add IPv6 tunneling support Jiri Benc
  2015-10-01 14:44 ` [PATCH net-next v2 1/4] openvswitch: add tunnel protocol to sw_flow_key Jiri Benc
  2015-10-01 14:44 ` [PATCH net-next v2 2/4] openvswitch: netlink attributes for IPv6 tunneling Jiri Benc
@ 2015-10-01 14:44 ` Jiri Benc
  2015-10-02  0:11   ` Pravin Shelar
  2015-10-01 14:44 ` [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info Jiri Benc
  3 siblings, 1 reply; 14+ messages in thread
From: Jiri Benc @ 2015-10-01 14:44 UTC (permalink / raw)
  To: netdev; +Cc: dev, Pravin Shelar, Jesse Gross

We already have ip_tunnel_key_init, this does the same for IPv6. Will be
used also by openvswitch in the next patch.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
New patch in v2 of the set.
---
 include/net/dst_metadata.h | 18 ++++++------------
 include/net/ip_tunnels.h   | 40 +++++++++++++++++++++++++++++++---------
 2 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index af9d5382f6cb..30e925aba1a4 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -85,23 +85,17 @@ static inline struct metadata_dst *ipv6_tun_rx_dst(struct sk_buff *skb,
 {
 	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
 	struct metadata_dst *tun_dst;
-	struct ip_tunnel_info *info;
 
 	tun_dst = tun_rx_dst(md_size);
 	if (!tun_dst)
 		return NULL;
 
-	info = &tun_dst->u.tun_info;
-	info->mode = IP_TUNNEL_INFO_IPV6;
-	info->key.tun_flags = flags;
-	info->key.tun_id = tunnel_id;
-	info->key.tp_src = 0;
-	info->key.tp_dst = 0;
-
-	info->key.u.ipv6.src = ip6h->saddr;
-	info->key.u.ipv6.dst = ip6h->daddr;
-	info->key.tos = ipv6_get_dsfield(ip6h);
-	info->key.ttl = ip6h->hop_limit;
+	tun_dst->u.tun_info.mode = IP_TUNNEL_INFO_IPV6;
+	ip6_tunnel_key_init(&tun_dst->u.tun_info.key,
+			    &ip6h->saddr, &ip6h->daddr,
+			    ipv6_get_dsfield(ip6h), ip6h->hop_limit,
+			    0, 0, tunnel_id, flags);
+
 	return tun_dst;
 }
 
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index f6dafec9102c..087b2e24e5e0 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -179,17 +179,12 @@ int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *op,
 int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *op,
 			    unsigned int num);
 
-static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
-				      __be32 saddr, __be32 daddr,
-				      u8 tos, u8 ttl,
-				      __be16 tp_src, __be16 tp_dst,
-				      __be64 tun_id, __be16 tun_flags)
+static inline void __ip_tunnel_key_init(struct ip_tunnel_key *key,
+					u8 tos, u8 ttl,
+					__be16 tp_src, __be16 tp_dst,
+					__be64 tun_id, __be16 tun_flags)
 {
 	key->tun_id = tun_id;
-	key->u.ipv4.src = saddr;
-	key->u.ipv4.dst = daddr;
-	memset((unsigned char *)key + IP_TUNNEL_KEY_IPV4_PAD,
-	       0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
 	key->tos = tos;
 	key->ttl = ttl;
 	key->tun_flags = tun_flags;
@@ -207,6 +202,33 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
 		       0, sizeof(*key) - IP_TUNNEL_KEY_SIZE);
 }
 
+static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
+				      __be32 saddr, __be32 daddr,
+				      u8 tos, u8 ttl,
+				      __be16 tp_src, __be16 tp_dst,
+				      __be64 tun_id, __be16 tun_flags)
+{
+	__ip_tunnel_key_init(key, tos, ttl, tp_src, tp_dst, tun_id,
+			     tun_flags);
+	key->u.ipv4.src = saddr;
+	key->u.ipv4.dst = daddr;
+	memset((unsigned char *)key + IP_TUNNEL_KEY_IPV4_PAD,
+	       0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
+}
+
+static inline void ip6_tunnel_key_init(struct ip_tunnel_key *key,
+				       const struct in6_addr *saddr,
+				       const struct in6_addr *daddr,
+				       u8 tos, u8 ttl,
+				       __be16 tp_src, __be16 tp_dst,
+				       __be64 tun_id, __be16 tun_flags)
+{
+	__ip_tunnel_key_init(key, tos, ttl, tp_src, tp_dst, tun_id,
+			     tun_flags);
+	key->u.ipv6.src = *saddr;
+	key->u.ipv6.dst = *daddr;
+}
+
 static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
 					       *tun_info)
 {
-- 
1.8.3.1

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

* [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info
  2015-10-01 14:44 [PATCH net-next v2 0/4] openvswitch: add IPv6 tunneling support Jiri Benc
                   ` (2 preceding siblings ...)
  2015-10-01 14:44 ` [PATCH net-next v2 3/4] ip_tunnels: introduce ip6_tunnel_key_init Jiri Benc
@ 2015-10-01 14:44 ` Jiri Benc
  2015-10-02  0:11   ` Pravin Shelar
  3 siblings, 1 reply; 14+ messages in thread
From: Jiri Benc @ 2015-10-01 14:44 UTC (permalink / raw)
  To: netdev; +Cc: dev, Pravin Shelar, Jesse Gross

For compat tunnel interfaces, reject IPv6 keys.

Also fixes a related thinko in vport-vxlan: upcall->egress_tun_info is not
yet set at the point where it is used, thus the obtained family is
incorrect. As this is IPv4 anyway, just use AF_INET.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
New patch in v2 of the set.
---
 net/openvswitch/vport-geneve.c |  4 ++-
 net/openvswitch/vport-gre.c    |  4 ++-
 net/openvswitch/vport-vxlan.c  |  6 ++--
 net/openvswitch/vport.c        | 62 ++++++++++++++++++++++++++++--------------
 net/openvswitch/vport.h        | 26 ++++++++++++++++++
 5 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c
index 2735e9c4a3b8..601fa3fbb19a 100644
--- a/net/openvswitch/vport-geneve.c
+++ b/net/openvswitch/vport-geneve.c
@@ -60,7 +60,9 @@ static int geneve_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
 	__be16 dport = htons(geneve_port->port_no);
 	__be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
 
-	return ovs_tunnel_get_egress_info(upcall, ovs_dp_get_net(vport->dp),
+	/* Only IPv4 supported in the compat layer. Pass NULL ipv6 socket. */
+	return ovs_tunnel_get_egress_info(upcall,
+					  ovs_dp_get_net(vport->dp), NULL,
 					  skb, IPPROTO_UDP, sport, dport);
 }
 
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index 4d24481669c9..a3cf5695031d 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -87,7 +87,9 @@ static struct vport *gre_create(const struct vport_parms *parms)
 static int gre_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
 				   struct dp_upcall_info *upcall)
 {
-	return ovs_tunnel_get_egress_info(upcall, ovs_dp_get_net(vport->dp),
+	/* Only IPv4 supported. Pass NULL ipv6 socket. */
+	return ovs_tunnel_get_egress_info(upcall,
+					  ovs_dp_get_net(vport->dp), NULL,
 					  skb, IPPROTO_GRE, 0, 0);
 }
 
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index fb3cdb85905d..0973acb5432c 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -151,8 +151,7 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
 {
 	struct vxlan_dev *vxlan = netdev_priv(vport->dev);
 	struct net *net = ovs_dp_get_net(vport->dp);
-	unsigned short family = ip_tunnel_info_af(upcall->egress_tun_info);
-	__be16 dst_port = vxlan_dev_dst_port(vxlan, family);
+	__be16 dst_port = vxlan_dev_dst_port(vxlan, AF_INET);
 	__be16 src_port;
 	int port_min;
 	int port_max;
@@ -160,7 +159,8 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
 	inet_get_local_port_range(net, &port_min, &port_max);
 	src_port = udp_flow_src_port(net, skb, 0, 0, true);
 
-	return ovs_tunnel_get_egress_info(upcall, net,
+	/* Only IPv4 supported in the compat layer. Pass NULL ipv6 socket. */
+	return ovs_tunnel_get_egress_info(upcall, net, NULL,
 					  skb, IPPROTO_UDP,
 					  src_port, dst_port);
 }
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index dc81dc619aa2..c58d95eed5fd 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -489,6 +489,7 @@ EXPORT_SYMBOL_GPL(ovs_vport_deferred_free);
 
 int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
 			       struct net *net,
+			       struct sock *ipv6_sk,
 			       struct sk_buff *skb,
 			       u8 ipproto,
 			       __be16 tp_src,
@@ -498,13 +499,9 @@ int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
 	const struct ip_tunnel_info *tun_info = skb_tunnel_info(skb);
 	const struct ip_tunnel_key *tun_key;
 	u32 skb_mark = skb->mark;
-	struct rtable *rt;
-	struct flowi4 fl;
 
 	if (unlikely(!tun_info))
 		return -EINVAL;
-	if (ip_tunnel_info_af(tun_info) != AF_INET)
-		return -EINVAL;
 
 	tun_key = &tun_info->key;
 
@@ -512,22 +509,47 @@ int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
 	 * The process may need to be changed if the corresponding process
 	 * in vports ops changed.
 	 */
-	rt = ovs_tunnel_route_lookup(net, tun_key, skb_mark, &fl, ipproto);
-	if (IS_ERR(rt))
-		return PTR_ERR(rt);
-
-	ip_rt_put(rt);
-
-	/* Generate egress_tun_info based on tun_info,
-	 * saddr, tp_src and tp_dst
-	 */
-	ip_tunnel_key_init(&egress_tun_info->key,
-			   fl.saddr, tun_key->u.ipv4.dst,
-			   tun_key->tos,
-			   tun_key->ttl,
-			   tp_src, tp_dst,
-			   tun_key->tun_id,
-			   tun_key->tun_flags);
+	if (ip_tunnel_info_af(tun_info) == AF_INET) {
+		struct rtable *rt;
+		struct flowi4 fl;
+
+		rt = ovs_tunnel_route_lookup(net, tun_key, skb_mark, &fl, ipproto);
+		if (IS_ERR(rt))
+			return PTR_ERR(rt);
+
+		ip_rt_put(rt);
+
+		/* Generate egress_tun_info based on tun_info,
+		* saddr, tp_src and tp_dst
+		*/
+		ip_tunnel_key_init(&egress_tun_info->key,
+				   fl.saddr, tun_key->u.ipv4.dst,
+				   tun_key->tos,
+				   tun_key->ttl,
+				   tp_src, tp_dst,
+				   tun_key->tun_id,
+				   tun_key->tun_flags);
+	} else {
+		struct dst_entry *ndst;
+		struct flowi6 fl6;
+
+		if (!ipv6_sk)
+			return -EPFNOSUPPORT;
+
+		ndst = ovs_tunnel6_route_lookup(net, ipv6_sk, tun_key,
+						skb_mark, &fl6, ipproto);
+		if (IS_ERR(ndst))
+			return PTR_ERR(ndst);
+		dst_release(ndst);
+
+		ip6_tunnel_key_init(&egress_tun_info->key,
+				    &fl6.saddr, &tun_key->u.ipv6.dst,
+				    tun_key->tos,
+				    tun_key->ttl,
+				    tp_src, tp_dst,
+				    tun_key->tun_id,
+				    tun_key->tun_flags);
+	}
 	egress_tun_info->options_len = tun_info->options_len;
 	egress_tun_info->mode = tun_info->mode;
 	upcall->egress_tun_opts = ip_tunnel_info_opts(egress_tun_info);
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index a413f3ae6a7b..8445d931e863 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -27,6 +27,8 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/u64_stats_sync.h>
+#include <net/addrconf.h>
+#include <net/ipv6.h>
 #include <net/route.h>
 
 #include "datapath.h"
@@ -55,6 +57,7 @@ u32 ovs_vport_find_upcall_portid(const struct vport *, struct sk_buff *);
 
 int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
 			       struct net *net,
+			       struct sock *ipv6_sk,
 			       struct sk_buff *,
 			       u8 ipproto,
 			       __be16 tp_src,
@@ -234,6 +237,29 @@ static inline struct rtable *ovs_tunnel_route_lookup(struct net *net,
 	return rt;
 }
 
+static inline struct dst_entry *ovs_tunnel6_route_lookup(struct net *net,
+							 struct sock *sk,
+							 const struct ip_tunnel_key *key,
+							 u32 mark,
+							 struct flowi6 *fl6,
+							 u8 protocol)
+{
+	struct dst_entry *dst;
+	int err;
+
+	memset(fl6, 0, sizeof(*fl6));
+	fl6->daddr = key->u.ipv6.dst;
+	fl6->saddr = key->u.ipv6.src;
+	fl6->flowi6_tos = RT_TOS(key->tos);
+	fl6->flowi6_mark = mark;
+	fl6->flowi6_proto = protocol;
+
+	err = ipv6_stub->ipv6_dst_lookup(net, sk, &dst, fl6);
+	if (err)
+		return ERR_PTR(err);
+	return dst;
+}
+
 static inline void ovs_vport_send(struct vport *vport, struct sk_buff *skb)
 {
 	vport->ops->send(vport, skb);
-- 
1.8.3.1

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

* Re: [PATCH net-next v2 1/4] openvswitch: add tunnel protocol to sw_flow_key
  2015-10-01 14:44 ` [PATCH net-next v2 1/4] openvswitch: add tunnel protocol to sw_flow_key Jiri Benc
@ 2015-10-02  0:10   ` Pravin Shelar
  0 siblings, 0 replies; 14+ messages in thread
From: Pravin Shelar @ 2015-10-02  0:10 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, dev, Jesse Gross

On Thu, Oct 1, 2015 at 7:44 AM, Jiri Benc <jbenc@redhat.com> wrote:
> Store tunnel protocol (AF_INET or AF_INET6) in sw_flow_key. This field now
> also acts as an indicator whether the flow contains tunnel data (this was
> previously indicated by tun_key.u.ipv4.dst being set but with IPv6 addresses
> in an union with IPv4 ones this won't work anymore).
>
> The new field was added to a hole in sw_flow_key.
>
> Signed-off-by: Jiri Benc <jbenc@redhat.com>
> ---
> v2: Set the tun_proto mask to 0xff in ip_tun_from_nlattr.
> ---
Acked-by: Pravin B Shelar <pshelar@nicira.com>

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

* Re: [PATCH net-next v2 2/4] openvswitch: netlink attributes for IPv6 tunneling
  2015-10-01 14:44 ` [PATCH net-next v2 2/4] openvswitch: netlink attributes for IPv6 tunneling Jiri Benc
@ 2015-10-02  0:10   ` Pravin Shelar
  0 siblings, 0 replies; 14+ messages in thread
From: Pravin Shelar @ 2015-10-02  0:10 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, dev, Jesse Gross

On Thu, Oct 1, 2015 at 7:44 AM, Jiri Benc <jbenc@redhat.com> wrote:
> Add netlink attributes for IPv6 tunnel addresses. This enables IPv6 support
> for tunnels.
>
> Signed-off-by: Jiri Benc <jbenc@redhat.com>
> ---
> v2: Changed description. Rebased tun_proto assignment in ip_tun_from_nlattr
>     to accomodate changes in the previous patch.
> ---
Acked-by: Pravin B Shelar <pshelar@nicira.com>

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

* Re: [PATCH net-next v2 3/4] ip_tunnels: introduce ip6_tunnel_key_init
  2015-10-01 14:44 ` [PATCH net-next v2 3/4] ip_tunnels: introduce ip6_tunnel_key_init Jiri Benc
@ 2015-10-02  0:11   ` Pravin Shelar
  2015-10-02  5:58     ` Jiri Benc
  0 siblings, 1 reply; 14+ messages in thread
From: Pravin Shelar @ 2015-10-02  0:11 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, dev, Jesse Gross

On Thu, Oct 1, 2015 at 7:44 AM, Jiri Benc <jbenc@redhat.com> wrote:
> We already have ip_tunnel_key_init, this does the same for IPv6. Will be
> used also by openvswitch in the next patch.
>
> Signed-off-by: Jiri Benc <jbenc@redhat.com>
> ---
> New patch in v2 of the set.
> ---
>  include/net/dst_metadata.h | 18 ++++++------------
>  include/net/ip_tunnels.h   | 40 +++++++++++++++++++++++++++++++---------
>  2 files changed, 37 insertions(+), 21 deletions(-)
>
> diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
> index af9d5382f6cb..30e925aba1a4 100644
> --- a/include/net/dst_metadata.h
> +++ b/include/net/dst_metadata.h
> @@ -85,23 +85,17 @@ static inline struct metadata_dst *ipv6_tun_rx_dst(struct sk_buff *skb,
>  {
>         const struct ipv6hdr *ip6h = ipv6_hdr(skb);
>         struct metadata_dst *tun_dst;
> -       struct ip_tunnel_info *info;
>
>         tun_dst = tun_rx_dst(md_size);
>         if (!tun_dst)
>                 return NULL;
>
> -       info = &tun_dst->u.tun_info;
> -       info->mode = IP_TUNNEL_INFO_IPV6;
> -       info->key.tun_flags = flags;
> -       info->key.tun_id = tunnel_id;
> -       info->key.tp_src = 0;
> -       info->key.tp_dst = 0;
> -
> -       info->key.u.ipv6.src = ip6h->saddr;
> -       info->key.u.ipv6.dst = ip6h->daddr;
> -       info->key.tos = ipv6_get_dsfield(ip6h);
> -       info->key.ttl = ip6h->hop_limit;
> +       tun_dst->u.tun_info.mode = IP_TUNNEL_INFO_IPV6;
> +       ip6_tunnel_key_init(&tun_dst->u.tun_info.key,
> +                           &ip6h->saddr, &ip6h->daddr,
> +                           ipv6_get_dsfield(ip6h), ip6h->hop_limit,
> +                           0, 0, tunnel_id, flags);
> +
>         return tun_dst;
>  }
>
> diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
> index f6dafec9102c..087b2e24e5e0 100644
> --- a/include/net/ip_tunnels.h
> +++ b/include/net/ip_tunnels.h
> @@ -179,17 +179,12 @@ int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *op,
>  int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *op,
>                             unsigned int num);
>
> -static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
> -                                     __be32 saddr, __be32 daddr,
> -                                     u8 tos, u8 ttl,
> -                                     __be16 tp_src, __be16 tp_dst,
> -                                     __be64 tun_id, __be16 tun_flags)
> +static inline void __ip_tunnel_key_init(struct ip_tunnel_key *key,
> +                                       u8 tos, u8 ttl,
> +                                       __be16 tp_src, __be16 tp_dst,
> +                                       __be64 tun_id, __be16 tun_flags)
>  {
>         key->tun_id = tun_id;
> -       key->u.ipv4.src = saddr;
> -       key->u.ipv4.dst = daddr;
> -       memset((unsigned char *)key + IP_TUNNEL_KEY_IPV4_PAD,
> -              0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
>         key->tos = tos;
>         key->ttl = ttl;
>         key->tun_flags = tun_flags;
> @@ -207,6 +202,33 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
>                        0, sizeof(*key) - IP_TUNNEL_KEY_SIZE);
>  }
>
> +static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
> +                                     __be32 saddr, __be32 daddr,
> +                                     u8 tos, u8 ttl,
> +                                     __be16 tp_src, __be16 tp_dst,
> +                                     __be64 tun_id, __be16 tun_flags)
> +{
> +       __ip_tunnel_key_init(key, tos, ttl, tp_src, tp_dst, tun_id,
> +                            tun_flags);
> +       key->u.ipv4.src = saddr;
> +       key->u.ipv4.dst = daddr;
> +       memset((unsigned char *)key + IP_TUNNEL_KEY_IPV4_PAD,
> +              0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
neat: since IP_TUNNEL_KEY_IPV4_PAD not really IPv4 tunnel key padding
anymore, This also needs to be renamed.

otherwise looks good.

Acked-by: Pravin B Shelar <pshelar@nicira.com>

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

* Re: [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info
  2015-10-01 14:44 ` [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info Jiri Benc
@ 2015-10-02  0:11   ` Pravin Shelar
  2015-10-02  6:00     ` Jiri Benc
  0 siblings, 1 reply; 14+ messages in thread
From: Pravin Shelar @ 2015-10-02  0:11 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, dev, Jesse Gross

On Thu, Oct 1, 2015 at 7:44 AM, Jiri Benc <jbenc@redhat.com> wrote:
> For compat tunnel interfaces, reject IPv6 keys.
>
> Also fixes a related thinko in vport-vxlan: upcall->egress_tun_info is not
> yet set at the point where it is used, thus the obtained family is
> incorrect. As this is IPv4 anyway, just use AF_INET.
>
> Signed-off-by: Jiri Benc <jbenc@redhat.com>
> ---
> New patch in v2 of the set.
> ---
>  net/openvswitch/vport-geneve.c |  4 ++-
>  net/openvswitch/vport-gre.c    |  4 ++-
>  net/openvswitch/vport-vxlan.c  |  6 ++--
>  net/openvswitch/vport.c        | 62 ++++++++++++++++++++++++++++--------------
>  net/openvswitch/vport.h        | 26 ++++++++++++++++++
>  5 files changed, 77 insertions(+), 25 deletions(-)
>
...

> diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
> index fb3cdb85905d..0973acb5432c 100644
> --- a/net/openvswitch/vport-vxlan.c
> +++ b/net/openvswitch/vport-vxlan.c
> @@ -151,8 +151,7 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
>  {
>         struct vxlan_dev *vxlan = netdev_priv(vport->dev);
>         struct net *net = ovs_dp_get_net(vport->dp);
> -       unsigned short family = ip_tunnel_info_af(upcall->egress_tun_info);
> -       __be16 dst_port = vxlan_dev_dst_port(vxlan, family);
> +       __be16 dst_port = vxlan_dev_dst_port(vxlan, AF_INET);
>         __be16 src_port;
>         int port_min;
>         int port_max;
> @@ -160,7 +159,8 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
>         inet_get_local_port_range(net, &port_min, &port_max);
>         src_port = udp_flow_src_port(net, skb, 0, 0, true);
>
> -       return ovs_tunnel_get_egress_info(upcall, net,
> +       /* Only IPv4 supported in the compat layer. Pass NULL ipv6 socket. */
> +       return ovs_tunnel_get_egress_info(upcall, net, NULL,
>                                           skb, IPPROTO_UDP,
>                                           src_port, dst_port);
>  }
> diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
> index dc81dc619aa2..c58d95eed5fd 100644
> --- a/net/openvswitch/vport.c
> +++ b/net/openvswitch/vport.c
> @@ -489,6 +489,7 @@ EXPORT_SYMBOL_GPL(ovs_vport_deferred_free);
>
>  int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
>                                struct net *net,
> +                              struct sock *ipv6_sk,
>                                struct sk_buff *skb,
>                                u8 ipproto,
>                                __be16 tp_src,
> @@ -498,13 +499,9 @@ int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
>         const struct ip_tunnel_info *tun_info = skb_tunnel_info(skb);
>         const struct ip_tunnel_key *tun_key;
>         u32 skb_mark = skb->mark;
> -       struct rtable *rt;
> -       struct flowi4 fl;
>
>         if (unlikely(!tun_info))
>                 return -EINVAL;
> -       if (ip_tunnel_info_af(tun_info) != AF_INET)
> -               return -EINVAL;
>
>         tun_key = &tun_info->key;
>
> @@ -512,22 +509,47 @@ int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
>          * The process may need to be changed if the corresponding process
>          * in vports ops changed.
>          */
> -       rt = ovs_tunnel_route_lookup(net, tun_key, skb_mark, &fl, ipproto);
> -       if (IS_ERR(rt))
> -               return PTR_ERR(rt);
> -
> -       ip_rt_put(rt);
> -
> -       /* Generate egress_tun_info based on tun_info,
> -        * saddr, tp_src and tp_dst
> -        */
> -       ip_tunnel_key_init(&egress_tun_info->key,
> -                          fl.saddr, tun_key->u.ipv4.dst,
> -                          tun_key->tos,
> -                          tun_key->ttl,
> -                          tp_src, tp_dst,
> -                          tun_key->tun_id,
> -                          tun_key->tun_flags);
> +       if (ip_tunnel_info_af(tun_info) == AF_INET) {
> +               struct rtable *rt;
> +               struct flowi4 fl;
> +
> +               rt = ovs_tunnel_route_lookup(net, tun_key, skb_mark, &fl, ipproto);
> +               if (IS_ERR(rt))
> +                       return PTR_ERR(rt);
> +
> +               ip_rt_put(rt);
> +
> +               /* Generate egress_tun_info based on tun_info,
> +               * saddr, tp_src and tp_dst
> +               */
> +               ip_tunnel_key_init(&egress_tun_info->key,
> +                                  fl.saddr, tun_key->u.ipv4.dst,
> +                                  tun_key->tos,
> +                                  tun_key->ttl,
> +                                  tp_src, tp_dst,
> +                                  tun_key->tun_id,
> +                                  tun_key->tun_flags);
> +       } else {
> +               struct dst_entry *ndst;
> +               struct flowi6 fl6;
> +
> +               if (!ipv6_sk)
> +                       return -EPFNOSUPPORT;
> +
> +               ndst = ovs_tunnel6_route_lookup(net, ipv6_sk, tun_key,
> +                                               skb_mark, &fl6, ipproto);
> +               if (IS_ERR(ndst))
> +                       return PTR_ERR(ndst);
> +               dst_release(ndst);
> +
> +               ip6_tunnel_key_init(&egress_tun_info->key,
> +                                   &fl6.saddr, &tun_key->u.ipv6.dst,
> +                                   tun_key->tos,
> +                                   tun_key->ttl,
> +                                   tp_src, tp_dst,
> +                                   tun_key->tun_id,
> +                                   tun_key->tun_flags);
> +       }

I dont see point of adding this code when IPv6 sampling not support by
the patch series.

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

* Re: [PATCH net-next v2 3/4] ip_tunnels: introduce ip6_tunnel_key_init
  2015-10-02  0:11   ` Pravin Shelar
@ 2015-10-02  5:58     ` Jiri Benc
  0 siblings, 0 replies; 14+ messages in thread
From: Jiri Benc @ 2015-10-02  5:58 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: netdev, dev, Jesse Gross

On Thu, 1 Oct 2015 17:11:43 -0700, Pravin Shelar wrote:
> On Thu, Oct 1, 2015 at 7:44 AM, Jiri Benc <jbenc@redhat.com> wrote:
> > +static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
> > +                                     __be32 saddr, __be32 daddr,
> > +                                     u8 tos, u8 ttl,
> > +                                     __be16 tp_src, __be16 tp_dst,
> > +                                     __be64 tun_id, __be16 tun_flags)
> > +{
> > +       __ip_tunnel_key_init(key, tos, ttl, tp_src, tp_dst, tun_id,
> > +                            tun_flags);
> > +       key->u.ipv4.src = saddr;
> > +       key->u.ipv4.dst = daddr;
> > +       memset((unsigned char *)key + IP_TUNNEL_KEY_IPV4_PAD,
> > +              0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
> neat: since IP_TUNNEL_KEY_IPV4_PAD not really IPv4 tunnel key padding
> anymore, This also needs to be renamed.

It is IPv4 address padding. It is used to zero out the part of the
union of IPv6 and IPv4 addresses that is not occupied by IPv4
addresses. The name was just too long to include "ADDR", too.

The original pad constant was renamed to IP_TUNNEL_KEY_SIZE, thus is
not referencing IPv4 anymore.

> otherwise looks good.
> 
> Acked-by: Pravin B Shelar <pshelar@nicira.com>

Thanks,

 Jiri

-- 
Jiri Benc

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

* Re: [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info
  2015-10-02  0:11   ` Pravin Shelar
@ 2015-10-02  6:00     ` Jiri Benc
  2015-10-02 19:32       ` Pravin Shelar
  0 siblings, 1 reply; 14+ messages in thread
From: Jiri Benc @ 2015-10-02  6:00 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: netdev, dev, Jesse Gross

On Thu, 1 Oct 2015 17:11:56 -0700, Pravin Shelar wrote:
> I dont see point of adding this code when IPv6 sampling not support by
> the patch series.

It was requested by Jesse:
http://article.gmane.org/gmane.linux.network/380348

I don't mind leaving this and the previous patch out, it's actually
what I did in v1.

 Jiri

-- 
Jiri Benc

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

* Re: [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info
  2015-10-02  6:00     ` Jiri Benc
@ 2015-10-02 19:32       ` Pravin Shelar
       [not found]         ` <CALnjE+qn7PrEYxKZ6c03-Bz63BcROVuqmwdp8sqi2eXvxY-yeg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Pravin Shelar @ 2015-10-02 19:32 UTC (permalink / raw)
  To: Jiri Benc; +Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev

On Thu, Oct 1, 2015 at 11:00 PM, Jiri Benc <jbenc@redhat.com> wrote:
> On Thu, 1 Oct 2015 17:11:56 -0700, Pravin Shelar wrote:
>> I dont see point of adding this code when IPv6 sampling not support by
>> the patch series.
>
> It was requested by Jesse:
> http://article.gmane.org/gmane.linux.network/380348
>

I don't think we can use this function, lwtunnel device need new ndo_
operation to export this information. So lets defer this patch till we
have solution for retrieving egress info from lwtunnel devices.

> I don't mind leaving this and the previous patch out, it's actually
> what I did in v1.
>
>  Jiri
>
> --
> Jiri Benc
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

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

* Re: [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info
       [not found]         ` <CALnjE+qn7PrEYxKZ6c03-Bz63BcROVuqmwdp8sqi2eXvxY-yeg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2015-10-03  0:57           ` Jesse Gross
  2015-10-05 18:05             ` Pravin Shelar
  0 siblings, 1 reply; 14+ messages in thread
From: Jesse Gross @ 2015-10-03  0:57 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev, Jiri Benc

On Fri, Oct 2, 2015 at 12:32 PM, Pravin Shelar <pshelar@nicira.com> wrote:
> On Thu, Oct 1, 2015 at 11:00 PM, Jiri Benc <jbenc@redhat.com> wrote:
>> On Thu, 1 Oct 2015 17:11:56 -0700, Pravin Shelar wrote:
>>> I dont see point of adding this code when IPv6 sampling not support by
>>> the patch series.
>>
>> It was requested by Jesse:
>> http://article.gmane.org/gmane.linux.network/380348
>>
>
> I don't think we can use this function, lwtunnel device need new ndo_
> operation to export this information. So lets defer this patch till we
> have solution for retrieving egress info from lwtunnel devices.

I don't entirely disagree with this but I'm also nervous about
completely leaving it out. It seems like when this issue does get
fixed, it is likely that the person who does it will just convert
whatever code is there and not necessarily think about IPv6 since it's
not an IPv6 feature. If that happens, we'll have a hidden problem in
IPv6, which is somewhat unfortunately as try to advance IPv6 forward.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

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

* Re: [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info
  2015-10-03  0:57           ` Jesse Gross
@ 2015-10-05 18:05             ` Pravin Shelar
  0 siblings, 0 replies; 14+ messages in thread
From: Pravin Shelar @ 2015-10-05 18:05 UTC (permalink / raw)
  To: Jesse Gross; +Cc: Jiri Benc, netdev, dev

On Fri, Oct 2, 2015 at 5:57 PM, Jesse Gross <jesse@nicira.com> wrote:
> On Fri, Oct 2, 2015 at 12:32 PM, Pravin Shelar <pshelar@nicira.com> wrote:
>> On Thu, Oct 1, 2015 at 11:00 PM, Jiri Benc <jbenc@redhat.com> wrote:
>>> On Thu, 1 Oct 2015 17:11:56 -0700, Pravin Shelar wrote:
>>>> I dont see point of adding this code when IPv6 sampling not support by
>>>> the patch series.
>>>
>>> It was requested by Jesse:
>>> http://article.gmane.org/gmane.linux.network/380348
>>>
>>
>> I don't think we can use this function, lwtunnel device need new ndo_
>> operation to export this information. So lets defer this patch till we
>> have solution for retrieving egress info from lwtunnel devices.
>
> I don't entirely disagree with this but I'm also nervous about
> completely leaving it out. It seems like when this issue does get
> fixed, it is likely that the person who does it will just convert
> whatever code is there and not necessarily think about IPv6 since it's
> not an IPv6 feature. If that happens, we'll have a hidden problem in
> IPv6, which is somewhat unfortunately as try to advance IPv6 forward.

The code is pretty different for different tunnel. It is possible to
take the code and reuse it. But that would involve lot of refactoring
into existing code for every flow tunnel based tunnel implementation.
I do not want to do it as part of fix to net branch.
I have sent out patch to fix the egress tunnel info issue with
lwtunnel. Once that is merged we can have complete IPv6 tunnel support
on net-next.

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

end of thread, other threads:[~2015-10-05 18:05 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-01 14:44 [PATCH net-next v2 0/4] openvswitch: add IPv6 tunneling support Jiri Benc
2015-10-01 14:44 ` [PATCH net-next v2 1/4] openvswitch: add tunnel protocol to sw_flow_key Jiri Benc
2015-10-02  0:10   ` Pravin Shelar
2015-10-01 14:44 ` [PATCH net-next v2 2/4] openvswitch: netlink attributes for IPv6 tunneling Jiri Benc
2015-10-02  0:10   ` Pravin Shelar
2015-10-01 14:44 ` [PATCH net-next v2 3/4] ip_tunnels: introduce ip6_tunnel_key_init Jiri Benc
2015-10-02  0:11   ` Pravin Shelar
2015-10-02  5:58     ` Jiri Benc
2015-10-01 14:44 ` [PATCH net-next v2 4/4] openvswitch: IPv6 support for ovs_tunnel_get_egress_info Jiri Benc
2015-10-02  0:11   ` Pravin Shelar
2015-10-02  6:00     ` Jiri Benc
2015-10-02 19:32       ` Pravin Shelar
     [not found]         ` <CALnjE+qn7PrEYxKZ6c03-Bz63BcROVuqmwdp8sqi2eXvxY-yeg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-10-03  0:57           ` Jesse Gross
2015-10-05 18:05             ` Pravin Shelar

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.