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 "[EMAIL PROTECTED]"

--- 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);
 
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to