From 44f1bb1a55b927fe9a37366885eaf04a1ca684de Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Tue, 4 May 1999 07:30:08 +0000 Subject: [PATCH] assorted dummynet cleanup: + plug an mbuf leak when dummynet used with bridging + make prototype of dummynet_io consistent with usage + code cleanup so that now bandwidth regulation is precise to the bit/s and not to (8*HZ) bit/s as before. --- sys/netinet/ip_dummynet.c | 58 +++++++++++++++++++++++---------------- sys/netinet/ip_dummynet.h | 7 +++-- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/sys/netinet/ip_dummynet.c b/sys/netinet/ip_dummynet.c index 26c92a56b32f..024998c6a109 100644 --- a/sys/netinet/ip_dummynet.c +++ b/sys/netinet/ip_dummynet.c @@ -10,7 +10,7 @@ * * This software is provided ``AS IS'' without any warranties of any kind. * - * $Id: ip_dummynet.c,v 1.11 1999/04/17 11:09:08 peter Exp $ + * $Id: ip_dummynet.c,v 1.12 1999/04/20 13:32:04 peter Exp $ */ /* @@ -153,9 +153,11 @@ dn_move(struct dn_pipe *pipe, int immediate) * such that the pkt would go out before the next tick. */ if (pipe->bandwidth) { - if (pipe->numbytes < len) + int len_scaled = len*8*hz ; + /* numbytes is in bit/sec, scaled 8*hz ... */ + if (pipe->numbytes < len_scaled) break; - pipe->numbytes -= len; + pipe->numbytes -= len_scaled; } pipe->r_len--; /* elements in queue */ pipe->r_len_bytes -= len ; @@ -217,7 +219,7 @@ dn_move(struct dn_pipe *pipe, int immediate) struct rtentry *tmp_rt = pkt->ro.ro_rt ; (void)ip_output((struct mbuf *)pkt, (struct mbuf *)pkt->ifp, - &(pkt->ro), pkt->dn_hlen, NULL); + &(pkt->ro), pkt->dn_dst, NULL); rt_unref (tmp_rt) ; } break ; @@ -225,8 +227,13 @@ dn_move(struct dn_pipe *pipe, int immediate) ip_input((struct mbuf *)pkt) ; break ; #ifdef BRIDGE - case DN_TO_BDG_FWD : - bdg_forward((struct mbuf **)&pkt, pkt->ifp); + case DN_TO_BDG_FWD : { + struct mbuf *m = (struct mbuf *)pkt ; + + bdg_forward(&m, pkt->ifp); + if (m) + m_freem(m); + } break ; #endif default: @@ -278,7 +285,8 @@ dummynet(void * __unused unused) */ int dummynet_io(int pipe_nr, int dir, - struct mbuf *m, struct ifnet *ifp, struct route *ro, int hlen, + struct mbuf *m, struct ifnet *ifp, struct route *ro, + struct sockaddr_in *dst, struct ip_fw_chain *rule) { struct dn_pkt *pkt; @@ -334,11 +342,21 @@ dummynet_io(int pipe_nr, int dir, pkt->ifp = ifp; if (dir == DN_TO_IP_OUT) { - pkt->ro = *ro; /* XXX copied! */ + /* + * we need to copy *ro because for icmp pkts (and maybe others) + * the caller passed a pointer into the stack. + */ + pkt->ro = *ro; if (ro->ro_rt) ro->ro_rt->rt_refcnt++ ; /* XXX */ + /* + * and again, dst might be a pointer into *ro... + */ + if (dst == &ro->ro_dst) /* dst points into ro */ + dst = &(pkt->ro.ro_dst) ; + + pkt->dn_dst = dst; } - pkt->dn_hlen = hlen; if (pipe->r.head == NULL) pipe->r.head = pkt; else @@ -470,11 +488,10 @@ ip_dn_ctl(struct sockopt *sopt) struct dn_pipe *q = (struct dn_pipe *)bp ; bcopy(p, bp, sizeof( *p ) ); - /* - * return bw and delay in bits/s and ms, respectively - */ - q->bandwidth *= (8*hz) ; - q->delay = (q->delay * 1000) / hz ; + /* + * return bw and delay in bits/s and ms, respectively + */ + q->delay = (q->delay * 1000) / hz ; bp += sizeof( *p ) ; } error = sooptcopyout(sopt, buf, size); @@ -491,25 +508,19 @@ ip_dn_ctl(struct sockopt *sopt) /* * The config program passes parameters as follows: * bandwidth = bits/second (0 = no limits); - * must be translated in bytes/tick. * delay = ms * must be translated in ticks. * queue_size = slots (0 = no limit) * queue_size_bytes = bytes (0 = no limit) * only one can be set, must be bound-checked */ - if ( p->bandwidth > 0 ) { - p->bandwidth = p->bandwidth / 8 / hz ; - if (p->bandwidth == 0) /* too little does not make sense! */ - p->bandwidth = 10 ; - } p->delay = ( p->delay * hz ) / 1000 ; if (p->queue_size == 0 && p->queue_size_bytes == 0) - p->queue_size = 100 ; + p->queue_size = 50 ; if (p->queue_size != 0 ) /* buffers are prevailing */ p->queue_size_bytes = 0 ; if (p->queue_size > 100) - p->queue_size = 100 ; + p->queue_size = 50 ; if (p->queue_size_bytes > 1024*1024) p->queue_size_bytes = 1024*1024 ; #if 0 @@ -591,8 +602,7 @@ ip_dn_ctl(struct sockopt *sopt) static void ip_dn_init(void) { - printf("DUMMYNET initialized (990326) -- size dn_pkt %d\n", - sizeof(struct dn_pkt)); + printf("DUMMYNET initialized (990504)\n"); all_pipes = NULL ; ip_dn_ctl_ptr = ip_dn_ctl; } diff --git a/sys/netinet/ip_dummynet.h b/sys/netinet/ip_dummynet.h index c0bb0e33492a..98eae8206156 100644 --- a/sys/netinet/ip_dummynet.h +++ b/sys/netinet/ip_dummynet.h @@ -10,7 +10,7 @@ * * This software is provided ``AS IS'' without any warranties of any kind. * - * $Id: ip_dummynet.h,v 1.3 1999/01/23 23:59:50 archie Exp $ + * $Id: ip_dummynet.h,v 1.4 1999/04/20 13:32:04 peter Exp $ */ #ifndef _IP_DUMMYNET_H @@ -39,7 +39,7 @@ struct dn_pkt { struct m_hdr hdr ; #define dn_next hdr.mh_nextpkt /* next element in queue */ #define dn_m hdr.mh_next /* packet to be forwarded */ -#define dn_hlen hdr.mh_len /* hlen, for ip_output */ +#define dn_dst hdr.mh_len /* dst, for ip_output */ #define dn_dir hdr.mh_flags /* IP_FW_F_IN or IP_FW_F_OUT */ int delay; /* stays queued until delay=0 */ struct ifnet *ifp; /* interface, for ip_output */ @@ -107,7 +107,8 @@ extern ip_dn_ctl_t *ip_dn_ctl_ptr; void dn_rule_delete(void *r); /* used in ip_fw.c */ int dummynet_io(int pipe, int dir, - struct mbuf *m, struct ifnet *ifp, struct route *ro, int hlen, + struct mbuf *m, struct ifnet *ifp, struct route *ro, + struct sockaddr_in * dst, struct ip_fw_chain *rule); #endif /* KERNEL */