summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2001-02-05 18:57:11 +0000
committerjulian <julian@FreeBSD.org>2001-02-05 18:57:11 +0000
commit86cb214594355ba9efe9aa0205cb878a8e8f3ecd (patch)
tree29fe75b4f90c31aeed1338596195c5243ec60a12
parent9c3b71e869cdd031139aee8095d94618d940d570 (diff)
downloadFreeBSD-src-86cb214594355ba9efe9aa0205cb878a8e8f3ecd.zip
FreeBSD-src-86cb214594355ba9efe9aa0205cb878a8e8f3ecd.tar.gz
Make netgraph modules refuse to link with modules of a different ABI version.
also try implement teh documented behaviour in socket nodes so that when there is only one hook, an unaddressed write/send will DTRT and send the data to that hook.
-rw-r--r--sys/netgraph/netgraph.h4
-rw-r--r--sys/netgraph/ng_base.c3
-rw-r--r--sys/netgraph/ng_socket.c107
3 files changed, 75 insertions, 39 deletions
diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h
index 548c7be..21db90b 100644
--- a/sys/netgraph/netgraph.h
+++ b/sys/netgraph/netgraph.h
@@ -1111,7 +1111,9 @@ static moduledata_t ng_##typename##_mod = { \
(typestructp) \
}; \
DECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order); \
-MODULE_DEPEND(ng_##typename, netgraph, 1, 1, 1)
+MODULE_DEPEND(ng_##typename, netgraph, NG_ABI_VERSION, \
+ NG_ABI_VERSION, \
+ NG_ABI_VERSION)
#define NETGRAPH_INIT(tn, tp) \
NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_ANY)
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index d071f5f..860d210 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -63,7 +63,7 @@
#include <netgraph/netgraph.h>
#include <netgraph/ng_parse.h>
-MODULE_VERSION(netgraph, 1);
+MODULE_VERSION(netgraph, NG_ABI_VERSION);
/* List of all active nodes */
static LIST_HEAD(, ng_node) ng_nodelist;
@@ -1423,6 +1423,7 @@ ng_rmnode_self(node_p node)
if (node == &ng_deadnode)
return (0);
+ node->nd_flags |= NG_INVALID;
if (node->nd_flags & NG_CLOSING)
return (0);
diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c
index 64635e9..63b37a2 100644
--- a/sys/netgraph/ng_socket.c
+++ b/sys/netgraph/ng_socket.c
@@ -108,6 +108,7 @@ static ng_constructor_t ngs_constructor;
static ng_rcvmsg_t ngs_rcvmsg;
static ng_shutdown_t ngs_shutdown;
static ng_newhook_t ngs_newhook;
+static ng_connect_t ngs_connect;
static ng_rcvdata_t ngs_rcvdata;
static ng_disconnect_t ngs_disconnect;
@@ -135,7 +136,7 @@ static struct ng_type typestruct = {
ngs_shutdown,
ngs_newhook,
NULL,
- NULL,
+ ngs_connect,
ngs_rcvdata,
ngs_disconnect,
NULL
@@ -380,11 +381,13 @@ ngd_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
/* Find the correct hook from 'hookname' */
LIST_FOREACH(hook, &pcbp->sockdata->node->nd_hooks, hk_hooks) {
- if (strcmp(hookname, NG_HOOK_NAME(hook)) == 0)
+ if (strcmp(hookname, NG_HOOK_NAME(hook)) == 0) {
break;
+ }
}
- if (hook == NULL)
+ if (hook == NULL) {
error = EHOSTUNREACH;
+ }
}
/* Send data (OK if hook is NULL) */
@@ -531,23 +534,23 @@ ng_attach_common(struct socket *so, int type)
static void
ng_detach_common(struct ngpcb *pcbp, int which)
{
- struct ngsock *sockdata;
+ struct ngsock *priv;
if (pcbp->sockdata) {
- sockdata = pcbp->sockdata;
+ priv = pcbp->sockdata;
pcbp->sockdata = NULL;
switch (which) {
case NG_CONTROL:
- sockdata->ctlsock = NULL;
+ priv->ctlsock = NULL;
break;
case NG_DATA:
- sockdata->datasock = NULL;
+ priv->datasock = NULL;
break;
default:
panic(__FUNCTION__);
}
- if ((--sockdata->refs == 0) && (sockdata->node != NULL))
- ng_rmnode_self(sockdata->node);
+ if ((--priv->refs == 0) && (priv->node != NULL))
+ ng_rmnode_self(priv->node);
}
pcbp->ng_socket->so_pcb = NULL;
pcbp->ng_socket = NULL;
@@ -626,7 +629,7 @@ ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp)
{
struct sockaddr_ng *sap;
node_p farnode;
- struct ngsock *sockdata;
+ struct ngsock *priv;
int error;
item_p item;
@@ -658,8 +661,8 @@ ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp)
NG_FREE_ITEM(item); /* drop the reference to the node */
return (EINVAL);
}
- sockdata = NG_NODE_PRIVATE(farnode);
- if (sockdata->datasock != NULL) {
+ priv = NG_NODE_PRIVATE(farnode);
+ if (priv->datasock != NULL) {
NG_FREE_ITEM(item); /* drop the reference to the node */
return (EADDRINUSE);
}
@@ -668,9 +671,9 @@ ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp)
* Link the PCB and the private data struct. and note the extra
* reference. Drop the extra reference on the node.
*/
- sockdata->datasock = pcbp;
- pcbp->sockdata = sockdata;
- sockdata->refs++; /* XXX possible race if it's being freed */
+ priv->datasock = pcbp;
+ pcbp->sockdata = priv;
+ priv->refs++; /* XXX possible race if it's being freed */
NG_FREE_ITEM(item); /* drop the reference to the node */
return (0);
}
@@ -681,10 +684,10 @@ ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp)
static int
ng_bind(struct sockaddr *nam, struct ngpcb *pcbp)
{
- struct ngsock *const sockdata = pcbp->sockdata;
+ struct ngsock *const priv = pcbp->sockdata;
struct sockaddr_ng *const sap = (struct sockaddr_ng *) nam;
- if (sockdata == NULL) {
+ if (priv == NULL) {
TRAP_ERROR;
return (EINVAL);
}
@@ -695,7 +698,7 @@ ng_bind(struct sockaddr *nam, struct ngpcb *pcbp)
TRAP_ERROR;
return (EINVAL);
}
- return (ng_name_node(sockdata->node, sap->sg_data));
+ return (ng_name_node(priv->node, sap->sg_data));
}
/*
@@ -753,6 +756,26 @@ 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.
+ */
+static int
+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) {
+ priv->datasock->ng_socket->so_state |= SS_ISCONNECTED;
+ } else {
+ priv->datasock->ng_socket->so_state &= ~SS_ISCONNECTED;
+ }
+ }
+ return (0);
+}
+
/*
* Incoming messages get passed up to the control socket.
* Unless they are for us specifically (socket_type)
@@ -760,8 +783,8 @@ ngs_newhook(node_p node, hook_p hook, const char *name)
static int
ngs_rcvmsg(node_p node, item_p item, hook_p lasthook)
{
- struct ngsock *const sockdata = NG_NODE_PRIVATE(node);
- struct ngpcb *const pcbp = sockdata->ctlsock;
+ struct ngsock *const priv = NG_NODE_PRIVATE(node);
+ struct ngpcb *const pcbp = priv->ctlsock;
struct sockaddr_ng *addr;
int addrlen;
int error = 0;
@@ -792,10 +815,10 @@ msg->header.token);
if (msg->header.typecookie == NGM_SOCKET_COOKIE) {
switch (msg->header.cmd) {
case NGM_SOCK_CMD_NOLINGER:
- sockdata->flags |= NGS_FLAG_NOLINGER;
+ priv->flags |= NGS_FLAG_NOLINGER;
break;
case NGM_SOCK_CMD_LINGER:
- sockdata->flags &= ~NGS_FLAG_NOLINGER;
+ priv->flags &= ~NGS_FLAG_NOLINGER;
break;
default:
error = EINVAL; /* unknown command */
@@ -830,8 +853,8 @@ msg->header.token);
static int
ngs_rcvdata(hook_p hook, item_p item)
{
- struct ngsock *const sockdata = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- struct ngpcb *const pcbp = sockdata->datasock;
+ struct ngsock *const priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
+ struct ngpcb *const pcbp = priv->datasock;
struct socket *so;
struct sockaddr_ng *addr;
char *addrbuf[NG_HOOKLEN + 1 + 4];
@@ -874,12 +897,22 @@ ngs_rcvdata(hook_p hook, item_p item)
static int
ngs_disconnect(hook_p hook)
{
- struct ngsock *const sockdata = NG_NODE_PRIVATE(NG_HOOK_NODE(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) {
+ priv->datasock->ng_socket->so_state |= SS_ISCONNECTED;
+ } else {
+ priv->datasock->ng_socket->so_state &= ~SS_ISCONNECTED;
+ }
+ }
- if ((sockdata->flags & NGS_FLAG_NOLINGER )
- && (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
- && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) {
- ng_rmnode_self(NG_HOOK_NODE(hook));
+ if ((priv->flags & NGS_FLAG_NOLINGER )
+ && (NG_NODE_NUMHOOKS(node) == 0)
+ && (NG_NODE_IS_VALID(node))) {
+ ng_rmnode_self(node);
}
return (0);
}
@@ -892,25 +925,25 @@ ngs_disconnect(hook_p hook)
static int
ngs_shutdown(node_p node)
{
- struct ngsock *const sockdata = NG_NODE_PRIVATE(node);
- struct ngpcb *const dpcbp = sockdata->datasock;
- struct ngpcb *const pcbp = sockdata->ctlsock;
+ struct ngsock *const priv = NG_NODE_PRIVATE(node);
+ struct ngpcb *const dpcbp = priv->datasock;
+ struct ngpcb *const pcbp = priv->ctlsock;
if (dpcbp != NULL) {
soisdisconnected(dpcbp->ng_socket);
dpcbp->sockdata = NULL;
- sockdata->datasock = NULL;
- sockdata->refs--;
+ priv->datasock = NULL;
+ priv->refs--;
}
if (pcbp != NULL) {
soisdisconnected(pcbp->ng_socket);
pcbp->sockdata = NULL;
- sockdata->ctlsock = NULL;
- sockdata->refs--;
+ priv->ctlsock = NULL;
+ priv->refs--;
}
NG_NODE_SET_PRIVATE(node, NULL);
NG_NODE_UNREF(node);
- FREE(sockdata, M_NETGRAPH_SOCK);
+ FREE(priv, M_NETGRAPH_SOCK);
return (0);
}
OpenPOWER on IntegriCloud