svn commit: r204357 - user/luigi/ipfw3-head/sys/netinet/ipfw

Luigi Rizzo luigi at FreeBSD.org
Fri Feb 26 12:40:02 UTC 2010


Author: luigi
Date: Fri Feb 26 12:40:01 2010
New Revision: 204357
URL: http://svn.freebsd.org/changeset/base/204357

Log:
  diff reduction

Modified:
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_qfq.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_dynamic.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_pfil.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c	Fri Feb 26 12:31:16 2010	(r204356)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c	Fri Feb 26 12:40:01 2010	(r204357)
@@ -316,7 +316,7 @@ heap_free(struct dn_heap *h)
  */
 
 struct dn_ht {
-        int buckets;            /* how many buckets */
+        int buckets;            /* how many buckets, really buckets - 1*/
         int entries;            /* how many entries */
         int ofs;	        /* offset of link field */
         uint32_t (*hash)(uintptr_t, int, void *arg);
@@ -338,13 +338,52 @@ dn_ht_init(struct dn_ht *ht, int buckets
 {
 	int l;
 
-	// printf("%s buckets %d ofs %d\n", __FUNCTION__, buckets, ofs);
+	/*
+	 * Notes about rounding bucket size to a power of two.
+	 * Given the original bucket size, we compute the nearest lower and
+	 * higher power of two, minus 1  (respectively b_min and b_max) because
+	 * this value will be used to do an AND with the index returned
+	 * by hash function.
+	 * To choice between these two values, the original bucket size is
+	 * compared with b_min. If the original size is greater than 4/3 b_min,
+	 * we round the bucket size to b_max, else to b_min.
+	 * This ratio try to round to the nearest power of two, advantaging
+	 * the greater size if the different between two power is relatively
+	 * big.
+	 * Rounding the bucket size to a power of two avoid the use of
+	 * module when calculating the correct bucket.
+	 * The ht->buckets variable store the bucket size - 1 to simply
+	 * do an AND between the index returned by hash function and ht->bucket
+	 * instead of a module.
+	 */
+	int b_min; /* min buckets */
+	int b_max; /* max buckets */
+	int b_ori; /* original buckets */
+
 	if (h == NULL || match == NULL) {
 		printf("--- missing hash or match function");
 		return NULL;
 	}
 	if (buckets < 1 || buckets > 65536)
 		return NULL;
+
+	b_ori = buckets;
+	/* calculate next power of 2, - 1*/
+	buckets |= buckets >> 1;
+	buckets |= buckets >> 2;
+	buckets |= buckets >> 4;
+	buckets |= buckets >> 8;
+	buckets |= buckets >> 16;
+
+	b_max = buckets; /* Next power */
+	b_min = buckets >> 1; /* Previous power */
+
+	/* Calculate the 'nearest' bucket size */
+	if (b_min * 4000 / 3000 < b_ori)
+		buckets = b_max;
+	else
+		buckets = b_min;
+
 	if (ht) {	/* see if we can reuse */
 		if (buckets <= ht->buckets) {
 			ht->buckets = buckets;
@@ -357,7 +396,10 @@ dn_ht_init(struct dn_ht *ht, int buckets
 		}
 	}
 	if (ht == NULL) {
-		l = sizeof(*ht) + buckets * sizeof(void **);
+		/* Allocate buckets + 1 entries because buckets is use to
+		 * do the AND with the index returned by hash function
+		 */
+		l = sizeof(*ht) + (buckets + 1) * sizeof(void **);
 		ht = malloc(l, M_DN_HEAP, M_NOWAIT | M_ZERO);
 	}
 	if (ht) {
@@ -408,9 +450,8 @@ dn_ht_find(struct dn_ht *ht, uintptr_t k
 	if (ht == NULL)	/* easy on an empty hash */
 		return NULL;
 	i = (ht->buckets == 1) ? 0 :
-		(ht->hash(key, flags, arg) % ht->buckets);
-	// printf("%s key %p in bucket %d entries %d\n",
-	//	__FUNCTION__, (void *)key, i, ht->entries);
+		(ht->hash(key, flags, arg) & ht->buckets);
+
 	for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) {
 		if (flags & DNHT_MATCH_PTR) {
 			if (key == (uintptr_t)p)
@@ -449,16 +490,14 @@ dn_ht_scan(struct dn_ht *ht, int (*fn)(v
 	int i, ret, found = 0;
 	void **curp, *cur, *next;
 
-	// printf("%p ht %p fn %p\n", __FUNCTION__, ht, fn);
 	if (ht == NULL || fn == NULL)
 		return 0;
-	for (i = 0; i < ht->buckets; i++) {
+	for (i = 0; i <= ht->buckets; i++) {
 		curp = &ht->ht[i];
 		while ( (cur = *curp) != NULL) {
 			next = *(void **)((char *)cur + ht->ofs);
 			ret = fn(cur, arg);
 			if (ret & DNHT_SCAN_DEL) {
-				// printf("element %p removed\n", cur);
 				found++;
 				ht->entries--;
 				*curp = next;
@@ -486,7 +525,7 @@ dn_ht_scan_bucket(struct dn_ht *ht, int 
 
 	if (ht == NULL || fn == NULL)
 		return 0;
-	if (*bucket >= ht->buckets)
+	if (*bucket > ht->buckets)
 		*bucket = 0;
 	i = *bucket;
 

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_qfq.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_qfq.c	Fri Feb 26 12:31:16 2010	(r204356)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_qfq.c	Fri Feb 26 12:40:01 2010	(r204357)
@@ -58,7 +58,7 @@ typedef	unsigned long	bitmap;
  * and the bitmap ops. Some machines have ffs
  */
 #if defined(_WIN32)
-static int fls(unsigned long n)
+int fls(unsigned int n)
 {
 	int i = 0;
 	for (i = 0; n > 0; n >>= 1, i++)

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Fri Feb 26 12:31:16 2010	(r204356)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Fri Feb 26 12:40:01 2010	(r204357)
@@ -93,6 +93,9 @@ MALLOC_DEFINE(M_DUMMYNET, "dummynet", "d
 extern	void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
 
 #ifdef SYSCTL_NODE
+
+SYSBEGIN(f4)
+
 SYSCTL_DECL(_net_inet);
 SYSCTL_DECL(_net_inet_ip);
 SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet");
@@ -151,6 +154,9 @@ SYSCTL_ULONG(_net_inet_ip_dummynet, OID_
 SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_drop,
     CTLFLAG_RD, &io_pkt_drop, 0,
     "Number of packets dropped by dummynet.");
+
+SYSEND
+
 #endif
 
 static void	dummynet_send(struct mbuf *);

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c	Fri Feb 26 12:31:16 2010	(r204356)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c	Fri Feb 26 12:40:01 2010	(r204357)
@@ -145,6 +145,8 @@ ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
 uint32_t dummy_def = IPFW_DEFAULT_RULE;
 uint32_t dummy_tables_max = IPFW_TABLES_MAX;
 
+SYSBEGIN(f3)
+
 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
     CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
@@ -180,6 +182,8 @@ SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_A
     "Deny packets with unknown IPv6 Extension Headers");
 #endif /* INET6 */
 
+SYSEND
+
 #endif /* SYSCTL_NODE */
 
 

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_dynamic.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_dynamic.c	Fri Feb 26 12:31:16 2010	(r204356)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_dynamic.c	Fri Feb 26 12:40:01 2010	(r204357)
@@ -187,6 +187,9 @@ static VNET_DEFINE(u_int32_t, dyn_max);	
 #define	V_dyn_max			VNET(dyn_max)
 
 #ifdef SYSCTL_NODE
+
+SYSBEGIN(f2)
+
 SYSCTL_DECL(_net_inet_ip_fw);
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets,
     CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0,
@@ -221,6 +224,9 @@ SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUT
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive,
     CTLFLAG_RW, &VNET_NAME(dyn_keepalive), 0,
     "Enable keepalives for dyn. rules");
+
+SYSEND
+
 #endif /* SYSCTL_NODE */
 
 

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_pfil.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_pfil.c	Fri Feb 26 12:31:16 2010	(r204356)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_pfil.c	Fri Feb 26 12:40:01 2010	(r204357)
@@ -77,6 +77,9 @@ int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
 static int ipfw_divert(struct mbuf **, int, struct ipfw_rule_ref *, int);
 
 #ifdef SYSCTL_NODE
+
+SYSBEGIN(f1)
+
 SYSCTL_DECL(_net_inet_ip_fw);
 SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, enable,
     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_enable), 0,
@@ -87,6 +90,9 @@ SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_
     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw6_enable), 0,
     ipfw_chg_hook, "I", "Enable ipfw+6");
 #endif /* INET6 */
+
+SYSEND
+
 #endif /* SYSCTL_NODE */
 
 /*
@@ -94,7 +100,7 @@ SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_
  * dummynet, divert, netgraph or other modules.
  * The packet may be consumed.
  */
-static int
+int
 ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
     struct inpcb *inp)
 {

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h	Fri Feb 26 12:31:16 2010	(r204356)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h	Fri Feb 26 12:40:01 2010	(r204357)
@@ -35,6 +35,12 @@
 
 #ifdef _KERNEL
 
+/*
+ * For platforms that do not have SYSCTL support, we wrap the
+ * SYSCTL_* into a function (one per file) to collect the values
+ * into an array at module initialization. The wrapping macros,
+ * SYSBEGIN() and SYSEND, are empty in the default case.
+ */
 #ifndef SYSBEGIN
 #define SYSBEGIN(x)
 #endif
@@ -126,8 +132,12 @@ enum {
 
 /* wrapper for freeing a packet, in case we need to do more work */
 #ifndef FREE_PKT
+#if defined(__linux__) || defined(_WIN32)
+#define FREE_PKT(m)	netisr_dispatch(-1, m)
+#else
 #define FREE_PKT(m)	m_freem(m)
 #endif
+#endif /* !FREE_PKT */
 
 /*
  * Function definitions.
@@ -253,6 +263,10 @@ int ipfw_ctl(struct sockopt *sopt);
 int ipfw_chk(struct ip_fw_args *args);
 void ipfw_reap_rules(struct ip_fw *head);
 
+/* In ip_fw_pfil */
+int ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
+     struct inpcb *inp);
+
 /* In ip_fw_table.c */
 struct radix_node;
 int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,


More information about the svn-src-user mailing list