Browse Source

Import upstream version 20

Sam Hopkins 9 years ago
parent
commit
cab50189ac
17 changed files with 517 additions and 410 deletions
  1. 3 0
      HACKING
  2. 34 12
      NEWS
  3. 208 28
      aoe.c
  4. 1 1
      ata.c
  5. 132 0
      bpf.c
  6. 0 6
      contrib/README
  7. 0 135
      contrib/o_direct.diff
  8. 0 11
      contrib/vblade-15-socketfilter.2.README
  9. 0 139
      contrib/vblade-15-socketfilter.2.diff
  10. 0 0
      contrib/vblade-17-aio.2.README
  11. 31 29
      contrib/vblade-15-aio.2.diff
  12. 54 2
      dat.h
  13. 7 1
      fns.h
  14. 6 38
      freebsd.c
  15. 20 7
      linux.c
  16. 4 1
      makefile
  17. 17 0
      vblade.8

+ 3 - 0
HACKING

@@ -25,3 +25,6 @@ When you send your patch, here are some things to cover:
 
   * What testing did you perform to ensure that your patch did not
     introduce bugs and accomplished what you intended?
+
+  * If your changes affect the end-user experience, have you updated
+    the vblade documentation?

+ 34 - 12
NEWS

@@ -1,10 +1,32 @@
 -*- change-log -*-
-2008-05-07 Ed L. Cashin <ecashin@coraid.com>
+2009-08-14 Sam Hopkins <sah@coraid.com>
+	bugfix: aoe command error did not set Error bit in flags
+	add support for AoEr11
+	set ident serial to shelf.slot:hostname
+	vblade-20
+
+2008-10-08 Ed Cashin <ecashin@coraid.com>
+	add Chris Webb's bpf fix for FreeBSD
+	add Ryan Thomas's fix to stop bufcnt being overridden
+	vblade-19
+	
+2008-07-14 Ed Cashin <ecashin@coraid.com>
+	add Chris Webb's block device options patch
+	add Chris Webb's socket options patch for better jumbo handling
+	remove obsolete contrib/o_direct.diff
+	vblade-18
+
+2008-06-09 Ed Cashin <ecashin@coraid.com>
+	add Chris Webb's latest BPF patch to vblade, remove from contrib
+	update contributed AIO patch for compatibility with current sources
+	vblade-17
+	
+2008-05-07 Ed Cashin <ecashin@coraid.com>
 	add Chris Webb's AIO patch to the contributions
 	add Chris Webb's BPF patch to the contributions
 	vblade-16
 
-2008-02-20 Ed L. Cashin <ecashin@coraid.com>
+2008-02-20 Ed Cashin <ecashin@coraid.com>
 	require the amount of data we use, not the amount ethernet requires
 	make sure the packet length agrees with the config query length
 	make sure the packet length agrees with the amount to write
@@ -40,7 +62,7 @@
 	add install target for makefile
 	vblade-11
 	
-2005-12-06 Ed L. Cashin <ecashin@coraid.com>
+2005-12-06 Ed Cashin <ecashin@coraid.com>
 	fix u64 configuration on FreeBSD
 	release vblade-10
 	
@@ -48,11 +70,11 @@
 	implemented config string support
 	added handler for ATA Check power mode command
 	
-2005-11-15 Ed L. Cashin <ecashin@coraid.com>
+2005-11-15 Ed Cashin <ecashin@coraid.com>
 	add compatibility with platforms lacking u64 (e.g., Slackware)
 	release vblade-9
 	
-2005-11-10 Ed L. Cashin <ecashin@coraid.com>
+2005-11-10 Ed Cashin <ecashin@coraid.com>
 	call atainit on program startup
 	put VBLADE_VERSION in dat.h and use it in firmware version
 	release vblade-7
@@ -66,27 +88,27 @@
 2005-11-10 "Stacey D. Son" <sson@verio.net>
 	include FreeBSD support
 	
-2005-10-03 Ed L. Cashin <ecashin@coraid.com>
+2005-10-03 Ed Cashin <ecashin@coraid.com>
 	don't invoke vblade with dash from vbladed
 	
-2005-08-31 20:14:12 GMT Ed L. Cashin <ecashin@coraid.com>
+2005-08-31 20:14:12 GMT Ed Cashin <ecashin@coraid.com>
 	ATA identify: don't juggle bytes in shorts on big endian arch
 	add manpage for vblade, vbladed
 	release vblade-6
 	
-2005-03-17 15:24:30 GMT	Ed L. Cashin <ecashin@coraid.com>
+2005-03-17 15:24:30 GMT	Ed Cashin <ecashin@coraid.com>
 	follow up on vblade-2's off-by-one patch, making end of device usable
 	release vblade-5
 	
-2005-03-15 22:03:17 GMT	Ed L. Cashin <ecashin@coraid.com>
+2005-03-15 22:03:17 GMT	Ed Cashin <ecashin@coraid.com>
 	don't rely on kernel headers for defining the aoe type 0x88a2
 	release vblade-4
 	
-2005-03-15 17:27:01 GMT	Ed L. Cashin <ecashin@coraid.com>
+2005-03-15 17:27:01 GMT	Ed Cashin <ecashin@coraid.com>
 	docs: aoe-2.6-7 is the first driver to support multiple blades per mac
 	release vblade-3
 	
-2005-03-11 18:30:26 GMT	Ed L. Cashin <ecashin@coraid.com>
+2005-03-11 18:30:26 GMT	Ed Cashin <ecashin@coraid.com>
 	put 64-bit configuration into config.h file
 	don't use uninitialized variables
 	broadcast config query on startup
@@ -95,7 +117,7 @@
 	add docs, remove daemonizing code from vblade
 	release vblade-2
 	
-2005-02-08 20:21:52 GMT	Ed L. Cashin <ecashin@coraid.com>
+2005-02-08 20:21:52 GMT	Ed Cashin <ecashin@coraid.com>
 	starting documentation
 	add script that daemonizes vblade process, logging output
 	make vblade sources -Wall clean, use daemon(3)

+ 208 - 28
aoe.c

@@ -1,4 +1,5 @@
 // aoe.c: the ATA over Ethernet virtual EtherDrive (R) blade
+#define _GNU_SOURCE
 #include "config.h"
 #include <stdio.h>
 #include <string.h>
