Deleted Added
full compact
ip_dummynet.c (132199) ip_dummynet.c (133920)
1/*
2 * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa
3 * Portions Copyright (c) 2000 Akamba Corp.
4 * All rights reserved
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
1/*
2 * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa
3 * Portions Copyright (c) 2000 Akamba Corp.
4 * All rights reserved
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/netinet/ip_dummynet.c 132199 2004-07-15 08:26:07Z phk $
27 * $FreeBSD: head/sys/netinet/ip_dummynet.c 133920 2004-08-17 22:05:54Z andre $
28 */
29
30#define DUMMYNET_DEBUG
31
32/*
33 * This module implements IP dummynet, a bandwidth limiter/delay emulator
34 * used in conjunction with the ipfw package.
35 * Description of the data structures used is in ip_dummynet.h

--- 138 unchanged lines hidden (view full) ---

174#define DUMMYNET_LOCK_ASSERT() do { \
175 mtx_assert(&dummynet_mtx, MA_OWNED); \
176 NET_ASSERT_GIANT(); \
177} while (0)
178
179static int config_pipe(struct dn_pipe *p);
180static int ip_dn_ctl(struct sockopt *sopt);
181
28 */
29
30#define DUMMYNET_DEBUG
31
32/*
33 * This module implements IP dummynet, a bandwidth limiter/delay emulator
34 * used in conjunction with the ipfw package.
35 * Description of the data structures used is in ip_dummynet.h

--- 138 unchanged lines hidden (view full) ---

174#define DUMMYNET_LOCK_ASSERT() do { \
175 mtx_assert(&dummynet_mtx, MA_OWNED); \
176 NET_ASSERT_GIANT(); \
177} while (0)
178
179static int config_pipe(struct dn_pipe *p);
180static int ip_dn_ctl(struct sockopt *sopt);
181
182static void rt_unref(struct rtentry *, const char *);
183static void dummynet(void *);
184static void dummynet_flush(void);
185void dummynet_drain(void);
186static ip_dn_io_t dummynet_io;
187static void dn_rule_delete(void *);
188
189int if_tx_rdy(struct ifnet *ifp);
190
182static void dummynet(void *);
183static void dummynet_flush(void);
184void dummynet_drain(void);
185static ip_dn_io_t dummynet_io;
186static void dn_rule_delete(void *);
187
188int if_tx_rdy(struct ifnet *ifp);
189
191static void
192rt_unref(struct rtentry *rt, const char *where)
193{
194 if (rt == NULL)
195 return ;
196 RT_LOCK(rt);
197 if (rt->rt_refcnt <= 0) {
198 printf("dummynet: warning, refcnt now %ld, decreasing (%s)\n",
199 rt->rt_refcnt, where);
200 }
201 RTFREE_LOCKED(rt);
202}
203
204/*
205 * Heap management functions.
206 *
207 * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
208 * Some macros help finding parent/children so we can optimize them.
209 *
210 * heap_init() is called to expand the heap when needed.
211 * Increment size in blocks of 16 entries.

--- 229 unchanged lines hidden (view full) ---

441 * before passing pkts out, because this might trigger recursive
442 * invocations of the procedures.
443 */
444static void
445transmit_event(struct dn_pipe *pipe)
446{
447 struct mbuf *m ;
448 struct dn_pkt_tag *pkt ;
190/*
191 * Heap management functions.
192 *
193 * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
194 * Some macros help finding parent/children so we can optimize them.
195 *
196 * heap_init() is called to expand the heap when needed.
197 * Increment size in blocks of 16 entries.

--- 229 unchanged lines hidden (view full) ---

427 * before passing pkts out, because this might trigger recursive
428 * invocations of the procedures.
429 */
430static void
431transmit_event(struct dn_pipe *pipe)
432{
433 struct mbuf *m ;
434 struct dn_pkt_tag *pkt ;
435 struct ip *ip;
449
450 DUMMYNET_LOCK_ASSERT();
451
452 while ( (m = pipe->head) ) {
453 pkt = dn_tag_get(m);
454 if ( !DN_KEY_LEQ(pkt->output_time, curr_time) )
455 break;
456 /*

--- 6 unchanged lines hidden (view full) ---

463 /* XXX: drop the lock for now to avoid LOR's */
464 DUMMYNET_UNLOCK();
465 switch (pkt->dn_dir) {
466 case DN_TO_IP_OUT:
467 (void)ip_output(m, NULL, NULL, pkt->flags, NULL, NULL);
468 break ;
469
470 case DN_TO_IP_IN :
436
437 DUMMYNET_LOCK_ASSERT();
438
439 while ( (m = pipe->head) ) {
440 pkt = dn_tag_get(m);
441 if ( !DN_KEY_LEQ(pkt->output_time, curr_time) )
442 break;
443 /*

--- 6 unchanged lines hidden (view full) ---

450 /* XXX: drop the lock for now to avoid LOR's */
451 DUMMYNET_UNLOCK();
452 switch (pkt->dn_dir) {
453 case DN_TO_IP_OUT:
454 (void)ip_output(m, NULL, NULL, pkt->flags, NULL, NULL);
455 break ;
456
457 case DN_TO_IP_IN :
458 ip = mtod(m, struct ip *);
459 ip->ip_len = htons(ip->ip_len);
460 ip->ip_off = htons(ip->ip_off);
471 ip_input(m) ;
472 break ;
473
474 case DN_TO_BDG_FWD :
475 /*
476 * The bridge requires/assumes the Ethernet header is
477 * contiguous in the first mbuf header. Insure this is true.
478 */

--- 643 unchanged lines hidden (view full) ---

1122 * depending on whether WF2Q or fixed bw is used.
1123 *
1124 * pipe_nr pipe or queue the packet is destined for.
1125 * dir where shall we send the packet after dummynet.
1126 * m the mbuf with the packet
1127 * ifp the 'ifp' parameter from the caller.
1128 * NULL in ip_input, destination interface in ip_output,
1129 * real_dst in bdg_forward
461 ip_input(m) ;
462 break ;
463
464 case DN_TO_BDG_FWD :
465 /*
466 * The bridge requires/assumes the Ethernet header is
467 * contiguous in the first mbuf header. Insure this is true.
468 */

--- 643 unchanged lines hidden (view full) ---

1112 * depending on whether WF2Q or fixed bw is used.
1113 *
1114 * pipe_nr pipe or queue the packet is destined for.
1115 * dir where shall we send the packet after dummynet.
1116 * m the mbuf with the packet
1117 * ifp the 'ifp' parameter from the caller.
1118 * NULL in ip_input, destination interface in ip_output,
1119 * real_dst in bdg_forward
1130 * ro route parameter (only used in ip_output, NULL otherwise)
1131 * dst destination address, only used by ip_output
1132 * rule matching rule, in case of multiple passes
1133 * flags flags from the caller, only used in ip_output
1134 *
1135 */
1136static int
1137dummynet_io(struct mbuf *m, int pipe_nr, int dir, struct ip_fw_args *fwa)
1138{
1139 struct dn_pkt_tag *pkt;

--- 69 unchanged lines hidden (view full) ---

1209
1210 pkt = (struct dn_pkt_tag *)(mtag+1);
1211 /* ok, i can handle the pkt now... */
1212 /* build and enqueue packet + parameters */
1213 pkt->rule = fwa->rule ;
1214 pkt->dn_dir = dir ;
1215
1216 pkt->ifp = fwa->oif;
1120 * rule matching rule, in case of multiple passes
1121 * flags flags from the caller, only used in ip_output
1122 *
1123 */
1124static int
1125dummynet_io(struct mbuf *m, int pipe_nr, int dir, struct ip_fw_args *fwa)
1126{
1127 struct dn_pkt_tag *pkt;

--- 69 unchanged lines hidden (view full) ---

1197
1198 pkt = (struct dn_pkt_tag *)(mtag+1);
1199 /* ok, i can handle the pkt now... */
1200 /* build and enqueue packet + parameters */
1201 pkt->rule = fwa->rule ;
1202 pkt->dn_dir = dir ;
1203
1204 pkt->ifp = fwa->oif;
1217 if (dir == DN_TO_IP_OUT) {
1218 /*
1219 * We need to copy *ro because for ICMP pkts (and maybe others)
1220 * the caller passed a pointer into the stack; dst might also be
1221 * a pointer into *ro so it needs to be updated.
1222 */
1223 pkt->ro = *(fwa->ro);
1224 if (pkt->ro.ro_rt) {
1225 RT_LOCK(pkt->ro.ro_rt);
1226 RT_ADDREF(pkt->ro.ro_rt) ;
1227 RT_UNLOCK(pkt->ro.ro_rt);
1228 }
1229 if (fwa->dst == (struct sockaddr_in *)&fwa->ro->ro_dst) /* dst points into ro */
1230 fwa->dst = (struct sockaddr_in *)&(pkt->ro.ro_dst) ;
1231 pkt->dn_dst = fwa->dst;
1205 if (dir == DN_TO_IP_OUT)
1232 pkt->flags = fwa->flags;
1206 pkt->flags = fwa->flags;
1233 }
1234 if (q->head == NULL)
1235 q->head = m;
1236 else
1237 q->tail->m_nextpkt = m;
1238 q->tail = m;
1239 q->len++;
1240 q->len_bytes += len ;
1241

--- 80 unchanged lines hidden (view full) ---

1322 return ( (fs && (fs->flags_fs & DN_NOERROR)) ? 0 : ENOBUFS);
1323}
1324
1325/*
1326 * Below, the rt_unref is only needed when (pkt->dn_dir == DN_TO_IP_OUT)
1327 * Doing this would probably save us the initial bzero of dn_pkt
1328 */
1329#define DN_FREE_PKT(_m) do { \
1207 if (q->head == NULL)
1208 q->head = m;
1209 else
1210 q->tail->m_nextpkt = m;
1211 q->tail = m;
1212 q->len++;
1213 q->len_bytes += len ;
1214

--- 80 unchanged lines hidden (view full) ---

1295 return ( (fs && (fs->flags_fs & DN_NOERROR)) ? 0 : ENOBUFS);
1296}
1297
1298/*
1299 * Below, the rt_unref is only needed when (pkt->dn_dir == DN_TO_IP_OUT)
1300 * Doing this would probably save us the initial bzero of dn_pkt
1301 */
1302#define DN_FREE_PKT(_m) do { \
1330 rt_unref(dn_tag_get(_m)->ro.ro_rt, __func__); \
1331 m_freem(_m); \
1332} while (0)
1333
1334/*
1335 * Dispose all packets and flow_queues on a flow_set.
1336 * If all=1, also remove red lookup table and other storage,
1337 * including the descriptor itself.
1338 * For the one in dn_pipe MUST also cleanup ready_heap...

--- 747 unchanged lines hidden (view full) ---

2086 return 0 ;
2087}
2088
2089static moduledata_t dummynet_mod = {
2090 "dummynet",
2091 dummynet_modevent,
2092 NULL
2093};
1303 m_freem(_m); \
1304} while (0)
1305
1306/*
1307 * Dispose all packets and flow_queues on a flow_set.
1308 * If all=1, also remove red lookup table and other storage,
1309 * including the descriptor itself.
1310 * For the one in dn_pipe MUST also cleanup ready_heap...

--- 747 unchanged lines hidden (view full) ---

2058 return 0 ;
2059}
2060
2061static moduledata_t dummynet_mod = {
2062 "dummynet",
2063 dummynet_modevent,
2064 NULL
2065};
2094DECLARE_MODULE(dummynet, dummynet_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
2095MODULE_DEPEND(dummynet, ipfw, 1, 1, 1);
2066DECLARE_MODULE(dummynet, dummynet_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
2067MODULE_DEPEND(dummynet, ipfw, 2, 2, 2);
2096MODULE_VERSION(dummynet, 1);
2068MODULE_VERSION(dummynet, 1);