Driver bge - broken jumbo frame support
Hi all, seems the jumbo frame support in bge driver for FreeBSD 4.10 is broken. With MTU set to 9000 bytes, the following happens (ping from other machine towards box with BCM5702): ping -s 8970 ... works fine (this generates packets 8998 bytes long) ping -s 8974 ... works fine (this generates 2 fragments: 8192 + 790 bytes) however ping -s 8972generates packets 9000 bytes long - this freezes the card completely (watchdog timeout restarts it). This means, that the driver is not able to receive full sized jumbo packet (9000 bytes long), only packet 2 bytes shorter (8998 bytes long). The problem is present in the RX path, since the bge driver is able to send out 9000 bytes long packet and receive reply fragments without problem. Here's the dmesg output: bge0: Broadcom BCM5702 Gigabit Ethernet, ASIC rev. 0x1002 mem 0xf980-0xf980 irq 10 at device 9.0 on pci0 bge0: watchdog timeout -- resetting bge0: gigabit link up Thanks in advance for any help. -- Marian Durkovic network manager Slovak Technical University Tel: +421 2 524 51 301 Computer Centre, Nam. Slobody 17 Fax: +421 2 524 94 351 812 43 Bratislava, Slovak RepublicE-mail/sip: [EMAIL PROTECTED] -- ___ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Question on SOCK_RAW, implement a bpf-other host tee
I'm trying to implement a 'tee' which reads from bpf, and sends matching packets to another layer-2 adjacent host. I'm doing this with SOCK_RAW to try and write the packet back out. The 'sendto' passes, but i don't see a packet anywhere. Am i correct that i can hand an arbitrarily crafted IP packet into sendto, and the stack will write the ethernet header on, pick an interface, etc, based on the address in the sendto? I have swapped the ip_len, ip_off fields. The program I have is below. This is on 4.7. The handler gets called, the packet there looks correct, no error on any system call, yet no output :( Suggestions? /* * Copyright 2004 Sandvine Incorporated. All rights reserved */ #include stdio.h #include unistd.h #include sys/types.h #include sys/socket.h #include netinet/in.h #include netinet/in_systm.h #include netinet/ip.h #include pcap.h void usage(const char *name) { fprintf(stderr, Usage: %s [-I input_interface] [-O output_interface] [-i output_ip(arp for mac)] [-v]\n, name); exit(1); } typedef struct { int s; struct in_addr output_ip; } context; static int verbose; static void handler(unsigned char *ct, const struct pcap_pkthdr *hdr, const unsigned char *pkt) { struct ip *ip = (struct ip *)(pkt + 14); context *ctxt = (context *)ct; struct sockaddr_in to; memset(to,0,sizeof(to)); to.sin_family = AF_INET; to.sin_addr = ctxt-output_ip; if (verbose) { fprintf(stderr, Send %d byte packet\n, hdr-len); } ip-ip_len = htons(ip-ip_len); ip-ip_off = htons(ip-ip_off); if (sendto(ctxt-s, ip, hdr-len-14, 0, (struct sockaddr *)to, sizeof(to)) != (hdr-len-14) ) { err(1, sendto); } } static int doit(const char *input_interface, const char *output_interface, struct in_addr output_ip) { char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *in_d, *out_d; context ctxt; int on = 1; struct bpf_program fp; in_d = pcap_open_live((char *)input_interface, 1600, 1, 20, errbuf); if (in_d == 0) { errx(1, open of %s failed: %s, input_interface, errbuf); } ctxt.output_ip.s_addr = htonl(output_ip.s_addr); ctxt.s = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); if (ctxt.s 0) errx(1, can't open raw socket); if (setsockopt(ctxt.s, IPPROTO_IP, IP_HDRINCL, (char *)on, sizeof(on)) 0) { err(1,setsockopt); } memset(fp,0,sizeof(fp)); if (pcap_compile(in_d, fp, ip, 0, 0xfff0) 0) { errx(1, failed to compile: %s,pcap_geterr(in_d)); } if (pcap_setfilter(in_d, fp) 0) { errx(1, failed to set filter); } pcap_loop(in_d, -1, handler, (unsigned char *)ctxt); } int main(int argc, char *argv[]) { int ch; char *input_interface = ipfw0; char *output_interface = em2; struct in_addr output_ip; output_ip.s_addr = 0; while ((ch = getopt(argc, argv, I:O:i:vh?)) != -1) { switch (ch) { case 'I': input_interface = optarg; break; case 'O': output_interface = optarg; break; case 'i': if (inet_aton(optarg,output_ip) 0) { errx(1, unknown ip %s, optarg); } break; case 'v': verbose = 1; break; case 'h': case '?': default: usage(argv[0]); } } if (verbose) fprintf(stderr, %s-%s(%s)\n, input_interface,output_interface,inet_ntoa(output_ip)); return doit(input_interface,output_interface,output_ip); } ___ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
RE: Question on SOCK_RAW, implement a bpf-other host tee
From: Don Bowman [mailto:[EMAIL PROTECTED] I'm trying to implement a 'tee' which reads from bpf, and sends matching packets to another layer-2 adjacent host. Sorry to follow up my own post, but... More specifically, it appears the packet does try and transmit, but the destination MAC is (uninitialised?) somewhat random, different on each packet, not legal. I can capture it on the correct output interface with tcpdump. The interface type is xl. Shouldn't the stack ARP for the destination in my 'sendto', and fill in the ether header? The ether-source is filled in, presumably by the driver. ___ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: Question on SOCK_RAW, implement a bpf-other host tee
Don Bowman wrote: [ ... ] Shouldn't the stack ARP for the destination in my 'sendto', and fill in the ether header? By using SOCK_RAW, you are bypassing the IP layer (or PF_INET, whatever you wish to call it), which I think means that you are also bypassing the ARP lookup code which normally would do so. The ether-source is filled in, presumably by the driver. Yes, and probably recomputing the frame-level checksum, but that's about it. When using raw sockets, one should try to pass in a packet that is completely filled in. I've found using libnet (in ports as net/libnet) is a pretty reasonable way of constructing packets, if need be: you build a packet one ISO layer at a time, and it will fill in the things not being handled when using SOCK_RAW. Oh, if it's easier to swap sender and dest addresses within an existing packet, say for ICMP ECHO_REQUEST :-), by all means do so. Still, libnet and libpcap play nicely together. Is the problem that you don't know or have the MAC addr of the destination handy? -- -Chuck ___ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]