@@ -13,18 +14,22 @@
 
 enum {
 	Nmasks= 32,
+	Nsrr= 256,
 	Alen= 6,
 };
 
 uchar masks[Nmasks*Alen];
 int nmasks;
+uchar srr[Nsrr*Alen];
+int nsrr;
 char config[Nconfig];
 int nconfig = 0;
 int maxscnt = 2;
 char *ifname;
+int bufcnt = Bufcount;
 
 void
-aoead(int fd)			// advertise the virtual blade
+aoead(int fd)	// advertise the virtual blade
 {
 	uchar buf[2000];
 	Conf *p;
@@ -39,7 +44,7 @@ aoead(int fd)			// advertise the virtual blade
 	p->h.maj = htons(shelf);
 	p->h.min = slot;
 	p->h.cmd = Config;
-	p->bufcnt = htons(Bufcount);
+	p->bufcnt = htons(bufcnt);
 	p->scnt = maxscnt = (getmtu(sfd, ifname) - sizeof (Ata)) / 512;
 	p->firmware = htons(FWV);
 	p->vercmd = 0x10 | Qread;
@@ -58,7 +63,7 @@ aoead(int fd)			// advertise the virtual blade
 }
 
 int
-isbcast(uchar *ea)		// replace with assembler routine
+isbcast(uchar *ea)
 {
 	uchar *b = (uchar *)"\377\377\377\377\377\377";
 
@@ -88,6 +93,12 @@ aoeata(Ata *p, int pktlen)	// do ATA reqeust
 	r.sectors = p->sectors;
 	r.feature = p->err;
 	r.cmd = p->cmd;
+	if (r.cmd != 0xec)
+	if (!rrok(p->h.src)) {
+		p->h.flags |= Error;
+		p->h.error = Res;
+		return len;
+	}
 	if (atacmd(&r, (uchar *)(p+1), maxscnt*512, pktlen - sizeof(*p)) < 0) {
 		p->h.flags |= Error;
 		p->h.error = BadArg;
@@ -148,39 +159,165 @@ confcmd(Conf *p, int payload)	// process conf request
 	}
 	memmove(p->data, config, nconfig);
 	p->len = htons(nconfig);
-	p->bufcnt = htons(Bufcount);
+	p->bufcnt = htons(bufcnt);
 	p->scnt = maxscnt = (getmtu(sfd, ifname) - sizeof (Ata)) / 512;
 	p->firmware = htons(FWV);
 	p->vercmd = 0x10 | QCMD(p);	// aoe v.1
 	return nconfig + sizeof *p - sizeof p->data;
 }
 
+static int
+aoesrr(Aoesrr *sh, int len)
+{
+	uchar *m, *e;
+	int n;
+
+	e = (uchar *) sh + len;
+	m = (uchar *) sh + Nsrrhdr;
+	switch (sh->rcmd) {
+	default:
+e:		sh->h.error = BadArg;
+		sh->h.flags |= Error;
+		break;
+	case 1:	// set
+		if (!rrok(sh->h.src)) {
+			sh->h.error = Res;
+			sh->h.flags |= Error;
+			break;
+		}
+	case 2:	// force set
+		n = sh->nmacs * 6;
+		if (e < m + n)
+			goto e;
+		nsrr = sh->nmacs;
+		memmove(srr, m, n);
+	case 0:	// read
+		break;
+	}
+	sh->nmacs = nsrr;
+	n = nsrr * 6;
+	memmove(m, srr, n);
+	return Nsrrhdr + n;
+}
+
+static int
+addmask(uchar *ea)
+{
+
+	uchar *p, *e;
+
+	p = masks;
+	e = p + nmasks;
+	for (; p<e; p += 6)
+		if (!memcmp(p, ea, 6))
+			return 2;
+	if (nmasks >= Nmasks)
+		return 0;
+	memmove(p, ea, 6);
+	nmasks++;
+	return 1;
+}
+
+static void
+rmmask(uchar *ea)
+{
+	uchar *p, *e;
+
+	p = masks;
+	e = p + nmasks;
+	for (; p<e; p+=6)
+		if (!memcmp(p, ea, 6)) {
+			memmove(p, p+6, e-p-6);
+			nmasks--;
+			return;
+		}
+}
+
+static int
+aoemask(Aoemask *mh, int len)
+{
+	Mdir *md, *mdi, *mde;
+	uchar *e;
+	int i, n;
+
+	n = 0;
+	e = (uchar *) mh + len;
+	md = mdi = (Mdir *) ((uchar *)mh + Nmaskhdr);
+	switch (mh->cmd) {
+	case Medit:
+		mde = md + mh->nmacs;
+		for (; md<mde; md++) {
+			switch (md->cmd) {
+			case MDdel:
+				rmmask(md->mac);
+				continue;
+			case MDadd:
+				if (addmask(md->mac))
+					continue;
+				mh->merror = MEfull;
+				mh->nmacs = md - mdi;
+				goto e;
+			case MDnop:
+				continue;
+			default:
+				mh->merror = MEbaddir;
+				mh->nmacs = md - mdi;
+				goto e;
+			}
+		}
+		// success.  fall thru to return list
+	case Mread:
+		md = mdi;
+		for (i=0; i<nmasks; i++) {
+			md->res = md->cmd = 0;
+			memmove(md->mac, &masks[i*6], 6);
+			md++;
+		}
+		mh->merror = 0;
+		mh->nmacs = nmasks;
+		n = sizeof *md * nmasks;
+		break;
+	default:
+		mh->h.flags |= Error;
+		mh->h.error = BadArg;
+	}
+e:	return n + Nmaskhdr;
+}
+
 void
 doaoe(Aoehdr *p, int n)
 {
 	int len;
-	enum {	// config query header size
-		CHDR_SIZ = sizeof(Conf) - sizeof(((Conf *)0)->data),
-	};
 
 	switch (p->cmd) {
 	case ATAcmd:
-		if (n < sizeof(Ata))
+		if (n < Natahdr)
 			return;
 		len = aoeata((Ata*)p, n);
 		break;
 	case Config:
-		if (n < CHDR_SIZ)
+		if (n < Ncfghdr)
+			return;
+		len = confcmd((Conf *)p, n);
+		break;
+	case Mask:
+		if (n < Nmaskhdr)
 			return;
-		len = confcmd((Conf *)p, n - CHDR_SIZ);
-		if (len == 0)
+		len = aoemask((Aoemask *)p, n);
+		break;
+	case Resrel:
+		if (n < Nsrrhdr)
 			return;
+		len = aoesrr((Aoesrr *)p, n);
 		break;
 	default:
 		p->error = BadCmd;
-		len = 1024;
+		p->flags |= Error;
+		len = n;
 		break;
 	}
+	if (len <= 0)
+		return;
 	memmove(p->dst, p->src, 6);
 	memmove(p->src, mac, 6);
 	p->maj = htons(shelf);
@@ -198,9 +335,21 @@ aoe(void)
 	Aoehdr *p;
 	uchar *buf;
 	int n, sh;
+	long pagesz;
 	enum { bufsz = 1<<16, };
 
-	buf = malloc(bufsz);
+	if ((pagesz = sysconf(_SC_PAGESIZE)) < 0) {
+		perror("sysconf");
+		exit(1);
+	}        
+	if ((buf = malloc(bufsz + pagesz)) == NULL) {
+		perror("malloc");
+		exit(1);
+	}
+	n = (size_t) buf + sizeof(Ata);
+	if (n & (pagesz - 1))
+		buf += pagesz - (n & (pagesz - 1));
+
 	aoead(sfd);
 
 	for (;;) {
@@ -225,13 +374,12 @@ aoe(void)
 			continue;
 		doaoe(p, n);
 	}
-	free(buf);
 }
 
 void
 usage(void)
 {
-	fprintf(stderr, "usage: %s [ -m mac[,mac...] ] shelf slot netif filename\n", 
+	fprintf(stderr, "usage: %s [-b bufcnt] [-d ] [-s] [-r] [ -m mac[,mac...] ] shelf slot netif filename\n", 
 		progname);
 	exit(1);
 }
@@ -289,16 +437,51 @@ maskok(uchar *ea)
 }
 
 int
