summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter/netinet/ip_htable.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ipfilter/netinet/ip_htable.c')
-rw-r--r--sys/contrib/ipfilter/netinet/ip_htable.c408
1 files changed, 105 insertions, 303 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_htable.c b/sys/contrib/ipfilter/netinet/ip_htable.c
index e5a0ad2..aaecaa6 100644
--- a/sys/contrib/ipfilter/netinet/ip_htable.c
+++ b/sys/contrib/ipfilter/netinet/ip_htable.c
@@ -1,3 +1,5 @@
+/* $FreeBSD$ */
+
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
*
@@ -51,7 +53,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.9 2007/02/02 23:06:16 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.4 2005/11/13 15:38:37 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
@@ -101,36 +103,30 @@ iplookupop_t *op;
char name[FR_GROUPLEN];
int err, i, unit;
- unit = op->iplo_unit;
- if ((op->iplo_arg & IPHASH_ANON) == 0)
- iph = fr_existshtable(unit, op->iplo_name);
- else
- iph = NULL;
-
+ KMALLOC(iph, iphtable_t *);
if (iph == NULL) {
- KMALLOC(iph, iphtable_t *);
- if (iph == NULL) {
- ipht_nomem[op->iplo_unit]++;
- return ENOMEM;
- }
- err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
- if (err != 0) {
- KFREE(iph);
- return EFAULT;
- }
- } else {
- if ((iph->iph_flags & IPHASH_DELETE) == 0)
- return EEXIST;
+ ipht_nomem[op->iplo_unit]++;
+ return ENOMEM;
+ }
+
+ err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
+ if (err != 0) {
+ KFREE(iph);
+ return EFAULT;
}
+ unit = op->iplo_unit;
if (iph->iph_unit != unit) {
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KFREE(iph);
- }
+ KFREE(iph);
return EINVAL;
}
- if ((op->iplo_arg & IPHASH_ANON) != 0) {
+ if ((op->iplo_arg & IPHASH_ANON) == 0) {
+ if (fr_findhtable(op->iplo_unit, op->iplo_name) != NULL) {
+ KFREE(iph);
+ return EEXIST;
+ }
+ } else {
i = IPHASH_ANON;
do {
i++;
@@ -151,33 +147,24 @@ iplookupop_t *op;
iph->iph_type |= IPHASH_ANON;
}
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KMALLOCS(iph->iph_table, iphtent_t **,
- iph->iph_size * sizeof(*iph->iph_table));
- if (iph->iph_table == NULL) {
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KFREE(iph);
- }
- ipht_nomem[unit]++;
- return ENOMEM;
- }
-
- bzero((char *)iph->iph_table,
- iph->iph_size * sizeof(*iph->iph_table));
- iph->iph_masks = 0;
- iph->iph_list = NULL;
+ KMALLOCS(iph->iph_table, iphtent_t **,
+ iph->iph_size * sizeof(*iph->iph_table));
+ if (iph->iph_table == NULL) {
+ KFREE(iph);
+ ipht_nomem[unit]++;
+ return ENOMEM;
+ }
- iph->iph_ref = 1;
- iph->iph_next = ipf_htables[unit];
- iph->iph_pnext = &ipf_htables[unit];
- if (ipf_htables[unit] != NULL)
- ipf_htables[unit]->iph_pnext = &iph->iph_next;
- ipf_htables[unit] = iph;
+ bzero((char *)iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
+ iph->iph_masks = 0;
- ipf_nhtables[unit]++;
- }
+ iph->iph_next = ipf_htables[unit];
+ iph->iph_pnext = &ipf_htables[unit];
+ if (ipf_htables[unit] != NULL)
+ ipf_htables[unit]->iph_pnext = &iph->iph_next;
+ ipf_htables[unit] = iph;
- iph->iph_flags &= ~IPHASH_DELETE;
+ ipf_nhtables[unit]++;
return 0;
}
@@ -185,24 +172,22 @@ iplookupop_t *op;
/*
*/
-int fr_removehtable(unit, name)
-int unit;
-char *name;
+int fr_removehtable(op)
+iplookupop_t *op;
{
iphtable_t *iph;
- iph = fr_findhtable(unit, name);
+
+ iph = fr_findhtable(op->iplo_unit, op->iplo_name);
if (iph == NULL)
return ESRCH;
- if (iph->iph_unit != unit) {
+ if (iph->iph_unit != op->iplo_unit) {
return EINVAL;
}
if (iph->iph_ref != 0) {
- (void) fr_clearhtable(iph);
- iph->iph_flags |= IPHASH_DELETE;
- return 0;
+ return EBUSY;
}
fr_delhtable(iph);
@@ -211,106 +196,40 @@ char *name;
}
-int fr_clearhtable(iph)
+void fr_delhtable(iph)
iphtable_t *iph;
{
iphtent_t *ipe;
+ int i;
- while ((ipe = iph->iph_list) != NULL)
- if (fr_delhtent(iph, ipe) != 0)
- return 1;
- return 0;
-}
-
-
-int fr_delhtable(iph)
-iphtable_t *iph;
-{
-
- if (fr_clearhtable(iph) != 0)
- return 1;
+ for (i = 0; i < iph->iph_size; i++)
+ while ((ipe = iph->iph_table[i]) != NULL)
+ if (fr_delhtent(iph, ipe) != 0)
+ return;
- if (iph->iph_pnext != NULL)
- *iph->iph_pnext = iph->iph_next;
+ *iph->iph_pnext = iph->iph_next;
if (iph->iph_next != NULL)
iph->iph_next->iph_pnext = iph->iph_pnext;
ipf_nhtables[iph->iph_unit]--;
- return fr_derefhtable(iph);
-}
-
-
-/*
- * Delete an entry from a hash table.
- */
-int fr_delhtent(iph, ipe)
-iphtable_t *iph;
-iphtent_t *ipe;
-{
-
- if (ipe->ipe_phnext != NULL)
- *ipe->ipe_phnext = ipe->ipe_hnext;
- if (ipe->ipe_hnext != NULL)
- ipe->ipe_hnext->ipe_phnext = ipe->ipe_phnext;
-
- if (ipe->ipe_pnext != NULL)
- *ipe->ipe_pnext = ipe->ipe_next;
- if (ipe->ipe_next != NULL)
- ipe->ipe_next->ipe_pnext = ipe->ipe_pnext;
-
- switch (iph->iph_type & ~IPHASH_ANON)
- {
- case IPHASH_GROUPMAP :
- if (ipe->ipe_group != NULL)
- fr_delgroup(ipe->ipe_group, IPL_LOGIPF, fr_active);
- break;
-
- default :
- ipe->ipe_ptr = NULL;
- ipe->ipe_value = 0;
- break;
- }
-
- return fr_derefhtent(ipe);
-}
-
-
-int fr_derefhtable(iph)
-iphtable_t *iph;
-{
- int refs;
-
- iph->iph_ref--;
- refs = iph->iph_ref;
-
if (iph->iph_ref == 0) {
KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
KFREE(iph);
}
-
- return refs;
}
-int fr_derefhtent(ipe)
-iphtent_t *ipe;
+void fr_derefhtable(iph)
+iphtable_t *iph;
{
-
- ipe->ipe_ref--;
- if (ipe->ipe_ref == 0) {
- ipf_nhtnodes[ipe->ipe_unit]--;
-
- KFREE(ipe);
-
- return 0;
- }
-
- return ipe->ipe_ref;
+ iph->iph_ref--;
+ if (iph->iph_ref == 0)
+ fr_delhtable(iph);
}
-iphtable_t *fr_existshtable(unit, name)
+iphtable_t *fr_findhtable(unit, name)
int unit;
char *name;
{
@@ -323,20 +242,6 @@ char *name;
}
-iphtable_t *fr_findhtable(unit, name)
-int unit;
-char *name;
-{
- iphtable_t *iph;
-
- iph = fr_existshtable(unit, name);
- if ((iph != NULL) && (iph->iph_flags & IPHASH_DELETE) == 0)
- return iph;
-
- return NULL;
-}
-
-
size_t fr_flushhtable(op)
iplookupflush_t *op;
{
@@ -349,11 +254,8 @@ iplookupflush_t *op;
for (i = 0; i <= IPL_LOGMAX; i++) {
if (op->iplf_unit == i || op->iplf_unit == IPL_LOGALL) {
while ((iph = ipf_htables[i]) != NULL) {
- if (fr_delhtable(iph) == 0) {
- freed++;
- } else {
- iph->iph_flags |= IPHASH_DELETE;
- }
+ fr_delhtable(iph);
+ freed++;
}
}
}
@@ -385,20 +287,13 @@ iphtent_t *ipeo;
hv = IPE_HASH_FN(ipe->ipe_addr.in4_addr, ipe->ipe_mask.in4_addr,
iph->iph_size);
- ipe->ipe_ref = 1;
- ipe->ipe_hnext = iph->iph_table[hv];
- ipe->ipe_phnext = iph->iph_table + hv;
+ ipe->ipe_ref = 0;
+ ipe->ipe_next = iph->iph_table[hv];
+ ipe->ipe_pnext = iph->iph_table + hv;
if (iph->iph_table[hv] != NULL)
- iph->iph_table[hv]->ipe_phnext = &ipe->ipe_hnext;
+ iph->iph_table[hv]->ipe_pnext = &ipe->ipe_next;
iph->iph_table[hv] = ipe;
-
- ipe->ipe_next = iph->iph_list;
- ipe->ipe_pnext = &iph->iph_list;
- if (ipe->ipe_next != NULL)
- ipe->ipe_next->ipe_pnext = &ipe->ipe_next;
- iph->iph_list = ipe;
-
if ((bits >= 0) && (bits != 32))
iph->iph_masks |= 1 << bits;
@@ -416,8 +311,44 @@ iphtent_t *ipeo;
break;
}
- ipe->ipe_unit = iph->iph_unit;
- ipf_nhtnodes[ipe->ipe_unit]++;
+ ipf_nhtnodes[iph->iph_unit]++;
+
+ return 0;
+}
+
+
+/*
+ * Delete an entry from a hash table.
+ */
+int fr_delhtent(iph, ipe)
+iphtable_t *iph;
+iphtent_t *ipe;
+{
+
+ if (ipe->ipe_ref != 0)
+ return EBUSY;
+
+
+ *ipe->ipe_pnext = ipe->ipe_next;
+ if (ipe->ipe_next != NULL)
+ ipe->ipe_next->ipe_pnext = ipe->ipe_pnext;
+
+ switch (iph->iph_type & ~IPHASH_ANON)
+ {
+ case IPHASH_GROUPMAP :
+ if (ipe->ipe_group != NULL)
+ fr_delgroup(ipe->ipe_group, IPL_LOGIPF, fr_active);
+ break;
+
+ default :
+ ipe->ipe_ptr = NULL;
+ ipe->ipe_value = 0;
+ break;
+ }
+
+ KFREE(ipe);
+
+ ipf_nhtnodes[iph->iph_unit]--;
return 0;
}
@@ -448,22 +379,22 @@ void *tptr, *aptr;
/* ------------------------------------------------------------------------ */
/* Function: fr_iphmfindip */
/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */
-/* Parameters: tptr(I) - pointer to the pool to search */
-/* ipversion(I) - IP protocol version (4 or 6) */
-/* aptr(I) - pointer to address information */
+/* Parameters: tptr(I) - pointer to the pool to search */
+/* version(I) - IP protocol version (4 or 6) */
+/* aptr(I) - pointer to address information */
/* */
/* Search the hash table for a given address and return a search result. */
/* ------------------------------------------------------------------------ */
-int fr_iphmfindip(tptr, ipversion, aptr)
+int fr_iphmfindip(tptr, version, aptr)
void *tptr, *aptr;
-int ipversion;
+int version;
{
struct in_addr *addr;
iphtable_t *iph;
iphtent_t *ipe;
int rval;
- if (ipversion != 4)
+ if (version != 4)
return -1;
if (tptr == NULL || aptr == NULL)
@@ -497,7 +428,7 @@ struct in_addr *addr;
maskloop:
ips = ntohl(addr->s_addr) & msk;
hv = IPE_HASH_FN(ips, msk, iph->iph_size);
- for (ipe = iph->iph_table[hv]; (ipe != NULL); ipe = ipe->ipe_hnext) {
+ for (ipe = iph->iph_table[hv]; (ipe != NULL); ipe = ipe->ipe_next) {
if (ipe->ipe_mask.in4_addr != msk ||
ipe->ipe_addr.in4_addr != ips) {
continue;
@@ -520,133 +451,4 @@ maskloop:
return ipe;
}
-
-int fr_htable_getnext(token, ilp)
-ipftoken_t *token;
-ipflookupiter_t *ilp;
-{
- iphtent_t *node, zn, *nextnode;
- iphtable_t *iph, zp, *nextiph;
- int err;
-
- err = 0;
- iph = NULL;
- node = NULL;
- nextiph = NULL;
- nextnode = NULL;
-
- READ_ENTER(&ip_poolrw);
-
- switch (ilp->ili_otype)
- {
- case IPFLOOKUPITER_LIST :
- iph = token->ipt_data;
- if (iph == NULL) {
- nextiph = ipf_htables[(int)ilp->ili_unit];
- } else {
- nextiph = iph->iph_next;
- }
-
- if (nextiph != NULL) {
- ATOMIC_INC(nextiph->iph_ref);
- if (nextiph->iph_next == NULL)
- token->ipt_alive = 0;
- } else {
- bzero((char *)&zp, sizeof(zp));
- nextiph = &zp;
- }
- break;
-
- case IPFLOOKUPITER_NODE :
- node = token->ipt_data;
- if (node == NULL) {
- iph = fr_findhtable(ilp->ili_unit, ilp->ili_name);
- if (iph == NULL)
- err = ESRCH;
- else {
- nextnode = iph->iph_list;
- }
- } else {
- nextnode = node->ipe_next;
- }
-
- if (nextnode != NULL) {
- ATOMIC_INC(nextnode->ipe_ref);
- if (nextnode->ipe_next == NULL)
- token->ipt_alive = 0;
- } else {
- bzero((char *)&zn, sizeof(zn));
- nextnode = &zn;
- }
- break;
- default :
- err = EINVAL;
- break;
- }
-
- RWLOCK_EXIT(&ip_poolrw);
- if (err != 0)
- return err;
-
- switch (ilp->ili_otype)
- {
- case IPFLOOKUPITER_LIST :
- if (iph != NULL) {
- WRITE_ENTER(&ip_poolrw);
- fr_derefhtable(iph);
- RWLOCK_EXIT(&ip_poolrw);
- }
- token->ipt_data = nextiph;
- err = COPYOUT(nextiph, ilp->ili_data, sizeof(*nextiph));
- if (err != 0)
- err = EFAULT;
- break;
-
- case IPFLOOKUPITER_NODE :
- if (node != NULL) {
- WRITE_ENTER(&ip_poolrw);
- fr_derefhtent(node);
- RWLOCK_EXIT(&ip_poolrw);
- }
- token->ipt_data = nextnode;
- err = COPYOUT(nextnode, ilp->ili_data, sizeof(*nextnode));
- if (err != 0)
- err = EFAULT;
- break;
- }
-
- return err;
-}
-
-
-void fr_htable_iterderef(otype, unit, data)
-u_int otype;
-int unit;
-void *data;
-{
-
- if (data == NULL)
- return;
-
- if (unit < 0 || unit > IPL_LOGMAX)
- return;
-
- switch (otype)
- {
- case IPFLOOKUPITER_LIST :
- WRITE_ENTER(&ip_poolrw);
- fr_derefhtable((iphtable_t *)data);
- RWLOCK_EXIT(&ip_poolrw);
- break;
-
- case IPFLOOKUPITER_NODE :
- WRITE_ENTER(&ip_poolrw);
- fr_derefhtent((iphtent_t *)data);
- RWLOCK_EXIT(&ip_poolrw);
- break;
- default :
- break;
- }
-}
-
#endif /* IPFILTER_LOOKUP */
OpenPOWER on IntegriCloud