[PATCH] Re: tap interface and locally generated packets
Maksim Yevmenkin
maksim.yevmenkin at savvis.net
Mon May 9 12:29:01 PDT 2005
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 at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe at freebsd.org"
-------------- next part --------------
--- 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);
More information about the freebsd-net
mailing list