+rrok(uchar *ea)
+{
+	int i, ok = 0;
+
+	if (nsrr == 0)
+		return 1;
+	for (i=0; !ok && i<nsrr; i++)
+		ok = memcmp(ea, &srr[i*Alen], Alen) == 0;
+	return ok;
+}
+
+void
+setserial(char *f, int sh, int sl)
+{
+	char h[32];
+
+	h[0] = 0;
+	gethostname(h, sizeof h);
+	snprintf(serial, Nserial, "%d.%d:%.*s", sh, sl, (int) sizeof h, h);
+}
+
+int
 main(int argc, char **argv)
 {
-	int ch, omode = O_RDONLY;
-	struct stat s;
+	int ch, omode = 0, readonly = 0;
 
+	bufcnt = Bufcount;
 	setbuf(stdin, NULL);
-	atainit();
 	progname = *argv;
-	while ((ch = getopt(argc, argv, "m:")) != -1) {
+	while ((ch = getopt(argc, argv, "b:dsrm:")) != -1) {
 		switch (ch) {
+		case 'b':
+			bufcnt = atoi(optarg);
+			break;
+		case 'd':
+#ifdef O_DIRECT
+			omode |= O_DIRECT;
+#endif
+			break;
+		case 's':
+			omode |= O_SYNC;
+			break;
+		case 'r':
+			readonly = 1;
+			break;
 		case 'm':
 			setmask(optarg);
 			break;
@@ -309,14 +492,9 @@ main(int argc, char **argv)
 	}
 	argc -= optind;
 	argv += optind;
-	if (argc != 4)
+	if (argc != 4 || bufcnt <= 0)
 		usage();
-	if (stat(argv[3], &s) < 0) {
-		perror("stat");
-		exit(1);
-	}
-	if (s.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))
-		omode = O_RDWR;
+	omode |= readonly ? O_RDONLY : O_RDWR;
 	bfd = open(argv[3], omode);
 	if (bfd == -1) {
 		perror("open");
@@ -324,15 +502,17 @@ main(int argc, char **argv)
 	}
 	shelf = atoi(argv[0]);
 	slot = atoi(argv[1]);
+	setserial(argv[3], shelf, slot);
 	size = getsize(bfd);
 	size /= 512;
 	ifname = argv[2];
-	sfd = dial(ifname);
+	sfd = dial(ifname, bufcnt);
 	getea(sfd, ifname, mac);
 	printf("pid %ld: e%d.%d, %lld sectors %s\n",
 		(long) getpid(), shelf, slot, size,
-		omode == O_RDWR ? "O_RDWR" : "O_RDONLY");
+		readonly ? "O_RDONLY" : "O_RDWR");
 	fflush(stdout);
+	atainit();
 	aoe();
 	return 0;
 }

+ 1 - 1
ata.c

@@ -88,7 +88,7 @@ atainit(void)
 	setfld(ident, 27, 40, "Coraid EtherDrive vblade");
 	sprintf(buf, "V%d", VBLADE_VERSION);
 	setfld(ident, 23, 8, buf);
-	setfld(ident, 10, 20, "SSN HERE");
+	setfld(ident, 10, 20, serial);
 }
 
 

+ 132 - 0
bpf.c

