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