Deleted Added
full compact
ip_dummynet.c (201122) ip_dummynet.c (201527)
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:

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

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
28#include <sys/cdefs.h>
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:

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

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
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_dummynet.c 201122 2009-12-28 10:47:04Z luigi $");
29__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_dummynet.c 201527 2010-01-04 19:01:22Z luigi $");
30
31#define DUMMYNET_DEBUG
32
33#include "opt_inet6.h"
34
35/*
36 * This module implements IP dummynet, a bandwidth limiter/delay emulator
37 * used in conjunction with the ipfw package.

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

457 bzero(h, sizeof(*h) );
458}
459
460/*
461 * --- end of heap management functions ---
462 */
463
464/*
30
31#define DUMMYNET_DEBUG
32
33#include "opt_inet6.h"
34
35/*
36 * This module implements IP dummynet, a bandwidth limiter/delay emulator
37 * used in conjunction with the ipfw package.

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

457 bzero(h, sizeof(*h) );
458}
459
460/*
461 * --- end of heap management functions ---
462 */
463
464/*
465 * Dispose a packet in dummynet. Use an inline functions so if we
465 * Dispose a list of packet. Use an inline functions so if we
466 * need to free extra state associated to a packet, this is a
467 * central point to do it.
468 */
466 * need to free extra state associated to a packet, this is a
467 * central point to do it.
468 */
469static __inline void *dn_free_pkt(struct mbuf *m)
470{
471 m_freem(m);
472 return NULL;
473}
474
475static __inline void dn_free_pkts(struct mbuf *mnext)
476{
477 struct mbuf *m;
478
479 while ((m = mnext) != NULL) {
480 mnext = m->m_nextpkt;
469
470static __inline void dn_free_pkts(struct mbuf *mnext)
471{
472 struct mbuf *m;
473
474 while ((m = mnext) != NULL) {
475 mnext = m->m_nextpkt;
481 dn_free_pkt(m);
476 FREE_PKT(m);
482 }
483}
484
485/*
486 * Return the mbuf tag holding the dummynet state. As an optimization
487 * this is assumed to be the first tag on the list. If this turns out
488 * wrong we'll need to search the list.
489 */

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

963static void
964dummynet_send(struct mbuf *m)
965{
966 struct mbuf *n;
967
968 for (; m != NULL; m = n) {
969 struct ifnet *ifp;
970 int dst;
477 }
478}
479
480/*
481 * Return the mbuf tag holding the dummynet state. As an optimization
482 * this is assumed to be the first tag on the list. If this turns out
483 * wrong we'll need to search the list.
484 */

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

958static void
959dummynet_send(struct mbuf *m)
960{
961 struct mbuf *n;
962
963 for (; m != NULL; m = n) {
964 struct ifnet *ifp;
965 int dst;
966 struct m_tag *tag;
971
972 n = m->m_nextpkt;
973 m->m_nextpkt = NULL;
967
968 n = m->m_nextpkt;
969 m->m_nextpkt = NULL;
974 if (m_tag_first(m) == NULL) {
970 tag = m_tag_first(m);
971 if (tag == NULL) {
975 dst = DIR_DROP;
976 } else {
977 struct dn_pkt_tag *pkt = dn_tag_get(m);
972 dst = DIR_DROP;
973 } else {
974 struct dn_pkt_tag *pkt = dn_tag_get(m);
975 /* extract the dummynet info, rename the tag */
978 dst = pkt->dn_dir;
979 ifp = pkt->ifp;
976 dst = pkt->dn_dir;
977 ifp = pkt->ifp;
978 /* rename the tag so it carries reinject info */
979 tag->m_tag_cookie = MTAG_IPFW_RULE;
980 tag->m_tag_id = 0;
980 }
981
982 switch (dst) {
983 case DIR_OUT:
981 }
982
983 switch (dst) {
984 case DIR_OUT:
985 SET_HOST_IPLEN(mtod(m, struct ip *));
984 ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
985 break ;
986 case DIR_IN :
987 /* put header in network format for ip_input() */
986 ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
987 break ;
988 case DIR_IN :
989 /* put header in network format for ip_input() */
988 SET_NET_IPLEN(mtod(m, struct ip *));
990 //SET_NET_IPLEN(mtod(m, struct ip *));
989 netisr_dispatch(NETISR_IP, m);
990 break;
991#ifdef INET6
992 case DIR_IN | PROTO_IPV6:
993 netisr_dispatch(NETISR_IPV6, m);
994 break;
995
996 case DIR_OUT | PROTO_IPV6:
991 netisr_dispatch(NETISR_IP, m);
992 break;
993#ifdef INET6
994 case DIR_IN | PROTO_IPV6:
995 netisr_dispatch(NETISR_IPV6, m);
996 break;
997
998 case DIR_OUT | PROTO_IPV6:
999 SET_HOST_IPLEN(mtod(m, struct ip *));
997 ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
998 break;
999#endif
1000 case DIR_FWD | PROTO_IFB: /* DN_TO_IFB_FWD: */
1001 if (bridge_dn_p != NULL)
1002 ((*bridge_dn_p)(m, ifp));
1003 else
1004 printf("dummynet: if_bridge not loaded\n");

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

1019 ether_demux(m->m_pkthdr.rcvif, m);
1020 break;
1021 case DIR_OUT | PROTO_LAYER2: /* N_TO_ETH_OUT: */
1022 ether_output_frame(ifp, m);
1023 break;
1024
1025 case DIR_DROP:
1026 /* drop the packet after some time */
1000 ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
1001 break;
1002#endif
1003 case DIR_FWD | PROTO_IFB: /* DN_TO_IFB_FWD: */
1004 if (bridge_dn_p != NULL)
1005 ((*bridge_dn_p)(m, ifp));
1006 else
1007 printf("dummynet: if_bridge not loaded\n");

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

1022 ether_demux(m->m_pkthdr.rcvif, m);
1023 break;
1024 case DIR_OUT | PROTO_LAYER2: /* N_TO_ETH_OUT: */
1025 ether_output_frame(ifp, m);
1026 break;
1027
1028 case DIR_DROP:
1029 /* drop the packet after some time */
1027 dn_free_pkt(m);
1030 FREE_PKT(m);
1028 break;
1029
1030 default:
1031 printf("dummynet: bad switch %d!\n", dst);
1031 break;
1032
1033 default:
1034 printf("dummynet: bad switch %d!\n", dst);
1032 dn_free_pkt(m);
1035 FREE_PKT(m);
1033 break;
1034 }
1035 }
1036}
1037
1038/*
1039 * Unconditionally expire empty queues in case of shortage.
1040 * Returns the number of queues freed.

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

1357{
1358 struct mbuf *m = *m0, *head = NULL, *tail = NULL;
1359 struct dn_pkt_tag *pkt;
1360 struct m_tag *mtag;
1361 struct dn_flow_set *fs = NULL;
1362 struct dn_pipe *pipe;
1363 uint64_t len = m->m_pkthdr.len;
1364 struct dn_flow_queue *q = NULL;
1036 break;
1037 }
1038 }
1039}
1040
1041/*
1042 * Unconditionally expire empty queues in case of shortage.
1043 * Returns the number of queues freed.

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

1360{
1361 struct mbuf *m = *m0, *head = NULL, *tail = NULL;
1362 struct dn_pkt_tag *pkt;
1363 struct m_tag *mtag;
1364 struct dn_flow_set *fs = NULL;
1365 struct dn_pipe *pipe;
1366 uint64_t len = m->m_pkthdr.len;
1367 struct dn_flow_queue *q = NULL;
1365 int is_pipe = fwa->cookie & 0x8000000 ? 0 : 1;
1368 int is_pipe = fwa->rule.info & IPFW_IS_PIPE;
1366
1367 KASSERT(m->m_nextpkt == NULL,
1368 ("dummynet_io: mbuf queue passed to dummynet"));
1369
1370 DUMMYNET_LOCK();
1371 io_pkt++;
1372 /*
1373 * This is a dummynet rule, so we expect an O_PIPE or O_QUEUE rule.
1369
1370 KASSERT(m->m_nextpkt == NULL,
1371 ("dummynet_io: mbuf queue passed to dummynet"));
1372
1373 DUMMYNET_LOCK();
1374 io_pkt++;
1375 /*
1376 * This is a dummynet rule, so we expect an O_PIPE or O_QUEUE rule.
1374 *
1375 * XXXGL: probably the pipe->fs and fs->pipe logic here
1376 * below can be simplified.
1377 */
1378 if (is_pipe) {
1377 */
1378 if (is_pipe) {
1379 pipe = locate_pipe(fwa->cookie & 0xffff);
1379 pipe = locate_pipe(fwa->rule.info & IPFW_INFO_MASK);
1380 if (pipe != NULL)
1381 fs = &(pipe->fs);
1382 } else
1380 if (pipe != NULL)
1381 fs = &(pipe->fs);
1382 } else
1383 fs = locate_flowset(fwa->cookie & 0xffff);
1383 fs = locate_flowset(fwa->rule.info & IPFW_INFO_MASK);
1384
1385 if (fs == NULL)
1386 goto dropit; /* This queue/pipe does not exist! */
1387 pipe = fs->pipe;
1388 if (pipe == NULL) { /* Must be a queue, try find a matching pipe. */
1389 pipe = locate_pipe(fs->parent_nr);
1390 if (pipe != NULL)
1391 fs->pipe = pipe;

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

1421 goto dropit; /* Cannot allocate packet header. */
1422 m_tag_prepend(m, mtag); /* Attach to mbuf chain. */
1423
1424 pkt = (struct dn_pkt_tag *)(mtag + 1);
1425 /*
1426 * Ok, i can handle the pkt now...
1427 * Build and enqueue packet + parameters.
1428 */
1384
1385 if (fs == NULL)
1386 goto dropit; /* This queue/pipe does not exist! */
1387 pipe = fs->pipe;
1388 if (pipe == NULL) { /* Must be a queue, try find a matching pipe. */
1389 pipe = locate_pipe(fs->parent_nr);
1390 if (pipe != NULL)
1391 fs->pipe = pipe;

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

1421 goto dropit; /* Cannot allocate packet header. */
1422 m_tag_prepend(m, mtag); /* Attach to mbuf chain. */
1423
1424 pkt = (struct dn_pkt_tag *)(mtag + 1);
1425 /*
1426 * Ok, i can handle the pkt now...
1427 * Build and enqueue packet + parameters.
1428 */
1429 pkt->slot = fwa->slot;
1430 pkt->rulenum = fwa->rulenum;
1431 pkt->rule_id = fwa->rule_id;
1432 pkt->chain_id = fwa->chain_id;
1429 pkt->rule = fwa->rule;
1430 pkt->rule.info &= IPFW_ONEPASS; /* only keep this info */
1433 pkt->dn_dir = dir;
1431 pkt->dn_dir = dir;
1434
1435 pkt->ifp = fwa->oif;
1436
1437 if (q->head == NULL)
1438 q->head = m;
1439 else
1440 q->tail->m_nextpkt = m;
1441 q->tail = m;
1442 q->len++;

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

1557 dummynet_send(head);
1558 return (0);
1559
1560dropit:
1561 io_pkt_drop++;
1562 if (q)
1563 q->drops++;
1564 DUMMYNET_UNLOCK();
1432 pkt->ifp = fwa->oif;
1433
1434 if (q->head == NULL)
1435 q->head = m;
1436 else
1437 q->tail->m_nextpkt = m;
1438 q->tail = m;
1439 q->len++;

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

1554 dummynet_send(head);
1555 return (0);
1556
1557dropit:
1558 io_pkt_drop++;
1559 if (q)
1560 q->drops++;
1561 DUMMYNET_UNLOCK();
1565 *m0 = dn_free_pkt(m);
1562 FREE_PKT(m);
1563 *m0 = NULL;
1566 return ((fs && (fs->flags_fs & DN_NOERROR)) ? 0 : ENOBUFS);
1567}
1568
1569/*
1570 * Dispose all packets and flow_queues on a flow_set.
1571 * If all=1, also remove red lookup table and other storage,
1572 * including the descriptor itself.
1573 * For the one in dn_pipe MUST also cleanup ready_heap...

--- 789 unchanged lines hidden ---
1564 return ((fs && (fs->flags_fs & DN_NOERROR)) ? 0 : ENOBUFS);
1565}
1566
1567/*
1568 * Dispose all packets and flow_queues on a flow_set.
1569 * If all=1, also remove red lookup table and other storage,
1570 * including the descriptor itself.
1571 * For the one in dn_pipe MUST also cleanup ready_heap...

--- 789 unchanged lines hidden ---