diff --git a/share/man/man4/ng_device.4 b/share/man/man4/ng_device.4 --- a/share/man/man4/ng_device.4 +++ b/share/man/man4/ng_device.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 19, 2004 +.Dd November 8, 2021 .Dt NG_DEVICE 4 .Os .Sh NAME @@ -48,7 +48,7 @@ .Pp The first node is created as .Pa /dev/ngd0 , -all subsequent nodes +subsequent nodes are .Pa /dev/ngd1 , /dev/ngd2 , etc. .Sh HOOKS @@ -64,10 +64,18 @@ .Sh CONTROL MESSAGES The .Nm device -node supports one non-generic control message: +node supports the generic control messages, plus the following: .Bl -tag -width 3n .It Dv NGM_DEVICE_GET_DEVNAME -Returns device name corresponding to a node. +Returns the device name corresponding to the node. +.It Dv NGM_DEVICE_ETHERALIGN +Apply the system ETHER_ALIGN offset to mbufs sent out the node's hook, +if running on an architecture that requires strict alignment. +Use this option when the data being injected via the device node ultimately +ends up being fed into the protocol stack as ethernet packets (e.g., via +an +.Xr ng_eiface 4 +node). .El .\" Additionally, the node accepts .\" .Xr ioctl 2 Ns s diff --git a/sys/netgraph/ng_device.h b/sys/netgraph/ng_device.h --- a/sys/netgraph/ng_device.h +++ b/sys/netgraph/ng_device.h @@ -39,6 +39,7 @@ /* Netgraph control messages */ enum { NGM_DEVICE_GET_DEVNAME, + NGM_DEVICE_ETHERALIGN, }; #if 0 diff --git a/sys/netgraph/ng_device.c b/sys/netgraph/ng_device.c --- a/sys/netgraph/ng_device.c +++ b/sys/netgraph/ng_device.c @@ -50,10 +50,12 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -63,6 +65,7 @@ #include #include #include +#include #define ERROUT(x) do { error = (x); goto done; } while (0) @@ -75,6 +78,25 @@ static ng_rcvdata_t ng_device_rcvdata; static ng_disconnect_t ng_device_disconnect; +/* List of commands and how to convert arguments to/from ASCII. */ +static const struct ng_cmdlist ng_device_cmds[] = { + { + NGM_DEVICE_COOKIE, + NGM_DEVICE_GET_DEVNAME, + "getdevname", + NULL, + &ng_parse_string_type + }, + { + NGM_DEVICE_COOKIE, + NGM_DEVICE_ETHERALIGN, + "etheralign", + NULL, + NULL + }, + { 0 } +}; + /* Netgraph type */ static struct ng_type ngd_typestruct = { .version = NG_ABI_VERSION, @@ -86,6 +108,7 @@ .newhook = ng_device_newhook, .rcvdata = ng_device_rcvdata, .disconnect = ng_device_disconnect, + .cmdlist = ng_device_cmds, }; NETGRAPH_INIT(device, &ngd_typestruct); @@ -97,6 +120,7 @@ struct cdev *ngddev; struct mtx ngd_mtx; int unit; + int ether_align; uint16_t flags; #define NGDF_OPEN 0x0001 #define NGDF_RWAIT 0x0002 @@ -194,6 +218,11 @@ /* XXX: race here? */ priv->ngddev->si_drv1 = priv; + /* Give this node the same name as the device (if possible). */ + if (ng_name_node(node, devtoname(priv->ngddev)) != 0) + log(LOG_WARNING, "%s: can't acquire netgraph name\n", + devtoname(priv->ngddev)); + return(0); } @@ -226,6 +255,13 @@ strlcpy((char *)resp->data, dn, strlen(dn) + 1); break; + case NGM_DEVICE_ETHERALIGN: + /* Use ETHER_ALIGN on arches that require it. */ +#ifndef __NO_STRICT_ALIGNMENT + priv->ether_align = ETHER_ALIGN; +#endif + break; + default: error = EINVAL; break; @@ -468,7 +504,8 @@ if (uio->uio_resid < 0 || uio->uio_resid > IP_MAXPACKET) return (EIO); - if ((m = m_uiotombuf(uio, M_NOWAIT, 0, 0, M_PKTHDR)) == NULL) + m = m_uiotombuf(uio, M_NOWAIT, 0, priv->ether_align, M_PKTHDR); + if (m == NULL) return (ENOBUFS); NET_EPOCH_ENTER(et);