* include files marked with XXX are probably not needed
*/
+#include "missing.h"
+
#include <sys/limits.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
-#include <sys/mutex.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/rwlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/time.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
-#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head */
+#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
#include <net/netisr.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* ip_len, ip_off */
#include <netinet/ip6.h> /* for ip6_input, ip6_output prototypes */
#include <netinet6/ip6_var.h>
-#include "missing.h"
-
/*
* We keep a private variable for the simulation time, but we could
* probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
static void dummynet_flush(void);
static void dummynet_send(struct mbuf *);
void dummynet_drain(void);
-static ip_dn_io_t dummynet_io;
static void dn_rule_delete(void *);
+static int dummynet_io(struct mbuf **, int , struct ip_fw_args *);
/*
* Heap management functions.
struct dn_heap *neh = &(p->not_eligible_heap);
int64_t p_numbytes = p->numbytes;
+ /*
+ * p->numbytes is only 32bits in FBSD7, but we might need 64 bits.
+ * Use a local variable for the computations, and write back the
+ * results when done, saturating if needed.
+ * The local variable has no impact on performance and helps
+ * reducing diffs between the various branches.
+ */
+
DUMMYNET_LOCK_ASSERT();
if (p->if_name[0] == 0) /* tx clock is simulated */
- /*
- * Since result may not fit into p->numbytes (32bit) we
- * are using 64bit var here.
- */
p_numbytes += (curr_time - p->sched_time) * p->bandwidth;
else { /*
* tx clock is for real,
*/
}
- /* Fit (adjust if necessary) 64bit result into 32bit variable. */
- if (p_numbytes > INT_MAX)
- p->numbytes = INT_MAX;
- else if (p_numbytes < INT_MIN)
- p->numbytes = INT_MIN;
- else
- p->numbytes = p_numbytes;
+ /* Write back p_numbytes (adjust 64->32bit if necessary). */
+ p->numbytes = p_numbytes;
/*
* If the delay line was empty call transmit_event() now.
u_int t = div64(curr_time - q->q_time,
fs->lookup_step);
- q->avg = (t >= 0 && t < fs->lookup_depth) ?
+ q->avg = (t < fs->lookup_depth) ?
SCALE_MUL(q->avg, fs->w_q_lookup[t]) : 0;
}
}
* Build and enqueue packet + parameters.
*/
pkt->rule = fwa->rule;
+ pkt->rule_id = fwa->rule_id;
+ pkt->chain_id = fwa->chain_id;
pkt->dn_dir = dir;
pkt->ifp = fwa->oif;
heap_extract(&(pipe->idle_heap), q);
q->S = MAX64(q->F, pipe->V);
}
- q->F = div64(q->S + (len << MY_M), fs->weight);
+ q->F = q->S + div64(len << MY_M, fs->weight);
if (pipe->not_eligible_heap.elements == 0 &&
pipe->scheduler_heap.elements == 0)
pkt = dn_tag_get(m);
pkt->dn_dir = DN_TO_DROP;
}
- dummynet_send(m); /* drop the packet */
+ dummynet_send(m); /* drop the packet */
*m0 = NULL;
return ((fs && (fs->flags_fs & DN_NOERROR)) ? 0 : ENOBUFS);
}
* Below, the rt_unref is only needed when (pkt->dn_dir == DN_TO_IP_OUT)
* Doing this would probably save us the initial bzero of dn_pkt
*/
-#define DN_FREE_PKT(_m) do { \
+#if defined( __linux__ )
+#define DN_FREE_PKT(_m) do { \
+ netisr_dispatch(-1, _m); \
+} while (0)
+#else
+#define DN_FREE_PKT(_m) do { \
m_freem(_m); \
} while (0)
+#endif
/*
* Dispose all packets and flow_queues on a flow_set.
* qsize = slots/bytes
*/
p->delay = (p->delay * hz) / 1000;
+ /* Scale burst size: bytes -> bits * hz */
+ p->burst *= 8 * hz;
/* We need either a pipe number or a flow_set number. */
if (p->pipe_nr == 0 && pfs->fs_nr == 0)
return (EINVAL);
*/
bcopy(pipe, bp, sizeof(*pipe));
pipe_bp->delay = (pipe_bp->delay * 1000) / hz;
+ pipe_bp->burst = div64(pipe_bp->burst, 8 * hz);
/*
* XXX the following is a hack based on ->next being the
* first field in dn_pipe and dn_flow_set. The correct
switch (sopt->sopt_name) {
default :
printf("dummynet: -- unknown option %d", sopt->sopt_name);
- error = EINVAL ;
+ error = EINVAL ;
break ;
case IP_DUMMYNET_GET :
break ;
case IP_DUMMYNET_DEL : /* remove a pipe or queue */
- p = malloc(sizeof(struct dn_pipe_max), M_TEMP, M_WAITOK);
- error = sooptcopyin(sopt, p, sizeof *p, sizeof *p);
+ p = malloc(sizeof(struct dn_pipe), M_TEMP, M_WAITOK);
+ error = sooptcopyin(sopt, p, sizeof (struct dn_pipe), sizeof *p);
if (error)
break ;