09fe63205c
- Stateful TCP offload drivers for Terminator 3 and 4 (T3 and T4) ASICs. These are available as t3_tom and t4_tom modules that augment cxgb(4) and cxgbe(4) respectively. The cxgb/cxgbe drivers continue to work as usual with or without these extra features. - iWARP driver for Terminator 3 ASIC (kernel verbs). T4 iWARP in the works and will follow soon. Build-tested with make universe. 30s overview ============ What interfaces support TCP offload? Look for TOE4 and/or TOE6 in the capabilities of an interface: # ifconfig -m | grep TOE Enable/disable TCP offload on an interface (just like any other ifnet capability): # ifconfig cxgbe0 toe # ifconfig cxgbe0 -toe Which connections are offloaded? Look for toe4 and/or toe6 in the output of netstat and sockstat: # netstat -np tcp | grep toe # sockstat -46c | grep toe Reviewed by: bz, gnn Sponsored by: Chelsio communications. MFC after: ~3 months (after 9.1, and after ensuring MFC is feasible)
181 lines
4.0 KiB
C
181 lines
4.0 KiB
C
/*
|
|
* This code lifted from:
|
|
* Simple `echo' pseudo-device KLD
|
|
* Murray Stokely
|
|
* Converted to 5.X by Søren (Xride) Straarup
|
|
*/
|
|
|
|
/*
|
|
* /bin/echo "server,port=9999,addr=192.168.69.142,validate" > /dev/krping
|
|
* /bin/echo "client,port=9999,addr=192.168.69.142,validate" > /dev/krping
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/systm.h> /* uprintf */
|
|
#include <sys/errno.h>
|
|
#include <sys/param.h> /* defines used in kernel.h */
|
|
#include <sys/kernel.h> /* types used in module initialization */
|
|
#include <sys/conf.h> /* cdevsw struct */
|
|
#include <sys/uio.h> /* uio struct */
|
|
#include <sys/malloc.h>
|
|
|
|
#include "krping.h"
|
|
|
|
#define BUFFERSIZE 512
|
|
|
|
/* Function prototypes */
|
|
static d_open_t krping_open;
|
|
static d_close_t krping_close;
|
|
static d_read_t krping_read;
|
|
static d_write_t krping_write;
|
|
|
|
/* Character device entry points */
|
|
static struct cdevsw krping_cdevsw = {
|
|
.d_version = D_VERSION,
|
|
.d_open = krping_open,
|
|
.d_close = krping_close,
|
|
.d_read = krping_read,
|
|
.d_write = krping_write,
|
|
.d_name = "krping",
|
|
};
|
|
|
|
typedef struct s_krping {
|
|
char msg[BUFFERSIZE];
|
|
int len;
|
|
} krping_t;
|
|
|
|
/* vars */
|
|
static struct cdev *krping_dev;
|
|
|
|
#undef MODULE_VERSION
|
|
#include <sys/module.h>
|
|
|
|
static int
|
|
krping_loader(struct module *m, int what, void *arg)
|
|
{
|
|
int err = 0;
|
|
|
|
switch (what) {
|
|
case MOD_LOAD: /* kldload */
|
|
krping_init();
|
|
krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,
|
|
0600, "krping");
|
|
printf("Krping device loaded.\n");
|
|
break;
|
|
case MOD_UNLOAD:
|
|
destroy_dev(krping_dev);
|
|
printf("Krping device unloaded.\n");
|
|
break;
|
|
default:
|
|
err = EOPNOTSUPP;
|
|
break;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
static int
|
|
krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
|
|
{
|
|
int err = 0;
|
|
return err;
|
|
}
|
|
|
|
static int
|
|
krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
krping_read(struct cdev *dev, struct uio *uio, int ioflag)
|
|
{
|
|
struct krping_cb *cb, *cb2;
|
|
int num=1;
|
|
struct krping_cb_list copy_cbs;
|
|
|
|
uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
|
|
"num", "device", "snd bytes", "snd msgs", "rcv bytes",
|
|
"rcv msgs", "wr bytes", "wr msgs", "rd bytes", "rd msgs");
|
|
TAILQ_INIT(©_cbs);
|
|
|
|
mtx_lock(&krping_mutex);
|
|
TAILQ_FOREACH(cb, &krping_cbs, list) {
|
|
cb2 = malloc(sizeof(*cb), M_DEVBUF, M_NOWAIT|M_ZERO);
|
|
if (!cb2)
|
|
break;
|
|
bcopy(cb, cb2, sizeof(*cb));
|
|
TAILQ_INSERT_TAIL(©_cbs, cb2, list);
|
|
}
|
|
mtx_unlock(&krping_mutex);
|
|
|
|
while (!TAILQ_EMPTY(©_cbs)) {
|
|
|
|
cb = TAILQ_FIRST(©_cbs);
|
|
TAILQ_REMOVE(©_cbs, cb, list);
|
|
if (cb->pd) {
|
|
uprintf("krping: %4d %10s %10u %10u %10u %10u %10u %10u %10u %10u\n",
|
|
num++, cb->pd->device->name, cb->stats.send_bytes,
|
|
cb->stats.send_msgs, cb->stats.recv_bytes,
|
|
cb->stats.recv_msgs, cb->stats.write_bytes,
|
|
cb->stats.write_msgs,
|
|
cb->stats.read_bytes,
|
|
cb->stats.read_msgs);
|
|
} else {
|
|
uprintf("krping: %d listen\n", num++);
|
|
}
|
|
free(cb, M_DEVBUF);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
krping_write(struct cdev *dev, struct uio *uio, int ioflag)
|
|
{
|
|
int err = 0;
|
|
int amt;
|
|
int remain = BUFFERSIZE;
|
|
char *cp;
|
|
krping_t *krpingmsg;
|
|
|
|
krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO);
|
|
if (!krpingmsg) {
|
|
uprintf("Could not malloc mem!\n");
|
|
return ENOMEM;
|
|
}
|
|
|
|
cp = krpingmsg->msg;
|
|
while (uio->uio_resid) {
|
|
amt = MIN(uio->uio_resid, remain);
|
|
if (amt == 0)
|
|
break;
|
|
|
|
/* Copy the string in from user memory to kernel memory */
|
|
err = uiomove(cp, amt, uio);
|
|
if (err) {
|
|
uprintf("Write failed: bad address!\n");
|
|
return err;
|
|
}
|
|
cp += amt;
|
|
remain -= amt;
|
|
}
|
|
|
|
if (uio->uio_resid != 0) {
|
|
uprintf("Message too big. max size is %d!\n", BUFFERSIZE);
|
|
return EMSGSIZE;
|
|
}
|
|
|
|
/* null terminate and remove the \n */
|
|
cp--;
|
|
*cp = 0;
|
|
krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);
|
|
uprintf("krping: write string = |%s|\n", krpingmsg->msg);
|
|
err = krping_doit(krpingmsg->msg);
|
|
free(krpingmsg, M_DEVBUF);
|
|
return(err);
|
|
}
|
|
|
|
DEV_MODULE(krping,krping_loader,NULL);
|