X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=dummynet%2Fip_dummynet.c;h=5b36eccbf39d05f872632988e371065dcab79a9e;hb=5ad9fec40da13c449d50def12f9cea6e24b6a708;hp=c0399bb408fd892cd82710fddeea071cdf12d598;hpb=6c2e192c3237bd46db6ad4230fed71d28f362331;p=ipfw.git diff --git a/dummynet/ip_dummynet.c b/dummynet/ip_dummynet.c index c0399bb..5b36ecc 100644 --- a/dummynet/ip_dummynet.c +++ b/dummynet/ip_dummynet.c @@ -56,6 +56,8 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_dummynet.c,v 1.110.2.4 2008/10/31 12:58:1 * include files marked with XXX are probably not needed */ +#include "missing.h" + #include #include #include @@ -64,15 +66,15 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_dummynet.c,v 1.110.2.4 2008/10/31 12:58:1 #include #include #include -#include #include #include +#include #include #include #include #include #include -#include /* IFNAMSIZ, struct ifaddr, ifq head */ +#include /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */ #include #include #include /* ip_len, ip_off */ @@ -85,8 +87,6 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_dummynet.c,v 1.110.2.4 2008/10/31 12:58:1 #include /* for ip6_input, ip6_output prototypes */ #include -#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) @@ -248,8 +248,8 @@ static void dummynet(void *); 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. @@ -697,13 +697,17 @@ ready_event_wfq(struct dn_pipe *p, struct mbuf **head, struct mbuf **tail) 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, @@ -814,13 +818,8 @@ ready_event_wfq(struct dn_pipe *p, struct mbuf **head, struct mbuf **tail) */ } - /* 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. @@ -1245,7 +1244,7 @@ red_drops(struct dn_flow_set *fs, struct dn_flow_queue *q, int len) 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; } } @@ -1423,6 +1422,8 @@ dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) * 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; @@ -1477,7 +1478,7 @@ dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) 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) @@ -1540,7 +1541,7 @@ dropit: 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); } @@ -1554,7 +1555,7 @@ dropit: netisr_dispatch(-1, _m); \ } while (0) #else -#define DN_FREE_PKT(_m) do { \ +#define DN_FREE_PKT(_m) do { \ m_freem(_m); \ } while (0) #endif @@ -1836,6 +1837,8 @@ config_pipe(struct dn_pipe *p) * 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); @@ -2212,6 +2215,7 @@ dummynet_get(struct sockopt *sopt) */ 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 @@ -2278,7 +2282,7 @@ ip_dn_ctl(struct sockopt *sopt) switch (sopt->sopt_name) { default : printf("dummynet: -- unknown option %d", sopt->sopt_name); - error = EINVAL ; + error = EINVAL ; break ; case IP_DUMMYNET_GET : @@ -2301,8 +2305,8 @@ ip_dn_ctl(struct sockopt *sopt) 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 ;