@@ -0,0 +1,132 @@
+// bpf.c: bpf packet filter for linux/freebsd
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include "dat.h"
+#include "fns.h"
+
+struct bpf_insn {
+	ushort code;
+	uchar jt;
+	uchar jf;
+	u_int32_t k;
+};
+
+struct bpf_program {
+	uint bf_len;
+	struct bpf_insn *bf_insns;
+};
+
+/* instruction classes */
+#define		BPF_CLASS(code) ((code) & 0x07)
+#define		BPF_LD		0x00
+#define		BPF_LDX		0x01
+#define		BPF_ST		0x02
+#define		BPF_STX		0x03
+#define		BPF_ALU		0x04
+#define		BPF_JMP		0x05
+#define		BPF_RET		0x06
+#define		BPF_MISC	0x07
+
+/* ld/ldx fields */
+#define		BPF_SIZE(code)	((code) & 0x18)
+#define		BPF_W		0x00
+#define		BPF_H		0x08
+#define		BPF_B		0x10
+#define		BPF_MODE(code)	((code) & 0xe0)
+#define		BPF_IMM 	0x00
+#define		BPF_ABS		0x20
+#define		BPF_IND		0x40
+#define		BPF_MEM		0x60
+#define		BPF_LEN		0x80
+#define		BPF_MSH		0xa0
+
+/* alu/jmp fields */
+#define		BPF_OP(code)	((code) & 0xf0)
+#define		BPF_ADD		0x00
+#define		BPF_SUB		0x10
+#define		BPF_MUL		0x20
+#define		BPF_DIV		0x30
+#define		BPF_OR		0x40
+#define		BPF_AND		0x50
+#define		BPF_LSH		0x60
+#define		BPF_RSH		0x70
+#define		BPF_NEG		0x80
+#define		BPF_JA		0x00
+#define		BPF_JEQ		0x10
+#define		BPF_JGT		0x20
+#define		BPF_JGE		0x30
+#define		BPF_JSET	0x40
+#define		BPF_SRC(code)	((code) & 0x08)
+#define		BPF_K		0x00
+#define		BPF_X		0x08
+
+/* ret - BPF_K and BPF_X also apply */
+#define		BPF_RVAL(code)	((code) & 0x18)
+#define		BPF_A		0x10
+
+/* misc */
+#define		BPF_MISCOP(code) ((code) & 0xf8)
+#define		BPF_TAX		0x00
+#define		BPF_TXA		0x80
+
+/* macros for insn array initializers */
+#define BPF_STMT(code, k) { (ushort)(code), 0, 0, k }
+#define BPF_JUMP(code, k, jt, jf) { (ushort)(code), jt, jf, k }
+
+void *
+create_bpf_program(int shelf, int slot)
+{
+	struct bpf_program *bpf_program;
+	struct bpf_insn insns[] = {
+		/* Load the type into register */
+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+		/* Does it match AoE Type (0x88a2)? No, goto INVALID */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x88a2, 0, 12),
+		/* Load the flags into register */
+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14),
+		/* Check to see if the Resp flag is set */
+		BPF_STMT(BPF_ALU+BPF_AND+BPF_K, Resp),
+		/* Yes, goto INVALID */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 9),
+		/* Load the shelf number into register */
+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
+		/* Does it match shelf number? No, goto CHECKBROADCAST */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, shelf, 0, 2),
+		/* Load the slot number into register */
+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
+		/* Does it match shelf number? Yes, goto VALID */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, slot, 4, 0),
+		/* CHECKBROADCAST: is (shelf, slot) == (0xffff, 0xff)? */
+		/* Load the shelf number into register */
+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
+		/* Is it 0xffff? No, goto INVALID */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xffff, 0, 3),
+		/* Load the slot number into register */
+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
+		/* Is it 0xff? No, goto INVALID */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xff, 0, 1),
+		/* VALID: return -1 (allow the packet to be read) */
+		BPF_STMT(BPF_RET+BPF_K, -1),
+		/* INVALID: return 0 (ignore the packet) */
+		BPF_STMT(BPF_RET+BPF_K, 0),
+	};
+	if ((bpf_program = malloc(sizeof(struct bpf_program))) == NULL
+	    || (bpf_program->bf_insns = malloc(sizeof(insns))) == NULL) {
+		perror("malloc");
+		exit(1);
+	}
+	bpf_program->bf_len = sizeof(insns)/sizeof(struct bpf_insn);
+	memcpy(bpf_program->bf_insns, insns, sizeof(insns));
+	return (void *)bpf_program;
+}
+
+void
+free_bpf_program(void *bpf_program)
+{
+	free(((struct bpf_program *) bpf_program)->bf_insns);
+	free(bpf_program);
+}

+ 0 - 6
contrib/README

@@ -10,9 +10,3 @@ patching file fns.h
 patching file freebsd.c
 patching file linux.c
 forfeit:~/vblade-12 # 
-
-contrib/o_direct.diff:
-
-Enable O_DIRECT on linux to minimize cache effects of the I/O to
-and from the file backing the vblade.
-

+ 0 - 135
contrib/o_direct.diff

@@ -1,135 +0,0 @@
-diff -uprN vblade-14rc1/aoe.c vblade-14rc2/aoe.c
---- vblade-14rc1/aoe.c	2006-11-20 12:48:05.000000000 -0500
-+++ vblade-14rc2/aoe.c	2006-11-20 13:14:04.000000000 -0500
-@@ -185,15 +185,42 @@ doaoe(Aoehdr *p)
- 	}
- }
- 
-+// allocate the buffer so that the ata data area
-+// is page aligned for o_direct on linux
-+
-+void *
-+bufalloc(uchar **buf, long len)
-+{
-+	long psize;
-+	unsigned long n;
-+
-+	psize = sysconf(_SC_PAGESIZE);
-+	if (psize == -1) {
-+		perror("sysconf");
-+		exit(EXIT_FAILURE);
-+	}
-+	n = len/psize + 3;
-+	*buf = malloc(psize * n);
-+	if (!*buf) {
-+		perror("malloc");
-+		exit(EXIT_FAILURE);
-+	}
-+	n = (unsigned long) *buf;
-+	n += psize * 2;
-+	n &= ~(psize - 1);
-+	return (void *) (n - sizeof (Ata));
-+}
-+
- void
- aoe(void)
- {
- 	Aoehdr *p;
-+	uchar *freeme;
- 	uchar *buf;
- 	int n, sh;
- 	enum { bufsz = 1<<16, };
- 
--	buf = malloc(bufsz);
-+	buf = bufalloc(&freeme, bufsz);
- 	aoead(sfd);
- 
- 	for (;;) {
-@@ -218,7 +245,7 @@ aoe(void)
- 			continue;
- 		doaoe(p);
- 	}
--	free(buf);
-+	free(freeme);
- }
- 
- void
-@@ -310,7 +337,7 @@ main(int argc, char **argv)
- 	}
- 	if (s.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))
- 		omode = O_RDWR;
--	bfd = open(argv[3], omode);
-+	bfd = opendisk(argv[3], omode);
- 	if (bfd == -1) {
- 		perror("open");
- 		exit(1);
-diff -uprN vblade-14rc1/fns.h vblade-14rc2/fns.h
---- vblade-14rc1/fns.h	2006-11-13 16:12:31.000000000 -0500
-+++ vblade-14rc2/fns.h	2006-11-20 13:13:44.000000000 -0500
-@@ -21,6 +21,7 @@ int	atacmd(Ataregs *, uchar *, int);
- 
- int	dial(char *);
- int	getea(int, char *, uchar *);
-+int	opendisk(const char *, int);
- int	putsec(int, uchar *, vlong, int);
- int	getsec(int, uchar *, vlong, int);
- int	putpkt(int, uchar *, int);
-diff -uprN vblade-14rc1/freebsd.c vblade-14rc2/freebsd.c
---- vblade-14rc1/freebsd.c	2006-11-13 13:57:34.000000000 -0500
-+++ vblade-14rc2/freebsd.c	2006-11-20 13:13:44.000000000 -0500
-@@ -241,6 +241,11 @@ getea(int s, char *eth, uchar *ea)
- 	return(0);
- }
- 
-+int
-+opendisk(const char *disk, int omode)
-+{
-+	return open(disk, omode);
-+}
- 
- int
- getsec(int fd, uchar *place, vlong lba, int nsec)
-diff -uprN vblade-14rc1/linux.c vblade-14rc2/linux.c
---- vblade-14rc1/linux.c	2006-11-13 13:57:34.000000000 -0500
-+++ vblade-14rc2/linux.c	2006-11-20 13:13:44.000000000 -0500
-@@ -1,5 +1,6 @@
- // linux.c: low level access routines for Linux
- #include "config.h"
-+#define _GNU_SOURCE
- #include <sys/socket.h>
- #include <stdio.h>
- #include <string.h>
-@@ -22,6 +23,7 @@
- #include <netinet/in.h>
- #include <linux/fs.h>
- #include <sys/stat.h>
-+#include <fcntl.h>
- 
- #include "dat.h"
- #include "fns.h"
-@@ -102,17 +104,21 @@ getmtu(int s, char *name)
- }
- 
- int
-+opendisk(const char *disk, int omode)
-+{
-+	return open(disk, omode|O_DIRECT);
-+}
-+
-+int
- getsec(int fd, uchar *place, vlong lba, int nsec)
- {
--	lseek(fd, lba * 512, 0);
--	return read(fd, place, nsec * 512);
-+	return pread(fd, place, nsec * 512, lba * 512);
- }
- 
- int
- putsec(int fd, uchar *place, vlong lba, int nsec)
- {
--	lseek(fd, lba * 512, 0);
--	return write(fd, place, nsec * 512);
-+	return pwrite(fd, place, nsec * 512, lba * 512);
- }
- 
- int

