aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netgraph/ng_device.c128
1 files changed, 33 insertions, 95 deletions
diff --git a/sys/netgraph/ng_device.c b/sys/netgraph/ng_device.c
index 6230ccf8e0ac..df6ee4cc2718 100644
--- a/sys/netgraph/ng_device.c
+++ b/sys/netgraph/ng_device.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2002 Mark Santcroos <marks@ripe.net>
- * Copyright (c) 2004 Gleb Smirnoff <glebius@FreeBSD.org>
+ * Copyright (c) 2004-2005 Gleb Smirnoff <glebius@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -88,7 +88,6 @@ NETGRAPH_INIT(device, &ngd_typestruct);
/* per node data */
struct ngd_private {
struct ifqueue readq;
- SLIST_ENTRY(ngd_private) links;
struct ng_node *node;
struct ng_hook *hook;
struct cdev *ngddev;
@@ -100,12 +99,11 @@ struct ngd_private {
};
typedef struct ngd_private *priv_p;
-/* List of all active nodes and mutex to protect it */
-static SLIST_HEAD(, ngd_private) ngd_nodes = SLIST_HEAD_INITIALIZER(ngd_nodes);
-static struct mtx ng_device_mtx;
+/* unit number allocator entity */
+static struct unrhdr *ngd_unit;
/* Maximum number of NGD devices */
-#define MAX_NGD 25 /* should be more than enough for now */
+#define MAX_NGD 999
static d_close_t ngdclose;
static d_open_t ngdopen;
@@ -129,14 +127,33 @@ static struct cdevsw ngd_cdevsw = {
.d_name = NG_DEVICE_DEVNAME,
};
-/* Helper functions */
-static int get_free_unit(void);
-
/******************************************************************************
* Netgraph methods
******************************************************************************/
/*
+ * Handle loading and unloading for this node type.
+ */
+static int
+ng_device_mod_event(module_t mod, int event, void *data)
+{
+ int error = 0;
+
+ switch (event) {
+ case MOD_LOAD:
+ ngd_unit = new_unrhdr(0, MAX_NGD, NULL);
+ break;
+ case MOD_UNLOAD:
+ delete_unrhdr(ngd_unit);
+ break;
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+ return (error);
+}
+
+/*
* create new node
*/
static int
@@ -150,17 +167,8 @@ ng_device_constructor(node_p node)
if (priv == NULL)
return (ENOMEM);
- mtx_lock(&ng_device_mtx);
- priv->unit = get_free_unit();
- if(priv->unit < 0) {
- printf("%s: No free unit found by get_free_unit(), "
- "increase MAX_NGD\n",__func__);
- mtx_unlock(&ng_device_mtx);
- FREE(priv, M_NETGRAPH);
- return(EINVAL);
- }
- SLIST_INSERT_HEAD(&ngd_nodes, priv, links);
- mtx_unlock(&ng_device_mtx);
+ /* Allocate unit number */
+ priv->unit = alloc_unr(ngd_unit);
/* Initialize mutexes and queue */
mtx_init(&priv->ngd_mtx, "ng_device", NULL, MTX_DEF);
@@ -177,6 +185,7 @@ ng_device_constructor(node_p node)
printf("%s(): make_dev() failed\n",__func__);
mtx_destroy(&priv->ngd_mtx);
mtx_destroy(&priv->readq.ifq_mtx);
+ free_unr(ngd_unit, priv->unit);
FREE(priv, M_NETGRAPH);
return(EINVAL);
}
@@ -203,9 +212,9 @@ ng_device_rcvmsg(node_p node, item_p item, hook_p lasthook)
if (msg->header.typecookie == NGM_DEVICE_COOKIE) {
switch (msg->header.cmd) {
case NGM_DEVICE_GET_DEVNAME:
- /* XXX: Fix when NGD_MAX us bigger */
+ /* XXX: Fix when MAX_NGD us bigger */
NG_MKRESPONSE(resp, msg,
- strlen(NG_DEVICE_DEVNAME) + 3, M_NOWAIT);
+ strlen(NG_DEVICE_DEVNAME) + 4, M_NOWAIT);
if (resp == NULL)
ERROUT(ENOMEM);
@@ -293,13 +302,11 @@ ng_device_disconnect(hook_p hook)
destroy_dev(priv->ngddev);
mtx_destroy(&priv->ngd_mtx);
- mtx_lock(&ng_device_mtx);
- SLIST_REMOVE(&ngd_nodes, priv, ngd_private, links);
- mtx_unlock(&ng_device_mtx);
-
IF_DRAIN(&priv->readq);
mtx_destroy(&(priv)->readq.ifq_mtx);
+ free_unr(ngd_unit, priv->unit);
+
FREE(priv, M_NETGRAPH);
ng_rmnode_self(NG_HOOK_NODE(hook));
@@ -376,16 +383,6 @@ ngdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td
DBG;
- SLIST_FOREACH(tmp,&sc->head,links) {
- if(tmp->ngddev == dev) {
- connection = tmp;
- }
- }
- if(connection == NULL) {
- printf("%s(): connection is still NULL, no dev found\n",__func__);
- return(-1);
- }
-
NG_MKMESSAGE(msg, NGM_DEVICE_COOKIE, cmd, sizeof(struct ngd_param_s),
M_NOWAIT);
if (msg == NULL) {
@@ -493,62 +490,3 @@ ngdpoll(struct cdev *dev, int events, struct thread *td)
return (revents);
}
-
-/******************************************************************************
- * Helper subroutines
- ******************************************************************************/
-
-static int
-get_free_unit()
-{
- struct ngd_private *priv = NULL;
- int n = 0;
- int unit = -1;
-
- DBG;
-
- mtx_assert(&ng_device_mtx, MA_OWNED);
-
- /* When there is no list yet, the first device unit is always 0. */
- if SLIST_EMPTY(&ngd_nodes)
- return(0);
-
- /* Just do a brute force loop to find the first free unit that is
- * smaller than MAX_NGD.
- * Set MAX_NGD to a large value, doesn't impact performance.
- */
- for(n = 0; n<MAX_NGD && unit == -1; n++) {
- SLIST_FOREACH(priv, &ngd_nodes, links) {
-
- if(priv->unit == n) {
- unit = -1;
- break;
- }
- unit = n;
- }
- }
-
- return (unit);
-}
-
-/*
- * Handle loading and unloading for this node type.
- */
-static int
-ng_device_mod_event(module_t mod, int event, void *data)
-{
- int error = 0;
-
- switch (event) {
- case MOD_LOAD:
- mtx_init(&ng_device_mtx, "ng_device global", NULL, MTX_DEF);
- break;
- case MOD_UNLOAD:
- mtx_destroy(&ng_device_mtx);
- break;
- default:
- error = EOPNOTSUPP;
- break;
- }
- return (error);
-}