mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 21:05:08 +00:00
netgraph/ng_bridge: Merge internal structures
In a earlier version of ng_bridge(4) the exernal visible host entry structure was a strict subset of the internal one. So internal view was a direct annotation of the external structure. This strict inheritance was lost many versions ago. There is no need to encapsulate a part of the internal represntation as a separate structure. This patch is a preparation to make the internal structure read only in the data path in order to make ng_bridge(4) multithreaded. Reviewed by: kp MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D28545
This commit is contained in:
parent
e9d419a053
commit
ccf4cd2e78
|
@ -134,13 +134,16 @@ typedef struct ng_bridge_private *priv_p;
|
|||
typedef struct ng_bridge_private const *priv_cp; /* read only access */
|
||||
|
||||
/* Information about a host, stored in a hash table entry */
|
||||
struct ng_bridge_hent {
|
||||
struct ng_bridge_host host; /* actual host info */
|
||||
SLIST_ENTRY(ng_bridge_hent) next; /* next entry in bucket */
|
||||
struct ng_bridge_host {
|
||||
u_char addr[6]; /* ethernet address */
|
||||
link_p link; /* link where addr can be found */
|
||||
u_int16_t age; /* seconds ago entry was created */
|
||||
u_int16_t staleness; /* seconds ago host last heard from */
|
||||
SLIST_ENTRY(ng_bridge_host) next; /* next entry in bucket */
|
||||
};
|
||||
|
||||
/* Hash table bucket declaration */
|
||||
SLIST_HEAD(ng_bridge_bucket, ng_bridge_hent);
|
||||
SLIST_HEAD(ng_bridge_bucket, ng_bridge_host);
|
||||
|
||||
/* Netgraph node methods */
|
||||
static ng_constructor_t ng_bridge_constructor;
|
||||
|
@ -567,7 +570,7 @@ ng_bridge_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
|||
case NGM_BRIDGE_GET_TABLE:
|
||||
{
|
||||
struct ng_bridge_host_ary *ary;
|
||||
struct ng_bridge_hent *hent;
|
||||
struct ng_bridge_host *host;
|
||||
int i = 0, bucket;
|
||||
|
||||
NG_MKRESPONSE(resp, msg, sizeof(*ary)
|
||||
|
@ -579,14 +582,14 @@ ng_bridge_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
|||
ary = (struct ng_bridge_host_ary *)resp->data;
|
||||
ary->numHosts = priv->numHosts;
|
||||
for (bucket = 0; bucket < priv->numBuckets; bucket++) {
|
||||
SLIST_FOREACH(hent, &priv->tab[bucket], next) {
|
||||
SLIST_FOREACH(host, &priv->tab[bucket], next) {
|
||||
memcpy(ary->hosts[i].addr,
|
||||
hent->host.addr,
|
||||
host->addr,
|
||||
sizeof(ary->hosts[i].addr));
|
||||
ary->hosts[i].age = hent->host.age;
|
||||
ary->hosts[i].staleness = hent->host.staleness;
|
||||
ary->hosts[i].age = host->age;
|
||||
ary->hosts[i].staleness = host->staleness;
|
||||
strncpy(ary->hosts[i].hook,
|
||||
NG_HOOK_NAME(hent->host.link->hook),
|
||||
NG_HOOK_NAME(host->link->hook),
|
||||
sizeof(ary->hosts[i].hook));
|
||||
i++;
|
||||
}
|
||||
|
@ -925,11 +928,11 @@ static struct ng_bridge_host *
|
|||
ng_bridge_get(priv_cp priv, const u_char *addr)
|
||||
{
|
||||
const int bucket = HASH(addr, priv->hashMask);
|
||||
struct ng_bridge_hent *hent;
|
||||
struct ng_bridge_host *host;
|
||||
|
||||
SLIST_FOREACH(hent, &priv->tab[bucket], next) {
|
||||
if (ETHER_EQUAL(hent->host.addr, addr))
|
||||
return (&hent->host);
|
||||
SLIST_FOREACH(host, &priv->tab[bucket], next) {
|
||||
if (ETHER_EQUAL(host->addr, addr))
|
||||
return (host);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -943,27 +946,27 @@ static int
|
|||
ng_bridge_put(priv_p priv, const u_char *addr, link_p link)
|
||||
{
|
||||
const int bucket = HASH(addr, priv->hashMask);
|
||||
struct ng_bridge_hent *hent;
|
||||
struct ng_bridge_host *host;
|
||||
|
||||
#ifdef INVARIANTS
|
||||
/* Assert that entry does not already exist in hashtable */
|
||||
SLIST_FOREACH(hent, &priv->tab[bucket], next) {
|
||||
KASSERT(!ETHER_EQUAL(hent->host.addr, addr),
|
||||
SLIST_FOREACH(host, &priv->tab[bucket], next) {
|
||||
KASSERT(!ETHER_EQUAL(host->addr, addr),
|
||||
("%s: entry %6D exists in table", __func__, addr, ":"));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate and initialize new hashtable entry */
|
||||
hent = malloc(sizeof(*hent), M_NETGRAPH_BRIDGE, M_NOWAIT);
|
||||
if (hent == NULL)
|
||||
host = malloc(sizeof(*host), M_NETGRAPH_BRIDGE, M_NOWAIT);
|
||||
if (host == NULL)
|
||||
return (0);
|
||||
bcopy(addr, hent->host.addr, ETHER_ADDR_LEN);
|
||||
hent->host.link = link;
|
||||
hent->host.staleness = 0;
|
||||
hent->host.age = 0;
|
||||
bcopy(addr, host->addr, ETHER_ADDR_LEN);
|
||||
host->link = link;
|
||||
host->staleness = 0;
|
||||
host->age = 0;
|
||||
|
||||
/* Add new element to hash bucket */
|
||||
SLIST_INSERT_HEAD(&priv->tab[bucket], hent, next);
|
||||
SLIST_INSERT_HEAD(&priv->tab[bucket], host, next);
|
||||
priv->numHosts++;
|
||||
|
||||
/* Resize table if necessary */
|
||||
|
@ -1008,12 +1011,12 @@ ng_bridge_rehash(priv_p priv)
|
|||
struct ng_bridge_bucket *const oldList = &priv->tab[oldBucket];
|
||||
|
||||
while (!SLIST_EMPTY(oldList)) {
|
||||
struct ng_bridge_hent *const hent
|
||||
struct ng_bridge_host *const host
|
||||
= SLIST_FIRST(oldList);
|
||||
|
||||
SLIST_REMOVE_HEAD(oldList, next);
|
||||
newBucket = HASH(hent->host.addr, newMask);
|
||||
SLIST_INSERT_HEAD(&newTab[newBucket], hent, next);
|
||||
newBucket = HASH(host->addr, newMask);
|
||||
SLIST_INSERT_HEAD(&newTab[newBucket], host, next);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1044,17 +1047,17 @@ ng_bridge_remove_hosts(priv_p priv, link_p link)
|
|||
int bucket;
|
||||
|
||||
for (bucket = 0; bucket < priv->numBuckets; bucket++) {
|
||||
struct ng_bridge_hent **hptr = &SLIST_FIRST(&priv->tab[bucket]);
|
||||
struct ng_bridge_host **hptr = &SLIST_FIRST(&priv->tab[bucket]);
|
||||
|
||||
while (*hptr != NULL) {
|
||||
struct ng_bridge_hent *const hent = *hptr;
|
||||
struct ng_bridge_host *const host = *hptr;
|
||||
|
||||
if (link == NULL || hent->host.link == link) {
|
||||
*hptr = SLIST_NEXT(hent, next);
|
||||
free(hent, M_NETGRAPH_BRIDGE);
|
||||
if (link == NULL || host->link == link) {
|
||||
*hptr = SLIST_NEXT(host, next);
|
||||
free(host, M_NETGRAPH_BRIDGE);
|
||||
priv->numHosts--;
|
||||
} else
|
||||
hptr = &SLIST_NEXT(hent, next);
|
||||
hptr = &SLIST_NEXT(host, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1095,20 +1098,20 @@ ng_bridge_timeout(node_p node, hook_p hook, void *arg1, int arg2)
|
|||
|
||||
/* Update host time counters and remove stale entries */
|
||||
for (bucket = 0; bucket < priv->numBuckets; bucket++) {
|
||||
struct ng_bridge_hent **hptr = &SLIST_FIRST(&priv->tab[bucket]);
|
||||
struct ng_bridge_host **hptr = &SLIST_FIRST(&priv->tab[bucket]);
|
||||
|
||||
while (*hptr != NULL) {
|
||||
struct ng_bridge_hent *const hent = *hptr;
|
||||
struct ng_bridge_host *const host = *hptr;
|
||||
|
||||
/* Remove hosts we haven't heard from in a while */
|
||||
if (++hent->host.staleness >= priv->conf.maxStaleness) {
|
||||
*hptr = SLIST_NEXT(hent, next);
|
||||
free(hent, M_NETGRAPH_BRIDGE);
|
||||
if (++host->staleness >= priv->conf.maxStaleness) {
|
||||
*hptr = SLIST_NEXT(host, next);
|
||||
free(host, M_NETGRAPH_BRIDGE);
|
||||
priv->numHosts--;
|
||||
} else {
|
||||
if (hent->host.age < 0xffff)
|
||||
hent->host.age++;
|
||||
hptr = &SLIST_NEXT(hent, next);
|
||||
if (host->age < 0xffff)
|
||||
host->age++;
|
||||
hptr = &SLIST_NEXT(host, next);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,13 +109,6 @@ struct ng_bridge_link_stats {
|
|||
|
||||
struct ng_bridge_link;
|
||||
typedef struct ng_bridge_link *link_p;
|
||||
/* Structure describing a single host */
|
||||
struct ng_bridge_host {
|
||||
u_char addr[6]; /* ethernet address */
|
||||
link_p link; /* link where addr can be found */
|
||||
u_int16_t age; /* seconds ago entry was created */
|
||||
u_int16_t staleness; /* seconds ago host last heard from */
|
||||
};
|
||||
|
||||
/* external representation of the host */
|
||||
struct ng_bridge_hostent {
|
||||
|
|
Loading…
Reference in a new issue