Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 09 May 2005 12:28:45 -0700
From:      Maksim Yevmenkin <maksim.yevmenkin@savvis.net>
To:        freebsd-net@freebsd.org
Cc:        patrickdk@patrickdk.com
Subject:   [PATCH] Re: tap interface and locally generated packets
Message-ID:  <427FB9ED.6010607@savvis.net>
In-Reply-To: <427FA14C.30805@savvis.net>
References:  <Pine.LNX.4.62.0505081401540.31842@server.dswett.patrickdk.com> <427E3336.3040907@savvis.net> <Pine.LNX.4.62.0505090230001.19060@server.dswett.patrickdk.com> <427FA14C.30805@savvis.net>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------030803080502010401040102
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Dear Hackers,

could someone please take/try a look at the attached patch? since i do 
not have a card that is capable of hardware checksumming i can not test 
it here.

thanks,
max

Maksim Yevmenkin wrote:
> Patrick,
> 
>> Yes, ifconfig -txcsum fixes the problem, so somewhere packets are not
>>  getting marked to be summed if the hardware checksum is turned on,
>> and packets don't go to the hardware card, but head to the tap
>> interface instead.
> 
> 
> i do not know how your network is setup exactly, but i would guess that 
> your ethernet bridge contains both tap and physical ethernet card that 
> is capable of hardware ip checksumming.
> 
> if the above guess is correct then what probably happens is:
> 
> 1) packet goes out
> 
> 2) because physical ethernet card can do ip checksumming, ip checksum is 
> not calculated
> 
> 3) the packet hits the bridge
> 
> 4) tap gets a copy of the packet without ip checksum
> 
> 5) openvpn/whatever reads the packet and sends it over the network
> 
> 6) remote peer gets the packet without ip checksum and drops it
> 
>> This will work for a for alittle while, but as these are high usage,
>>  gigabit links, and tend to have alot of traffic on them, where as
>> the tap interface is low load. It could cause a descent amount of cpu
>> load. Thanks.
> 
> 
> again, the problem is not in the tap(4) (imo). because physical ethernet 
> card is capable of hardware ip checksumming, ip checksum is not 
> generated until the packet is about to be transmitted over the wire. 
> ethernet bridge(4) just picks the packet earlier.
> 
> it is possible (imo) to ensure that packets that go out on the tap 
> interface have proper ip checksum. we could modify tapread() function 
> and check if mbuf packet header has checksum flags. i will look into 
> this and will send you a patch in a few days.
> 
> in the mean time all ethernet interfaces in the bridge should have the 
> same set of features.
> 
> thanks,
> max
> 
>>
>> On Sun, 8 May 2005, Maksim Yevmenkin wrote:
>>
>>> Patrick,
>>>
>>>> I have been working with tap interfaces, bridging and openvpn
>>>>
>>>> Bridging works perfectly, and openvpn does too
>>>>
>>>> Packet pings from the tap interface works to any ip address, on
>>>> the local machine or computer on the bridged network
>>>>
>>>> Attempting to make a tcp connection works for bridged network,
>>>> but not the machine the tap interface is on
>>>>
>>>> I have found this is due to tcp checksums not being generated, 
>>>> Packets recieved over the tap interface on the client machine
>>>> have blank (bad) checksums.
>>>>
>>>> I have looked at the source and it seems there is no interface to
>>>> add the checksums to be generated for the tap interface.
>>>
>>>
>>>
>>> tap(4) interface should not modify anything inside the packet. the
>>>  whole point is to accept _complete_ ethernet frame from user-space
>>>  (just as it comes from the wire) and pass it up the stack.
>>>
>>> my guess would be that something else is not generating proper ip 
>>> checksum. just a crazy thought: are you offloading ip checksum'ing
>>> to your ethernet card? if so, please try to disable it and see if
>>> it helps.
>>>
>>> thanks, max
>>>
>>>
> 
> _______________________________________________
> freebsd-net@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"


--------------030803080502010401040102
Content-Type: text/plain;
 name="if_tap.c.ip_checksum.diff.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="if_tap.c.ip_checksum.diff.txt"

--- if_tap.c.orig	Fri Apr 29 15:22:56 2005
+++ if_tap.c	Mon May  9 12:25:07 2005
@@ -64,6 +64,9 @@
 #include <net/route.h>
 
 #include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <machine/in_cksum.h>
 
 #include <net/if_tapvar.h>
 #include <net/if_tap.h>
@@ -772,6 +775,36 @@
 			error = tsleep(tp,PCATCH|(PZERO+1),"taprd",0);
 			if (error)
 				return (error);
+		}
+
+		/* make sure we have packet header */
+		M_ASSERTPKTHDR(m);
+
+		/*
+		 * this is a hack. apparently tap interface could get a packet
+		 * without ip checksum. my current theory is that this happens
+		 * when tap is used in ethernet bridge with physical ethernet
+		 * card capable of hardware ip checksumming. so, check the
+		 * csum_flags in the packet header to see if we should generate
+		 * ip checksum.
+		 */
+
+		if (m->m_pkthdr.csum_flags & CSUM_IP) {
+			struct ip	*ip;
+			int		 len;
+
+			len = min(m->m_pkthdr.len, ETHER_HDR_LEN + 60);
+
+			if (m->m_len < len) {
+				m = m_pullup(m, len);
+				if (m == NULL)
+					continue;
+			}
+
+			m->m_data += ETHER_HDR_LEN;
+			ip = mtod(m, struct ip *);
+			ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
+			m->m_data -= ETHER_HDR_LEN;
 		}
 	} while (m == NULL);
 

--------------030803080502010401040102--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?427FB9ED.6010607>