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>