Some cleanup and small changes:
- Use malloc() and free() instead of MALLOC() and FREE() macros. - Do not check malloc results if M_WAITOK was used. - Remove linked list of all netgraph sockets. It isn't needed. - Use ng_findhook() instead of searching the list ourselves. - Use NG_WAITOK in syscalls. - Remove unneeded includes. - style(9)
This commit is contained in:
parent
81ba27c8d9
commit
dcaf468dcb
@ -51,8 +51,6 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/lock.h>
|
||||
@ -61,13 +59,10 @@
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#ifdef NOTYET
|
||||
#include <sys/vnode.h>
|
||||
#endif
|
||||
@ -125,8 +120,9 @@ static int ng_attach_cntl(struct socket *so);
|
||||
static int ng_attach_common(struct socket *so, int type);
|
||||
static void ng_detach_common(struct ngpcb *pcbp, int type);
|
||||
static void ng_socket_free_priv(struct ngsock *priv);
|
||||
/*static int ng_internalize(struct mbuf *m, struct thread *p); */
|
||||
|
||||
#ifdef NOTYET
|
||||
static int ng_internalize(struct mbuf *m, struct thread *p);
|
||||
#endif
|
||||
static int ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp);
|
||||
static int ng_bind(struct sockaddr *nam, struct ngpcb *pcbp);
|
||||
|
||||
@ -158,11 +154,6 @@ static u_long ngpdg_recvspace = 20 * 1024;
|
||||
SYSCTL_INT(_net_graph, OID_AUTO, recvspace, CTLFLAG_RW,
|
||||
&ngpdg_recvspace , 0, "Maximum space for incoming Netgraph datagrams");
|
||||
|
||||
/* List of all sockets */
|
||||
static LIST_HEAD(, ngpcb) ngsocklist;
|
||||
|
||||
static struct mtx ngsocketlist_mtx;
|
||||
|
||||
#define sotongpcb(so) ((struct ngpcb *)(so)->so_pcb)
|
||||
|
||||
/* If getting unexplained errors returned, set this to "kdb_enter("X"); */
|
||||
@ -222,39 +213,37 @@ ngc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
}
|
||||
#endif /* NOTYET */
|
||||
|
||||
/* Require destination as there may be >= 1 hooks on this node */
|
||||
/* Require destination as there may be >= 1 hooks on this node. */
|
||||
if (addr == NULL) {
|
||||
error = EDESTADDRREQ;
|
||||
goto release;
|
||||
}
|
||||
|
||||
/* Allocate an expendable buffer for the path, chop off
|
||||
* the sockaddr header, and make sure it's NUL terminated */
|
||||
/*
|
||||
* Allocate an expendable buffer for the path, chop off
|
||||
* the sockaddr header, and make sure it's NUL terminated.
|
||||
*/
|
||||
len = sap->sg_len - 2;
|
||||
MALLOC(path, char *, len + 1, M_NETGRAPH_PATH, M_WAITOK);
|
||||
if (path == NULL) {
|
||||
error = ENOMEM;
|
||||
goto release;
|
||||
}
|
||||
path = malloc(len + 1, M_NETGRAPH_PATH, M_WAITOK);
|
||||
bcopy(sap->sg_data, path, len);
|
||||
path[len] = '\0';
|
||||
|
||||
/* Move the actual message out of mbufs into a linear buffer.
|
||||
* Start by adding up the size of the data. (could use mh_len?) */
|
||||
/*
|
||||
* Move the actual message out of mbufs into a linear buffer.
|
||||
* Start by adding up the size of the data. (could use mh_len?)
|
||||
*/
|
||||
for (len = 0, m0 = m; m0 != NULL; m0 = m0->m_next)
|
||||
len += m0->m_len;
|
||||
|
||||
/* Move the data into a linear buffer as well. Messages are not
|
||||
* delivered in mbufs. */
|
||||
MALLOC(msg, struct ng_mesg *, len + 1, M_NETGRAPH_MSG, M_WAITOK);
|
||||
if (msg == NULL) {
|
||||
error = ENOMEM;
|
||||
goto release;
|
||||
}
|
||||
/*
|
||||
* Move the data into a linear buffer as well.
|
||||
* Messages are not delivered in mbufs.
|
||||
*/
|
||||
msg = malloc(len + 1, M_NETGRAPH_MSG, M_WAITOK);
|
||||
m_copydata(m, 0, len, (char *)msg);
|
||||
|
||||
if (msg->header.version != NG_VERSION) {
|
||||
FREE(msg, M_NETGRAPH_MSG);
|
||||
free(msg, M_NETGRAPH_MSG);
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
}
|
||||
@ -279,13 +268,13 @@ ngc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
mkp->type);
|
||||
error = kern_kldload(curthread, filename, &fileid);
|
||||
if (error != 0) {
|
||||
FREE(msg, M_NETGRAPH_MSG);
|
||||
free(msg, M_NETGRAPH_MSG);
|
||||
goto release;
|
||||
}
|
||||
|
||||
/* See if type has been loaded successfully. */
|
||||
if ((type = ng_findtype(mkp->type)) == NULL) {
|
||||
FREE(msg, M_NETGRAPH_MSG);
|
||||
free(msg, M_NETGRAPH_MSG);
|
||||
(void)kern_kldunload(curthread, fileid,
|
||||
LINKER_UNLOAD_NORMAL);
|
||||
error = ENXIO;
|
||||
@ -294,15 +283,9 @@ ngc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
}
|
||||
}
|
||||
|
||||
if ((item = ng_package_msg(msg, M_WAITOK)) == NULL) {
|
||||
error = ENOMEM;
|
||||
#ifdef TRACE_MESSAGES
|
||||
printf("ng_package_msg: err=%d\n", error);
|
||||
#endif
|
||||
goto release;
|
||||
}
|
||||
if ((error = ng_address_path((pcbp->sockdata->node), item,
|
||||
path, 0)) != 0) {
|
||||
item = ng_package_msg(msg, M_WAITOK);
|
||||
if ((error = ng_address_path((pcbp->sockdata->node), item, path, 0))
|
||||
!= 0) {
|
||||
#ifdef TRACE_MESSAGES
|
||||
printf("ng_address_path: errx=%d\n", error);
|
||||
#endif
|
||||
@ -334,7 +317,7 @@ ngc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
|
||||
error = ng_snd_item(item, NG_PROGRESS);
|
||||
|
||||
if (error == EINPROGRESS) {
|
||||
if (error == EINPROGRESS) {
|
||||
mtx_lock(&priv->mtx);
|
||||
if (priv->error == -1)
|
||||
msleep(priv, &priv->mtx, 0, "ngsock", 0);
|
||||
@ -346,7 +329,7 @@ ngc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
|
||||
release:
|
||||
if (path != NULL)
|
||||
FREE(path, M_NETGRAPH_PATH);
|
||||
free(path, M_NETGRAPH_PATH);
|
||||
if (control != NULL)
|
||||
m_freem(control);
|
||||
if (m != NULL)
|
||||
@ -367,11 +350,11 @@ ngc_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
static int
|
||||
ngc_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
{
|
||||
printf(" program tried to connect control socket to remote node\n ");
|
||||
/*
|
||||
* At this time refuse to do this.. it used to
|
||||
* do something but it was undocumented and not used.
|
||||
*/
|
||||
printf("program tried to connect control socket to remote node\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -404,7 +387,7 @@ ngd_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
{
|
||||
struct ngpcb *const pcbp = sotongpcb(so);
|
||||
struct sockaddr_ng *const sap = (struct sockaddr_ng *) addr;
|
||||
int len, error;
|
||||
int len, error;
|
||||
hook_p hook = NULL;
|
||||
char hookname[NG_HOOKSIZ];
|
||||
|
||||
@ -432,7 +415,7 @@ ngd_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
goto release;
|
||||
}
|
||||
/*
|
||||
* if exactly one hook exists, just use it.
|
||||
* If exactly one hook exists, just use it.
|
||||
* Special case to allow write(2) to work on an ng_socket.
|
||||
*/
|
||||
hook = LIST_FIRST(&pcbp->sockdata->node->nd_hooks);
|
||||
@ -450,18 +433,15 @@ ngd_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
hookname[len] = '\0';
|
||||
|
||||
/* Find the correct hook from 'hookname' */
|
||||
LIST_FOREACH(hook, &pcbp->sockdata->node->nd_hooks, hk_hooks) {
|
||||
if (strcmp(hookname, NG_HOOK_NAME(hook)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
hook = ng_findhook(pcbp->sockdata->node, hookname);
|
||||
if (hook == NULL) {
|
||||
error = EHOSTUNREACH;
|
||||
goto release;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send data (OK if hook is NULL) */
|
||||
NG_SEND_DATA_ONLY(error, hook, m); /* makes m NULL */
|
||||
/* Send data. */
|
||||
NG_SEND_DATA_FLAGS(error, hook, m, NG_WAITOK);
|
||||
|
||||
release:
|
||||
if (control != NULL)
|
||||
@ -539,14 +519,11 @@ ng_attach_cntl(struct socket *so)
|
||||
int error;
|
||||
|
||||
/* Allocate node private info */
|
||||
MALLOC(priv, struct ngsock *,
|
||||
sizeof(*priv), M_NETGRAPH_SOCK, M_WAITOK | M_ZERO);
|
||||
if (priv == NULL)
|
||||
return (ENOMEM);
|
||||
priv = malloc(sizeof(*priv), M_NETGRAPH_SOCK, M_WAITOK | M_ZERO);
|
||||
|
||||
/* Setup protocol control block */
|
||||
if ((error = ng_attach_common(so, NG_CONTROL)) != 0) {
|
||||
FREE(priv, M_NETGRAPH_SOCK);
|
||||
free(priv, M_NETGRAPH_SOCK);
|
||||
return (error);
|
||||
}
|
||||
pcbp = sotongpcb(so);
|
||||
@ -561,7 +538,7 @@ ng_attach_cntl(struct socket *so)
|
||||
|
||||
/* Make the generic node components */
|
||||
if ((error = ng_make_node_common(&typestruct, &priv->node)) != 0) {
|
||||
FREE(priv, M_NETGRAPH_SOCK);
|
||||
free(priv, M_NETGRAPH_SOCK);
|
||||
ng_detach_common(pcbp, NG_CONTROL);
|
||||
return (error);
|
||||
}
|
||||
@ -577,7 +554,7 @@ ng_attach_cntl(struct socket *so)
|
||||
static int
|
||||
ng_attach_data(struct socket *so)
|
||||
{
|
||||
return(ng_attach_common(so, NG_DATA));
|
||||
return (ng_attach_common(so, NG_DATA));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -590,25 +567,19 @@ ng_attach_common(struct socket *so, int type)
|
||||
struct ngpcb *pcbp;
|
||||
int error;
|
||||
|
||||
/* Standard socket setup stuff */
|
||||
/* Standard socket setup stuff. */
|
||||
error = soreserve(so, ngpdg_sendspace, ngpdg_recvspace);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
/* Allocate the pcb */
|
||||
MALLOC(pcbp, struct ngpcb *, sizeof(*pcbp), M_PCB, M_WAITOK | M_ZERO);
|
||||
if (pcbp == NULL)
|
||||
return (ENOMEM);
|
||||
/* Allocate the pcb. */
|
||||
pcbp = malloc(sizeof(struct ngpcb), M_PCB, M_WAITOK | M_ZERO);
|
||||
pcbp->type = type;
|
||||
|
||||
/* Link the pcb and the socket */
|
||||
so->so_pcb = (caddr_t) pcbp;
|
||||
/* Link the pcb and the socket. */
|
||||
so->so_pcb = (caddr_t)pcbp;
|
||||
pcbp->ng_socket = so;
|
||||
|
||||
/* Add the socket to linked list */
|
||||
mtx_lock(&ngsocketlist_mtx);
|
||||
LIST_INSERT_HEAD(&ngsocklist, pcbp, socks);
|
||||
mtx_unlock(&ngsocketlist_mtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -642,10 +613,7 @@ ng_detach_common(struct ngpcb *pcbp, int which)
|
||||
}
|
||||
|
||||
pcbp->ng_socket->so_pcb = NULL;
|
||||
mtx_lock(&ngsocketlist_mtx);
|
||||
LIST_REMOVE(pcbp, socks);
|
||||
mtx_unlock(&ngsocketlist_mtx);
|
||||
FREE(pcbp, M_PCB);
|
||||
free(pcbp, M_PCB);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -660,7 +628,7 @@ ng_socket_free_priv(struct ngsock *priv)
|
||||
|
||||
if (priv->refs == 0) {
|
||||
mtx_destroy(&priv->mtx);
|
||||
FREE(priv, M_NETGRAPH_SOCK);
|
||||
free(priv, M_NETGRAPH_SOCK);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -750,21 +718,20 @@ ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp)
|
||||
int error;
|
||||
item_p item;
|
||||
|
||||
/* If we are already connected, don't do it again */
|
||||
/* If we are already connected, don't do it again. */
|
||||
if (pcbp->sockdata != NULL)
|
||||
return (EISCONN);
|
||||
|
||||
/* Find the target (victim) and check it doesn't already have a data
|
||||
* socket. Also check it is a 'socket' type node.
|
||||
* Use ng_package_data() and address_path() to do this.
|
||||
/*
|
||||
* Find the target (victim) and check it doesn't already have
|
||||
* a data socket. Also check it is a 'socket' type node.
|
||||
* Use ng_package_data() and ng_address_path() to do this.
|
||||
*/
|
||||
|
||||
sap = (struct sockaddr_ng *) nam;
|
||||
/* The item will hold the node reference */
|
||||
/* The item will hold the node reference. */
|
||||
item = ng_package_data(NULL, NG_WAITOK);
|
||||
if (item == NULL) {
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
if ((error = ng_address_path(NULL, item, sap->sg_data, 0)))
|
||||
return (error); /* item is freed on failure */
|
||||
|
||||
@ -810,10 +777,9 @@ ng_bind(struct sockaddr *nam, struct ngpcb *pcbp)
|
||||
TRAP_ERROR;
|
||||
return (EINVAL);
|
||||
}
|
||||
if ((sap->sg_len < 4)
|
||||
|| (sap->sg_len > (NG_NODESIZ + 2))
|
||||
|| (sap->sg_data[0] == '\0')
|
||||
|| (sap->sg_data[sap->sg_len - 3] != '\0')) {
|
||||
if ((sap->sg_len < 4) || (sap->sg_len > (NG_NODESIZ + 2)) ||
|
||||
(sap->sg_data[0] == '\0') ||
|
||||
(sap->sg_data[sap->sg_len - 3] != '\0')) {
|
||||
TRAP_ERROR;
|
||||
return (EINVAL);
|
||||
}
|
||||
@ -880,8 +846,8 @@ ngs_newhook(node_p node, hook_p hook, const char *name)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* if only one hook, allow read(2) and write(2) to work.
|
||||
/*
|
||||
* If only one hook, allow read(2) and write(2) to work.
|
||||
*/
|
||||
static int
|
||||
ngs_connect(hook_p hook)
|
||||
@ -889,13 +855,11 @@ ngs_connect(hook_p hook)
|
||||
node_p node = NG_HOOK_NODE(hook);
|
||||
struct ngsock *priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
if ((priv->datasock)
|
||||
&& (priv->datasock->ng_socket)) {
|
||||
if (NG_NODE_NUMHOOKS(node) == 1) {
|
||||
if ((priv->datasock) && (priv->datasock->ng_socket)) {
|
||||
if (NG_NODE_NUMHOOKS(node) == 1)
|
||||
priv->datasock->ng_socket->so_state |= SS_ISCONNECTED;
|
||||
} else {
|
||||
else
|
||||
priv->datasock->ng_socket->so_state &= ~SS_ISCONNECTED;
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@ -987,7 +951,8 @@ ngs_rcvdata(hook_p hook, item_p item)
|
||||
|
||||
NGI_GET_M(item, m);
|
||||
NG_FREE_ITEM(item);
|
||||
/* If there is no data socket, black-hole it */
|
||||
|
||||
/* If there is no data socket, black-hole it. */
|
||||
if (pcbp == NULL) {
|
||||
NG_FREE_M(m);
|
||||
return (0);
|
||||
@ -1002,8 +967,8 @@ ngs_rcvdata(hook_p hook, item_p item)
|
||||
bcopy(NG_HOOK_NAME(hook), addr->sg_data, addrlen);
|
||||
addr->sg_data[addrlen] = '\0';
|
||||
|
||||
/* Try to tell the socket which hook it came in on */
|
||||
if (sbappendaddr(&so->so_rcv, (struct sockaddr *) addr, m, NULL) == 0) {
|
||||
/* Try to tell the socket which hook it came in on. */
|
||||
if (sbappendaddr(&so->so_rcv, (struct sockaddr *)addr, m, NULL) == 0) {
|
||||
m_freem(m);
|
||||
TRAP_ERROR;
|
||||
return (ENOBUFS);
|
||||
@ -1024,20 +989,17 @@ ngs_disconnect(hook_p hook)
|
||||
node_p node = NG_HOOK_NODE(hook);
|
||||
struct ngsock *const priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
if ((priv->datasock)
|
||||
&& (priv->datasock->ng_socket)) {
|
||||
if (NG_NODE_NUMHOOKS(node) == 1) {
|
||||
if ((priv->datasock) && (priv->datasock->ng_socket)) {
|
||||
if (NG_NODE_NUMHOOKS(node) == 1)
|
||||
priv->datasock->ng_socket->so_state |= SS_ISCONNECTED;
|
||||
} else {
|
||||
else
|
||||
priv->datasock->ng_socket->so_state &= ~SS_ISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
if ((priv->flags & NGS_FLAG_NOLINGER )
|
||||
&& (NG_NODE_NUMHOOKS(node) == 0)
|
||||
&& (NG_NODE_IS_VALID(node))) {
|
||||
if ((priv->flags & NGS_FLAG_NOLINGER) &&
|
||||
(NG_NODE_NUMHOOKS(node) == 0) && (NG_NODE_IS_VALID(node)))
|
||||
ng_rmnode_self(node);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1150,7 +1112,7 @@ struct domain ngdomain = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Handle loading and unloading for this node type
|
||||
* Handle loading and unloading for this node type.
|
||||
* This is to handle auxiliary linkages (e.g protocol domain addition).
|
||||
*/
|
||||
static int
|
||||
@ -1160,24 +1122,15 @@ ngs_mod_event(module_t mod, int event, void *data)
|
||||
|
||||
switch (event) {
|
||||
case MOD_LOAD:
|
||||
mtx_init(&ngsocketlist_mtx, "ng_socketlist", NULL, MTX_DEF);
|
||||
/* Register protocol domain */
|
||||
/* Register protocol domain. */
|
||||
net_add_domain(&ngdomain);
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
/* Insure there are no open netgraph sockets */
|
||||
if (!LIST_EMPTY(&ngsocklist)) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef NOTYET
|
||||
if ((LIST_EMPTY(&ngsocklist)) && (typestruct.refs == 0)) {
|
||||
/* Unregister protocol domain XXX can't do this yet.. */
|
||||
if ((error = net_rm_domain(&ngdomain)) != 0)
|
||||
break;
|
||||
mtx_destroy(&ngsocketlist_mtx);
|
||||
} else
|
||||
if ((error = net_rm_domain(&ngdomain)) != 0)
|
||||
break;
|
||||
else
|
||||
#endif
|
||||
error = EBUSY;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user