-----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]