Date: Tue, 5 Jan 2010 18:26:26 +0000 (UTC) From: Luigi Rizzo <luigi@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r201598 - user/luigi/ipfw3-head/sys/netinet Message-ID: <201001051826.o05IQQS0076459@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: luigi Date: Tue Jan 5 18:26:26 2010 New Revision: 201598 URL: http://svn.freebsd.org/changeset/base/201598 Log: start bringing in the definitions for the new kernel-userland API Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Tue Jan 5 18:25:41 2010 (r201597) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Tue Jan 5 18:26:26 2010 (r201598) @@ -31,19 +31,298 @@ #define _IP_DUMMYNET_H /* - * Definition of dummynet data structures. In the structures, I decided - * not to use the macros in <sys/queue.h> in the hope of making the code - * easier to port to other architectures. The type of lists and queue we - * use here is pretty simple anyways. + * Definition of the kernel-userland API for dummynet. + * + * Setsockopt() and getsockopt() pass a batch of objects, each + * of them starting with a "struct dn_id" which should fully identify + * the object and its relation with others in the sequence. + * objects in a batch of requests. + * This struct store in the type field an identifier of the type of object + * passed (for example a pipe, a scheduler...). The subtype + * field contains more detail info, if needed. + */ + +struct dn_id { + uint16_t len; /* total len including this header */ + uint8_t type; + uint8_t subtype; + uint32_t id; /* identifier in the sequence */ +}; + +/* + * These values are in the type field of struct dn_id. + * To preserve the ABI, never rearrange the list or delete + * entries with the exception of DN_LAST + */ +enum { + DN_PIPE = 1, + DN_FS, + DN_SCH, + DN_SCH_I, + DN_QUEUE, + DN_DELAY_LINE, + DN_PROFILE, + DN_FS_EXT, + DN_QUEUE_EXT, + DN_UNKNOW, + DN_CMD_CONFIGURE, + DN_CMD_DELETE, + DN_LAST, +}; + +/* These values are in the subtype field of struct gen */ +enum dn_configure { + DN_CONF_PIPE = 1, + DN_CONF_QUEUE = 2, + DN_CONF_SCHED = 3, +}; + +/* These values are in the flag field of a scheduler + * Some of them are used only by kernel (k) + */ +enum sched_flag { + DN_SCH_RECONFIGURE = 0x0001, /* (k) */ + DN_SCH_HAVE_MASK = 0x0002, + DN_SCH_DELETE = 0x0004, /* (k) */ + DN_SCH_REENQUEUE = 0x0008, /* (k) */ + DN_SCH_ACTIVE = 0x0010, /* (k) */ +// DN_SCH_BUSY = 0x0020, /* (k) */ + DN_SCH_DELETE_DELAY_LINE = 0x0040, /* (k) */ +}; + +SLIST_HEAD(new_queue_head, new_queue); +typedef uint64_t dn_key; + +/* Pipe template + * All pipe are linked in a list, there is a 1-1 mapping between + * 'ipfw pipe XX ...' commands and pipe XX + */ +struct new_pipe { + struct dn_id id; + + /* these initial fields are set from the command line + * pipe N config bw B delay D profile PRF (mask M1 plr P queue Q + * buckets BB ) ... + * The second set of parameters (M1, ...) belong to the + * scheduler or the flowset. They can be specified in 'pipe config' + * only for backward compatibility. + * Userland sets bw and delay in bits/s and milliseconds. + * The kernel converts this back and forth to bits/tick and ticks. + */ + int32_t pipe_nr ; /* N, number */ + int bandwidth; /* B, really, bits/tick. */ + int delay ; /* D, really, ticks */ + + /* + * When the tx clock comes from an interface (if_name[0] != '\0'), + * its name is stored below. + */ + char if_name[IFNAMSIZ]; + + /* fields to simulate a delay profile */ +#define ED_MAX_NAME_LEN 32 + char name[ED_MAX_NAME_LEN]; + int loss_level; + int samples_no; + int user_samples[0]; /* this has actually samples_no slots */ + + /* + * The following parameters set at runtime and only valid + * in the kernel. Userland should not look at these fields. + */ + int *samples; /* pointer to memory for user_samples[] */ + struct ifnet *ifp; + int ready ; /* set if ifp != NULL and we got a signal from it */ + + SLIST_ENTRY(new_pipe) next; /* Global list of all pipes */ +}; + +/* + * generic text string, in case we need one + */ +struct new_text { + struct dn_id id; + int len; + char text[0]; /* len bytes, NUL terminated */ +}; + +/* + * description of a flow set. + * All flowset are linked in a list, there is a 1-1 mapping between + * 'ipfw queue XX ...' commands and flowset XX + * (plus there is a FIFO flowset for each pipe) + */ +struct new_fs { + struct dn_id id; + + /* these initial fields are set from the command line + * queue N config mask M pipe P buckets B plr PLR queue QSZ ... + */ + int fs_nr; /* N, the flowset number */ + /* The flowset implicitly created for pipe N is N+offset */ + + int qsize; /* QSZ, queue size in slots or bytes */ + + /* Number of buckets used for the hash table in this fs. */ + int bucket; /* B */ + int plr ; /* PLR, pkt loss rate (2^31-1 means 100%) */ + + /* Copy of command line */ + struct new_text *cmdline; + + /* mask to select the appropriate queue */ + struct ipfw_flow_id flow_mask; /* M */ + int sched_nr; /* P, the pipe we attach to */ + + /*--- parameters set at runtime */ + SLIST_ENTRY(new_fs) next; /* list of flow sets */ + + /* Used to link flowset to be configured */ + struct new_fs *confnext; + + /* DN_FS_DELETE + * DN_FS_REENQUEUE + * DN_HAVE_FLOW_MASK + * DN_QSIZE_IS_BYTES + * DN_NOERROR + */ + int flags; + + /* Number of queues attached to this flowset */ + int active_f; + + /* Number of packets in the scheduler mutex queue */ + int busy; + + /* Scheduler associated with this flowset, set when the + * scheduler for the pipe P is defined. + */ + struct new_sch *ptr_sched; + int ptr_sched_val; /* to check if the pointer is correct */ + + /* + * Pointer to scheduler-specific parameters for this flowset + * (for examples, the weight parameter of wf2q+ algorithm goes here) + */ + struct dn_id *alg_fs; + /* Pointer to scheduler functions */ + struct scheduler *fp; +}; + +/* + * Scheduler instance. + * Contains variables and all queues relative to a this instance. + * This struct is created a runtime. + */ +struct new_sch_inst { + struct dn_id sch_id; + + struct new_sch_inst *next; /* next item in the bucket */ + + /* Parent scheduler */ + int sched_nr; + struct new_sch * ptr_sched; + + int hash_slot; /* used to print the id of the scheduler instance */ + + /* flow id associated with this scheduler instance */ + struct ipfw_flow_id id; + + int flags; /* DN_SCHED_ACTIVE */ + + /* Pointer to the delay line for this scheduler instance */ + struct delay_line *dline; + + /* List of queues that will be returned when user type a command like + * 'ipfw pipe | queue list'. + * List is automatically update when a queue is created and destroyed + */ + struct new_queue_head ql_list; + + int64_t numbytes; /* bits I can transmit (more or less). */ + dn_key sched_time ; /* time pipe was scheduled in ready_heap */ + dn_key idle_time; /* start of scheduler instance idle time */ +}; + +/* Scheduler template + * All scheduler are linked in a list, there is a 1-1 mapping between + * 'ipfw sched XX ...' commands and sched XX + * (plus there is a FIFO scheduler for each pipe) */ +struct new_sch { + struct dn_id g; + + /* these initial fields are set from the command line + * sched N config mask M ... + */ + + int sched_nr; /* N, scheduler number */ + uint64_t burst; /* burst size, scaled. bits*Hz */ + int bucket; /* number of buckets for the instances */ + + /* mask to select the appropriate scheduler instance */ + struct ipfw_flow_id sched_mask; /* M */ + + /*--- parameters set at runtime */ + + /* This structure is in a list of schedulers where we do + * the lookup when necessary. 'next' is the link field. + * Also, all instances of this scheduler may be in a heap used + * to fetch them when they are ready. 'inst_counter' counts + * how many instances are in the heap and can be used + * as a reference count. + */ + SLIST_ENTRY(new_sch) next; /* List of all templates */ + + /* number of scheduler instances for this scheduler in the ready_heap + * Used to check when we can delete a scheduler safely + */ + int inst_counter; + + /* Pointer to the parent pipe */ + int pipe_nr; + struct new_pipe *ptr_pipe; + + /* Copy of command line */ + #define DN_MAX_COMMAND 256 + char command_line[DN_MAX_COMMAND]; + + /* Hash table contains all scheduler instances associated with + * this scheduler + */ + int sch_i_size; + int sch_i_elements; + struct new_sch_inst **sch_i; + + /* + * DN_HAVE_SCH_MASK + * DN_SCH_DELETE + * DN_SCH_REENQUEUE + * DN_SCH_REENQUEUE + * DN_FORCE_DELETE_DELAY_LINE + */ + int flags; + + /* Pointer to scheduler functions */ + struct scheduler *fp; + + /* Counter of packets pending to entering in this scheduler. + * Used to avoid to delete the scheduler if some packets are in the mutex + * queue + */ + int busy; + /* Mutex to protect a single scheduler */ + // struct mtx sch_mtx; +}; + +/*---- old parameters ---*/ /* * The maximum hash table size for queues. This value must be a power * of 2. */ #define DN_MAX_HASH_SIZE 65536 -typedef uint64_t dn_key; /* * Overall structure of dummynet (with WF2Q+):
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001051826.o05IQQS0076459>