/* 
 * $Source: /b/cvsroot//wu_arl/msr/rp/plugins/delay/delay.h,v $
 * $Author: kenw $
 * $Date: 2004/08/10 17:10:39 $
 * $Revision: 1.7 $
 *
 * Changes:
 * Wed Apr 11 10:42:14 CDT 2001 - Initial version fredk
 *
 */

/* CAVEAT:  You can only create one instance since there is only one queue.
 *		You could generalize to N instances if you modify
 *		dropdelay_create_instance.
 */

#include <msr/msr.h>
#include <rp/rp_plugin.h>

#define PLUGIN_ID	610
#define DELAY_TIME	50	// Initial delay in msec
				// Initial drop params
#define NPASS		1	//   #pkts to pass
#define NDROP		1	//   #pkts to drop
				//   When deteriministic dropping:
				//   The pass-drop sequence is repeated.
				//   So, 1-1 causes pkts 1, 3, 5, etc. to
				//   be dropped.  1-0 means all pkts are
				//   passed.

#define PROBABILISTIC	0	// Drop type (default)
#define DETERMINISTIC	1	// .
#define	MAXINT		(u_int32_t)((u_int32_t)(2147483647U+1))	// 2^31
				// This has to match the value in rand.c

static int cbPeriod = 500;	// callback period in usec (500 usec, 1 tick)

/* includes here */
struct lkmtp;
struct lkm_table;

/* dropdelay instance
 * 	After init:	pkt_count = fwd_count = drop_count = 0
 * 			earliest_depart_time = 0
 *			delay_time = DELAY_TIME
 *			drop_num = DROP_NUM, drop_den = DROP_DEN
 *			drop_type = PROBABILISTIC
 * 	After bind:	(pkt_count = fwd_count) and (drop_count = 0)
 * 	After unbind:	(drop_count = qlen) and (qlen = 0)
 */
struct dropdelay_instance {
  /* First the base class structure */
  struct rp_instance rootinstance;
  HDRQ_t qhead;			// addr of 1st buffer in delay queue
  int	qlen;			// #pkts in delay queue
  int	pkt_count;		// #pkts handled by instance
  int	drop_count;		// #pkts dropped by instance
  int	fwd_count;		// #pkts forwarded by instance
  int	max_qlen;		// maximum queue length
  int	earliest_depart_time;	// earliest time nxt pkt should be sent (msec)
  int	delay_time;		// amount to delay (msec)
  int	drop_type;		// drop type (0: probabilistic; 1: deterministic)
  u_int32_t	pass;		// dropping params
  u_int32_t	drop;		// .
  u_int32_t	drop_hi;	// drop*(MAXINT/(drop+pass))
};

/* function prototypes */
void dropdelay_init_class(void);
struct rp_class *dropdelay_get_class(void);
struct rp_instance *dropdelay_create_instance(struct rp_class *, u_int32_t);
void dropdelay_handle_packet(struct rp_instance *, void *);
void dropdelay_free_instance(struct rp_instance *);
void dropdelay_bind_instance(struct rp_instance *);
void dropdelay_unbind_instance(struct rp_instance *);
int  dropdelay_handle_msg(struct rp_instance *, void *, u_int8_t, u_int8_t, u_int8_t *);
#ifdef PLUGIN_DEBUG
int dropdelay(struct lkm_table *, int , int);
#else
int dropdelay(struct lkm_table *, int , int, struct kernel_plugin_fct_struct * );
#endif
int dropdelay_load(struct lkm_table *, int);
int dropdelay_unload(struct lkm_table *, int);

