svn commit: r202710 - in user/luigi/ipfw3-head: sbin/ipfw
sys/netinet sys/netinet/ipfw
Luigi Rizzo
luigi at FreeBSD.org
Wed Jan 20 18:28:24 UTC 2010
Author: luigi
Date: Wed Jan 20 18:28:24 2010
New Revision: 202710
URL: http://svn.freebsd.org/changeset/base/202710
Log:
continue debugging in presence of sched and flow mask:
In the kernel:
- fix deletion of multiple scheduler instances
by making the callback return DNHT_SCAN_DEL
- remove some debugging messages;
- copy more objects in dummynet_get()
In userland:
- fix parser so that flags are passed correctly when a mask is specified;
- improve printing of 'ipfw pipe show' and 'ipfw sched show'
- remove some debugging messages
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/dn_heap.c
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 Wed Jan 20 18:22:56 2010 (r202709)
+++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Wed Jan 20 18:28:24 2010 (r202710)
@@ -137,115 +137,77 @@ sort_q(void *arg, const void *pa, const
res = 1;
return (int)(rev ? res : -res);
}
+#endif
static void
-list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
+print_mask(struct ipfw_flow_id *id)
+{
+ if (!IS_IP6_FLOW_ID(id)) {
+ printf(" "
+ "mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
+ id->proto,
+ id->src_ip, id->src_port,
+ id->dst_ip, id->dst_port);
+
+ printf("BKT Prot ___Source IP/port____ "
+ "____Dest. IP/port____ "
+ "Tot_pkt/bytes Pkt/Byte Drp\n");
+ } else {
+ char buf[255];
+ printf("\n mask: proto: 0x%02x, flow_id: 0x%08x, ",
+ id->proto, id->flow_id6);
+ inet_ntop(AF_INET6, &(id->src_ip6), buf, sizeof(buf));
+ printf("%s/0x%04x -> ", buf, id->src_port);
+ inet_ntop(AF_INET6, &(id->dst_ip6), buf, sizeof(buf));
+ printf("%s/0x%04x\n", buf, id->dst_port);
+
+ printf("BKT ___Prot___ _flow-id_ "
+ "______________Source IPv6/port_______________ "
+ "_______________Dest. IPv6/port_______________ "
+ "Tot_pkt/bytes Pkt/Byte Drp\n");
+ }
+}
+
+static void
+list_queue(struct new_inst *ni)
{
- int l;
- int index_printed, indexes = 0;
char buff[255];
struct protoent *pe;
+ struct in_addr ina;
+ struct ipfw_flow_id *id = &ni->fid;
- if (fs->rq_elements == 0)
- return;
-
- if (co.do_sort != 0)
- qsort_r(q, fs->rq_elements, sizeof *q, NULL, sort_q);
-
- /* Print IPv4 flows */
- index_printed = 0;
- for (l = 0; l < fs->rq_elements; l++) {
- struct in_addr ina;
-
+ pe = getprotobynumber(id->proto);
/* XXX: Should check for IPv4 flows */
- if (IS_IP6_FLOW_ID(&(q[l].id)))
- continue;
-
- if (!index_printed) {
- index_printed = 1;
- if (indexes > 0) /* currently a no-op */
- printf("\n");
- indexes++;
- printf(" "
- "mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
- fs->flow_mask.proto,
- fs->flow_mask.src_ip, fs->flow_mask.src_port,
- fs->flow_mask.dst_ip, fs->flow_mask.dst_port);
-
- printf("BKT Prot ___Source IP/port____ "
- "____Dest. IP/port____ "
- "Tot_pkt/bytes Pkt/Byte Drp\n");
- }
-
- printf("%3d ", q[l].hash_slot);
- pe = getprotobynumber(q[l].id.proto);
+ printf("%3d ", ni->oid.id);
+ if (!IS_IP6_FLOW_ID(id)) {
if (pe)
printf("%-4s ", pe->p_name);
else
- printf("%4u ", q[l].id.proto);
- ina.s_addr = htonl(q[l].id.src_ip);
+ printf("%4u ", id->proto);
+ ina.s_addr = htonl(id->src_ip);
printf("%15s/%-5d ",
- inet_ntoa(ina), q[l].id.src_port);
- ina.s_addr = htonl(q[l].id.dst_ip);
+ inet_ntoa(ina), id->src_port);
+ ina.s_addr = htonl(id->dst_ip);
printf("%15s/%-5d ",
- inet_ntoa(ina), q[l].id.dst_port);
- printf("%4llu %8llu %2u %4u %3u\n",
- align_uint64(&q[l].tot_pkts),
- align_uint64(&q[l].tot_bytes),
- q[l].len, q[l].len_bytes, q[l].drops);
- if (co.verbose)
- printf(" S %20llu F %20llu\n",
- align_uint64(&q[l].S), align_uint64(&q[l].F));
- }
-
- /* Print IPv6 flows */
- index_printed = 0;
- for (l = 0; l < fs->rq_elements; l++) {
- if (!IS_IP6_FLOW_ID(&(q[l].id)))
- continue;
-
- if (!index_printed) {
- index_printed = 1;
- if (indexes > 0)
- printf("\n");
- indexes++;
- printf("\n mask: proto: 0x%02x, flow_id: 0x%08x, ",
- fs->flow_mask.proto, fs->flow_mask.flow_id6);
- inet_ntop(AF_INET6, &(fs->flow_mask.src_ip6),
- buff, sizeof(buff));
- printf("%s/0x%04x -> ", buff, fs->flow_mask.src_port);
- inet_ntop( AF_INET6, &(fs->flow_mask.dst_ip6),
- buff, sizeof(buff) );
- printf("%s/0x%04x\n", buff, fs->flow_mask.dst_port);
-
- printf("BKT ___Prot___ _flow-id_ "
- "______________Source IPv6/port_______________ "
- "_______________Dest. IPv6/port_______________ "
- "Tot_pkt/bytes Pkt/Byte Drp\n");
- }
- printf("%3d ", q[l].hash_slot);
- pe = getprotobynumber(q[l].id.proto);
+ inet_ntoa(ina), id->dst_port);
+ } else {
+ /* Print IPv6 flows */
if (pe != NULL)
printf("%9s ", pe->p_name);
else
- printf("%9u ", q[l].id.proto);
- printf("%7d %39s/%-5d ", q[l].id.flow_id6,
- inet_ntop(AF_INET6, &(q[l].id.src_ip6), buff, sizeof(buff)),
- q[l].id.src_port);
+ printf("%9u ", id->proto);
+ printf("%7d %39s/%-5d ", id->flow_id6,
+ inet_ntop(AF_INET6, &(id->src_ip6), buff, sizeof(buff)),
+ id->src_port);
printf(" %39s/%-5d ",
- inet_ntop(AF_INET6, &(q[l].id.dst_ip6), buff, sizeof(buff)),
- q[l].id.dst_port);
- printf(" %4llu %8llu %2u %4u %3u\n",
- align_uint64(&q[l].tot_pkts),
- align_uint64(&q[l].tot_bytes),
- q[l].len, q[l].len_bytes, q[l].drops);
- if (co.verbose)
- printf(" S %20llu F %20llu\n",
- align_uint64(&q[l].S),
- align_uint64(&q[l].F));
+ inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)),
+ id->dst_port);
}
+ printf("%4llu %8llu %2u %4u %3u\n",
+ align_uint64(&ni->tot_pkts),
+ align_uint64(&ni->tot_bytes),
+ ni->length, ni->len_bytes, ni->drops);
}
-#endif
static void
print_flowset_parms(struct new_fs *fs, char *prefix)
@@ -256,7 +218,7 @@ print_flowset_parms(struct new_fs *fs, c
char red[90]; /* Display RED parameters */
l = fs->qsize;
- if (fs->flags & DN_QSIZE_IS_BYTES) {
+ if (fs->flags & DN_QSIZE_BYTES) {
if (l >= 8192)
sprintf(qs, "%d KB", l / 1024);
else
@@ -335,11 +297,18 @@ list_pipes(struct dn_id *oid, struct dn_
printf("respond to cmd %d buflen %d\n", oid->type, oid->id);
break;
case DN_SCH: {
- struct new_sch *s = (struct new_sch *)s;
- sprintf(buf + strlen(buf), " type %s", s->type);
+ struct new_sch *s = (struct new_sch *)oid;
+ flush_buf(buf);
+ printf(" type %s flags 0x%x %d buckets\n", s->type, s->flags, s->buckets);
+ if (s->flags & DN_HAVE_MASK)
+ print_mask(&s->sched_mask);
}
break;
+ case DN_NI:
+ list_queue((struct new_inst *)oid);
+ break;
+
case DN_PIPE: {
struct new_pipe *p = (struct new_pipe *)oid;
double b = p->bandwidth;
@@ -350,7 +319,7 @@ list_pipes(struct dn_id *oid, struct dn_
flush_buf(buf);
/* data rate */
if (b == 0)
- sprintf(bwbuf, "unlimited");
+ sprintf(bwbuf, "unlimited ");
else if (b >= 1000000)
sprintf(bwbuf, "%7.3f Mbit/s", b/1000000);
else if (b >= 1000)
@@ -359,8 +328,8 @@ list_pipes(struct dn_id *oid, struct dn_
sprintf(bwbuf, "%7.3f bit/s ", b);
if (humanize_number(burst, sizeof(burst), p->burst,
- "Byte", HN_AUTOSCALE, 0) < 0 || co.verbose)
- sprintf(burst, "%ju Byte\n", p->burst);
+ "", HN_AUTOSCALE, 0) < 0 || co.verbose)
+ sprintf(burst, "%d", (int)p->burst);
sprintf(buf, "%05d: %s %4d ms burst %s",
p->pipe_nr, bwbuf, p->delay, burst);
}
@@ -783,6 +752,7 @@ ipfw_config_pipe(int ac, char **av)
struct new_cmd *cmd = NULL;
struct ipfw_flow_id *mask = NULL;
int lmax = sizeof(*cmd); /* always present */
+ int _foo = 0, *flags = &_foo;
/* worst case: 2 schedulers, 1 profile, 1 pipe, 1 flowset */
lmax += 2*sizeof(*sch) + 2*sizeof(*p) + sizeof(*fs) + sizeof(*pf);
@@ -809,12 +779,13 @@ ipfw_config_pipe(int ac, char **av)
/* type should be wfq, but we set the default in the kernel. */
sch->oid.subtype = 0;
mask = &sch->sched_mask;
- /* XXX the FIFO scheduler is created from the WFQ one */
+ flags = &sch->flags;
+ /* the FIFO scheduler is created in the kernel from the WFQ one */
/* the WFQ pipe */
p = o_next(&buf, sizeof(*p), DN_PIPE);
p->pipe_nr = i;
- /* XXX the FIFO pipe is created from WFQ pipe */
+ /* the FIFO pipe is created in the kerne from WFQ pipe */
/*
* FIFO flowsets N+i are automatically created for
@@ -830,12 +801,14 @@ ipfw_config_pipe(int ac, char **av)
fs = o_next(&buf, sizeof(*fs), DN_FS);
fs->fs_nr = i;
mask = &fs->flow_mask;
+ flags = &fs->flags;
break;
case 3: /* scheduler */
sch = o_next(&buf, sizeof(*sch), DN_SCH);
sch->sched_nr = i;
mask = &sch->sched_mask;
+ flags = &sch->flags;
/* room in case we have a FIFO scheduler */
fs = o_next(&buf, sizeof(*fs), DN_FS);
fs->fs_nr = i + DN_MAX_ID;
@@ -874,11 +847,11 @@ ipfw_config_pipe(int ac, char **av)
end = NULL;
fs->qsize = strtoul(av[0], &end, 0);
if (*end == 'K' || *end == 'k') {
- fs->flags |= DN_QSIZE_IS_BYTES;
+ fs->flags |= DN_QSIZE_BYTES;
fs->qsize *= 1024;
} else if (*end == 'B' ||
_substrcmp2(end, "by", "bytes") == 0) {
- fs->flags |= DN_QSIZE_IS_BYTES;
+ fs->flags |= DN_QSIZE_BYTES;
}
ac--; av++;
break;
@@ -926,7 +899,7 @@ ipfw_config_pipe(int ac, char **av)
n2mask(&mask->dst_ip6, 128);
n2mask(&mask->src_ip6, 128);
mask->flow_id6 = ~0;
- fs->flags |= DN_HAVE_FLOW_MASK;
+ *flags |= DN_HAVE_MASK;
goto end_mask;
case TOK_DSTIP:
@@ -1002,7 +975,7 @@ ipfw_config_pipe(int ac, char **av)
fs->flow_mask.proto = (uint8_t)a;
}
if (a != 0)
- fs->flags |= DN_HAVE_FLOW_MASK;
+ *flags |= DN_HAVE_MASK;
ac--; av++;
} /* end while, config masks */
end_mask:
@@ -1134,8 +1107,8 @@ end_mask:
errx(EX_DATAERR, "sched must be > 0");
#endif
- if (fs->flags & DN_QSIZE_IS_BYTES) {
- size_t len;
+ if (fs->flags & DN_QSIZE_BYTES) {
+ size_t len;
long limit;
len = sizeof(limit);
@@ -1254,7 +1227,7 @@ dummynet_list(int ac, char *av[], int sh
oid.id = 0;
switch (co.do_pipe) {
case 1:
- oid.subtype = DN_SCH; /* list pipe */
+ oid.subtype = DN_PIPE; /* list pipe */
break;
case 2:
oid.subtype = DN_FS; /* list queue */
@@ -1265,7 +1238,7 @@ dummynet_list(int ac, char *av[], int sh
}
/* XXX we could use oid.id for the filter */
ret = do_cmd(-IP_DUMMYNET3, &oid, (uintptr_t)&l);
- printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id);
+ // printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id);
if (ret != 0 || oid.id <= sizeof(oid))
return;
l = oid.id;
@@ -1274,7 +1247,7 @@ dummynet_list(int ac, char *av[], int sh
err(1, "no memory in %s", __FUNCTION__);
*x = oid;
ret = do_cmd(-IP_DUMMYNET3, x, (uintptr_t)&l);
- printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id);
+ // printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id);
list_pipes(x, O_NEXT(x, l), NULL);
free(x);
}
Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Wed Jan 20 18:22:56 2010 (r202709)
+++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Wed Jan 20 18:28:24 2010 (r202710)
@@ -63,8 +63,9 @@ enum {
DN_QUEUE,
DN_DELAY_LINE,
DN_PROFILE,
- DN_FS_EXT,
- DN_QUEUE_EXT,
+ DN_NI, /* new_inst */
+ //DN_FS_EXT,
+ //DN_QUEUE_EXT,
DN_TEXT, /* subtype is the object */
DN_CMD_CONFIGURE, /* objects follow */
DN_CMD_DELETE, /* subtype + list of entries */
@@ -82,8 +83,13 @@ enum { /* subtype for schedulers, flowse
enum { /* user flags */
DN_HAVE_MASK = 0x0001,
+ DN_NOERROR = 0x0002,
DN_QSIZE_BYTES = 0x0008,
- DN_NOERROR = 0x0010,
+ DN_IS_RED = 0x0020,
+ DN_IS_GENTLE_RED= 0x0040,
+#if 0
+#define DN_HAS_PROFILE 0x0020 /* the pipe has a delay profile. */
+#endif
};
typedef uint64_t dn_key;
@@ -253,11 +259,5 @@ flow using a number of heaps defined int
*
*/
-#define DN_HAVE_FLOW_MASK 0x0001
-#define DN_IS_RED 0x0002
-#define DN_IS_GENTLE_RED 0x0004
-#define DN_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */
-#define DN_NOERROR 0x0010 /* do not report ENOBUFS on drops */
-#define DN_HAS_PROFILE 0x0020 /* the pipe has a delay profile. */
#endif /* _IP_DUMMYNET_H */
Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Wed Jan 20 18:22:56 2010 (r202709)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Wed Jan 20 18:28:24 2010 (r202710)
@@ -447,7 +447,7 @@ dn_ht_scan(struct dn_ht *ht, int (*fn)(v
next = *(void **)((char *)cur + ht->ofs);
ret = fn(cur, arg);
if (ret & DNHT_SCAN_DEL) {
- printf("element %p removed\n", cur);
+ // printf("element %p removed\n", cur);
found++;
ht->entries--;
*curp = next;
Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Wed Jan 20 18:22:56 2010 (r202709)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Wed Jan 20 18:28:24 2010 (r202710)
@@ -117,6 +117,19 @@ void dn_free_pkts(struct mbuf *mnext)
}
}
+static int
+bound_var(int *v, int dflt, int lo, int hi, const char *msg)
+{
+ if (*v < lo) {
+ *v = dflt;
+ printf("force %s to %d\n", msg, *v);
+ } else if (*v > hi) {
+ *v = hi;
+ printf("clamp %s to %d\n", msg, *v);
+ }
+ return *v;
+}
+
/*---- flow_id mask, hash and compare functions ---*/
static struct ipfw_flow_id *
flow_id_mask(struct ipfw_flow_id *mask, struct ipfw_flow_id *id)
@@ -264,7 +277,7 @@ dn_delete_queue(struct new_queue *q, int
{
struct new_fsk *fs = q->fs;
- printf(" +++ %s fs %p si %p\n", __FUNCTION__, fs, q->_si);
+ // printf("%s fs %p si %p\n", __FUNCTION__, fs, q->_si);
/* notify the parent scheduler that the queue is going away */
if (fs && fs->sched->fp->free_queue)
fs->sched->fp->free_queue(q);
@@ -272,6 +285,7 @@ dn_delete_queue(struct new_queue *q, int
if (flags & DN_DELETE) {
if (q->mq.head)
dn_free_pkts(q->mq.head);
+ bzero(q, sizeof(*q)); // safety
free(q, M_DUMMYNET);
dn_cfg.queue_count--;
}
@@ -408,8 +422,10 @@ si_new(uintptr_t key, int flags, void *a
return si;
error:
- if (si)
+ if (si) {
+ bzero(si, sizeof(*si)); // safety
free(si, M_DUMMYNET);
+ }
return NULL;
}
@@ -436,7 +452,7 @@ si_destroy(void *_si, void *arg)
bzero(si, sizeof(*si)); /* safety */
free(si, M_DUMMYNET);
dn_cfg.si_count--;
- return 0;
+ return DNHT_SCAN_DEL;
}
/*
@@ -590,7 +606,7 @@ delete_fs(int i, int locked)
if (!locked)
DN_BH_WLOCK();
fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
- printf("%s fs %d found %p\n", __FUNCTION__, i, fs);
+ // printf("%s fs %d found %p\n", __FUNCTION__, i, fs);
if (fs) {
fsk_detach(fs, DN_DETACH | DN_DELETE_FS);
err = 0;
@@ -686,9 +702,8 @@ schk_delete_cb(void *obj, void *arg)
s->siht = NULL;
if (s->fp->destroy)
s->fp->destroy(s);
- bzero(s, sizeof(*s));
+ bzero(s, sizeof(*s)); // safety
free(obj, M_DUMMYNET);
- // printf("<<< %s done sched %d destroyed\n", __FUNCTION__, i);
dn_cfg.schk_count--;
return DNHT_SCAN_DEL;
}
@@ -704,12 +719,12 @@ delete_schk(int i)
struct new_schk *s;
s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
- printf("%s sched %d %p\n", __FUNCTION__, i, s);
+ // printf("%s sched %d %p\n", __FUNCTION__, i, s);
if (!s)
return EINVAL;
/* detach flowsets, delete traffic */
+ delete_fs(i + DN_MAX_ID, 1); /* first remove internal pipe */
schk_delete_cb(s, (void*)(uintptr_t)DN_DELETE);
- delete_fs(i + DN_MAX_ID, 1); /* remove internal pipe */
return 0;
}
@@ -717,17 +732,17 @@ delete_schk(int i)
/*--- end of schk hashtable support ---*/
static int
-copy_obj(char **start, char *end, void *_o)
+copy_obj(char **start, char *end, void *_o, const char *msg, int i)
{
struct dn_id *o = _o;
int have = end - *start;
if (have < o->len || o->len == 0 || o->type == 0) {
- printf("XXX %s ERROR type %d have %d need %d\n",
- __FUNCTION__, o->type, have, o->len);
+ printf("XXX %s ERROR type %d %s %d have %d need %d\n",
+ __FUNCTION__, o->type, msg, i, have, o->len);
return 1;
}
- printf("%s type %d len %d\n", __FUNCTION__, o->type, o->len);
+ // printf("%s type %d %s %d len %d\n", __FUNCTION__, o->type, msg, i, o->len);
bcopy(_o, *start, o->len);
*start += o->len;
return 0;
@@ -748,7 +763,7 @@ copy_flowset(struct copy_args *a, struct
struct new_fs *ufs = (struct new_fs *)(*a->start);
if (!fs)
return 0;
- if (copy_obj(a->start, a->end, &fs->fs))
+ if (copy_obj(a->start, a->end, &fs->fs, "flowset", fs->fs.fs_nr))
return DNHT_SCAN_END;
ufs->oid.id = 0; /* XXX number of queues ? */
if (flags) { /* copy queues */
@@ -757,41 +772,63 @@ copy_flowset(struct copy_args *a, struct
}
static int
+copy_si_cb(void *obj, void *arg)
+{
+ struct new_sch_inst *si = obj;
+ struct copy_args *a = arg;
+ struct new_inst *ni = (struct new_inst *)(*a->start);
+ if (copy_obj(a->start, a->end, &si->ni, "inst", si->sched->sch.sched_nr))
+ return DNHT_SCAN_END;
+ ni->oid.type = DN_NI;
+ return 0;
+}
+
+static int
+copy_si(struct copy_args *a, struct new_schk *s, int flags)
+{
+ if (s->sch.flags & DN_HAVE_MASK) {
+ dn_ht_scan(s->siht, copy_si_cb, a);
+ } else {
+ if (s->siht)
+ copy_si_cb(s->siht, a);
+ }
+ return 0;
+}
+
+static int
copy_data_helper(void *_o, void *_arg)
{
struct copy_args *a = _arg;
- if (a->type == DN_SCH) { /* scanning schedulers */
- struct new_schk *s = _o;
+ if (a->type == DN_PIPE || /* pipe show */
+ a->type == DN_SCH) { /* sched show */
+ struct new_schk *s = _o; /* we get only schedulers */
+ if (a->type == DN_SCH && s->sch.sched_nr >= DN_MAX_ID)
+ return 0; /* not valid scheduler */
+ if (a->type == DN_PIPE && s->sch.sched_nr <= DN_MAX_ID)
+ return 0; /* not valid pipe */
if (a->flags & DN_C_PIPE) {
- printf("copy pipe %d\n", s->sch.sched_nr);
- if (copy_obj(a->start, a->end, &s->pipe))
+ if (copy_obj(a->start, a->end, &s->pipe, "pipe", s->sch.sched_nr))
return DNHT_SCAN_END;
- printf("copy int-fs for pipe %d %p\n",
- s->sch.sched_nr, s->fs);
if (copy_flowset(a, s->fs, 0))
return DNHT_SCAN_END;
- printf("copy pipe %d done\n", s->sch.sched_nr);
}
if (a->flags & DN_C_SCH) {
- printf("copy sched %d\n", s->sch.sched_nr);
- if (copy_obj(a->start, a->end, &s->sch))
+ if (copy_obj(a->start, a->end, &s->sch, "sched", s->sch.sched_nr))
return DNHT_SCAN_END;
- printf("copy sched %d done\n", s->sch.sched_nr);
}
if (a->flags & DN_C_SCH_INST) {
- printf("XXX todo: scan sched instances\n");
+ copy_si(a, s, 0);
}
}
- if (a->type == DN_FS) { /* scanning flowsets */
+ if (a->type == DN_FS) { /* queue show, skip internal flowsets */
struct new_fsk *fs = _o;
+ if (fs->fs.fs_nr >= DN_MAX_ID)
+ return 0;
/* if extra is set, only copy unlinked ones */
if (a->extra == 0 || fs->sched == NULL) {
- printf("copy fs %d to sched %d\n", fs->fs.fs_nr,
- fs->sched ? fs->sched->sch.sched_nr : -1);
if (copy_flowset(a, fs, 0))
return DNHT_SCAN_END;
- printf("copy fs %d done\n",fs->fs.fs_nr);
}
}
return 0;
@@ -927,7 +964,7 @@ config_fs(struct new_fs *nfs, struct dn_
return NULL;
// printf("%s flowset %d\n", __FUNCTION__, i);
/* XXX other sanity checks */
- if (nfs->flags & DN_QSIZE_IS_BYTES) {
+ if (nfs->flags & DN_QSIZE_BYTES) {
if (nfs->qsize > dn_cfg.pipe_byte_limit)
nfs->qsize = dn_cfg.pipe_byte_limit;
} else {
@@ -938,15 +975,8 @@ config_fs(struct new_fs *nfs, struct dn_
}
if (nfs->flags & DN_HAVE_MASK) {
/* make sure we have some buckets */
- if (nfs->buckets < 1) {
- nfs->buckets = dn_cfg.hash_size;
- printf("%s force buckets to %d\n",
- __FUNCTION__, nfs->buckets);
- } else if (nfs->buckets > dn_cfg.max_hash_size) {
- nfs->buckets = dn_cfg.max_hash_size;
- printf("%s clamp buckets to %d\n",
- __FUNCTION__, nfs->buckets);
- }
+ bound_var(&nfs->buckets, dn_cfg.hash_size,
+ 1, dn_cfg.max_hash_size, "flowset buckets");
} else {
nfs->buckets = 1; /* we only need 1 */
}
@@ -1018,6 +1048,10 @@ config_sched(struct new_sch *_nsch, stru
i = a.sch->sched_nr;
if (i <= 0 || i >= DN_MAX_ID)
return EINVAL;
+ /* make sure we have some buckets */
+ if (a.sch->flags & DN_HAVE_MASK)
+ bound_var(&a.sch->buckets, dn_cfg.hash_size,
+ 1, dn_cfg.max_hash_size, "sched buckets");
/* XXX other sanity checks */
bzero(&p, sizeof(p));
DN_BH_WLOCK();
@@ -1288,9 +1322,11 @@ compute_space(struct dn_id *cmd, int *to
switch (cmd->subtype) {
default:
return -1;
- case DN_SCH: /* pipe show */
- x = DN_C_SCH | DN_C_PIPE | DN_C_FS |
- DN_C_SCH_INST | DN_C_QUEUE;
+ case DN_PIPE: /* pipe show */
+ x = DN_C_PIPE | DN_C_FS | DN_SCH | DN_C_SCH_INST;
+ break;
+ case DN_SCH: /* sched show */
+ x = DN_C_SCH | DN_C_PIPE | DN_C_SCH_INST;
break;
case DN_FS: /* queue show */
x = DN_C_FS | DN_C_QUEUE;
@@ -1371,18 +1407,11 @@ dummynet_get(struct sockopt *sopt)
a.start = &buf;
a.end = end;
a.flags = to_copy;
- a.extra = 0;
- printf("copy schedulers (%d : %d)\n",
- dn_cfg.schk_count,
- dn_ht_entries(dn_cfg.schedhash));
- a.type = DN_SCH;
- dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
- printf("copy unlinked flowsets (%d : %d)\n",
- dn_cfg.fsk_count,
- dn_ht_entries(dn_cfg.fshash));
- a.type = DN_FS;
- a.extra = 1;
- dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
+ a.type = cmd.subtype;
+ if (a.type == DN_FS)
+ dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
+ else
+ dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
}
DN_BH_WUNLOCK();
error = sooptcopyout(sopt, start, buf - start);
@@ -1435,8 +1464,7 @@ ip_dn_ctl(struct sockopt *sopt)
printf("argument len %d invalid\n", l);
break;
}
- printf("%s size %d\n", __FUNCTION__, l);
- p = malloc(l, M_TEMP, M_WAITOK);
+ p = malloc(l, M_TEMP, M_WAITOK); // XXX can it fail ?
error = sooptcopyin(sopt, p, l, l);
if (error)
break ;
More information about the svn-src-user
mailing list