All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio
@ 2014-10-30 18:26 Ben Hutchings
  2014-10-30 18:27 ` [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio Ben Hutchings
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Ben Hutchings @ 2014-10-30 18:26 UTC (permalink / raw)
  To: netdev; +Cc: Hannes Frederic Sowa, virtualization

[-- Attachment #1: Type: text/plain, Size: 834 bytes --]

The virtio net protocol supports UFO but does not provide for passing a
fragment ID for fragmentation of IPv6 packets.  We used to generate a
fragment ID wherever such a packet was fragmented, but currently we
always use ID=0!

v2: Add blank lines after declarations

Ben.

Ben Hutchings (2):
  drivers/net: Disable UFO through virtio
  drivers/net,ipv6: Select IPv6 fragment idents for virtio UFO packets

 drivers/net/macvtap.c    | 16 ++++++++--------
 drivers/net/tun.c        | 25 ++++++++++++++++---------
 drivers/net/virtio_net.c | 24 ++++++++++++++----------
 include/net/ipv6.h       |  2 ++
 net/ipv6/output_core.c   | 34 ++++++++++++++++++++++++++++++++++
 5 files changed, 74 insertions(+), 27 deletions(-)

-- 
Ben Hutchings
The program is absolutely right; therefore, the computer must be wrong.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

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

* [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio
  2014-10-30 18:26 [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio Ben Hutchings
@ 2014-10-30 18:27 ` Ben Hutchings
  2014-10-30 18:47   ` Eric Dumazet
  2014-11-19  9:14   ` Michael S. Tsirkin
  2014-10-30 18:27 ` [PATCH v2 net 2/2] drivers/net,ipv6: Select IPv6 fragment idents for virtio UFO packets Ben Hutchings
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 12+ messages in thread
From: Ben Hutchings @ 2014-10-30 18:27 UTC (permalink / raw)
  To: netdev; +Cc: Hannes Frederic Sowa, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 8295 bytes --]

IPv6 does not allow fragmentation by routers, so there is no
fragmentation ID in the fixed header.  UFO for IPv6 requires the ID to
be passed separately, but there is no provision for this in the virtio
net protocol.

Until recently our software implementation of UFO/IPv6 generated a new
ID, but this was a bug.  Now we will use ID=0 for any UFO/IPv6 packet
passed through a tap, which is even worse.

Unfortunately there is no distinction between UFO/IPv4 and v6
features, so disable UFO on taps and virtio_net completely until we
have a proper solution.

We cannot depend on VM managers respecting the tap feature flags, so
keep accepting UFO packets but log a warning the first time we do
this.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
---
 drivers/net/macvtap.c    | 13 +++++--------
 drivers/net/tun.c        | 19 +++++++++++--------
 drivers/net/virtio_net.c | 24 ++++++++++++++----------
 3 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 65e2892..2aeaa61 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -65,7 +65,7 @@ static struct cdev macvtap_cdev;
 static const struct proto_ops macvtap_socket_ops;
 
 #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
-		      NETIF_F_TSO6 | NETIF_F_UFO)
+		      NETIF_F_TSO6)
 #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
 #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG)
 
@@ -569,6 +569,8 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
 			gso_type = SKB_GSO_TCPV6;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
+			pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
+				     current->comm);
 			gso_type = SKB_GSO_UDP;
 			break;
 		default:
@@ -614,8 +616,6 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
 			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 		else if (sinfo->gso_type & SKB_GSO_TCPV6)
 			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
-		else if (sinfo->gso_type & SKB_GSO_UDP)
-			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
 		else
 			BUG();
 		if (sinfo->gso_type & SKB_GSO_TCP_ECN)
@@ -950,9 +950,6 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
 			if (arg & TUN_F_TSO6)
 				feature_mask |= NETIF_F_TSO6;
 		}
-
-		if (arg & TUN_F_UFO)
-			feature_mask |= NETIF_F_UFO;
 	}
 
 	/* tun/tap driver inverts the usage for TSO offloads, where
@@ -963,7 +960,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
 	 * When user space turns off TSO, we turn off GSO/LRO so that
 	 * user-space will not receive TSO frames.
 	 */
-	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO))
+	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
 		features |= RX_OFFLOADS;
 	else
 		features &= ~RX_OFFLOADS;
@@ -1064,7 +1061,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
 	case TUNSETOFFLOAD:
 		/* let the user check for future flags */
 		if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
-			    TUN_F_TSO_ECN | TUN_F_UFO))
+			    TUN_F_TSO_ECN))
 			return -EINVAL;
 
 		rtnl_lock();
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 186ce54..280d3d2 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -174,7 +174,7 @@ struct tun_struct {
 	struct net_device	*dev;
 	netdev_features_t	set_features;
 #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
-			  NETIF_F_TSO6|NETIF_F_UFO)
+			  NETIF_F_TSO6)
 
 	int			vnet_hdr_sz;
 	int			sndbuf;
@@ -1149,8 +1149,18 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
+		{
+			static bool warned;
+
+			if (!warned) {
+				warned = true;
+				netdev_warn(tun->dev,
+					    "%s: using disabled UFO feature; please fix this program\n",
+					    current->comm);
+			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 			break;
+		}
 		default:
 			tun->dev->stats.rx_frame_errors++;
 			kfree_skb(skb);
@@ -1251,8 +1261,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 			else if (sinfo->gso_type & SKB_GSO_TCPV6)
 				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
-			else if (sinfo->gso_type & SKB_GSO_UDP)
-				gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
 			else {
 				pr_err("unexpected GSO type: "
 				       "0x%x, gso_size %d, hdr_len %d\n",
@@ -1762,11 +1770,6 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
 				features |= NETIF_F_TSO6;
 			arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
 		}
-
-		if (arg & TUN_F_UFO) {
-			features |= NETIF_F_UFO;
-			arg &= ~TUN_F_UFO;
-		}
 	}
 
 	/* This gives the user a way to test for new features in future by
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d75256bd..ec2a8b4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -491,8 +491,17 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
+		{
+			static bool warned;
+
+			if (!warned) {
+				warned = true;
+				netdev_warn(dev,
+					    "host using disabled UFO feature; please fix it\n");
+			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 			break;
+		}
 		case VIRTIO_NET_HDR_GSO_TCPV6:
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
 			break;
@@ -881,8 +890,6 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
 			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
 			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
-		else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
-			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
 		else
 			BUG();
 		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
@@ -1705,7 +1712,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 			dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
 
 		if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
-			dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
+			dev->hw_features |= NETIF_F_TSO
 				| NETIF_F_TSO_ECN | NETIF_F_TSO6;
 		}
 		/* Individual feature bits: what can host handle? */
@@ -1715,11 +1722,9 @@ static int virtnet_probe(struct virtio_device *vdev)
 			dev->hw_features |= NETIF_F_TSO6;
 		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
 			dev->hw_features |= NETIF_F_TSO_ECN;
-		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
-			dev->hw_features |= NETIF_F_UFO;
 
 		if (gso)
-			dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
+			dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
 		/* (!csum && gso) case will be fixed by register_netdev() */
 	}
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
@@ -1757,8 +1762,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 	/* If we can receive ANY GSO packets, we must allocate large ones. */
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
 	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
-	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
-	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
+	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
 		vi->big_packets = true;
 
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
@@ -1952,9 +1956,9 @@ static struct virtio_device_id id_table[] = {
 static unsigned int features[] = {
 	VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
 	VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
-	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
+	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6,
 	VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
-	VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
+	VIRTIO_NET_F_GUEST_ECN,
 	VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
 	VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
 	VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,


-- 
Ben Hutchings
The program is absolutely right; therefore, the computer must be wrong.

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* [PATCH v2 net 2/2] drivers/net,ipv6: Select IPv6 fragment idents for virtio UFO packets
  2014-10-30 18:26 [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio Ben Hutchings
  2014-10-30 18:27 ` [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio Ben Hutchings
@ 2014-10-30 18:27 ` Ben Hutchings
  2014-10-30 18:27 ` Ben Hutchings
  2014-10-31  0:02 ` [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio David Miller
  3 siblings, 0 replies; 12+ messages in thread
From: Ben Hutchings @ 2014-10-30 18:27 UTC (permalink / raw)
  To: netdev; +Cc: Hannes Frederic Sowa, virtualization

[-- Attachment #1: Type: text/plain, Size: 4608 bytes --]

UFO is now disabled on all drivers that work with virtio net headers,
but userland may try to send UFO/IPv6 packets anyway.  Instead of
sending with ID=0, we should select identifiers on their behalf (as we
used to).

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
---
 drivers/net/macvtap.c  |  3 +++
 drivers/net/tun.c      |  6 +++++-
 include/net/ipv6.h     |  2 ++
 net/ipv6/output_core.c | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 2aeaa61..6f226de 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -16,6 +16,7 @@
 #include <linux/idr.h>
 #include <linux/fs.h>
 
+#include <net/ipv6.h>
 #include <net/net_namespace.h>
 #include <net/rtnetlink.h>
 #include <net/sock.h>
@@ -572,6 +573,8 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
 			pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
 				     current->comm);
 			gso_type = SKB_GSO_UDP;
+			if (skb->protocol == htons(ETH_P_IPV6))
+				ipv6_proxy_select_ident(skb);
 			break;
 		default:
 			return -EINVAL;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 280d3d2..7302398 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -65,6 +65,7 @@
 #include <linux/nsproxy.h>
 #include <linux/virtio_net.h>
 #include <linux/rcupdate.h>
+#include <net/ipv6.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/rtnetlink.h>
@@ -1139,6 +1140,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 		break;
 	}
 
+	skb_reset_network_header(skb);
+
 	if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
 		pr_debug("GSO!\n");
 		switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
@@ -1159,6 +1162,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 					    current->comm);
 			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+			if (skb->protocol == htons(ETH_P_IPV6))
+				ipv6_proxy_select_ident(skb);
 			break;
 		}
 		default:
@@ -1189,7 +1194,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 		skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
 	}
 
-	skb_reset_network_header(skb);
 	skb_probe_transport_header(skb, 0);
 
 	rxhash = skb_get_hash(skb);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 97f4720..4292929 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -671,6 +671,8 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
 	return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
 }
 
+void ipv6_proxy_select_ident(struct sk_buff *skb);
+
 int ip6_dst_hoplimit(struct dst_entry *dst);
 
 static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index fc24c39..97f41a3 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -3,11 +3,45 @@
  * not configured or static.  These functions are needed by GSO/GRO implementation.
  */
 #include <linux/export.h>
+#include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
 #include <net/addrconf.h>
 #include <net/secure_seq.h>
 
+/* This function exists only for tap drivers that must support broken
+ * clients requesting UFO without specifying an IPv6 fragment ID.
+ *
+ * This is similar to ipv6_select_ident() but we use an independent hash
+ * seed to limit information leakage.
+ *
+ * The network header must be set before calling this.
+ */
+void ipv6_proxy_select_ident(struct sk_buff *skb)
+{
+	static u32 ip6_proxy_idents_hashrnd __read_mostly;
+	struct in6_addr buf[2];
+	struct in6_addr *addrs;
+	u32 hash, id;
+
+	addrs = skb_header_pointer(skb,
+				   skb_network_offset(skb) +
+				   offsetof(struct ipv6hdr, saddr),
+				   sizeof(buf), buf);
+	if (!addrs)
+		return;
+
+	net_get_random_once(&ip6_proxy_idents_hashrnd,
+			    sizeof(ip6_proxy_idents_hashrnd));
+
+	hash = __ipv6_addr_jhash(&addrs[1], ip6_proxy_idents_hashrnd);
+	hash = __ipv6_addr_jhash(&addrs[0], hash);
+
+	id = ip_idents_reserve(hash, 1);
+	skb_shinfo(skb)->ip6_frag_id = htonl(id);
+}
+EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
+
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 {
 	u16 offset = sizeof(struct ipv6hdr);

-- 
Ben Hutchings
The program is absolutely right; therefore, the computer must be wrong.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

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

* [PATCH v2 net 2/2] drivers/net,ipv6: Select IPv6 fragment idents for virtio UFO packets
  2014-10-30 18:26 [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio Ben Hutchings
  2014-10-30 18:27 ` [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio Ben Hutchings
  2014-10-30 18:27 ` [PATCH v2 net 2/2] drivers/net,ipv6: Select IPv6 fragment idents for virtio UFO packets Ben Hutchings
@ 2014-10-30 18:27 ` Ben Hutchings
  2014-10-31  0:02 ` [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio David Miller
  3 siblings, 0 replies; 12+ messages in thread
From: Ben Hutchings @ 2014-10-30 18:27 UTC (permalink / raw)
  To: netdev; +Cc: Hannes Frederic Sowa, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 4608 bytes --]

UFO is now disabled on all drivers that work with virtio net headers,
but userland may try to send UFO/IPv6 packets anyway.  Instead of
sending with ID=0, we should select identifiers on their behalf (as we
used to).

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
---
 drivers/net/macvtap.c  |  3 +++
 drivers/net/tun.c      |  6 +++++-
 include/net/ipv6.h     |  2 ++
 net/ipv6/output_core.c | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 2aeaa61..6f226de 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -16,6 +16,7 @@
 #include <linux/idr.h>
 #include <linux/fs.h>
 
+#include <net/ipv6.h>
 #include <net/net_namespace.h>
 #include <net/rtnetlink.h>
 #include <net/sock.h>
@@ -572,6 +573,8 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
 			pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
 				     current->comm);
 			gso_type = SKB_GSO_UDP;
+			if (skb->protocol == htons(ETH_P_IPV6))
+				ipv6_proxy_select_ident(skb);
 			break;
 		default:
 			return -EINVAL;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 280d3d2..7302398 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -65,6 +65,7 @@
 #include <linux/nsproxy.h>
 #include <linux/virtio_net.h>
 #include <linux/rcupdate.h>
+#include <net/ipv6.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/rtnetlink.h>
@@ -1139,6 +1140,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 		break;
 	}
 
+	skb_reset_network_header(skb);
+
 	if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
 		pr_debug("GSO!\n");
 		switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
@@ -1159,6 +1162,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 					    current->comm);
 			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+			if (skb->protocol == htons(ETH_P_IPV6))
+				ipv6_proxy_select_ident(skb);
 			break;
 		}
 		default:
@@ -1189,7 +1194,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 		skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
 	}
 
-	skb_reset_network_header(skb);
 	skb_probe_transport_header(skb, 0);
 
 	rxhash = skb_get_hash(skb);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 97f4720..4292929 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -671,6 +671,8 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
 	return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
 }
 
+void ipv6_proxy_select_ident(struct sk_buff *skb);
+
 int ip6_dst_hoplimit(struct dst_entry *dst);
 
 static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index fc24c39..97f41a3 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -3,11 +3,45 @@
  * not configured or static.  These functions are needed by GSO/GRO implementation.
  */
 #include <linux/export.h>
+#include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
 #include <net/addrconf.h>
 #include <net/secure_seq.h>
 
+/* This function exists only for tap drivers that must support broken
+ * clients requesting UFO without specifying an IPv6 fragment ID.
+ *
+ * This is similar to ipv6_select_ident() but we use an independent hash
+ * seed to limit information leakage.
+ *
+ * The network header must be set before calling this.
+ */
+void ipv6_proxy_select_ident(struct sk_buff *skb)
+{
+	static u32 ip6_proxy_idents_hashrnd __read_mostly;
+	struct in6_addr buf[2];
+	struct in6_addr *addrs;
+	u32 hash, id;
+
+	addrs = skb_header_pointer(skb,
+				   skb_network_offset(skb) +
+				   offsetof(struct ipv6hdr, saddr),
+				   sizeof(buf), buf);
+	if (!addrs)
+		return;
+
+	net_get_random_once(&ip6_proxy_idents_hashrnd,
+			    sizeof(ip6_proxy_idents_hashrnd));
+
+	hash = __ipv6_addr_jhash(&addrs[1], ip6_proxy_idents_hashrnd);
+	hash = __ipv6_addr_jhash(&addrs[0], hash);
+
+	id = ip_idents_reserve(hash, 1);
+	skb_shinfo(skb)->ip6_frag_id = htonl(id);
+}
+EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
+
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 {
 	u16 offset = sizeof(struct ipv6hdr);

-- 
Ben Hutchings
The program is absolutely right; therefore, the computer must be wrong.

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* Re: [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio
  2014-10-30 18:27 ` [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio Ben Hutchings
@ 2014-10-30 18:47   ` Eric Dumazet
  2014-10-30 22:20     ` Ben Hutchings
  2014-11-19  9:14   ` Michael S. Tsirkin
  1 sibling, 1 reply; 12+ messages in thread
From: Eric Dumazet @ 2014-10-30 18:47 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, Hannes Frederic Sowa, virtualization


On Thu, 2014-10-30 at 18:27 +0000, Ben Hutchings wrote:


> +		{
> +			static bool warned;
> +
> +			if (!warned) {
> +				warned = true;
> +				netdev_warn(tun->dev,
> +					    "%s: using disabled UFO feature; please fix this program\n",
> +					    current->comm);
> +			}
>

It might be time to add netdev_warn_once() ;)

Alternatively, you could use 
	pr_warn_once("%s: using disabled UFO feature; please fix this program\n",
		     tun->dev->name, current->comm);

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

* Re: [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio
  2014-10-30 18:47   ` Eric Dumazet
@ 2014-10-30 22:20     ` Ben Hutchings
  2014-10-30 23:16       ` Eric Dumazet
  0 siblings, 1 reply; 12+ messages in thread
From: Ben Hutchings @ 2014-10-30 22:20 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, Hannes Frederic Sowa, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 817 bytes --]

On Thu, 2014-10-30 at 11:47 -0700, Eric Dumazet wrote:
> On Thu, 2014-10-30 at 18:27 +0000, Ben Hutchings wrote:
> 
> 
> > +		{
> > +			static bool warned;
> > +
> > +			if (!warned) {
> > +				warned = true;
> > +				netdev_warn(tun->dev,
> > +					    "%s: using disabled UFO feature; please fix this program\n",
> > +					    current->comm);
> > +			}
> >
> 
> It might be time to add netdev_warn_once() ;)

Could do.  I'm trying to make small fixes that are suitable for stable.

> Alternatively, you could use 
> 	pr_warn_once("%s: using disabled UFO feature; please fix this program\n",
> 		     tun->dev->name, current->comm);

That's missing a "%s: ", but yes that would also work.

Ben.

-- 
Ben Hutchings
The program is absolutely right; therefore, the computer must be wrong.

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* Re: [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio
  2014-10-30 22:20     ` Ben Hutchings
@ 2014-10-30 23:16       ` Eric Dumazet
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Dumazet @ 2014-10-30 23:16 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, Hannes Frederic Sowa, virtualization

On Thu, 2014-10-30 at 22:20 +0000, Ben Hutchings wrote:

> Could do.  I'm trying to make small fixes that are suitable for stable.

Oh right, makes sense ;)

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

* Re: [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio
  2014-10-30 18:26 [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio Ben Hutchings
                   ` (2 preceding siblings ...)
  2014-10-30 18:27 ` Ben Hutchings
@ 2014-10-31  0:02 ` David Miller
  3 siblings, 0 replies; 12+ messages in thread
From: David Miller @ 2014-10-31  0:02 UTC (permalink / raw)
  To: ben; +Cc: netdev, hannes, virtualization

From: Ben Hutchings <ben@decadent.org.uk>
Date: Thu, 30 Oct 2014 18:26:32 +0000

> The virtio net protocol supports UFO but does not provide for passing a
> fragment ID for fragmentation of IPv6 packets.  We used to generate a
> fragment ID wherever such a packet was fragmented, but currently we
> always use ID=0!
> 
> v2: Add blank lines after declarations

Series applied and queued up for -stable, thanks Ben.

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

* Re: [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio
  2014-10-30 18:27 ` [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio Ben Hutchings
  2014-10-30 18:47   ` Eric Dumazet
@ 2014-11-19  9:14   ` Michael S. Tsirkin
  2014-11-21  1:47     ` Jason Wang
  2014-11-21 18:46     ` Ben Hutchings
  1 sibling, 2 replies; 12+ messages in thread
From: Michael S. Tsirkin @ 2014-11-19  9:14 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, Hannes Frederic Sowa, virtualization

On Thu, Oct 30, 2014 at 06:27:12PM +0000, Ben Hutchings wrote:
> IPv6 does not allow fragmentation by routers, so there is no
> fragmentation ID in the fixed header.  UFO for IPv6 requires the ID to
> be passed separately, but there is no provision for this in the virtio
> net protocol.
> 
> Until recently our software implementation of UFO/IPv6 generated a new
> ID, but this was a bug.  Now we will use ID=0 for any UFO/IPv6 packet
> passed through a tap, which is even worse.
> 
> Unfortunately there is no distinction between UFO/IPv4 and v6
> features, so disable UFO on taps and virtio_net completely until we
> have a proper solution.
> 
> We cannot depend on VM managers respecting the tap feature flags, so
> keep accepting UFO packets but log a warning the first time we do
> this.
> 
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")


There's something I don't understand here. I see:

        NETIF_F_UFO_BIT,                /* ... UDPv4 fragmentation */

this comment is wrong then?

The patches drastically regress performance for UDPv4 for VMs only, but
isn't it likely many other devices based their code on this comment?

How about we disable UFO for IPv6 globally, and put the
flag back in?
We can then gradually add NETIF_F_UFO6_BIT for devices that
actually support UFO for IPv6.

Thoughts?



> ---
>  drivers/net/macvtap.c    | 13 +++++--------
>  drivers/net/tun.c        | 19 +++++++++++--------
>  drivers/net/virtio_net.c | 24 ++++++++++++++----------
>  3 files changed, 30 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> index 65e2892..2aeaa61 100644
> --- a/drivers/net/macvtap.c
> +++ b/drivers/net/macvtap.c
> @@ -65,7 +65,7 @@ static struct cdev macvtap_cdev;
>  static const struct proto_ops macvtap_socket_ops;
>  
>  #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
> -		      NETIF_F_TSO6 | NETIF_F_UFO)
> +		      NETIF_F_TSO6)
>  #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
>  #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG)
>  
> @@ -569,6 +569,8 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
>  			gso_type = SKB_GSO_TCPV6;
>  			break;
>  		case VIRTIO_NET_HDR_GSO_UDP:
> +			pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
> +				     current->comm);
>  			gso_type = SKB_GSO_UDP;
>  			break;
>  		default:
> @@ -614,8 +616,6 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
>  			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
>  		else if (sinfo->gso_type & SKB_GSO_TCPV6)
>  			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
> -		else if (sinfo->gso_type & SKB_GSO_UDP)
> -			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
>  		else
>  			BUG();
>  		if (sinfo->gso_type & SKB_GSO_TCP_ECN)
> @@ -950,9 +950,6 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
>  			if (arg & TUN_F_TSO6)
>  				feature_mask |= NETIF_F_TSO6;
>  		}
> -
> -		if (arg & TUN_F_UFO)
> -			feature_mask |= NETIF_F_UFO;
>  	}
>  
>  	/* tun/tap driver inverts the usage for TSO offloads, where
> @@ -963,7 +960,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
>  	 * When user space turns off TSO, we turn off GSO/LRO so that
>  	 * user-space will not receive TSO frames.
>  	 */
> -	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO))
> +	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
>  		features |= RX_OFFLOADS;
>  	else
>  		features &= ~RX_OFFLOADS;
> @@ -1064,7 +1061,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
>  	case TUNSETOFFLOAD:
>  		/* let the user check for future flags */
>  		if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
> -			    TUN_F_TSO_ECN | TUN_F_UFO))
> +			    TUN_F_TSO_ECN))
>  			return -EINVAL;
>  
>  		rtnl_lock();
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 186ce54..280d3d2 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -174,7 +174,7 @@ struct tun_struct {
>  	struct net_device	*dev;
>  	netdev_features_t	set_features;
>  #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
> -			  NETIF_F_TSO6|NETIF_F_UFO)
> +			  NETIF_F_TSO6)
>  
>  	int			vnet_hdr_sz;
>  	int			sndbuf;
> @@ -1149,8 +1149,18 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
>  			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
>  			break;
>  		case VIRTIO_NET_HDR_GSO_UDP:
> +		{
> +			static bool warned;
> +
> +			if (!warned) {
> +				warned = true;
> +				netdev_warn(tun->dev,
> +					    "%s: using disabled UFO feature; please fix this program\n",
> +					    current->comm);
> +			}
>  			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
>  			break;
> +		}
>  		default:
>  			tun->dev->stats.rx_frame_errors++;
>  			kfree_skb(skb);
> @@ -1251,8 +1261,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
>  				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
>  			else if (sinfo->gso_type & SKB_GSO_TCPV6)
>  				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
> -			else if (sinfo->gso_type & SKB_GSO_UDP)
> -				gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
>  			else {
>  				pr_err("unexpected GSO type: "
>  				       "0x%x, gso_size %d, hdr_len %d\n",
> @@ -1762,11 +1770,6 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
>  				features |= NETIF_F_TSO6;
>  			arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
>  		}
> -
> -		if (arg & TUN_F_UFO) {
> -			features |= NETIF_F_UFO;
> -			arg &= ~TUN_F_UFO;
> -		}
>  	}
>  
>  	/* This gives the user a way to test for new features in future by
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index d75256bd..ec2a8b4 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -491,8 +491,17 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
>  			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
>  			break;
>  		case VIRTIO_NET_HDR_GSO_UDP:
> +		{
> +			static bool warned;
> +
> +			if (!warned) {
> +				warned = true;
> +				netdev_warn(dev,
> +					    "host using disabled UFO feature; please fix it\n");
> +			}
>  			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
>  			break;
> +		}
>  		case VIRTIO_NET_HDR_GSO_TCPV6:
>  			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
>  			break;
> @@ -881,8 +890,6 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
>  			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
>  		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
>  			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
> -		else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
> -			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
>  		else
>  			BUG();
>  		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
> @@ -1705,7 +1712,7 @@ static int virtnet_probe(struct virtio_device *vdev)
>  			dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
>  
>  		if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
> -			dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
> +			dev->hw_features |= NETIF_F_TSO
>  				| NETIF_F_TSO_ECN | NETIF_F_TSO6;
>  		}
>  		/* Individual feature bits: what can host handle? */
> @@ -1715,11 +1722,9 @@ static int virtnet_probe(struct virtio_device *vdev)
>  			dev->hw_features |= NETIF_F_TSO6;
>  		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
>  			dev->hw_features |= NETIF_F_TSO_ECN;
> -		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
> -			dev->hw_features |= NETIF_F_UFO;
>  
>  		if (gso)
> -			dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
> +			dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
>  		/* (!csum && gso) case will be fixed by register_netdev() */
>  	}
>  	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
> @@ -1757,8 +1762,7 @@ static int virtnet_probe(struct virtio_device *vdev)
>  	/* If we can receive ANY GSO packets, we must allocate large ones. */
>  	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
>  	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
> -	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
> -	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
> +	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
>  		vi->big_packets = true;
>  
>  	if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
> @@ -1952,9 +1956,9 @@ static struct virtio_device_id id_table[] = {
>  static unsigned int features[] = {
>  	VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
>  	VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
> -	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
> +	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6,
>  	VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
> -	VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
> +	VIRTIO_NET_F_GUEST_ECN,
>  	VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
>  	VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
>  	VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
> 
> 
> -- 
> Ben Hutchings
> The program is absolutely right; therefore, the computer must be wrong.



> _______________________________________________
> Virtualization mailing list
> Virtualization@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* Re: [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio
  2014-11-19  9:14   ` Michael S. Tsirkin
@ 2014-11-21  1:47     ` Jason Wang
  2014-11-21 18:46     ` Ben Hutchings
  1 sibling, 0 replies; 12+ messages in thread
From: Jason Wang @ 2014-11-21  1:47 UTC (permalink / raw)
  To: Michael S. Tsirkin, Ben Hutchings
  Cc: netdev, Hannes Frederic Sowa, virtualization

On 11/19/2014 05:14 PM, Michael S. Tsirkin wrote:
> On Thu, Oct 30, 2014 at 06:27:12PM +0000, Ben Hutchings wrote:
>> > IPv6 does not allow fragmentation by routers, so there is no
>> > fragmentation ID in the fixed header.  UFO for IPv6 requires the ID to
>> > be passed separately, but there is no provision for this in the virtio
>> > net protocol.
>> > 
>> > Until recently our software implementation of UFO/IPv6 generated a new
>> > ID, but this was a bug.  Now we will use ID=0 for any UFO/IPv6 packet
>> > passed through a tap, which is even worse.
>> > 
>> > Unfortunately there is no distinction between UFO/IPv4 and v6
>> > features, so disable UFO on taps and virtio_net completely until we
>> > have a proper solution.
>> > 
>> > We cannot depend on VM managers respecting the tap feature flags, so
>> > keep accepting UFO packets but log a warning the first time we do
>> > this.
>> > 
>> > Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
>> > Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
> There's something I don't understand here. I see:
>
>         NETIF_F_UFO_BIT,                /* ... UDPv4 fragmentation */
>
> this comment is wrong then?

Looks wrong, at least ufo6 depends check this bit in ip6_output.c

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

* Re: [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio
  2014-11-19  9:14   ` Michael S. Tsirkin
  2014-11-21  1:47     ` Jason Wang
@ 2014-11-21 18:46     ` Ben Hutchings
  2014-11-23 10:33       ` Michael S. Tsirkin
  1 sibling, 1 reply; 12+ messages in thread
From: Ben Hutchings @ 2014-11-21 18:46 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: netdev, Hannes Frederic Sowa, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 1911 bytes --]

On Wed, 2014-11-19 at 11:14 +0200, Michael S. Tsirkin wrote:
> On Thu, Oct 30, 2014 at 06:27:12PM +0000, Ben Hutchings wrote:
> > IPv6 does not allow fragmentation by routers, so there is no
> > fragmentation ID in the fixed header.  UFO for IPv6 requires the ID to
> > be passed separately, but there is no provision for this in the virtio
> > net protocol.
> > 
> > Until recently our software implementation of UFO/IPv6 generated a new
> > ID, but this was a bug.  Now we will use ID=0 for any UFO/IPv6 packet
> > passed through a tap, which is even worse.
> > 
> > Unfortunately there is no distinction between UFO/IPv4 and v6
> > features, so disable UFO on taps and virtio_net completely until we
> > have a proper solution.
> > 
> > We cannot depend on VM managers respecting the tap feature flags, so
> > keep accepting UFO packets but log a warning the first time we do
> > this.
> > 
> > Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> > Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
> 
> 
> There's something I don't understand here. I see:
> 
>         NETIF_F_UFO_BIT,                /* ... UDPv4 fragmentation */
> 
> this comment is wrong then?

Yes.

> The patches drastically regress performance for UDPv4 for VMs only, but
> isn't it likely many other devices based their code on this comment?

There's only one hardware driver that implements UFO (s2io), and it does
handle IPv6.

> How about we disable UFO for IPv6 globally, and put the
> flag back in?
> We can then gradually add NETIF_F_UFO6_BIT for devices that
> actually support UFO for IPv6.

Since the corresponding virtio feature bit is understood to include
UFO/IPv6, and existing VMs rely on that, I don't see what this solves.

Ben.

-- 
Ben Hutchings
Beware of bugs in the above code;
I have only proved it correct, not tried it. - Donald Knuth

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* Re: [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio
  2014-11-21 18:46     ` Ben Hutchings
@ 2014-11-23 10:33       ` Michael S. Tsirkin
  0 siblings, 0 replies; 12+ messages in thread
From: Michael S. Tsirkin @ 2014-11-23 10:33 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, Hannes Frederic Sowa, virtualization

On Fri, Nov 21, 2014 at 06:46:52PM +0000, Ben Hutchings wrote:
> On Wed, 2014-11-19 at 11:14 +0200, Michael S. Tsirkin wrote:
> > On Thu, Oct 30, 2014 at 06:27:12PM +0000, Ben Hutchings wrote:
> > > IPv6 does not allow fragmentation by routers, so there is no
> > > fragmentation ID in the fixed header.  UFO for IPv6 requires the ID to
> > > be passed separately, but there is no provision for this in the virtio
> > > net protocol.
> > > 
> > > Until recently our software implementation of UFO/IPv6 generated a new
> > > ID, but this was a bug.  Now we will use ID=0 for any UFO/IPv6 packet
> > > passed through a tap, which is even worse.
> > > 
> > > Unfortunately there is no distinction between UFO/IPv4 and v6
> > > features, so disable UFO on taps and virtio_net completely until we
> > > have a proper solution.
> > > 
> > > We cannot depend on VM managers respecting the tap feature flags, so
> > > keep accepting UFO packets but log a warning the first time we do
> > > this.
> > > 
> > > Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> > > Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
> > 
> > 
> > There's something I don't understand here. I see:
> > 
> >         NETIF_F_UFO_BIT,                /* ... UDPv4 fragmentation */
> > 
> > this comment is wrong then?
> 
> Yes.
> 
> > The patches drastically regress performance for UDPv4 for VMs only, but
> > isn't it likely many other devices based their code on this comment?
> 
> There's only one hardware driver that implements UFO (s2io), and it does
> handle IPv6.
> 
> > How about we disable UFO for IPv6 globally, and put the
> > flag back in?
> > We can then gradually add NETIF_F_UFO6_BIT for devices that
> > actually support UFO for IPv6.
> 
> Since the corresponding virtio feature bit is understood to include
> UFO/IPv6, and existing VMs rely on that, I don't see what this solves.
> 
> Ben.


I'm confused. Patching virtio has 0 effect on existing VMs - they
are running old drivers anyway.

Here's the proposal for guest side:

- Add NETIF_F_UFO6_BIT, set in s2io.
- Teach IPv6 to check NETIF_F_UFO6_BIT and not NETIF_F_UFO_BIT.

What is accomplishes is good speed for virtio with UDP over IPv4,
and correct, slower transmission for IPv6.

Of course this does not help old guests but your patch
to which I'm replying doesn't affect old guests either.

Or did I miss something?

> -- 
> Ben Hutchings
> Beware of bugs in the above code;
> I have only proved it correct, not tried it. - Donald Knuth

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

end of thread, other threads:[~2014-11-23 10:33 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-30 18:26 [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio Ben Hutchings
2014-10-30 18:27 ` [PATCH v2 net 1/2] drivers/net: Disable UFO through virtio Ben Hutchings
2014-10-30 18:47   ` Eric Dumazet
2014-10-30 22:20     ` Ben Hutchings
2014-10-30 23:16       ` Eric Dumazet
2014-11-19  9:14   ` Michael S. Tsirkin
2014-11-21  1:47     ` Jason Wang
2014-11-21 18:46     ` Ben Hutchings
2014-11-23 10:33       ` Michael S. Tsirkin
2014-10-30 18:27 ` [PATCH v2 net 2/2] drivers/net,ipv6: Select IPv6 fragment idents for virtio UFO packets Ben Hutchings
2014-10-30 18:27 ` Ben Hutchings
2014-10-31  0:02 ` [PATCH v2 net 0/2] drivers/net,ipv6: Fix IPv6 fragment ID selection for virtio David Miller

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.