On Thu, Dec 01, 2011 at 11:51:18PM -0200, Christiano F. Haesbaert wrote:
> I think I've found the problem.
> 
> when a packet comes from ral0 ---> 10.0.0.1, the bridge changes the
> received interface to vr0, which has IFCAP_CSUM_IPv4.
> 
> So when the icmp layer is about to test the checksum, it assumes the
> output interface is the same one which the packet came in (in our
> case, vr0, and not ral0). So the checksum does not get calculated.
> 
> That's why it works when we remove the capabilities from vr0.

Hi again,

Could you try the following diff ?
Please remember to undo the modifications of the previous diff.

The thing is in_proto_cksum_out() correctly escapes hw checksumming if
the interface is a member of a bridge, the same should be done for ip
checksums.

Index: ip_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.224
diff -d -u -p -w -r1.224 ip_output.c
--- ip_output.c 2 Dec 2011 03:15:31 -0000       1.224
+++ ip_output.c 26 Dec 2011 22:22:34 -0000
@@ -746,7 +746,8 @@ sendit:
         */
        if (ntohs(ip->ip_len) <= mtu) {
                ip->ip_sum = 0;
-               if ((ifp->if_capabilities & IFCAP_CSUM_IPv4)) {
+               if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
+                   (ifp->if_bridge == NULL)) {
                        m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
                        ipstat.ips_outhwcsum++;
                } else
@@ -892,7 +893,8 @@ ip_fragment(struct mbuf *m, struct ifnet
                mhip->ip_off = htons((u_int16_t)mhip->ip_off);
                mhip->ip_sum = 0;
                if ((ifp != NULL) &&
-                   (ifp->if_capabilities & IFCAP_CSUM_IPv4)) {
+                   (ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
+                   (ifp->if_bridge == NULL)) {
                        m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
                        ipstat.ips_outhwcsum++;
                } else
@@ -911,7 +913,8 @@ ip_fragment(struct mbuf *m, struct ifnet
        ip->ip_off |= htons(IP_MF);
        ip->ip_sum = 0;
        if ((ifp != NULL) &&
-           (ifp->if_capabilities & IFCAP_CSUM_IPv4)) {
+           (ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
+           (ifp->if_bridge == NULL)) {
                m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
                ipstat.ips_outhwcsum++;
        } else

Reply via email to