Date: Thu, 21 Jan 2010 17:34:01 +0000 (UTC) From: Luigi Rizzo <luigi@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r202758 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet sys/netinet/ipfw Message-ID: <201001211734.o0LHY1kg095927@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: luigi Date: Thu Jan 21 17:34:01 2010 New Revision: 202758 URL: http://svn.freebsd.org/changeset/base/202758 Log: + more renaming (pipe->link, dn_sched ->dn_alg) + implement more listing options; Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h user/luigi/ipfw3-head/sys/netinet/ip_dummynet.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_rr.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.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 Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Thu Jan 21 17:34:01 2010 (r202758) @@ -67,7 +67,7 @@ static struct _s_x dummynet_params[] = { { "bw", TOK_BW }, { "bandwidth", TOK_BW }, { "delay", TOK_DELAY }, - { "link", TOK_PIPE }, + { "link", TOK_LINK }, { "pipe", TOK_PIPE }, { "queue", TOK_QUEUE }, { "flowset", TOK_FLOWSET }, @@ -79,7 +79,7 @@ static struct _s_x dummynet_params[] = { { "dst-ip6", TOK_DSTIP6}, { "src-ipv6", TOK_SRCIP6}, { "src-ip6", TOK_SRCIP6}, - { "profile", TOK_PIPE_PROFILE}, + { "profile", TOK_PROFILE}, { "burst", TOK_BURST}, { "dummynet-params", TOK_NULL }, { NULL, 0 } /* terminator */ @@ -179,7 +179,7 @@ list_flow(struct dn_flow *ni) pe = getprotobynumber(id->proto); /* XXX: Should check for IPv4 flows */ - printf("%3d ", ni->oid.id); + printf("%3u ", (ni->oid.id) & 0xff); if (!IS_IP6_FLOW_ID(id)) { if (pe) printf("%-4s ", pe->p_name); @@ -243,9 +243,17 @@ print_flowset_parms(struct new_fs *fs, c #endif sprintf(red, "droptail"); - printf("%s %s%s %d queues (%d buckets) %s\n", - prefix, qs, plr, fs->oid.id, fs->buckets, red); - prefix[0] = '\0'; + if (prefix[0]) { + printf("%s %s%s %d queues (%d buckets) %s\n", + prefix, qs, plr, fs->oid.id, fs->buckets, red); + prefix[0] = '\0'; + } else { + printf("q%05d %s%s %d queues (%d buckets) %s sched %d\n", + fs->fs_nr, qs, plr, fs->oid.id, fs->buckets, red, + fs->sched_nr); + if (fs->flags & DN_HAVE_MASK) + print_mask(&fs->flow_mask); + } } static void @@ -273,7 +281,8 @@ flush_buf(char *buf) * generic list routine. We expect objects in a specific order, i.e. * PIPES AND SCHEDULERS: * link; scheduler; internal flowset if any; instances - * XXX do we need the queue ? + * we can tell a pipe from the number. + * * FLOWSETS: * flowset; queues; * link i (int queue); scheduler i; si(i) { flowsets() : queues } @@ -294,13 +303,31 @@ list_pipes(struct dn_id *oid, struct dn_ flush_buf(buf); printf("unrecognized object %d size %d\n", oid->type, oid->len); break; + case DN_TEXT: /* list of attached flowsets */ + { + int i, l; + struct { + struct dn_id id; + uint16_t p[0]; + } *d = (void *)oid; + l = (oid->len - sizeof(*oid))/sizeof(uint16_t); + if (l == 0) + break; + printf(" Children flowsets: "); + for (i = 0; i < l; i++) + printf("%d ", d->p[i]); + printf("\n"); + break; + } case DN_CMD_GET: - printf("respond to cmd %d buflen %d\n", oid->type, oid->id); + if (co.verbose) + printf("answer for cmd %d, len %d\n", oid->type, oid->id); break; case DN_SCH: { struct new_sch *s = (struct new_sch *)oid; flush_buf(buf); - printf(" type %s flags 0x%x %d buckets\n", + printf(" sched %d type %s flags 0x%x %d buckets\n", + s->sched_nr, s->name, s->flags, s->buckets); if (s->flags & DN_HAVE_MASK) print_mask(&s->sched_mask); @@ -333,7 +360,7 @@ list_pipes(struct dn_id *oid, struct dn_ "", HN_AUTOSCALE, 0) < 0 || co.verbose) sprintf(burst, "%d", (int)p->burst); sprintf(buf, "%05d: %s %4d ms burst %s", - p->link_nr, bwbuf, p->delay, burst); + p->link_nr % DN_MAX_ID, bwbuf, p->delay, burst); } break; @@ -382,7 +409,7 @@ ipfw_delete_pipe(int pipe_or_queue, int { struct { struct dn_id oid; - uint32_t a[1]; /* more if we want a list */ + uint32_t a[1]; /* add more if we want a list */ } cmd; oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION); cmd.oid.subtype = (co.do_pipe == 1) ? DN_LINK : @@ -764,8 +791,7 @@ ipfw_config_pipe(int ac, char **av) */ lmax = sizeof(struct dn_id); /* command header */ lmax += sizeof(struct new_sch) + sizeof(struct dn_link) + - sizeof(struct new_fs) + - sizeof(struct new_profile); + sizeof(struct new_fs) + sizeof(struct new_profile); av++; ac--; /* Pipe number */ @@ -779,49 +805,51 @@ ipfw_config_pipe(int ac, char **av) errx(1, "no memory for buffer"); } /* all commands start with a 'CONFIGURE' and a version */ - o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIGURE); + o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG); base->id = DN_API_VERSION; switch (co.do_pipe) { - case 1: - /* the WFQ scheduler */ + case 1: /* "pipe N config ..." */ + /* Allocate space for the WF2Q+ scheduler, its link + * and the FIFO flowset. Set the number, but leave + * the scheduler subtype and other parameters to 0 + * so the kernel will use appropriate defaults. + * XXX todo: add a flag to record if a parameter + * is actually configured. + * If we do a 'pipe config' mask -> sched_mask. + * The FIFO scheduler and link are derived from the + * WF2Q+ one in the kernel. + */ sch = o_next(&buf, sizeof(*sch), DN_SCH); + p = o_next(&buf, sizeof(*p), DN_LINK); + fs = o_next(&buf, sizeof(*fs), DN_FS); + sch->sched_nr = i; - /* type should be wfq, but we set the default in the kernel. */ - sch->oid.subtype = 0; + sch->oid.subtype = 0; /* defaults to WF2Q+ */ mask = &sch->sched_mask; flags = &sch->flags; - /* the FIFO scheduler is created in the kernel from the WFQ one */ - /* the WFQ link */ - p = o_next(&buf, sizeof(*p), DN_LINK); p->link_nr = i; - /* the FIFO link is created in the kernel from WFQ link */ - /* - * FIFO flowsets N+i are automatically created for - * FIFO schedulers i, but we provide room to pass - * queue parameters - */ - fs = o_next(&buf, sizeof(*fs), DN_FS); + /* This flowset is only for the FIFO scheduler */ fs->fs_nr = i + 2*DN_MAX_ID; fs->sched_nr = i + DN_MAX_ID; break; - case 2: /* flowset */ + case 2: /* "queue N config ... " */ fs = o_next(&buf, sizeof(*fs), DN_FS); fs->fs_nr = i; mask = &fs->flow_mask; flags = &fs->flags; break; - case 3: /* scheduler */ + case 3: /* "sched N config ..." */ sch = o_next(&buf, sizeof(*sch), DN_SCH); + fs = o_next(&buf, sizeof(*fs), DN_FS); 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 is used only with !MULTIQUEUE schedulers */ fs->fs_nr = i + DN_MAX_ID; fs->sched_nr = i; break; @@ -1075,7 +1103,7 @@ end_mask: ac--; av++; break; - case TOK_PIPE_PROFILE: + case TOK_PROFILE: NEED((!pf), "profile already set"); NEED(p, "profile"); { Modified: user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Thu Jan 21 17:34:01 2010 (r202758) @@ -82,6 +82,7 @@ enum tokens { TOK_ACCEPT, TOK_COUNT, TOK_PIPE, + TOK_LINK, TOK_QUEUE, TOK_FLOWSET, TOK_SCHED, @@ -157,7 +158,7 @@ enum tokens { TOK_SCHED_MASK, TOK_BW, TOK_DELAY, - TOK_PIPE_PROFILE, + TOK_PROFILE, TOK_BURST, TOK_RED, TOK_GRED, Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Thu Jan 21 17:34:01 2010 (r202758) @@ -71,10 +71,9 @@ enum { DN_DELAY_LINE, DN_PROFILE, DN_FLOW, /* struct dn_flow */ - //DN_FS_EXT, - //DN_QUEUE_EXT, DN_TEXT, /* opaque text is the object */ - DN_CMD_CONFIGURE, /* objects follow */ + + DN_CMD_CONFIG = 0x80, /* objects follow */ DN_CMD_DELETE, /* subtype + list of entries */ DN_CMD_GET, /* subtype + list of entries */ DN_CMD_FLUSH, @@ -115,21 +114,21 @@ struct dn_link { }; /* - * A flowset, which is a template for queues. Store here parameters + * A flowset, which is a template for flows. Contains parameters * from the command line: id, target scheduler, queue sizes, plr, - * flow masks, buckets for the queue hash, and possibly scheduler- + * flow masks, buckets for the flow hash, and possibly scheduler- * specific parameters (weight, quantum and so on). */ struct new_fs { struct dn_id oid; - int fs_nr; /* the flowset number */ + uint32_t fs_nr; /* the flowset number */ int flags; /* userland flags */ int qsize; /* queue size in slots or bytes */ - int plr; /* PLR, pkt loss rate (2^31-1 means 100%) */ - int buckets; /* buckets used for the queue hash table */ + int32_t plr; /* PLR, pkt loss rate (2^31-1 means 100%) */ + uint32_t buckets; /* buckets used for the queue hash table */ - struct ipfw_flow_id flow_mask; /* M */ - int sched_nr; /* the scheduler we attach to */ + struct ipfw_flow_id flow_mask; + uint32_t sched_nr; /* the scheduler we attach to */ /* generic scheduler parameters */ int weight; int quantum; @@ -148,7 +147,6 @@ struct dn_flow { uint32_t length; /* Queue lenght, in packets */ uint32_t len_bytes; /* Queue lenght, in bytes */ uint32_t drops; - int hash_slot; /* XXX do we need it ? */ uint64_t tot_pkts; /* statistics counters */ uint64_t tot_bytes; }; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Thu Jan 21 17:34:01 2010 (r202758) @@ -33,12 +33,12 @@ #define DN_MULTIQUEUE 0x01 /* - * Descriptor for the scheduler. + * Descriptor for a scheduling algorithm. * Contains all function pointers for a given scheduler * This is typically created when a module is loaded, and stored * in a global list of schedulers. */ -struct dn_sched { +struct dn_alg { uint32_t type; /* the scheduler type */ uint32_t flags; /* DN_MULTIQUEUE if supports multiple queues */ const char *name; /* scheduler name */ @@ -62,7 +62,7 @@ struct dn_sched { size_t q_datalen; /* per-queue parameters (e.g. S,F) */ - SLIST_ENTRY(dn_sched) next; /* Next scheduler in the list */ + SLIST_ENTRY(dn_alg) next; /* Next scheduler in the list */ /* * Methods implemented by the scheduler: Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Thu Jan 21 17:34:01 2010 (r202758) @@ -92,7 +92,7 @@ fifo_free_sched(struct new_sch_inst *si) * contains the type of the scheduler, the name, the size of extra * data structures, and function pointers. */ -static struct dn_sched fifo_desc = { +static struct dn_alg fifo_desc = { .type = DN_SCHED_FIFO, .name = "FIFO", Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_rr.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_rr.c Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_rr.c Thu Jan 21 17:34:01 2010 (r202758) @@ -257,7 +257,7 @@ rr_free_queue(struct new_queue *_q) * contains the type of the scheduler, the name, the size of the * structures and function pointers. */ -static struct dn_sched rr_desc = { +static struct dn_alg rr_desc = { .type = DN_SCHED_RR, .name = "RR", .flags = DN_MULTIQUEUE, Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Thu Jan 21 17:34:01 2010 (r202758) @@ -257,7 +257,7 @@ wf2qp_free_sched(struct new_sch_inst *_s static int wf2qp_new_fsk(struct new_fsk *fs) { - printf("%s called\n", __FUNCTION__); + // printf("%s called\n", __FUNCTION__); if (fs->fs.weight < 1) fs->fs.weight = 1; else if (fs->fs.weight > 100) @@ -314,7 +314,7 @@ wf2qp_free_queue(struct new_queue *q) * contains the type of the scheduler, the name, the size of the * structures and function pointers. */ -static struct dn_sched wf2qp_desc = { +static struct dn_alg wf2qp_desc = { .type = DN_SCHED_WF2QP, .name = "WF2Q+", .flags = DN_MULTIQUEUE, Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Thu Jan 21 17:34:01 2010 (r202758) @@ -64,7 +64,7 @@ SLIST_HEAD(new_schk_head, new_schk); SLIST_HEAD(new_sch_inst_head, new_sch_inst); SLIST_HEAD(new_fsk_head, new_fsk); SLIST_HEAD(new_queue_head, new_queue); -SLIST_HEAD(dn_sched_head, dn_sched); +SLIST_HEAD(dn_alg_head, dn_alg); struct mq { /* a basic queue of packets*/ struct mbuf *head, *tail; @@ -116,7 +116,7 @@ struct dn_parms { struct dn_ht *schedhash; /* list of flowsets without a scheduler -- use sch_chain */ struct new_fsk_head fsu; /* list of unlinked flowsets */ - struct dn_sched_head schedlist; /* list of algorithms */ + struct dn_alg_head schedlist; /* list of algorithms */ /* if the upper half is busy doing something long, * can set the busy flag and we will enqueue packets in @@ -159,7 +159,7 @@ struct delay_line { */ struct new_fsk { /* kernel side of a flowset */ struct new_fs fs; - SLIST_ENTRY(new_fsk) fsk_next; /* hash chain list */ + SLIST_ENTRY(new_fsk) fsk_next; /* hash chain for fshash */ struct ipfw_flow_id fsk_mask; @@ -167,7 +167,6 @@ struct new_fsk { /* kernel side of a flo struct dn_ht *_qht; struct new_schk *sched; /* Sched we are linked to */ SLIST_ENTRY(new_fsk) sch_chain; /* list of fsk attached to sched */ - // void *sched_info; /* scheduler-specific info */ }; /* @@ -182,9 +181,8 @@ struct new_queue { struct dn_flow ni; /* oid, flow_id, stats */ struct mq mq; /* packets queue */ struct new_sch_inst *_si; /* owner scheduler instance */ - SLIST_ENTRY(new_queue) q_next; /* hash chain list for fs */ + SLIST_ENTRY(new_queue) q_next; /* hash chain list for qht */ struct new_fsk *fs; /* parent flowset. */ - /* If fs->kflags & DN_DELETE, remove the queue when empty. */ }; /* @@ -197,17 +195,19 @@ struct new_queue { */ struct new_schk { struct new_sch sch; - struct dn_sched *fp; /* Pointer to scheduler functions */ - struct dn_link link; /* the link is embedded */ - struct new_profile *profile; - struct dn_id *cfg; /* extra config arguments */ + struct dn_alg *fp; /* Pointer to scheduler functions */ + struct dn_link link; /* The link, embedded */ + struct new_profile *profile; /* delay profile, if any */ + struct dn_id *cfg; /* extra config arguments */ - SLIST_ENTRY(new_schk) schk_next; /* hash chain list */ + SLIST_ENTRY(new_schk) schk_next; /* hash chain for schedhash */ struct new_fsk_head fsk_list; /* all fsk linked to me */ - struct new_fsk *fs; /* flowset for !MULTIQUEUE */ + struct new_fsk *fs; /* Flowset for !MULTIQUEUE */ - /* Hash table of all instances (through sched_mask) */ + /* Hash table of all instances (through sch.sched_mask) + * or single instance if no mask. Always valid. + */ struct dn_ht *siht; }; @@ -218,8 +218,8 @@ struct new_schk { * This struct is created a runtime. */ struct new_sch_inst { - struct dn_flow ni; /* oid, id and stats */ - SLIST_ENTRY(new_sch_inst) si_next; /* next item in the bucket */ + struct dn_flow ni; /* oid, flowid and stats */ + SLIST_ENTRY(new_sch_inst) si_next; /* hash chain for siht */ struct delay_line dline; struct new_schk *sched; /* the template */ int kflags; /* DN_ACTIVE */ @@ -247,9 +247,8 @@ int dummynet_io(struct mbuf **, int , st void dummynet_task(void *context, int pending); void dn_reschedule(void); -struct new_queue *ipdn_q_find(struct new_fsk *fs, struct new_sch_inst *si, - struct ipfw_flow_id *id); - -struct new_sch_inst *ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id); +struct new_queue *ipdn_q_find(struct new_fsk *, struct new_sch_inst *, + struct ipfw_flow_id *); +struct new_sch_inst *ipdn_si_find(struct new_schk *, struct ipfw_flow_id *); #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 Thu Jan 21 17:26:11 2010 (r202757) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Thu Jan 21 17:34:01 2010 (r202758) @@ -28,16 +28,16 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +/* + * Configuration and internal object management for dummynet. + */ + #include "opt_inet6.h" /* debug support */ -// #define D(fmt, args...) do {} while (0) #define ND(fmt, args...) do {} while (0) #define D(fmt, args...) printf("%s " fmt "\n", __FUNCTION__ , ## args) -/* - * Configuration and internal object management for dummynet. - */ #include <sys/param.h> #include <sys/systm.h> @@ -64,15 +64,15 @@ __FBSDID("$FreeBSD$"); #include <netinet/ipfw/dn_sched.h> /* which objects to copy */ -#define DN_C_PIPE 0x01 +#define DN_C_LINK 0x01 #define DN_C_SCH 0x02 -#define DN_C_SCH_INST 0x04 +#define DN_C_FLOW 0x04 #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 dn_alg *fp; struct new_sch *sch; }; @@ -96,10 +96,10 @@ dn_reschedule(void) /*----- end of callout hooks -----*/ /* Return a scheduler descriptor given the type or name. */ -static struct dn_sched * +static struct dn_alg * find_sched_type(int type, char *name) { - struct dn_sched *d; + struct dn_alg *d; SLIST_FOREACH(d, &dn_cfg.schedlist, next) { if (d->type == type || (name && !strcmp(d->name, name))) @@ -113,10 +113,12 @@ bound_var(int *v, int dflt, int lo, int { if (*v < lo) { *v = dflt; - printf("force %s to %d\n", msg, *v); + if (msg) + printf("default %s to %d\n", msg, *v); } else if (*v > hi) { *v = hi; - printf("clamp %s to %d\n", msg, *v); + if (msg) + printf("clamp %s to %d\n", msg, *v); } return *v; } @@ -772,15 +774,42 @@ struct copy_args { }; static int +copy_q_cb(void *obj, void *arg) +{ + struct new_queue *q = obj; + struct copy_args *a = arg; + struct dn_flow *ni = (struct dn_flow *)(*a->start); + if (copy_obj(a->start, a->end, &q->ni, "queue", -1)) + return DNHT_SCAN_END; + ni->oid.type = DN_FLOW; /* override the DN_QUEUE */ + ni->oid.id = si_hash((uintptr_t)&ni->fid, 0, NULL); + return 0; +} + +static int +copy_q(struct copy_args *a, struct new_fsk *fs, int flags) +{ + if (!fs->_qht) + return 0; + if (fs->fs.flags & DN_HAVE_MASK) + dn_ht_scan(fs->_qht, copy_q_cb, a); + else + copy_q_cb(fs->_qht, a); + return 0; +} + +static int copy_flowset(struct copy_args *a, struct new_fsk *fs, int flags) { struct new_fs *ufs = (struct new_fs *)(*a->start); if (!fs) return 0; + ND("flowset %d", fs->fs.fs_nr); 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 */ + copy_q(a, fs, 0); } return 0; } @@ -795,6 +824,7 @@ copy_si_cb(void *obj, void *arg) si->sched->sch.sched_nr)) return DNHT_SCAN_END; ni->oid.type = DN_FLOW; /* override the DN_SCH_I */ + ni->oid.id = si_hash((uintptr_t)si, DNHT_KEY_IS_OBJ, NULL); return 0; } @@ -809,6 +839,33 @@ copy_si(struct copy_args *a, struct new_ } static int +copy_fsk_list(struct copy_args *a, struct new_schk *s, int flags) +{ + struct new_fsk *fs; + struct dn_id *o; + uint16_t *p; + + int n = 0, space = sizeof(*o); + SLIST_FOREACH(fs, &s->fsk_list, sch_chain) { + if (fs->fs.fs_nr < DN_MAX_ID) + n++;; + } + space += 2*n; + D("sched %d has %d flowsets", s->sch.sched_nr, n); + if (a->end - *(a->start) < space) + return DNHT_SCAN_END; + o = (struct dn_id *)(*(a->start)); + o->len = space; + *a->start += o->len; + o->type = DN_TEXT; + p = (uint16_t *)(o+1); + SLIST_FOREACH(fs, &s->fsk_list, sch_chain) + if (fs->fs.fs_nr < DN_MAX_ID) + *p++ = fs->fs.fs_nr; + return 0; +} + +static int copy_data_helper(void *_o, void *_arg) { struct copy_args *a = _arg; @@ -820,7 +877,7 @@ copy_data_helper(void *_o, void *_arg) return 0; /* not valid scheduler */ if (a->type == DN_LINK && s->sch.sched_nr <= DN_MAX_ID) return 0; /* not valid pipe */ - if (a->flags & DN_C_PIPE) { + if (a->flags & DN_C_LINK) { if (copy_obj(a->start, a->end, &s->link, "link", s->sch.sched_nr)) return DNHT_SCAN_END; @@ -831,8 +888,11 @@ copy_data_helper(void *_o, void *_arg) if (copy_obj(a->start, a->end, &s->sch, "sched", s->sch.sched_nr)) return DNHT_SCAN_END; + /* list all attached flowsets */ + if (copy_fsk_list(a, s, 0)) + return DNHT_SCAN_END; } - if (a->flags & DN_C_SCH_INST) { + if (a->flags & DN_C_FLOW) { copy_si(a, s, 0); } } @@ -840,11 +900,9 @@ copy_data_helper(void *_o, void *_arg) 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) { - if (copy_flowset(a, fs, 0)) - return DNHT_SCAN_END; - } + if (copy_flowset(a, fs, 0)) + return DNHT_SCAN_END; + copy_q(a, fs, 0); } return 0; } @@ -869,11 +927,15 @@ fsk_attach(struct new_fsk *fs, struct ne /* XXX compute fsk_mask */ fs->fsk_mask = fs->fs.flow_mask; if (fs->sched->sch.flags & DN_HAVE_MASK) - flow_id_or(&fs->fsk_mask, &fs->sched->sch.sched_mask); + flow_id_or(&fs->sched->sch.sched_mask, &fs->fsk_mask); if (!fs->_qht) return; D("XXX TODO requeue from fs %d to sch %d", fs->fs.fs_nr, s->sch.sched_nr); + /* + * The requeue is complex -- in general we need to + * reclassify every single packet. + */ } /* update all flowsets which may refer to this scheduler */ @@ -999,22 +1061,17 @@ config_fs(struct new_fs *nfs, struct dn_ DN_BH_WLOCK(); do { /* exit with break when done */ struct new_schk *s; - - fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT, NULL); - if (fs == NULL) - break; - if (nfs->sched_nr == 0) { - if (fs->fs.sched_nr != 0) { /* reuse */ - nfs->sched_nr = fs->fs.sched_nr; - } else { - D("missing sched for flowset %d", i); - fs = NULL; - break; - } + int flags = nfs->sched_nr ? DNHT_INSERT : 0; + fs = dn_ht_find(dn_cfg.fshash, i, flags, NULL); + if (fs == NULL) { + D("missing sched for flowset %d", i); + break; } + if (nfs->sched_nr == 0) /* reuse */ + nfs->sched_nr = fs->fs.sched_nr; dn_cfg.id++; if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0) { - D("flowset %d unchanged", i); + ND("flowset %d unchanged", i); break; /* no change, nothing to do */ } s = locate_scheduler(nfs->sched_nr); @@ -1022,7 +1079,7 @@ config_fs(struct new_fs *nfs, struct dn_ * queues if we need to reattach. Then update the * configuration, and possibly attach to the new sched. */ - D("fs %d changed args/sched %d %p to %d %p", + D("fs %d changed sched %d@%p to %d@%p", fs->fs.fs_nr, fs->fs.sched_nr, fs->sched, nfs->sched_nr, s); if (fs->sched) { @@ -1115,7 +1172,7 @@ again: /* run twice, for wfq and fifo */ /* already existing. */ D("sched %d type changed from %s to %s", i, s->fp->name, a.fp->name); - D(" type/sub %d/%d -> %d/%d", + ND(" type/sub %d/%d -> %d/%d", s->sch.oid.type, s->sch.oid.subtype, a.sch->oid.type, a.sch->oid.subtype); if (s->link.link_nr == 0) @@ -1129,7 +1186,7 @@ again: /* run twice, for wfq and fifo */ schk_delete_cb(s, (void *)DN_DELETE); goto again; } else { - D("sched %d unchanged type %s", i, a.fp->name); + ND("sched %d unchanged type %s", i, a.fp->name); } /* complete initialization */ s->sch = *a.sch; @@ -1263,6 +1320,7 @@ do_config(void *p, int l) struct dn_id *next, *o; int err = 0, err2 = 0; struct dn_id *arg = NULL; + uint32_t *a; o = p; if (o->id != DN_API_VERSION) { @@ -1285,17 +1343,22 @@ do_config(void *p, int l) D("cmd %d not implemented", o->type); break; - case DN_CMD_CONFIGURE: /* simply a header */ - /* XXX add a version check */ + case DN_CMD_CONFIG: /* simply a header */ break; case DN_CMD_DELETE: + /* the argument is in the first uint32 after o */ + a = (uint32_t *)(o+1); + if (o->len < sizeof(*o) + sizeof(*a)) { + err = EINVAL; + break; + } switch (o->subtype) { case DN_LINK: /* delete base and derived schedulers */ DN_BH_WLOCK(); - err = delete_schk(o->id); - err2 = delete_schk(o->id + DN_MAX_ID); + err = delete_schk(*a); + err2 = delete_schk(*a + DN_MAX_ID); DN_BH_WUNLOCK(); if (!err) err = err2; @@ -1308,8 +1371,8 @@ do_config(void *p, int l) break; case DN_FS: - err = (o->id<1 || o->id >= DN_MAX_ID) ? - EINVAL : delete_fs(o->id, 0) ; + err = (*a <1 || *a >= DN_MAX_ID) ? + EINVAL : delete_fs(*a, 0) ; break; } break; @@ -1353,10 +1416,10 @@ compute_space(struct dn_id *cmd, int *to default: return -1; case DN_LINK: /* pipe show */ - x = DN_C_PIPE | DN_C_FS | DN_SCH | DN_C_SCH_INST; + x = DN_C_LINK | DN_C_FS | DN_SCH | DN_C_FLOW; break; case DN_SCH: /* sched show */ - x = DN_C_SCH | DN_C_PIPE | DN_C_SCH_INST; + x = DN_C_SCH | DN_C_LINK | DN_C_FLOW; break; case DN_FS: /* queue show */ x = DN_C_FS | DN_C_QUEUE; @@ -1367,12 +1430,12 @@ compute_space(struct dn_id *cmd, int *to 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) + if (x & DN_C_LINK) need += dn_cfg.schk_count * sizeof(struct dn_link); /* 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) + if (x & DN_C_FLOW) need += dn_cfg.si_count * sizeof(struct dn_flow); return need; } @@ -1590,9 +1653,9 @@ dummynet_modevent(module_t mod, int type /* modevent helpers for the modules */ static int -load_dn_sched(struct dn_sched *d) +load_dn_sched(struct dn_alg *d) { - struct dn_sched *s; + struct dn_alg *s; if (d == NULL) return 1; /* error */ @@ -1620,9 +1683,9 @@ load_dn_sched(struct dn_sched *d) } static int -unload_dn_sched(struct dn_sched *s) +unload_dn_sched(struct dn_alg *s) { - struct dn_sched *tmp, *r; + struct dn_alg *tmp, *r; int err = EINVAL; D("called for %s", s->name); @@ -1634,7 +1697,7 @@ unload_dn_sched(struct dn_sched *s) D("ref_count = %d", r->ref_count); err = (r->ref_count != 0) ? EBUSY : 0; if (err == 0) - SLIST_REMOVE(&dn_cfg.schedlist, r, dn_sched, next); + SLIST_REMOVE(&dn_cfg.schedlist, r, dn_alg, next); break; } DN_BH_WUNLOCK(); @@ -1645,7 +1708,7 @@ unload_dn_sched(struct dn_sched *s) int dn_sched_modevent(module_t mod, int cmd, void *arg) { - struct dn_sched *sch = arg; + struct dn_alg *sch = arg; if (cmd == MOD_LOAD) return load_dn_sched(sch);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001211734.o0LHY1kg095927>