svn commit: r202407 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet sys/netinet/ipfw

Luigi Rizzo luigi at FreeBSD.org
Fri Jan 15 18:31:45 UTC 2010


Author: luigi
Date: Fri Jan 15 18:31:44 2010
New Revision: 202407
URL: http://svn.freebsd.org/changeset/base/202407

Log:
  move profile to a better place.
  fix printing of queue parameters

Modified:
  user/luigi/ipfw3-head/sbin/ipfw/dummynet.c
  user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h
  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/sbin/ipfw/dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c	Fri Jan 15 17:55:18 2010	(r202406)
+++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c	Fri Jan 15 18:31:44 2010	(r202407)
@@ -58,7 +58,7 @@ static struct _s_x dummynet_params[] = {
 	{ "proto",		TOK_PROTO },
 	{ "weight",		TOK_WEIGHT },
 	{ "all",		TOK_ALL },
-	//{ "mask",		TOK_MASK },
+	{ "mask",		TOK_MASK }, /* alias for both */
 	{ "sched_mask",		TOK_SCHED_MASK },
 	{ "flow_mask",		TOK_FLOW_MASK },
 	{ "droptail",		TOK_DROPTAIL },
@@ -68,7 +68,7 @@ static struct _s_x dummynet_params[] = {
 	{ "bandwidth",		TOK_BW },
 	{ "delay",		TOK_DELAY },
 	{ "pipe",		TOK_PIPE },
-	{ "queue",		TOK_FLOWSET },
+	{ "queue",		TOK_QUEUE },
 	{ "flowset",		TOK_FLOWSET },
 	{ "sched",		TOK_SCHED },
 	{ "pri",		TOK_PRI },
@@ -245,9 +245,10 @@ list_queues(struct dn_flow_set *fs, stru
 			    align_uint64(&q[l].F));
 	}
 }
+#endif
 
 static void
