Date: Thu, 23 Sep 2004 15:52:34 -0700 From: John-Mark Gurney <gurney_j@resnet.uoregon.edu> To: Sean McNeil <sean@mcneil.com> Cc: freebsd-current@freebsd.org Subject: Re: re0 device txcsum issue Message-ID: <20040923225234.GL72089@funkthat.com> In-Reply-To: <1095978035.59583.4.camel@server.mcneil.com> References: <1095978035.59583.4.camel@server.mcneil.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--vmttodhTwj0NAgWp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Sean McNeil wrote this message on Thu, Sep 23, 2004 at 15:20 -0700: > Is anyone willing to work with me to help trace down this problem? It > has been outstanding for a long time and I would dearly like it fixed. > I'm willing to help in any capacity to trace down the culprit. > > To recap, on the re0 device (possibly others) running -current on an > amd64 processor there are times when udp packets get improper checksum > calculations with txcsum set for the interface. This causes a deadlock > in nfs as the client just contunuously requests this packet and it is > rejected because of the checksum being bad. I have recently been working with the re driver, so I'm somewhat familar with the driver. I haven't seen any issues, but I also don't have an AMD64 system to test with. Have you tried to find out if it is packet size related? are you trying to use jumbo frames? rwatson committed netsend to the src/tools tree that could help this, and I have attached udpcheck.py which is a client/server script to test/verify packet sizes of difference sizes. -- John-Mark Gurney Voice: +1 415 225 5579 "All that I will do, has been done, All that I have, has not." --vmttodhTwj0NAgWp Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="udpcheck.py" #!/usr/bin/env python import getopt import time import socket import struct import sys def debug(cmd): if verbose: sys.stdout.write(cmd + '\n') sys.stdout.flush() def genmaxpacket(): pkt = [] for i in range(256): pkt.append(chr(i)) for i in range(8192): pkt.append(chr(i / 256) + chr(i % 256)) return ''.join(pkt) def usage(): print 'Usage: udpcheck.py [ -v ] -s <port>' print ' udpcheck.py [ -v ] <host> <port> [ -s <lenstart> ] [ -e <lenend> ]' sys.exit(2) def main(): try: opts, args = getopt.getopt(sys.argv[1:], "sv") except getopt.GetoptError: usage() global verbose verbose = False server = False for o, a in opts: if o == '-v': verbose = True elif o == '-s': server = True if (server and len(args) != 1) or (not server and len(args) < 2): usage() if server: doserver(args[0]) else: doclient(args[0], args[1], args[2:]) def doserver(port): '''I guess I had better start documenting the protocol. Single caracter is the command: e: exit server q: quit connection s: send client a udp packet of !H length from maxpacket r: receive udp packet from client of length, response will be !H length of received packet followed by length.''' maxpacket = genmaxpacket() # Start up sockets for server udpout = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) cn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) cn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) cn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) try: port = int(port) except ValueError: port = socket.getservbyname(port, 'tcp') cn.bind(('', port)) udpout.bind(('', port)) cn.listen(-1) # Start processing commands from a client exit = False while not exit: cli, remote = cn.accept() debug("connection from: " + str(remote)) #Handle client cmd = cli.recv(1) while cmd: debug("command: " + cmd) if cmd == 'e': exit = True break elif cmd == 'q': break elif cmd == 's': rlen = struct.unpack("!H", cli.recv(2))[0] debug("len: %d" % rlen) udpout.sendto(maxpacket[:rlen], remote) elif cmd == 'r': rlen = struct.unpack("!H", cli.recv(2))[0] debug("len: %d" % rlen) rdata = udpout.recv(rlen) cli.send(struct.pack("!H", len(rdata))) cli.send(rdata) cmd = cli.recv(1) del cli def doclient(host, port, args): error = False errors = [] maxpacket = genmaxpacket() lenstart = 1 lenend = 2048 dosend = True dorecv = True try: opts, args = getopt.getopt(args, "s:e:") except getopt.GetoptError: usage() for o, a in opts: if o == '-s': lenstart = int(a) elif o == '-e': lenend = int(a) if lenstart <= 0 or lenend <= 0: usage() # Establish connection to server inf = socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM)[0] serv = socket.socket(inf[0], inf[1]) serv.connect(inf[4]) serv.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) udprecv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udprecv.bind(serv.getsockname()) # Start work # Receive/Send is viewed from server, so local client is doing opposite for i in range(lenstart, lenend): if dosend: debug("sending len: %d" % i) serv.send('s' + struct.pack("!H", i)) data = udprecv.recv(i * 2) debug("recv len: %d" % len(data)) if data != maxpacket[:i]: print 'packet recv mismatch at:', i errors.append(('s', i)) error = True if dorecv: debug("recving len: %d" % i) serv.send('r' + struct.pack("!H", i * 2)) udprecv.sendto(maxpacket[:i], inf[4]) rlen = struct.unpack("!H", serv.recv(2))[0] debug('rlen: %d' % rlen) rdata = serv.recv(rlen) if rdata != maxpacket[:rlen] or rlen != i: print 'packet send mismatch at:', i errors.append(('r', i)) error = True serv.send('q') if error: print errors sys.exit(1) if __name__ == '__main__': main() --vmttodhTwj0NAgWp--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040923225234.GL72089>