o Use subr_unit allocator. This simplifies code much:
- Remove get_free_unit(). - Remove SLIST of nodes. - Remove global mutex. o Increase NGD_MAX to 999. o Move ngd_mod_event() up to netgraph methods.
This commit is contained in:
parent
de52d21a02
commit
5cdd064d8a
@ -1,6 +1,6 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2002 Mark Santcroos <marks@ripe.net>
|
* 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
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -88,7 +88,6 @@ NETGRAPH_INIT(device, &ngd_typestruct);
|
|||||||
/* per node data */
|
/* per node data */
|
||||||
struct ngd_private {
|
struct ngd_private {
|
||||||
struct ifqueue readq;
|
struct ifqueue readq;
|
||||||
SLIST_ENTRY(ngd_private) links;
|
|
||||||
struct ng_node *node;
|
struct ng_node *node;
|
||||||
struct ng_hook *hook;
|
struct ng_hook *hook;
|
||||||
struct cdev *ngddev;
|
struct cdev *ngddev;
|
||||||
@ -100,12 +99,11 @@ struct ngd_private {
|
|||||||
};
|
};
|
||||||
typedef struct ngd_private *priv_p;
|
typedef struct ngd_private *priv_p;
|
||||||
|
|
||||||
/* List of all active nodes and mutex to protect it */
|
/* unit number allocator entity */
|
||||||
static SLIST_HEAD(, ngd_private) ngd_nodes = SLIST_HEAD_INITIALIZER(ngd_nodes);
|
static struct unrhdr *ngd_unit;
|
||||||
static struct mtx ng_device_mtx;
|
|
||||||
|
|
||||||
/* Maximum number of NGD devices */
|
/* 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_close_t ngdclose;
|
||||||
static d_open_t ngdopen;
|
static d_open_t ngdopen;
|
||||||
@ -129,13 +127,32 @@ static struct cdevsw ngd_cdevsw = {
|
|||||||
.d_name = NG_DEVICE_DEVNAME,
|
.d_name = NG_DEVICE_DEVNAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Helper functions */
|
|
||||||
static int get_free_unit(void);
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Netgraph methods
|
* 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
|
* create new node
|
||||||
*/
|
*/
|
||||||
@ -150,17 +167,8 @@ ng_device_constructor(node_p node)
|
|||||||
if (priv == NULL)
|
if (priv == NULL)
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
|
|
||||||
mtx_lock(&ng_device_mtx);
|
/* Allocate unit number */
|
||||||
priv->unit = get_free_unit();
|
priv->unit = alloc_unr(ngd_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);
|
|
||||||
|
|
||||||
/* Initialize mutexes and queue */
|
/* Initialize mutexes and queue */
|
||||||
mtx_init(&priv->ngd_mtx, "ng_device", NULL, MTX_DEF);
|
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__);
|
printf("%s(): make_dev() failed\n",__func__);
|
||||||
mtx_destroy(&priv->ngd_mtx);
|
mtx_destroy(&priv->ngd_mtx);
|
||||||
mtx_destroy(&priv->readq.ifq_mtx);
|
mtx_destroy(&priv->readq.ifq_mtx);
|
||||||
|
free_unr(ngd_unit, priv->unit);
|
||||||
FREE(priv, M_NETGRAPH);
|
FREE(priv, M_NETGRAPH);
|
||||||
return(EINVAL);
|
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) {
|
if (msg->header.typecookie == NGM_DEVICE_COOKIE) {
|
||||||
switch (msg->header.cmd) {
|
switch (msg->header.cmd) {
|
||||||
case NGM_DEVICE_GET_DEVNAME:
|
case NGM_DEVICE_GET_DEVNAME:
|
||||||
/* XXX: Fix when NGD_MAX us bigger */
|
/* XXX: Fix when MAX_NGD us bigger */
|
||||||
NG_MKRESPONSE(resp, msg,
|
NG_MKRESPONSE(resp, msg,
|
||||||
strlen(NG_DEVICE_DEVNAME) + 3, M_NOWAIT);
|
strlen(NG_DEVICE_DEVNAME) + 4, M_NOWAIT);
|
||||||
|
|
||||||
if (resp == NULL)
|
if (resp == NULL)
|
||||||
ERROUT(ENOMEM);
|
ERROUT(ENOMEM);
|
||||||
@ -293,13 +302,11 @@ ng_device_disconnect(hook_p hook)
|
|||||||
destroy_dev(priv->ngddev);
|
destroy_dev(priv->ngddev);
|
||||||
mtx_destroy(&priv->ngd_mtx);
|
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);
|
IF_DRAIN(&priv->readq);
|
||||||
mtx_destroy(&(priv)->readq.ifq_mtx);
|
mtx_destroy(&(priv)->readq.ifq_mtx);
|
||||||
|
|
||||||
|
free_unr(ngd_unit, priv->unit);
|
||||||
|
|
||||||
FREE(priv, M_NETGRAPH);
|
FREE(priv, M_NETGRAPH);
|
||||||
|
|
||||||
ng_rmnode_self(NG_HOOK_NODE(hook));
|
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;
|
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),
|
NG_MKMESSAGE(msg, NGM_DEVICE_COOKIE, cmd, sizeof(struct ngd_param_s),
|
||||||
M_NOWAIT);
|
M_NOWAIT);
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
@ -493,62 +490,3 @@ ngdpoll(struct cdev *dev, int events, struct thread *td)
|
|||||||
|
|
||||||
return (revents);
|
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);
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user