The issue is that your network card uses a type of checksum offloading that
is not supported by earlier versions of OVS.  I recently added support to
the 'next' branch in our git repository, which hasn't been released yet but
you can try if you are feeling adventurous.

Alternately, I attached a version of the patch that should apply to 0.99.1.
 Let me know how it goes.

Jesse

On Fri, Jan 29, 2010 at 9:55 AM, Paolo Cravero <[email protected]> wrote:

> Good morning/evening,
> I tried both with 0.90.x and 0.99.1: as soon as I attach the network cable
> to a physical interface managed by openvswitch module, the system goes into
> kernel panic.
>
> Configuration in /etc/ovs-vswitchd.conf is:
>
> bridge.bridge0.port=peth0
> bridge.bridge0.port=eth1
> bridge.bridge0.port=oveth0
> bridge.bridge0.port=oveth1
> iface.oveth0.internal=true
> iface.oveth1.internal=true
>
> OS is CentOS 5.3 (yum updated today):
> Linux 2.6.18-164.11.1.el5xen #1 SMP Wed Jan 20 08:06:04 EST 2010 x86_64
> x86_64 x86_64 GNU/Linux
>
> Note: kernel panics occur with the non-xen kernel too.
>
> Physical interface peth0 is a Marvell Technology Group Ltd. 88E8053 PCI-E
> Gigabit Ethernet Controller (rev 20)
>
> I remove the bridge module. Load OVS:
>
> /sbin/insmod /root/setup/a/datapath/linux-2.6/openvswitch_mod.ko
> ovs-vswitchd /etc/ovs-vswitchd.conf
>
> As long as the cable is unplugged I can do all sort of configurations as of
> documentation. When I attach the network cable ... bump!
>
> Upstream switch is a Cisco device with parameters I cannot control.
>
> Am I doing something wrong? (quite possible since I'm new to linux kernel
> switches) Is it a hardware problem? Else?
>
> Thank you in advance for any support you'll be able to give.
> Paolo Cravero
>
>
>
> _______________________________________________
> discuss mailing list
> [email protected]
> http://openvswitch.org/mailman/listinfo/discuss_openvswitch.org
>
diff --git a/datapath/actions.c b/datapath/actions.c
index 8b32de4..95f4eea 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -302,6 +302,7 @@ int dp_xmit_skb(struct sk_buff *skb)
 		return -E2BIG;
 	}
 
+	forward_ip_summed(skb);
 	dev_queue_xmit(skb);
 
 	return len;
diff --git a/datapath/datapath.c b/datapath/datapath.c
index ba363fb..9b0136f 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -624,6 +624,62 @@ out:
 }
 #endif /* CONFIG_XEN && HAVE_PROTO_DATA_VALID */
 
+ /* Types of checksums that we can receive (these all refer to L4 checksums):
+ * 1. CHECKSUM_NONE: Device that did not compute checksum, contains full
+ *	(though not verified) checksum in packet but not in skb->csum.  Packets
+ *	from the bridge local port will also have this type.
+ * 2. CHECKSUM_COMPLETE (CHECKSUM_HW): Good device that computes checksums,
+ *	also the GRE module.  This is the same as CHECKSUM_NONE, except it has
+ *	a valid skb->csum.  Importantly, both contain a full checksum (not
+ *	verified) in the packet itself.  The only difference is that if the
+ *	packet gets to L4 processing on this machine (not in DomU) we won't
+ *	have to recompute the checksum to verify.  Most hardware devices do not
+ *	produce packets with this type, even if they support receive checksum
+ *	offloading (they produce type #5).
+ * 3. CHECKSUM_PARTIAL (CHECKSUM_HW): Packet without full checksum and needs to
+ *	be computed if it is sent off box.  Unfortunately on earlier kernels,
+ *	this case is impossible to distinguish from #2, despite having opposite
+ *	meanings.  Xen adds an extra field on earlier kernels (see #4) in order
+ *	to distinguish the different states.  The only real user of this type
+ *	with bridging is Xen (on later kernels).
+ * 4. CHECKSUM_UNNECESSARY (with proto_csum_blank true): This packet was
+ *	generated locally by a Xen DomU and has a partial checksum.  If it is
+ *	handled on this machine (Dom0 or DomU), then the checksum will not be
+ *	computed.  If it goes off box, the checksum in the packet needs to
+ *	completed.  Calling skb_checksum_setup converts this to CHECKSUM_HW
+ *	(CHECKSUM_PARTIAL) so that the checksum can be completed.  In later
+ *	kernels, this combination is replaced with CHECKSUM_PARTIAL.
+ * 5. CHECKSUM_UNNECESSARY (with proto_csum_blank false): Packet with a correct
+ *	full checksum or using a protocol without a checksum.  skb->csum is
+ *	undefined.  This is common from devices with receive checksum
+ *	offloading.  This is somewhat similar to CHECKSUM_NONE, except that
+ *	nobody will try to verify the checksum with CHECKSUM_UNNECESSARY.
+ *
+ * Note that on earlier kernels, CHECKSUM_COMPLETE and CHECKSUM_PARTIAL are
+ * both defined as CHECKSUM_HW.  Normally the meaning of CHECKSUM_HW is clear
+ * based on whether it is on the transmit or receive path.  After the datapath
+ * it will be intepreted as CHECKSUM_PARTIAL.  If the packet already has a
+ * checksum, we will panic.  Since we can receive packets with checksums, we
+ * assume that all CHECKSUM_HW packets have checksums and map them to
+ * CHECKSUM_NONE, which has a similar meaning (the it is only different if the
+ * packet is processed by the local IP stack, in which case it will need to
+ * be reverified).  If we receive a packet with CHECKSUM_HW that really means
+ * CHECKSUM_PARTIAL, it will be sent with the wrong checksum.  However, there
+ * shouldn't be any devices that do this with bridging.
+ *
+ * The bridge has similar behavior and this function closely resembles
+ * skb_forward_csum().  It is slightly different because we are only concerned
+ * with bridging and not other types of forwarding and can get away with
+ * slightly more optimal behavior.*/
+void
+forward_ip_summed(struct sk_buff *skb)
+{
+#ifdef CHECKSUM_HW
+	if (skb->ip_summed == CHECKSUM_HW)
+		skb->ip_summed = CHECKSUM_NONE;
+#endif
+}
+
 /* Append each packet in 'skb' list to 'queue'.  There will be only one packet
  * unless we broke up a GSO packet. */
 static int
@@ -720,6 +776,8 @@ dp_output_control(struct datapath *dp, struct sk_buff *skb, int queue_no,
 	if (skb_queue_len(queue) >= DP_MAX_QUEUE_LEN)
 		goto err_kfree_skb;
 
+	forward_ip_summed(skb);
+
 	/* Break apart GSO packets into their component pieces.  Otherwise
 	 * userspace may try to stuff a 64kB packet into a 1500-byte MTU. */
 	if (skb_is_gso(skb)) {
diff --git a/datapath/datapath.h b/datapath/datapath.h
index 3b5a67b..d44efd6 100644
--- a/datapath/datapath.h
+++ b/datapath/datapath.h
@@ -217,5 +217,6 @@ static inline int vswitch_skb_checksum_setup(struct sk_buff *skb)
 	return 0;
 }
 #endif
+void forward_ip_summed(struct sk_buff *skb);
 
 #endif /* datapath.h */
_______________________________________________
discuss mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/discuss_openvswitch.org

Reply via email to