-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

River Tarnell:
> This frame format is passed unmodified to ip_mdata_to_mhi (I have 
> confirmed this using DTrace).  It therefore looks at the PPP header for 
> the ethertype, doesn't find one, and starts scanning backwards over junk 
> data (the PPPoE header) until it finds a match -- i.e., two bytes which 
> are either ETHERTYPE_IP or ETHERTYPE_IPV6.  In most cases, it never 
> will, so it returns (line 7837) without marking the packet as multicast.  
 
> However, sometimes (effectively randomly), it will find what it thinks 
> is an ethernet header, and then try to interpret the garbage data as the 
> ethernet dst address.  If the garbage happens to have the right bit set, 
> it will mark the packet as multicast, and it will be dropped in 
> ire_recv_forward_v4.

To confirm this I used the DTrace script below, which mimics the 
backward search ip_mdata_to_mhi does.  It produced the following output:

  1  -> ip_mdata_to_mhi                       area to search = 46 bytes
- -04: ethertype=aefd src = 71:1b:88:64:11:00 dst = ee:fb:00:23:eb:6c
- -08: ethertype=8864 src = 00:23:eb:6c:71:1b dst = d4:85:64:c9:ee:fb
- -12: ethertype=eb6c src = 64:c9:ee:fb:00:23 dst = d4:85:64:c9:d4:85
- -16: ethertype=eefb src = 64:c9:d4:85:64:c9 dst = 08:00:45:00:d4:85
- -20: ethertype=d485 src = 45:00:d4:85:64:c9 dst = 81:00:00:04:08:00 Multicast!
- -24: ethertype=d485 src = 00:04:08:00:45:00 dst = 64:c9:ee:fb:81:00
- -28: ethertype=800 src = ee:fb:81:00:00:04 dst = 2d:1a:d4:85:64:c9 IP!  
Multicast!
- -32: ethertype=8100 src = d4:85:64:c9:ee:fb dst = 00:08:5d:13:2d:1a
- -36: ethertype=64c9 src = 5d:13:2d:1a:d4:85 dst = 65:20:63:61:00:08 Multicast!
- -40: ethertype=2d1a src = 63:61:00:08:5d:13 dst = 6e:20:74:68:65:20
- -44: ethertype=8 src = 74:68:65:20:63:61 dst = 65:64:20:6f:6e:20 Multicast!
- -48: ethertype=6520 src = 20:6f:6e:20:74:68 dst = 00:00:72:69:65:64

So, at -28 bytes, it finds data which appears to be a multicast Ethernet 
frame, and happens to have the right ethertype as well.  This output 
only occurs while the dropped packet problem is happening.

This is the D script used:

#!/usr/sbin/dtrace -FCs

#define IRAF_L2DST_MULTICAST    0x01000000      /* Multicast at L2 */
#define IRAF_L2DST_BROADCAST    0x02000000      /* Broadcast at L2 */

#include <sys/mac.h>
#include <sys/ethernet.h>

ip_mdata_to_mhi:entry
{
        self->mp = (mblk_t *) arg1;
        self->pether = (struct ether_header *) (((char *)self->mp->b_rptr) - 
sizeof(struct ether_header));
        self->src = self->pether->ether_shost;
        self->dst = self->pether->ether_dhost;
        self->etype = self->pether->ether_type;
        self->ill = (ill_t *) arg0;
        printf("area to search = %d bytes\n", (char *) self->pether - (char 
*)self->mp->b_datap->db_base);
        self->origheader = self->pether;

#define DO()                                                                    
                                        \
                self->pether = (struct ether_header *) ((char *)self->pether - 
4);                                      \
                printf("-%02d: ethertype=%x src = %02x:%02x:%02x:%02x:%02x:%02x 
dst = %02x:%02x:%02x:%02x:%02x:%02x%s%s\n",     \
                (int) ((char *)self->origheader - (char *)self->pether), 
htons(self->pether->ether_type),               \
                ((char *) self->pether)[6], ((char *) self->pether)[7], ((char 
*) self->pether)[8],                     \
                ((char *) self->pether)[9], ((char *) self->pether)[10], ((char 
*) self->pether)[11],                   \
                ((char *) self->pether)[0], ((char *) self->pether)[1], ((char 
*) self->pether)[2],                     \
                ((char *) self->pether)[3], ((char *) self->pether)[4], ((char 
*) self->pether)[5],                     \
                htons(self->pether->ether_type) == ETHERTYPE_IP                 
                                        \
                        ? " IP!"                                                
                                        \
                        : htons(self->pether->ether_type) == ETHERTYPE_IPV6     
                                        \
                                ? " IPv6!"                                      
                                        \
                                : "",                                           
                                        \
                (((char *) self->pether)[0] & 0x1) ? " Multicast!" : "")
                
        DO();
        DO();
        DO();
        DO();
        DO();
        DO();
        DO();
        DO();
        DO();
        DO();
        DO();
        DO();
}

        - river.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (SunOS)

iEYEARECAAYFAk2Cht0ACgkQIXd7fCuc5vLdPACePG+WZboH+heoVd9JSiTi9vU/
7LAAoKG4jJ81B2s+SW93RA0RCeg62ajc
=Zk0Z
-----END PGP SIGNATURE-----
_______________________________________________
networking-discuss mailing list
[email protected]

Reply via email to