+ 0 - 11
contrib/vblade-15-socketfilter.2.README

@@ -1,11 +0,0 @@
-This patch uses the Berkeley Packet Filter (BPF) feature so that the
-kernel only hands packets to a vblade process when they match its
-shelf and slot address.
-
-Without this patch, each vblade process would be woken up only to
-discard an AoE packet destined for a different vblade running on the
-same host.
-
-This patch currently introduces a build dependency on the headers from
-libpcap.  Usually a Linux distribution will include these headers in a
-package with a name something like "libpcap-dev".

+ 0 - 139
contrib/vblade-15-socketfilter.2.diff

@@ -1,139 +0,0 @@
-diff -uNpr vblade-15-orig/freebsd.c vblade-15-lsf/freebsd.c
---- vblade-15-orig/freebsd.c	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-lsf/freebsd.c	2008-04-30 10:45:11.000000000 +0100
-@@ -54,40 +54,44 @@ dial(char *eth)
- 
- 	/* packet filter for bpf */
- 	struct bpf_insn bpf_insns[] = {
--	  /* Load the type into register */
--	  BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
--	  /* Does it match AoE Type (0x88a2)? No, goto INVALID */
--	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x88a2, 0, 10),
--	  /* Load the flags into register */
--	  BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14),
--	  /* Check to see if the Resp flag is set */
--	  BPF_STMT(BPF_ALU+BPF_AND+BPF_K, Resp),
--	  /* Yes, goto INVALID */
--	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 7),
--	  /* Load the command into register */
--	  BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 19),
--	  /* Is this a ATAcmd? No, goto VALID */
--	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ATAcmd, 0, 4),
--	  /* Load the shelf number into register */
--	  BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
--	  /* Does it match shelf number? No, goto INVALID */
--	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) shelf, 0, 3),
--	  /* Load the slot number into register */
--	  BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
--	  /* Does it match shelf number? No, goto INVALID */
--	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) slot, 0, 1),
--	  /* VALID: return -1 (allow the packet to be read) */
--	  BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
--	  /* INVALID: return 0 (ignore the packet) */
--	  BPF_STMT(BPF_RET+BPF_K, 0),
-+		/* Load the type into register */
-+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
-+		/* Does it match AoE Type (0x88a2)? No, goto INVALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x88a2, 0, 12),
-+		/* Load the flags into register */
-+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14),
-+		/* Check to see if the Resp flag is set */
-+		BPF_STMT(BPF_ALU+BPF_AND+BPF_K, Resp),
-+		/* Yes, goto INVALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 9),
-+		/* Load the shelf number into register */
-+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
-+		/* Does it match shelf number? No, goto CHECKBROADCAST */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) shelf, 0, 2),
-+		/* Load the slot number into register */
-+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
-+		/* Does it match shelf number? Yes, goto VALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) slot, 4, 0),
-+		/* CHECKBROADCAST: is (shelf, slot) == (0xffff, 0xff)? */
-+		/* Load the shelf number into register */
-+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
-+		/* Is it 0xffff? No, goto INVALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) 0xffff, 0, 3),
-+		/* Load the slot number into register */
-+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
-+		/* Is it 0xff? No, goto INVALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) 0xff, 0, 1),
-+		/* VALID: return -1 (allow the packet to be read) */
-+		BPF_STMT(BPF_RET+BPF_K, (u_int) -1),
-+		/* INVALID: return 0 (ignore the packet) */
-+		BPF_STMT(BPF_RET+BPF_K, 0),
- 	};
- 
- 	struct bpf_program bpf_program = {
--	  sizeof(bpf_insns)/sizeof(struct bpf_insn),
--	  bpf_insns
-+		sizeof(bpf_insns)/sizeof(struct bpf_insn),
-+		bpf_insns
- 	};
--
--
-+	
- 	strncpy(device, BPF_DEV, sizeof BPF_DEV);
- 
- 	/* find a bpf device we can use, check /dev/bpf[0-9] */
-diff -uNpr vblade-15-orig/linux.c vblade-15-lsf/linux.c
---- vblade-15-orig/linux.c	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-lsf/linux.c	2008-04-30 10:46:04.000000000 +0100
-@@ -22,6 +22,7 @@
- #include <netinet/in.h>
- #include <linux/fs.h>
- #include <sys/stat.h>
-+#include <pcap-bpf.h>
- 
- #include "dat.h"
- #include "fns.h"
-@@ -54,6 +55,49 @@ dial(char *eth)		// get us a raw connect
- 		perror("bind funky");
- 		return -1;
- 	}
-+
-+	/* bpf packet filter for socket */
-+	struct bpf_insn bpf_insns[] = {
-+		/* Load the type into register */
-+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
-+		/* Does it match AoE Type (0x88a2)? No, goto INVALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x88a2, 0, 12),
-+		/* Load the flags into register */
-+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14),
-+		/* Check to see if the Resp flag is set */
-+		BPF_STMT(BPF_ALU+BPF_AND+BPF_K, Resp),
-+		/* Yes, goto INVALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 9),
-+		/* Load the shelf number into register */
-+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
-+		/* Does it match shelf number? No, goto CHECKBROADCAST */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) shelf, 0, 2),
-+		/* Load the slot number into register */
-+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
-+		/* Does it match shelf number? Yes, goto VALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) slot, 4, 0),
-+		/* CHECKBROADCAST: is (shelf, slot) == (0xffff, 0xff)? */
-+		/* Load the shelf number into register */
-+		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
-+		/* Is it 0xffff? No, goto INVALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) 0xffff, 0, 3),
-+		/* Load the slot number into register */
-+		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
-+		/* Is it 0xff? No, goto INVALID */
-+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) 0xff, 0, 1),
-+		/* VALID: return -1 (allow the packet to be read) */
-+		BPF_STMT(BPF_RET+BPF_K, (u_int) -1),
-+		/* INVALID: return 0 (ignore the packet) */
-+		BPF_STMT(BPF_RET+BPF_K, 0),
-+	};
-+
-+	struct bpf_program bpf_program = {
-+		sizeof(bpf_insns)/sizeof(struct bpf_insn),
-+		bpf_insns
-+	};
-+
-+	setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf_program, sizeof(bpf_program));
-+
- 	return s;
- }
- 