-print_flowset_parms(struct dn_flow_set *fs, char *prefix)
+print_flowset_parms(struct new_fs *fs, char *prefix)
 {
 	int l;
 	char qs[30];
@@ -255,7 +256,7 @@ print_flowset_parms(struct dn_flow_set *
 	char red[90];	/* Display RED parameters */
 
 	l = fs->qsize;
-	if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
+	if (fs->flags & DN_QSIZE_IS_BYTES) {
 		if (l >= 8192)
 			sprintf(qs, "%d KB", l / 1024);
 		else
@@ -266,6 +267,7 @@ print_flowset_parms(struct dn_flow_set *
 		sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
 	else
 		plr[0] = '\0';
+#if 0
 	if (fs->flags_fs & DN_IS_RED)	/* RED parameters */
 		sprintf(red,
 		    "\n\t %cRED w_q %f min_th %d max_th %d max_p %f",
@@ -275,14 +277,16 @@ print_flowset_parms(struct dn_flow_set *
 		    SCALE_VAL(fs->max_th),
 		    1.0 * fs->max_p / (double)(1 << SCALE_RED));
 	else
+#endif
 		sprintf(red, "droptail");
 
 	printf("%s %s%s %d queues (%d buckets) %s\n",
-	    prefix, qs, plr, fs->rq_elements, fs->rq_size, red);
+	    prefix, qs, plr, fs->oid.id, fs->buckets, red);
+	prefix[0] = '\0';
 }
 
 static void
-print_extra_delay_parms(struct dn_pipe *p)
+print_extra_delay_parms(struct new_profile *p)
 {
 	double loss;
 	if (p->samples_no <= 0)
@@ -293,7 +297,6 @@ print_extra_delay_parms(struct dn_pipe *
 	printf("\t profile: name \"%s\" loss %f samples %d\n",
 		p->name, loss, p->samples_no);
 }
-#endif
 
 static void
 flush_buf(char *buf)
@@ -311,11 +314,10 @@ flush_buf(char *buf)
 static void
 list_pipes(struct dn_id *oid, struct dn_id *end, int *filt)
 {
-    char buf[80];	/* pending buffer */
+    char buf[160];	/* pending buffer */
     buf[0] = '\0';
 
     for (; oid != end; oid = O_NEXT(oid, oid->len)) {
-	/* XXX check oid->len */
 	if (oid->len < sizeof(*oid))
 		errx(1, "invalid oid len %d\n", oid->len);
 
@@ -342,14 +344,15 @@ list_pipes(struct dn_id *oid, struct dn_
 		sprintf(burst, "%ju Byte\n", p->burst);
 	    sprintf(buf, "%05d: %s %4d ms burst %s",
 		p->pipe_nr, bwbuf, p->delay, burst);
-	    //	print_flowset_parms(&(p->fs), prefix);
-	    // print_extra_delay_parms(p);
 	    }
 	    break;
+
 	case DN_FS:
-	    flush_buf(buf);
-	    printf("XXX flowset unimplemented\n");
+	    print_flowset_parms((struct new_fs *)oid, buf);
 	    break;
+	case DN_PROFILE:
+	    flush_buf(buf);
+	    print_extra_delay_parms((struct new_profile *)oid);
 	}
     }
     flush_buf(buf);
@@ -863,10 +866,12 @@ ipfw_config_pipe(int ac, char **av)
 		case TOK_BUCKETS:
 			NEED(fs, "buckets is only for pipes or flowsets");
 			NEED1("buckets needs argument\n");
-			// XXX fs->rq_size = strtoul(av[0], NULL, 0);
+			fs->buckets = strtoul(av[0], NULL, 0);
 			ac--; av++;
 			break;
 
+		case TOK_FLOW_MASK:
+		case TOK_SCHED_MASK:
 		case TOK_MASK:
 			NEED(mask, "tok_mask");
 			NEED1("mask needs mask specifier\n");

Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h	Fri Jan 15 17:55:18 2010	(r202406)
+++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h	Fri Jan 15 18:31:44 2010	(r202407)
@@ -119,12 +119,10 @@ struct new_pipe {
 	 * The kernel converts this back and forth to bits/tick and ticks.
 	 * XXX what about burst ?
 	 */
-	int32_t pipe_nr ;           /* N, number               */
-	int bandwidth;              /* B, really, bits/tick.   */
-	int delay ;                 /* D, really, ticks        */
-	uint64_t burst; /* burst size, scaled. bits*Hz  XXX */
-
-	struct new_profile *profile;
+	int32_t		pipe_nr;
+	int		bandwidth;	/* bit/s or bits/tick.   */
+	int		delay;		/* ms and ticks */
+	uint64_t	burst;		/* scaled. bits*Hz  XXX */
 };
 
 /*

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Fri Jan 15 17:55:18 2010	(r202406)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Fri Jan 15 18:31:44 2010	(r202407)
@@ -287,16 +287,16 @@ transmit_event(struct mq *q, struct dela
  * in milliseconds so we need to divide by 1000.
  */
 static uint64_t
-extra_bits(struct mbuf *m, struct new_pipe *p)
+extra_bits(struct mbuf *m, struct new_schk *s)
 {
 	int index;
 	uint64_t bits;
-	struct new_profile *pf = p->profile;
+	struct new_profile *pf = s->profile;
 
 	if (!pf || pf->samples_no == 0)
 		return 0;
 	index  = random() % pf->samples_no;
-	bits = div64((uint64_t)pf->samples[index] * p->bandwidth, 1000);
+	bits = div64((uint64_t)pf->samples[index] * s->pipe.bandwidth, 1000);
 	if (index >= pf->loss_level) {
 		struct dn_pkt_tag *dt = dn_tag_get(m);
 		if (dt)
@@ -339,7 +339,7 @@ serve_sched(struct mq *q, struct new_sch
 		uint64_t len_scaled;
 		done++;
 		len_scaled = bw == 0 ? 0 : hz *
-		    (m->m_pkthdr.len * 8 + extra_bits(m, &s->pipe));
+		    (m->m_pkthdr.len * 8 + extra_bits(m, s));
 		si->credit -= len_scaled;
 		/* Move packet in the delay line */
 		dn_tag_get(m)->output_time += s->pipe.delay ;

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h	Fri Jan 15 17:55:18 2010	(r202406)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h	Fri Jan 15 18:31:44 2010	(r202407)
@@ -115,7 +115,7 @@ struct delay_line {
  * there is no flow_mask).
  * When we remove a flowset, mark as DN_DELETE so it can go away
  * when the hash table will be empty.
- * XXX refcnt is redundant.
+ * XXX refcnt is redundant, the info is already in qht->entries
  */
 struct new_fsk { /* kernel side of a flowset */
 	struct new_fs fs;
@@ -160,6 +160,7 @@ struct new_schk {
 	int kflags;
 	struct dn_sched *fp;	/* Pointer to scheduler functions */
 	struct new_pipe pipe;	/* the pipe is embedded */
+	struct new_profile *profile;
 	struct dn_id *cfg; /* extra config arguments */
 
 	SLIST_ENTRY(new_schk) schk_next;  /* hash chain list */

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Fri Jan 15 17:55:18 2010	(r202406)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Fri Jan 15 18:31:44 2010	(r202407)
@@ -90,7 +90,7 @@ dn_reschedule(void)
 static struct dn_sched *
 find_sched_type(int type, char *name)
 {
-	struct dn_sched *d = NULL;
+	struct dn_sched *d;
 
 	SLIST_FOREACH(d, &dn_cfg.schedlist, next) {
 		if (d->type == type || (name && !strcmp(d->name, name)))
@@ -168,9 +168,10 @@ static int
 flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2)
 {
 	int is_v6 = IS_IP6_FLOW_ID(id1);
+
 	if (is_v6 != IS_IP6_FLOW_ID(id2))
 		return 1; /* a ipv4 and a ipv6 flow */
-	    
+
 	if (!is_v6 && id1->dst_ip == id2->dst_ip &&
 	    id1->src_ip == id2->src_ip &&
 	    id1->dst_port == id2->dst_port &&
@@ -204,6 +205,7 @@ q_hash(uintptr_t key, int flags, void *a
 	struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
 		&((struct new_queue *)key)->ni.id :
 		(struct ipfw_flow_id *)key;
+
 	return flow_id_hash(id);
 }
 
@@ -263,22 +265,19 @@ si_hash(uintptr_t key, int flags, void *
 	struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
 		&((struct new_sch_inst *)key)->ni.id :
 		(struct ipfw_flow_id *)key;
+
 	return flow_id_hash(id);
 }
 
 static int
 si_match(void *obj, uintptr_t key, int flags, void *arg)
 {
-	struct new_sch_inst *o;
+	struct new_sch_inst *o = obj;
 	struct ipfw_flow_id *id2;
 
-	if (flags & DNHT_KEY_IS_OBJ) {
-		/* compare pointers */
-		id2 = &((struct new_sch_inst *)key)->ni.id;
-	} else {
-		id2 = (struct ipfw_flow_id *)key;
-	}
-	o = (struct new_sch_inst *)obj;
+	id2 = (flags & DNHT_KEY_IS_OBJ) ?
+		&((struct new_sch_inst *)key)->ni.id :
+		(struct ipfw_flow_id *)key;
 	return flow_id_cmp(&o->ni.id,  id2) == 0;
 }
 
@@ -361,7 +360,7 @@ ipdn_si_find(struct new_schk *s, struct 
 {
 	struct new_sch_inst *si;
 
-	if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) {
+	if (!(s->sch.flags & DN_HAVE_MASK)) {
 		if (s->siht == NULL)
 			s->siht = si_new((uintptr_t)id, 0, s);
 		si = (struct new_sch_inst *)s->siht;
@@ -394,6 +393,7 @@ fsk_match(void *obj, uintptr_t key, int 
 	struct new_fsk *fs = obj;
 	int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key :
 		((struct new_fsk *)key)->fs.fs_nr;
+
 	return !(fs->kflags & DN_DELETE) && (fs->fs.fs_nr == i);
 }
 
@@ -404,6 +404,7 @@ fsk_new(uintptr_t key, int flags, void *
 
 	fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO);
 	if (fs) {
+		set_oid(&fs->fs.oid, DN_FS, 0, sizeof(fs->fs));
 		dn_cfg.fsk_count++;
 		SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
 	}
@@ -523,9 +524,14 @@ static int
 copy_obj(char **start, char *end, void *_o)
 {
 	struct dn_id *o = _o;
+	int have = end - *start;
 
-	if (end - *start < o->len)
+	if (have < o->len) {
+		printf("%s overflow type %d have %d need %d\n",
+			__FUNCTION__, o->type, have, o->len);
 		return 1;
+	}
+	printf("%s type %d len %d\n", __FUNCTION__, o->type, o->len);
 	bcopy(_o, *start, o->len);
 	*start += o->len;
 	return 0;
@@ -542,12 +548,15 @@ struct copy_args {
 static int
 copy_data_helper(void *_o, void *_arg)
 {
-	struct copy_args *a = (struct copy_args *)_arg;
+	struct copy_args *a = _arg;
+
 	if (a->type == DN_SCH) {	/* scanning schedulers */
 		struct new_schk *s = _o;
 		if (a->flags & DN_C_PIPE) {
 			if (copy_obj(a->start, a->end, &s->pipe))
 				return HEAP_SCAN_END;
+			if (s->fs && copy_obj(a->start, a->end, &s->fs->fs))
+				return HEAP_SCAN_END;
 		}
 		if (a->flags & DN_C_SCH) {
 			if (copy_obj(a->start, a->end, &s->sch))
@@ -556,19 +565,14 @@ copy_data_helper(void *_o, void *_arg)
 		if (a->flags & DN_C_SCH_INST) {
 			printf("XXX todo: scan sched instances\n");
 		}
-		if (a->flags & DN_C_FS) {
-			struct new_fsk *fs = _o;
-			if (copy_obj(a->start, a->end, &fs->fs))
-				return HEAP_SCAN_END;
-		}
-		if (a->flags & DN_C_QUEUE) {
-			printf("XXX todo: scan queue instances\n");
-		}
 	}
 	if (a->type == DN_FS) {	/* scanning flowsets */
 		struct new_fsk *fs = _o;
+		struct new_fs *ufs =
+		    (struct new_fs *)(*a->start);
 		if (copy_obj(a->start, a->end, &fs->fs))
 			return HEAP_SCAN_END;
+		ufs->oid.id = fs->refcnt;
 	}
 	return 0;
 }
@@ -827,6 +831,9 @@ again: /* run twice, for wfq and fifo */
 		fs.fs_nr = i + DN_MAX_ID;
 		fs.sched_nr = i;
 		s->fs = config_fs(&fs, NULL, 1 /* locked */);
+		printf("+++ sched %d fs %p len %d ty %d\n",
+			s->sch.sched_nr,
+			s->fs, s->fs->fs.oid.len, s->fs->fs.oid.type);
 	}
 	/* call init function after the flowset is created */
 	if (s->fp->config)
@@ -850,7 +857,6 @@ static int
 config_profile(struct new_profile *pf, struct dn_id *arg)
 {
 	struct new_schk *s;
-	struct new_pipe *p;
 	int i;
 
 	if (pf->oid.len < sizeof(*pf)) {
@@ -870,16 +876,15 @@ config_profile(struct new_profile *pf, s
 		printf("%s: no scheduler %d\n", __FUNCTION__, i);
 		return EINVAL;
 	}
-	p = &s->pipe;
 	dn_cfg.id++;
 	/*
 	 * If we had a profile and the new one does not fit,
 	 * or it is deleted, then we need to free memory.
 	 */
-	if (p->profile && (pf->samples_no == 0 ||
-			p->profile->oid.len < pf->oid.len)) {
-		free(p->profile, M_DUMMYNET);
-		p->profile = NULL;
+	if (s->profile && (pf->samples_no == 0 ||
+			s->profile->oid.len < pf->oid.len)) {
+		free(s->profile, M_DUMMYNET);
+		s->profile = NULL;
 	}
 	/*
 	 * if we have a new profile, possibly allocate memory
@@ -887,20 +892,20 @@ config_profile(struct new_profile *pf, s
 	 */
 	if (pf->samples_no > 0) {
 		int olen;
-		if (p->profile == NULL)
-			p->profile = malloc(pf->oid.len,
+		if (s->profile == NULL)
+			s->profile = malloc(pf->oid.len,
 			    M_DUMMYNET, M_NOWAIT | M_ZERO);
-		if (p->profile == NULL) {
+		if (s->profile == NULL) {
 			DUMMYNET_UNLOCK();
 			printf("%s: no memory\n", __FUNCTION__);
 			return ENOMEM;
 		}
 		/* preserve larger length */
-		olen = p->profile->oid.len;
+		olen = s->profile->oid.len;
 		if (olen < pf->oid.len)
 			olen = pf->oid.len;
-		bcopy(pf, p->profile, pf->oid.len);
-		p->profile->oid.len = olen;
+		bcopy(pf, s->profile, pf->oid.len);
+		s->profile->oid.len = olen;
 	}
 	DUMMYNET_UNLOCK();
 	return 0;
@@ -1018,23 +1023,31 @@ do_config(void *p, int l)
 static int
 compute_space(struct dn_id *cmd, int *to_copy)
 {
-	int need;
+	int x = 0, need = 0;
 
-	*to_copy = 0;
 	switch (cmd->subtype) {
 	default:
 		return -1;
 	case DN_SCH:	/* pipe show */
-		*to_copy = DN_C_SCH | DN_C_PIPE | DN_C_SCH_INST | DN_C_QUEUE;
-		need = dn_cfg.schk_count *
-			(sizeof(struct new_sch) + sizeof(struct new_pipe));
-		need += dn_cfg.si_count * sizeof(struct new_inst);
+		x = DN_C_SCH | DN_C_PIPE | DN_C_FS |
+			DN_C_SCH_INST | DN_C_QUEUE;
 		break;
 	case DN_FS:	/* queue show */
-		*to_copy = DN_C_FS | DN_C_QUEUE;
-		need = dn_cfg.fsk_count * (sizeof(struct new_fs));
+		x = DN_C_FS | DN_C_QUEUE;
 		break;
 	}
+	*to_copy = x;
+	if (x & DN_C_SCH)
+		need += dn_cfg.schk_count * sizeof(struct new_sch);
+	if (x & DN_C_FS)
+		need += dn_cfg.fsk_count * sizeof(struct new_fs);
+	if (x & DN_C_PIPE)
+		need += dn_cfg.schk_count * sizeof(struct new_pipe);
+	/* XXX queue space might be variable */
+	if (x & DN_C_QUEUE)
+		need += dn_cfg.queue_count * sizeof(struct new_queue);
+	if (x & DN_C_SCH_INST)
+		need += dn_cfg.si_count * sizeof(struct new_inst);
 	return need;
 }
 
@@ -1092,8 +1105,10 @@ dummynet_get(struct sockopt *sopt)
 		a.flags = to_copy;
 		a.type = DN_SCH;
 		dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
+#if 0 // XXX temporarily disable
 		a.type = DN_FS;
 		dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
+#endif
 	}
 	DUMMYNET_UNLOCK();
 	error = sooptcopyout(sopt, start, buf - start);


More information about the svn-src-user mailing list