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

Luigi Rizzo luigi at FreeBSD.org
Sun Jan 31 15:38:26 UTC 2010


Author: luigi
Date: Sun Jan 31 15:38:26 2010
New Revision: 203293
URL: http://svn.freebsd.org/changeset/base/203293

Log:
  fix a problem in the order of initialization. The callback
  new_sched can only
  be called after creating the internal flowset, so we need to
  postpone calls to si_new until after  that.
  This means that siht remains NULL until then in the case !HAVE_MASK,
  which in turn means we create the scheduler instance as the first
  packet comes in.

Modified:
  user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt	Sun Jan 31 15:19:16 2010	(r203292)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt	Sun Jan 31 15:38:26 2010	(r203293)
@@ -2,6 +2,7 @@ Notes on the internal structure of dummy
 by Riccardo Panicucci and Luigi Rizzo
 Work supported by the EC project ONELAB2
 
+
 *********
 * INDEX *
 *********
@@ -28,6 +29,12 @@ How to implement a new scheduler
 
 
 
+OPEN ISSUES
+------------------------------
+20100131 deleting RR causes infinite loop
+	presumably in the rr_free_queue() call -- seems to hang
+	forever when deleting a live flow
+------------------------------
 
 Dummynet is a traffic shaper and network emulator. Packets are
 selected by an external filter such as ipfw, and passed to the emulator

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Sun Jan 31 15:19:16 2010	(r203292)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Sun Jan 31 15:38:26 2010	(r203293)
@@ -471,7 +471,7 @@ si_destroy(void *_si, void *arg)
 /*
  * Find the scheduler instance for this packet. If we need to apply
  * a mask, do on a local copy of the flow_id to preserve the original.
- * Assume siht is always initialized.
+ * Assume siht is always initialized if we have a mask.
  */
 struct new_sch_inst *
 ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id)
@@ -482,9 +482,10 @@ ipdn_si_find(struct new_schk *s, struct 
 		flow_id_mask(&s->sch.sched_mask, &id_t);
 		return dn_ht_find(s->siht, (uintptr_t)&id_t,
 			DNHT_INSERT, s);
-	} else {
-		return (struct new_sch_inst *)s->siht;
 	}
+	if (!s->siht)
+		s->siht = si_new(0, 0, s);
+	return (struct new_sch_inst *)s->siht;
 }
 
 /* callback to flush credit for the scheduler instance */
@@ -503,7 +504,7 @@ schk_reset_credit(struct new_schk *s)
 {
 	if (s->sch.flags & DN_HAVE_MASK)
 		dn_ht_scan(s->siht, si_reset_credit, NULL);
-	else
+	else if (s->siht)
 		si_reset_credit(s->siht, NULL);
 }
 /*---- end of sch_inst hashtable ---------------------*/
@@ -672,14 +673,14 @@ schk_new(uintptr_t key, int flags, void 
 	SLIST_INIT(&s->fsk_list);
 	/* initialize the hash table or create the single instance */
 	s->fp = a->fp;	/* si_new needs this */
-	s->siht = (s->sch.flags & DN_HAVE_MASK) ?
-		dn_ht_init(NULL, s->sch.buckets,
+	if (s->sch.flags & DN_HAVE_MASK) {
+		s->siht = dn_ht_init(NULL, s->sch.buckets,
 			offsetof(struct new_sch_inst, si_next),
-			si_hash, si_match, si_new) :
-		si_new(0, 0, s);
-	if (s->siht == NULL) {
-		free(s, M_DUMMYNET);
-		return NULL;
+			si_hash, si_match, si_new);
+		if (s->siht == NULL) {
+			free(s, M_DUMMYNET);
+			return NULL;
+		}
 	}
 	s->fp = NULL;	/* mark as a new scheduler */
 	dn_cfg.schk_count++;
@@ -709,7 +710,7 @@ schk_delete_cb(void *obj, void *arg)
 	/* no more flowset pointing to us now */
 	if (s->sch.flags & DN_HAVE_MASK)
 		dn_ht_scan(s->siht, si_destroy, NULL);
-	else
+	else if (s->siht)
 		si_destroy(s->siht, NULL);
 	s->siht = NULL;
 	if (s->fp->destroy)
@@ -828,7 +829,7 @@ copy_si(struct copy_args *a, struct new_
 {
 	if (s->sch.flags & DN_HAVE_MASK)
 		dn_ht_scan(s->siht, copy_si_cb, a);
-	else
+	else if (s->siht)
 		copy_si_cb(s->siht, a);
 	return 0;
 }


More information about the svn-src-user mailing list