contrib/vblade-15-aio.2.README → contrib/vblade-17-aio.2.README


+ 31 - 29
contrib/vblade-15-aio.2.diff

@@ -1,6 +1,6 @@
-diff -uprN vblade-15/aoe.c vblade-15-aio/aoe.c
---- vblade-15/aoe.c	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-aio/aoe.c	2008-04-19 22:31:21.000000000 +0100
+diff -uprN vblade-17.orig/aoe.c vblade-17/aoe.c
+--- vblade-17.orig/aoe.c	2008-06-09 10:53:07.000000000 -0400
++++ vblade-17/aoe.c	2008-06-09 11:05:23.000000000 -0400
 @@ -8,6 +8,9 @@
  #include <sys/stat.h>
  #include <fcntl.h>
@@ -284,9 +284,9 @@ diff -uprN vblade-15/aoe.c vblade-15-aio/aoe.c
  	if (bfd == -1) {
  		perror("open");
  		exit(1);
-diff -uprN vblade-15/ata.c vblade-15-aio/ata.c
---- vblade-15/ata.c	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-aio/ata.c	2008-04-19 22:12:32.000000000 +0100
+diff -uprN vblade-17.orig/ata.c vblade-17/ata.c
+--- vblade-17.orig/ata.c	2008-06-09 10:53:07.000000000 -0400
++++ vblade-17/ata.c	2008-06-09 11:05:23.000000000 -0400
 @@ -3,6 +3,8 @@
  #include <string.h>
  #include <stdio.h>
@@ -343,9 +343,9 @@ diff -uprN vblade-15/ata.c vblade-15-aio/ata.c
  	return 0;
  }
 -
-diff -uprN vblade-15/dat.h vblade-15-aio/dat.h
---- vblade-15/dat.h	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-aio/dat.h	2008-04-19 16:34:35.000000000 +0100
+diff -uprN vblade-17.orig/dat.h vblade-17/dat.h
+--- vblade-17.orig/dat.h	2008-06-09 10:53:07.000000000 -0400
++++ vblade-17/dat.h	2008-06-09 11:05:23.000000000 -0400
 @@ -111,6 +111,8 @@ enum {
  	Nconfig = 1024,
  
@@ -355,10 +355,10 @@ diff -uprN vblade-15/dat.h vblade-15-aio/dat.h
  };
  
  int	shelf, slot;
-diff -uprN vblade-15/fns.h vblade-15-aio/fns.h
---- vblade-15/fns.h	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-aio/fns.h	2008-04-17 00:11:36.000000000 +0100
-@@ -15,14 +15,16 @@ int	maskok(uchar *);
+diff -uprN vblade-17.orig/fns.h vblade-17/fns.h
+--- vblade-17.orig/fns.h	2008-06-09 10:53:07.000000000 -0400
++++ vblade-17/fns.h	2008-06-09 11:07:21.000000000 -0400
+@@ -15,7 +15,8 @@ int	maskok(uchar *);
  // ata.c
  
  void	atainit(void);
@@ -366,7 +366,9 @@ diff -uprN vblade-15/fns.h vblade-15-aio/fns.h
 +int	atacmd(Ataregs *, uchar *, int, int, struct aiocb *);
 +int	atacmdcomplete(Ataregs *, struct aiocb *);
  
- // os specific
+ // bpf.c
+ 
+@@ -26,8 +27,9 @@ void	free_bpf_program(void *);
  
  int	dial(char *);
  int	getea(int, char *, uchar *);
@@ -378,10 +380,10 @@ diff -uprN vblade-15/fns.h vblade-15-aio/fns.h
  int	putpkt(int, uchar *, int);
  int	getpkt(int, uchar *, int);
  vlong	getsize(int);
-diff -uprN vblade-15/freebsd.c vblade-15-aio/freebsd.c
---- vblade-15/freebsd.c	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-aio/freebsd.c	2008-04-19 22:24:57.000000000 +0100
-@@ -241,19 +241,40 @@ getea(int s, char *eth, uchar *ea)
+diff -uprN vblade-17.orig/freebsd.c vblade-17/freebsd.c
+--- vblade-17.orig/freebsd.c	2008-06-09 10:53:07.000000000 -0400
++++ vblade-17/freebsd.c	2008-06-09 11:05:23.000000000 -0400
+@@ -209,19 +209,40 @@ getea(int s, char *eth, uchar *ea)
  	return(0);
  }
  
@@ -428,9 +430,9 @@ diff -uprN vblade-15/freebsd.c vblade-15-aio/freebsd.c
  static int pktn = 0;
  static uchar *pktbp = NULL;
  
