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

Luigi Rizzo luigi at FreeBSD.org
Mon Jan 18 22:39:33 UTC 2010


Author: luigi
Date: Mon Jan 18 22:39:33 2010
New Revision: 202597
URL: http://svn.freebsd.org/changeset/base/202597

Log:
  various formatting fixes

Modified:
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h	Mon Jan 18 21:56:08 2010	(r202596)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h	Mon Jan 18 22:39:33 2010	(r202597)
@@ -141,7 +141,8 @@ int heap_scan(struct dn_heap *, int (*)(
  *
  * DNHT_MATCH_PTR	during a lookup, match pointers instead
  *	of calling match(). Normally used when removing specific
- *	entries. XXX should it imply DNHT_KEY_IS_OBJ ?
+ *	entries. Does not imply KEY_IS_OBJ as the latter _is_ used
+ *	by the match function.
  *
  * DNHT_INSERT		insert the element if not found.
  *	Calls new() to allocates a new object unless

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h	Mon Jan 18 21:56:08 2010	(r202596)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h	Mon Jan 18 22:39:33 2010	(r202597)
@@ -53,14 +53,14 @@ struct dn_sched {
 	/*    + parameters attached to the template, e.g.
 	 *	default queue sizes, weights, quantum size, and so on;
 	 */
-	size_t schk_len;
+	size_t schk_datalen;
 
 	/*    + per-instance parameters, such as timestamps,
 	 *	containers for queues, etc;
 	 */
-	size_t sch_inst_len;
+	size_t si_datalen;
 
-	size_t queue_len;	/* per-queue parameters (e.g. S,F) */
+	size_t q_datalen;	/* per-queue parameters (e.g. S,F) */
 
 	SLIST_ENTRY(dn_sched) next; /* Next scheduler in the list */
 

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c	Mon Jan 18 21:56:08 2010	(r202596)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c	Mon Jan 18 22:39:33 2010	(r202597)
@@ -84,7 +84,7 @@ static struct dn_sched fifo_desc = {
 	.type = DN_SCHED_FIFO,
 	.name = "FIFO",
 
-	.sch_inst_len = sizeof(struct new_queue),
+	.si_datalen = sizeof(struct new_queue),
 
 	.enqueue = fifo_enqueue,
 	.dequeue = fifo_dequeue,

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c	Mon Jan 18 21:56:08 2010	(r202596)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c	Mon Jan 18 22:39:33 2010	(r202597)
@@ -305,8 +305,8 @@ static struct dn_sched wf2qp_desc = {
 	.name = "WF2Q+",
 	.flags = DN_MULTIQUEUE,
 
-	.sch_inst_len = sizeof(struct wf2qp_si),
-	.queue_len = sizeof(struct wf2qp_queue),
+	.si_datalen = sizeof(struct wf2qp_si),
+	.q_datalen = sizeof(struct wf2qp_queue),
 
 	.enqueue = wf2qp_enqueue,
 	.dequeue = wf2qp_dequeue,

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Mon Jan 18 21:56:08 2010	(r202596)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Mon Jan 18 22:39:33 2010	(r202597)
@@ -576,7 +576,7 @@ dummynet_io(struct mbuf **m0, int dir, s
 		goto dropit;	/* This queue/pipe does not exist! */
 	if (fs->sched == NULL)	/* should not happen */
 		goto dropit;
-	/* dn_si_find can be fast */
+	/* find scheduler instance, possibly applying mask */
 	si = ipdn_si_find(fs->sched, &(fwa->f_id));
 	if (si == NULL)
 		goto dropit;
@@ -591,13 +591,16 @@ dummynet_io(struct mbuf **m0, int dir, s
 		struct new_queue template;
 		template.si = si;
 		template.fs = fs;
-		/* XXX could be simplified if no flow_mask */
-		q = dn_ht_find(fs->qht, (uintptr_t)&(fwa->f_id),
-			DNHT_INSERT, &template);
+		if (fs->fs.flags & DN_HAVE_MASK) {
+			q = dn_ht_find(fs->qht, (uintptr_t)&(fwa->f_id),
+				DNHT_INSERT, &template);
+		} else { /* qht is simply a queue */
+			if (fs->qht == NULL)
+				fs->qht = q_new(0, 0, &template);
+			q = (struct new_queue *)fs->qht;
+		}
 		if (q == NULL)
 			goto dropit;
-	} else {
-		q = NULL;
 	}
 	if (fs->sched->fp->enqueue(si, q, m)) {
 		printf("%s dropped by enqueue\n", __FUNCTION__);

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h	Mon Jan 18 21:56:08 2010	(r202596)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h	Mon Jan 18 22:39:33 2010	(r202597)
@@ -219,5 +219,7 @@ void dummynet_task(void *context, int pe
 void dn_reschedule(void);
 
 struct new_sch_inst *ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id);
+void * q_new(uintptr_t key, int flags, void *arg);
+
 
 #endif /* _IP_DN_PRIVATE_H */

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Mon Jan 18 21:56:08 2010	(r202596)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Mon Jan 18 22:39:33 2010	(r202597)
@@ -65,6 +65,12 @@ __FBSDID("$FreeBSD$");
 #define DN_C_FS		0x08
 #define DN_C_QUEUE	0x10
 
+/* we use this argument in case of a schk_new */
+struct schk_new_arg {
+	struct dn_sched *fp;
+	struct new_sch *sch;
+};
+
 /*---- callout hooks. ----*/
 static struct callout dn_timeout;
 static struct task	dn_task;
@@ -98,9 +104,8 @@ find_sched_type(int type, char *name)
 }
 
 /*
- * Dispose a list of packet. Use an inline functions so if we
- * need to free extra state associated to a packet, this is a
- * central point to do it.
+ * Dispose a list of packet. Use a functions so if we need to do
+ * more work, this is a central point to do it.
  */
 static void dn_free_pkts(struct mbuf *mnext)
 {
@@ -130,7 +135,6 @@ flow_id_mask(struct ipfw_flow_id *mask, 
 		id->dst_ip &= mask->dst_ip;
 		id->src_ip &= mask->src_ip;
 	}
-
 	return id;
 }
 
@@ -226,13 +230,12 @@ q_match(void *obj, uintptr_t key, int fl
 /*
  * create a new queue instance for the given 'key'.
  */
-static void *
+void *
 q_new(uintptr_t key, int flags, void *arg)
 {   
-	struct ipfw_flow_id *id = (struct ipfw_flow_id *)key;
 	struct new_queue *q, *template = arg;
 	struct new_fsk *fs = template->fs;
-	int size = sizeof(*q) + fs->sched->fp->queue_len;
+	int size = sizeof(*q) + fs->sched->fp->q_datalen;
 
 	q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO);
 	if (q == NULL) {
@@ -241,7 +244,8 @@ q_new(uintptr_t key, int flags, void *ar
 	}
 
 	set_oid(&q->ni.oid, DN_QUEUE, size);
-	q->ni.id = *id;
+	if (fs->fs.flags & DN_HAVE_MASK)
+		q->ni.id = *(struct ipfw_flow_id *)key;
 	q->fs = fs;
 	q->si = template->si;
 	fs->refcnt++;
@@ -288,24 +292,22 @@ si_new(uintptr_t key, int flags, void *a
 {
 	struct new_schk *s = arg;
 	struct new_sch_inst *si;
-	int l = sizeof(*si) + s->fp->sch_inst_len;
+	int l = sizeof(*si) + s->fp->si_datalen;
 
 	si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
 	if (si == NULL)
 		goto error;
-	/* XXX note we set the length only for the initial part which
-	 * is passed up to userland.
-	 */
+	/* Set length only for the part passed up to userland. */
 	set_oid(&si->ni.oid, DN_SCH_I, sizeof(struct new_inst));
 	set_oid(&(si->dline.oid), DN_DELAY_LINE, sizeof(struct delay_line));
-	si->ni.oid.id = si->dline.oid.id = -1; /* mark outside scheduler */
+	/* mark si and dline as outside the event queue */
+	si->ni.oid.id = si->dline.oid.id = -1;
 
 	si->sched = s;
 	si->dline.si = si;
 
 	if (s->fp->new_sched) {
-		int ret;
-		ret = s->fp->new_sched(si);
+		int ret = s->fp->new_sched(si);
 		if (ret) {
 			printf("%s: new_sched error %d\n", __FUNCTION__, ret);
 			goto error;
@@ -389,7 +391,7 @@ static int
 fsk_match(void *obj, uintptr_t key, int flags, void *arg)
 {
 	struct new_fsk *fs = obj;
-	int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key :
+	int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
 		((struct new_fsk *)key)->fs.fs_nr;
 
 	return !(fs->kflags & DN_DELETE) && (fs->fs.fs_nr == i);
@@ -440,7 +442,7 @@ fsk_destroy(struct new_fsk *fs, int do_f
 		
 	fs->sched = NULL;
 	if (do_free) {
-		if (fs->qht)
+		if (fs->qht) /* only if DN_HAVE_MASK */
 			dn_ht_free(fs->qht, 0);
 		free(fs, M_DUMMYNET);
 	}
@@ -448,6 +450,20 @@ fsk_destroy(struct new_fsk *fs, int do_f
 /*----- end of flowset hashtable support -------------*/
 
 /*
+ * delete the queues in qht, consider the presence of a flow_mask
+ */
+static void
+delete_qht(struct new_fsk *fs)
+{
+	if (fs->fs.flags & DN_HAVE_MASK)
+		dn_ht_scan(fs->qht, dn_delete_queue, NULL);
+	else {
+		dn_delete_queue(fs->qht, NULL);
+		fs->qht = NULL;
+	}
+}
+
+/*
  * Destroy all flowsets in a list. Used when deleting a scheduler,
  * or for all those in fsunlinked.
  * For 'ipfw queue flush' we need a callback.
@@ -473,8 +489,7 @@ fsk_destroy_list(struct new_fsk_head *h,
 		 * If the flowset was marked delete, destroy it.
 		 * otherwise move it to fsunlinked.
 		 */
-		if (fs->qht)
-			dn_ht_scan(fs->qht, dn_delete_queue, NULL);
+		delete_qht(fs);
 		fs->sched = NULL;
 		if (fs->kflags & DN_DELETE) {
 			if (fs->qht)
@@ -521,9 +536,9 @@ reset_credit(void *_si, void *arg)
 static void
 schk_reset_credit(struct new_schk *s)
 {
-	if (s->sch.flags & DN_HAVE_MASK) {
+	if (s->sch.flags & DN_HAVE_MASK)
 		dn_ht_scan(s->siht, reset_credit, NULL);
-	} else if (s->siht)
+	else if (s->siht)
 		reset_credit(s->siht, NULL);
 }
 
@@ -585,9 +600,8 @@ copy_data_helper(void *_o, void *_arg)
 }
 
 /*
- * callback for sched delete.
- * Tell all attached flowsets to remove their queues,
- * unlink the flowsets.
+ * Callback for sched delete. Tell all attached flowsets to
+ * remove their queues, unlink the flowsets.
  */
 static int
 schk_del_cb(void *obj, void *arg)
@@ -681,7 +695,6 @@ update_fs(struct new_schk *s)
 static int
 config_pipe(struct new_pipe *p, struct dn_id *arg)
 {
-	struct new_schk *s;
 	int i;
 
 	if (p->oid.len < sizeof(*p)) {
@@ -703,21 +716,19 @@ config_pipe(struct new_pipe *p, struct d
 	p->burst *= 8 * hz;
 
 	DUMMYNET_LOCK();
- again:
-	s = locate_scheduler(i);
-	if (s == NULL) {
+	/* do it twice, base pipe and FIFO pipe */
+	for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
+	    struct new_schk *s = locate_scheduler(i);
+	    if (s == NULL) {
 		DUMMYNET_UNLOCK();
 		printf("%s sched %d not found\n", __FUNCTION__, i);
 		return EINVAL;
-	}
-	/* copy all parameters */
-	s->pipe.delay = p->delay;
-	s->pipe.bandwidth = p->bandwidth;
-	s->pipe.burst = p->burst;
-	schk_reset_credit(s);
-	if (i < DN_MAX_ID) {	/* repeat for the FIFO pipe */
-		i += DN_MAX_ID;
-		goto again;
+	    }
+	    /* copy all parameters */
+	    s->pipe.delay = p->delay;
+	    s->pipe.bandwidth = p->bandwidth;
+	    s->pipe.burst = p->burst;
+	    schk_reset_credit(s);
 	}
 	dn_cfg.id++;
 	DUMMYNET_UNLOCK();
@@ -762,42 +773,49 @@ config_fs(struct new_fs *nfs, struct dn_
 	}
 	if (!locked)
 		DUMMYNET_LOCK();
-again:
-	fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT, NULL);
-	if (fs == NULL)
-		goto done;
-	dn_cfg.id++;
-	if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0)
-		goto done; /* no change, nothing to do */
-	fs->fs = *nfs;	/* update config */
-	/*
-	 * XXX note that if we modify some scheduler-specific parameter,
-	 * such as weights, we must notify the scheduler otherwise things
-	 * might go really badly, such as sum-of-weights mismatches.
-	 */
-	s = locate_scheduler(nfs->sched_nr);
-	if (fs->sched != NULL) {
-		/* we had a scheduler before, let the flowset die
-		 * and create a new one with the new parameters.
+	do { /* exit with break when done */
+		fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT, NULL);
+		if (fs == NULL)
+			break;
+		dn_cfg.id++;
+		if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0)
+			break; /* no change, nothing to do */
+		fs->fs = *nfs;	/* update config */
+		/*
+		 * XXX note that if we modify some scheduler-specific
+		 * parameter, e.g. weights, we must notify the
+		 * scheduler otherwise things might go really badly,
+		 * such as sum-of-weights mismatches.
 		 */
-		fs->kflags |= DN_DELETE;
-		goto again;
-	}
-	if (s) {
+		s = locate_scheduler(nfs->sched_nr);
+		if (fs->sched != NULL) {
+			/* we had a scheduler before, let the flowset
+			 * die and create a new one with the new
+			 * parameters.
+			 */
+			fs->kflags |= DN_DELETE;
+			continue;
+		}
+		if (s == NULL)
+			break;
+
 		/* have a new scheduler, remove from unlinked
 		 * and add to the list of children of s
 		 */
 		SLIST_REMOVE(&dn_cfg.fsu, fs, new_fsk, sch_chain);
 		fs->sched = s;
 		SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain);
-		if (s->fp->flags & DN_MULTIQUEUE)
+		/* only create the hash table if the scheduler supports
+		 * multiple queues and we have a flow mask.
+		 */
+		if (s->fp->flags & DN_MULTIQUEUE &&
+			    fs->fs.flags & DN_HAVE_MASK)
 			fs->qht = dn_ht_init(NULL, nfs->buckets,
-					offsetof(struct new_queue, q_next),
-					q_hash, q_match, q_new);
+				offsetof(struct new_queue, q_next),
+				q_hash, q_match, q_new);
 		if (s->fp->new_fsk)
 			s->fp->new_fsk(fs);
-	}
-done:
+	} while (0);
 	if (!locked)
 		DUMMYNET_UNLOCK();
 	return fs;
@@ -808,32 +826,33 @@ done:
  * For !MULTIQUEUE schedulers, also set up the flowset.
  */
 static int
-config_sched(struct new_sch *nsch, struct dn_id *arg)
+config_sched(struct new_sch *_nsch, struct dn_id *arg)
 {
 	struct new_schk *s;
-	struct dn_sched *fp;
+	struct schk_new_arg a; /* argument for schk_new */
 	struct new_fsk_head *pending = NULL;
 	int i, notify_fs = 0;
 
-	if (nsch->oid.len != sizeof(*nsch)) {
+	a.sch = _nsch;
+	if (a.sch->oid.len != sizeof(*a.sch)) {
 		printf("%s: bad sched len\n", __FUNCTION__);
 		return EINVAL;
 	}
-	i = nsch->sched_nr;
+	i = a.sch->sched_nr;
 	if (i <= 0 || i >= DN_MAX_ID)
 		return EINVAL;
 	/* XXX other sanity checks */
 	DUMMYNET_LOCK();
 again: /* run twice, for wfq and fifo */
-	fp = find_sched_type(nsch->oid.subtype, nsch->type);
-	if (fp == NULL) {
+	a.fp = find_sched_type(a.sch->oid.subtype, a.sch->type);
+	if (a.fp == NULL) {
 		DUMMYNET_UNLOCK();
-		printf("invalid scheduler type %d\n", nsch->oid.subtype);
+		printf("invalid scheduler type %s %d\n",
+			a.sch->type, a.sch->oid.subtype);
 		return EINVAL;
 	}
-	nsch->oid.subtype = fp->type;
-	s = dn_ht_find(dn_cfg.schedhash, (uintptr_t)nsch,
-		DNHT_KEY_IS_OBJ | DNHT_INSERT, fp);
+	a.sch->oid.subtype = a.fp->type;
+	s = dn_ht_find(dn_cfg.schedhash, i, DNHT_INSERT, &a);
 	if (s == NULL) {
 		DUMMYNET_UNLOCK();
 		printf("cannot allocate scheduler\n");
@@ -843,19 +862,17 @@ again: /* run twice, for wfq and fifo */
 	notify_fs = 0;
 	if (s->fp == NULL) { /* new scheduler, nothing to clean up */
 		notify_fs = 1;
-	} else if (s->fp != fp) {
+	} else if (s->fp != a.fp) {
 		printf("sched %d type changed from %s to %s"
 			" let it drain and reallocate\n",
-			i, s->fp->name, fp->name);
+			i, s->fp->name, a.fp->name);
 		/* mark delete so it won't be matched.
 		 * XXX todo: make it die when its queues are done.
 		 * XXX otherwise do a real delete.
-		 * XXX MISSING:
-		 * The flowsets are still linked to the old scheduler.
-		 * we should clone the flowsets, put them in the
-		 * fsunlinked list, and mark the old flowsets as DELETE,
-		 * so they die as the queues drain out. We must postpone
-		 * the cloning to after the new scheduler has been created.
+		 * XXX Reconfiguration should be done differently,
+		 * removing packets from the old scheduler and
+		 * requeueing to the new one. Otherwise we can have
+		 * reordering and unwanted effects.
 		 */
 		s->kflags |= DN_DELETE;
 		notify_fs = 1;
@@ -863,7 +880,7 @@ again: /* run twice, for wfq and fifo */
 		goto again;
 	}
 	/* complete initialization */
-	s->fp = fp;
+	s->fp = a.fp;
 	s->cfg = arg;
 	// XXX schk_reset_credit(s);
 	/* create the internal flowset if needed */
@@ -884,6 +901,7 @@ again: /* run twice, for wfq and fifo */
 		s->fp->config(s, 1);
 	if (pending) {
 		struct new_fsk *fs;
+		/* XXX should do the requeue here */
 		/* mark and clone flowsets for the old scheduler */
 		SLIST_FOREACH(fs, pending, sch_chain) {
 			int dying = fs->kflags & DN_DELETE;
@@ -897,8 +915,8 @@ again: /* run twice, for wfq and fifo */
 		update_fs(s);
 	if (i < DN_MAX_ID) { /* update the FIFO instance */
 		i += DN_MAX_ID;
-		nsch->sched_nr = i;
-		nsch->oid.subtype = DN_SCHED_FIFO;
+		a.sch->sched_nr = i;
+		a.sch->oid.subtype = DN_SCHED_FIFO;
 		goto again;
 	}
 	DUMMYNET_UNLOCK();
@@ -968,8 +986,9 @@ config_profile(struct new_profile *pf, s
 static int
 del_fs(int i)
 {
-	struct new_fsk *fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
+	struct new_fsk *fs;
 
+	fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
 	printf("%s fs %d found %p\n", __FUNCTION__, i, fs);
 	if (fs == NULL)
 		return EINVAL;
@@ -983,7 +1002,9 @@ del_fs(int i)
 static int
 del_schk(int i)
 {
-	struct new_schk *s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
+	struct new_schk *s;
+
+	s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
 	printf("%s sched %d %p\n", __FUNCTION__, i, s);
 	if (s) {
 		schk_del_cb(s, NULL);
@@ -1031,9 +1052,9 @@ do_config(void *p, int l)
 				/* delete base and derived schedulers */
 				if ( (err = del_schk(o->id)) )
 					break;
-				if ( (err = del_schk(o->id + DN_MAX_ID)) )
-					break;
+				err = del_schk(o->id + DN_MAX_ID);
 				break;
+
 			default:
 				printf("invalid delete type %d\n",
 					o->subtype);
@@ -1043,7 +1064,6 @@ do_config(void *p, int l)
 			case DN_FS:
 				err = (o->id < 1 || o->id >= DN_MAX_ID) ?
 					EINVAL : del_fs(o->id) ;
-					break;
 				break;
 			}
 			break;
@@ -1075,6 +1095,7 @@ do_config(void *p, int l)
 	}
 	return err;
 }
+
 static int
 compute_space(struct dn_id *cmd, int *to_copy)
 {
@@ -1155,6 +1176,7 @@ dummynet_get(struct sockopt *sopt)
 	/* start copying other objects */
 	{
 		struct copy_args a;
+
 		a.start = &buf;
 		a.end = end;
 		a.flags = to_copy;
@@ -1170,7 +1192,8 @@ dummynet_get(struct sockopt *sopt)
 }
 
 /*
- * Handler for the various dummynet socket options (get, flush, config, del)
+ * Handler for the various dummynet socket options
+ * (get, flush, config, del)
  */
 static int
 ip_dn_ctl(struct sockopt *sopt)
@@ -1226,20 +1249,14 @@ ip_dn_ctl(struct sockopt *sopt)
 	if (p != NULL)
 		free(p, M_TEMP);
 
-    return error ;
+	return error ;
 }
 
 /*------------------------------------------------------------
  * Scheduler hash. When searching by index we pass sched_nr,
  * otherwise we pass struct new_sch * which is the first field in
  * struct new_schk so we can cast between the two. We use this trick
- * because in the create phase we need to pass an additional argument
- * (struct dn_sched *)and the hash table API does not support that.
- * To work around the problem, we pass a struct new_sch *, store the
- * struct dn_sched * in sch->oid.id, and set DNHT_KEY_IS_OBJ but
- * not
- * XXX the way to remove this restriction is adding an argument to
- * the 'find' call, which is passed to the various functions.
+ * because in the create phase (but it should be fixed).
  */
 static int
 schk_hash(uintptr_t key, int flags, void *_arg)
@@ -1264,25 +1281,23 @@ schk_match(void *obj, uintptr_t key, int
  * a new object or a previously existing one.
  */
 static void *
-schk_new(uintptr_t key, int flags, void *_fp)
+schk_new(uintptr_t key, int flags, void *arg)
 {
+	struct schk_new_arg *a = arg;
 	struct new_schk *s;
-	struct new_sch *sch = (struct new_sch *)key;
-	int l;
+	int l = sizeof(*s) +a->fp->schk_datalen;
 
-	l = sizeof(*s) + ((struct dn_sched *)_fp)->schk_len;
-	
 	s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
 	if (s == NULL)
 		return NULL;
 	set_oid(&s->pipe.oid, DN_PIPE, sizeof(s->pipe));
-	s->sch = *sch; // copy initial values
-	s->pipe.pipe_nr = sch->sched_nr;
+	s->sch = *a->sch; // copy initial values
+	s->pipe.pipe_nr = s->sch.sched_nr;
 	SLIST_INIT(&s->fsk_list);
 	/* initialize the hash table if needed. Otherwise,
 	 * ht points to the single instance we own
 	 */
-	if (sch->flags & DN_HAVE_MASK) {
+	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);
@@ -1304,7 +1319,6 @@ ip_dn_init(void)
 
 	/* create hash tables for schedulers and flowsets.
 	 * In both we search by key and by pointer.
-	 * Insertion in schedhash uses externally allocated objects.
 	 */
 	dn_cfg.schedhash = dn_ht_init(NULL, dn_cfg.hash_size,
 		offsetof(struct new_schk, schk_next),


More information about the svn-src-user mailing list