-diff -uprN vblade-15/linux.c vblade-15-aio/linux.c
---- vblade-15/linux.c	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-aio/linux.c	2008-04-19 22:23:51.000000000 +0100
+diff -uprN vblade-17.orig/linux.c vblade-17/linux.c
+--- vblade-17.orig/linux.c	2008-06-09 10:53:07.000000000 -0400
++++ vblade-17/linux.c	2008-06-09 11:05:23.000000000 -0400
 @@ -1,5 +1,6 @@
  // linux.c: low level access routines for Linux
  #include "config.h"
@@ -457,7 +459,7 @@ diff -uprN vblade-15/linux.c vblade-15-aio/linux.c
  int
  dial(char *eth)		// get us a raw connection to an interface
  {
-@@ -76,7 +78,7 @@ getea(int s, char *name, uchar *ea)
+@@ -84,7 +86,7 @@ getea(int s, char *name, uchar *ea)
  	struct ifreq xx;
  	int n;
  
@@ -466,7 +468,7 @@ diff -uprN vblade-15/linux.c vblade-15-aio/linux.c
  	n = ioctl(s, SIOCGIFHWADDR, &xx);
  	if (n == -1) {
  		perror("Can't get hw addr");
-@@ -102,17 +104,37 @@ getmtu(int s, char *name)
+@@ -110,17 +112,37 @@ getmtu(int s, char *name)
  }
  
  int
@@ -510,9 +512,9 @@ diff -uprN vblade-15/linux.c vblade-15-aio/linux.c
  }
  
  int
-diff -uprN vblade-15/linux.h vblade-15-aio/linux.h
---- vblade-15/linux.h	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-aio/linux.h	2008-04-16 23:03:07.000000000 +0100
+diff -uprN vblade-17.orig/linux.h vblade-17/linux.h
+--- vblade-17.orig/linux.h	2008-06-09 10:53:07.000000000 -0400
++++ vblade-17/linux.h	2008-06-09 11:05:23.000000000 -0400
 @@ -6,6 +6,6 @@ typedef long long vlong;
  int	dial(char *);
  int	getindx(int, char *);
@@ -522,9 +524,9 @@ diff -uprN vblade-15/linux.h vblade-15-aio/linux.h
 +int	getsec(int, uchar *, vlong, int, struct aiocb *);
 +int	putsec(int, uchar *, vlong, int, struct aiocb *);
  vlong	getsize(int);
-diff -uprN vblade-15/makefile vblade-15-aio/makefile
---- vblade-15/makefile	2008-03-07 20:22:16.000000000 +0000
-+++ vblade-15-aio/makefile	2008-04-16 19:09:46.000000000 +0100
+diff -uprN vblade-17.orig/makefile vblade-17/makefile
+--- vblade-17.orig/makefile	2008-06-09 10:53:07.000000000 -0400
++++ vblade-17/makefile	2008-06-09 11:05:23.000000000 -0400
 @@ -13,7 +13,7 @@ CFLAGS += -Wall -g -O2
  CC = gcc
  

+ 54 - 2
dat.h

@@ -6,7 +6,7 @@
  */
 
 enum {
-	VBLADE_VERSION		= 16,
+	VBLADE_VERSION		= 20,
 
 	// Firmware version
 	FWV			= 0x4000 + VBLADE_VERSION,
@@ -33,7 +33,9 @@ typedef struct Aoehdr Aoehdr;
 typedef struct Ata Ata;
 typedef struct Conf Conf;
 typedef struct Ataregs Ataregs;
-
+typedef struct Mdir Mdir;
+typedef struct Aoemask Aoemask;
+typedef struct Aoesrr Aoesrr;
 
 struct Ataregs
 {
@@ -80,12 +82,36 @@ struct Conf
 	uchar	data[1024];
 };
 
+// mask directive
+struct Mdir {
+	uchar res;
+	uchar cmd;
+	uchar mac[6];
+};
+
+struct Aoemask {
+	Aoehdr h;
+	uchar res;
+	uchar cmd;
+	uchar merror;
+	uchar nmacs;
+//	struct Mdir m[0];
+};
+
+struct Aoesrr {
+	Aoehdr h;
+	uchar rcmd;
+	uchar nmacs;
+//	uchar mac[6][nmacs];
+};
 
 enum {
 	AoEver = 1,
 
 	ATAcmd = 0,		// command codes
 	Config,
+	Mask,
+	Resrel,
 
 	Resp = (1<<3),		// flags
 	Error = (1<<2),
@@ -95,6 +121,7 @@ enum {
 	DevUnavailable,
 	ConfigErr,
 	BadVersion,
+	Res,
 
 	Write = (1<<0),
 	Async = (1<<1),
@@ -111,6 +138,29 @@ enum {
 	Nconfig = 1024,
 
 	Bufcount = 16,
+
+	/* mask commands */
+	Mread= 0,	
+	Medit,
+
+	/* mask directives */
+	MDnop= 0,
+	MDadd,
+	MDdel,
+
+	/* mask errors */
+	MEunspec= 1,
+	MEbaddir,
+	MEfull,
+
+	/* header sizes, including aoe hdr */
+	Naoehdr= 24,
+	Natahdr= Naoehdr + 12,
+	Ncfghdr= Naoehdr + 8,
+	Nmaskhdr= Naoehdr + 4,
+	Nsrrhdr= Naoehdr + 2,
+
+	Nserial= 20,
 };
 
 int	shelf, slot;
@@ -120,3 +170,5 @@ int	bfd;		// block file descriptor
 int	sfd;		// socket file descriptor
 vlong	size;		// size of vblade
 char	*progname;
+char	serial[Nserial+1];
+

+ 7 - 1
fns.h

@@ -11,15 +11,21 @@ void	aoeflush(int, int);
 void	aoetick(void);
 void	aoerequest(int, int, vlong, int, uchar *, int);
 int	maskok(uchar *);
+int	rrok(uchar *);
 
 // ata.c
 
 void	atainit(void);
 int	atacmd(Ataregs *, uchar *, int, int);
 
+// bpf.c
+
+void *	create_bpf_program(int, int);
+void	free_bpf_program(void *);
+
 // os specific
 
-int	dial(char *);
+int	dial(char *, int);
 int	getea(int, char *, uchar *);
 int	putsec(int, uchar *, vlong, int);
 int	getsec(int, uchar *, vlong, int);

+ 6 - 38
freebsd.c

@@ -42,7 +42,7 @@ static uchar *pktbuf = NULL;
 static int pktbufsz = 0;
 
 int
-dial(char *eth)
+dial(char *eth, int bufcnt)
 {
 	char m;
 	int fd = -1;
@@ -52,42 +52,8 @@ dial(char *eth)
 	char device[sizeof BPF_DEV];
 	struct ifreq ifr;
 
-	/* packet filter for bpf */
-	struct bpf_insn bpf_insns[] = {
-	  /* Load the type into register */
-	  BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
-	  /* Does it match AoE Type (0x88a2)? No, goto INVALID */
-	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x88a2, 0, 10),
-	  /* Load the flags into register */
-	  BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14),
-	  /* Check to see if the Resp flag is set */
-	  BPF_STMT(BPF_ALU+BPF_AND+BPF_K, Resp),
-	  /* Yes, goto INVALID */
-	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 7),
-	  /* Load the command into register */
-	  BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 19),
-	  /* Is this a ATAcmd? No, goto VALID */
-	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ATAcmd, 0, 4),
-	  /* Load the shelf number into register */
-	  BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
-	  /* Does it match shelf number? No, goto INVALID */
-	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) shelf, 0, 3),
-	  /* Load the slot number into register */
-	  BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
-	  /* Does it match shelf number? No, goto INVALID */
-	  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (u_int) slot, 0, 1),
-	  /* VALID: return -1 (allow the packet to be read) */
-	  BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
-	  /* INVALID: return 0 (ignore the packet) */
-	  BPF_STMT(BPF_RET+BPF_K, 0),
-	};
-
-	struct bpf_program bpf_program = {
-	  sizeof(bpf_insns)/sizeof(struct bpf_insn),
-	  bpf_insns
-	};
-
-
+	struct bpf_program *bpf_program = create_bpf_program(shelf, slot);
+	
 	strncpy(device, BPF_DEV, sizeof BPF_DEV);
 
 	/* find a bpf device we can use, check /dev/bpf[0-9] */
@@ -183,14 +149,16 @@ dial(char *eth)
 	}
 	bufsize = v;
 
-	if (ioctl(fd, BIOCSETF, (caddr_t)&bpf_program) < 0) {
+	if (ioctl(fd, BIOCSETF, (caddr_t)bpf_program) < 0) {
 		perror("BIOSETF");
 		goto bad;
 	} 
 
+	free_bpf_program(bpf_program);
 	return(fd);
 
 bad:
+	free_bpf_program(bpf_program);
 	close(fd);
 	return(-1);
 }

+ 20 - 7
linux.c

@@ -1,4 +1,5 @@
 // linux.c: low level access routines for Linux
+#define _GNU_SOURCE
 #include "config.h"
 #include <sys/socket.h>
 #include <stdio.h>
@@ -16,6 +17,7 @@
 #include <linux/if_ether.h>   /* The L2 protocols */
 #endif
 
+#include <fcntl.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <net/if.h>
@@ -32,10 +34,9 @@ int	getea(int, char *, uchar *);
 
 
 int
-dial(char *eth)		// get us a raw connection to an interface
+dial(char *eth, int bufcnt)		// get us a raw connection to an interface
 {
-	int i;
-	int n, s;
+	int i, n, s;
 	struct sockaddr_ll sa;
 	enum { aoe_type = 0x88a2 };
 
@@ -54,6 +55,20 @@ dial(char *eth)		// get us a raw connection to an interface
 		perror("bind funky");
 		return -1;
 	}
+
+	struct bpf_program {
+		ulong bf_len;
+		void *bf_insns;
+	} *bpf_program = create_bpf_program(shelf, slot);
+	setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, bpf_program, sizeof(*bpf_program));
+	free_bpf_program(bpf_program);
+
+	n = bufcnt * getmtu(s, eth);
+	if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) < 0)
+		perror("setsockopt SOL_SOCKET, SO_SNDBUF");
+	if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) < 0)
+		perror("setsockopt SOL_SOCKET, SO_RCVBUF");
+
 	return s;
 }
 
@@ -104,15 +119,13 @@ getmtu(int s, char *name)
 int
 getsec(int fd, uchar *place, vlong lba, int nsec)
 {
-	lseek(fd, lba * 512, 0);
-	return read(fd, place, nsec * 512);
+	return pread(fd, place, nsec * 512, lba * 512);
 }
 
 int
 putsec(int fd, uchar *place, vlong lba, int nsec)
 {
-	lseek(fd, lba * 512, 0);
-	return write(fd, place, nsec * 512);
+	return pwrite(fd, place, nsec * 512, lba * 512);
 }
 
 int

+ 4 - 1
makefile

@@ -8,7 +8,7 @@ sbindir = ${prefix}/sbin
 sharedir = ${prefix}/share
 mandir = ${sharedir}/man
 
-O=aoe.o ${PLATFORM}.o ata.o
+O=aoe.o bpf.o ${PLATFORM}.o ata.o
 CFLAGS += -Wall -g -O2
 CC = gcc
 
@@ -24,6 +24,9 @@ ${PLATFORM}.o : ${PLATFORM}.c config.h dat.h fns.h makefile
 ata.o : ata.c config.h dat.h fns.h makefile
 	${CC} ${CFLAGS} -c $<
 
+bpf.o : bpf.c
+	${CC} ${CFLAGS} -c $<
+
 config.h : config/config.h.in makefile
 	@if ${CC} ${CFLAGS} config/u64.c > /dev/null 2>&1; then \
 	  sh -xc "cp config/config.h.in config.h"; \

+ 17 - 0
vblade.8

@@ -34,6 +34,23 @@ communications.
 The name of the regular file or block device to export.
 .SS Options
 .TP
+\fB-b\fP
+The -b flag takes an argument, the advertised buffer count, specifying
+the maximum number of outstanding messages the server can queue for
+processing.
+.TP
+\fB-d\fP
+The -d flag selects O_DIRECT mode for accessing the underlying block
+device.
+.TP
+\fB-s\fP
+The -s flag selects O_SYNC mode for accessing the underlying block
+device, so all writes are committed to disk before returning to the
+client.
+.TP
+\fB-r\fP
+The -r flag restricts the export of the device to be read-only.
+.TP
 \fB-m\fP
 The -m flag takes an argument, a comma separated list of MAC addresses
 permitted access to the vblade.  A MAC address can be specified in upper