File:  [pfSense CVS Repository] / tools / patches / RELENG_7 / dummynet.RELENG_7.diff
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Tue Oct 28 19:12:57 2008 UTC (22 months ago) by ermal
Branches: MAIN
CVS tags: HEAD
Spell correctly.

Index: contrib/pf/pfctl/parse.y
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/contrib/pf/pfctl/parse.y,v
retrieving revision 1.3
diff -u -r1.3 parse.y
--- contrib/pf/pfctl/parse.y	21 Oct 2008 15:23:00 -0000	1.3
+++ contrib/pf/pfctl/parse.y	28 Oct 2008 20:02:51 -0000
@@ -32,6 +32,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/sysctl.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -46,6 +47,9 @@
 #include <altq/altq_hfsc.h>
 #include <altq/altq_fairq.h>
 
+#include <netinet/ip_fw.h>
+#include <netinet/ip_dummynet.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <netdb.h>
@@ -209,6 +213,9 @@
 	char			*tag;
 	char			*match_tag;
 	u_int8_t		 match_tag_not;
+	u_int32_t		 dnpipe;
+	u_int32_t		 pdnpipe;
+	u_int32_t		 free_flags;
 	int			 rtableid;
 } filter_opts;
 
@@ -265,6 +272,8 @@
 
 struct node_hfsc_opts	hfsc_opts;
 struct node_fairq_opts	fairq_opts;
+struct dn_pipe          dnpipe_opts;
+struct dn_flow_set    	dnqueue_opts;
 
 int	yyerror(const char *, ...);
 int	disallow_table(struct node_host *, const char *);
@@ -399,6 +408,8 @@
 		struct filter_opts	 filter_opts;
 		struct antispoof_opts	 antispoof_opts;
 		struct queue_opts	 queue_opts;
+		struct dn_pipe		 dnpipe_opts;
+		struct dn_flow_set	 dnqueue_opts;
 		struct scrub_opts	 scrub_opts;
 		struct table_opts	 table_opts;
 		struct pool_opts	 pool_opts;
@@ -426,6 +437,8 @@
 %token	BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY
 %token	ALTQ CBQ PRIQ HFSC FAIRQ BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT
 %token	QUEUE PRIORITY QLIMIT HOGS BUCKETS RTABLE
+%token  DNPIPE DNQUEUE DUMMYNET DNGRED DNRED WEIGHT MASK DELAY BUCKETS PLR
+%token  SRCIP DSTIP SRCPORT DSTPORT SRCIP6 DSTIP6 FLOWID NOERROR
 %token	LOAD RULESET_OPTIMIZATION
 %token	STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
 %token	MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH
@@ -468,6 +481,8 @@
 %type	<v.number>		priqflags_list priqflags_item
 %type	<v.hfsc_opts>		hfscopts_list hfscopts_item hfsc_opts
 %type	<v.fairq_opts>		fairqopts_list fairqopts_item fairq_opts
+%type 	<v.dnpipe_opts>         dnpipe_opts
+%type 	<v.dnqueue_opts>        dnqueue_opts mask_specifier
 %type	<v.queue_bwspec>	bandwidth
 %type	<v.filter_opts>		filter_opts filter_opt filter_opts_l
 %type	<v.antispoof_opts>	antispoof_opts antispoof_opt antispoof_opts_l
@@ -490,6 +505,8 @@
 		| ruleset loadrule '\n'
 		| ruleset altqif '\n'
 		| ruleset queuespec '\n'
+		| ruleset dummynetif '\n'
+		| ruleset dnqueuespec '\n'
 		| ruleset varset '\n'
 		| ruleset antispoof '\n'
 		| ruleset tabledef '\n'
@@ -1447,14 +1464,22 @@
 
 			bps = strtod($1, &cp);
 			if (cp != NULL) {
-				if (!strcmp(cp, "b"))
+				if (!strcmp(cp, "b") || !strcmp(cp, "bit"))
 					; /* nothing */
-				else if (!strcmp(cp, "Kb"))
+				else if (!strcmp(cp, "Kb") || !strcmp(cp, "Kbit"))
 					bps *= 1000;
-				else if (!strcmp(cp, "Mb"))
+				else if (!strcmp(cp, "Mb") || !strcmp(cp, "Mbit"))
 					bps *= 1000 * 1000;
-				else if (!strcmp(cp, "Gb"))
+				else if (!strcmp(cp, "Gb") || !strcmp(cp, "Gbit"))
 					bps *= 1000 * 1000 * 1000;
+				else if (!strcmp(cp, "B") || !strcmp(cp, "Byte"))
+					; /* nothing */
+				else if (!strcmp(cp, "KB") || !strcmp(cp, "Kbyte"))
+					bps *= 1024;
+				else if (!strcmp(cp, "MB") || !strcmp(cp, "Mbyte"))
+					bps *= 1024 * 1024;
+				else if (!strcmp(cp, "GB") || !strcmp(cp, "Gbyte"))
+					bps *= 1024 * 1024 * 1024;
 				else if (!strcmp(cp, "%")) {
 					if (bps < 0 || bps > 100) {
 						yyerror("bandwidth spec "
@@ -1731,6 +1756,255 @@
 		}
 		;
 
+dummynetif      : DNPIPE number dnpipe_opts dnqueue_opts        {
+                        struct dn_pipe p;
+
+                        if (check_rulestate(PFCTL_STATE_QUEUE))
+                                YYERROR;
+
+                        memset(&p, 0, sizeof(p));
+
+                        p.bandwidth = $3.bandwidth;
+                        p.delay = $3.delay;
+			if ($2 < 1) {
+				yyerror("pipe number must be greater than 0");
+				YYERROR;
+			}
+			p.pipe_nr = $2;
+                        memcpy(&p.fs, &$4,
+                                sizeof(p.fs));
+			if (p.fs.flags_fs & DN_IS_RED)
+				calculate_dnred(&p.fs, p.bandwidth);
+
+                        if (pfctl_add_dummynet(pf, &p)) {
+				yyerror("errors in dnpipe definition");
+                                YYERROR;
+			}
+                }
+dnqueuespec     : DNQUEUE number DNPIPE number dnqueue_opts {
+		        struct dn_pipe p;
+
+                        if (check_rulestate(PFCTL_STATE_QUEUE)) 
+                                YYERROR;
+
+                        memset(&p, 0, sizeof(p));
+
+                        if ($4 < 1) {
+                                yyerror("pipe must be specified for queue");
+                                YYERROR;
+                        }
+			if ($2 < 1) {
+				yyerror("queue number must be greater than 0");
+				YYERROR;
+			}
+					
+                        memcpy(&p.fs, &$5, sizeof(p.fs));
+			p.fs.fs_nr = $2;
+                        p.fs.parent_nr = $4;
+			p.pipe_nr = 0;
+			if (p.fs.flags_fs & DN_IS_RED)
+				calculate_dnred(&p.fs, p.bandwidth);
+
+                        if (pfctl_add_dummynet(pf, &p)) {
+                                yyerror("errors in dnqueue definition");
+                                YYERROR;
+                        }
+                }
+                ;
+
+dnpipe_opts     :       /* XXX: fix this */ {
+	                bzero(&dnpipe_opts, sizeof dnpipe_opts);
+                }
+                        dnpipe_opts_l
+                       	{ $$ = dnpipe_opts; }
+                |	/* empty */ {
+                        bzero(&dnpipe_opts, sizeof dnpipe_opts);
+                        $$ = dnpipe_opts;
+                }
+                ;
+
+dnpipe_opts_l   : dnpipe_opts_l dnpipe_opt
+	        | dnpipe_opt
+                ;
+
+dnpipe_opt      : BANDWIDTH bandwidth   {
+                        dnpipe_opts.bandwidth = $2.bw_absolute;
+                }
+                | DELAY number          {
+                        if ($2 > 0 && $2 < 10001)
+                                dnpipe_opts.delay = $2;
+                        else {
+                                yyerror("delay needs argument 0..10000ms");
+                                YYERROR;
+                        }
+                }
+                ;
+
+dnqueue_opts    : /* XXX: fix this */ {
+		        bzero(&dnqueue_opts, sizeof dnqueue_opts);
+                }
+                    dnqueue_opts_l
+                        { $$ = dnqueue_opts; }
+                | /* empty */ {
+                        bzero(&queue_opts, sizeof queue_opts);
+                        $$ = dnqueue_opts;
+                }
+                ;
+
+dnqueue_opts_l  : dnqueue_opts_l dnqueue_opt
+		| dnqueue_opt
+                ;
+
+dnqueue_opt     : BUCKETS number       {
+		        if ($2 < 16 || $2 > 65535) {
+                                yyerror("buckets out of range: [16-65535]");
+                                YYERROR;
+                        }
+                        dnqueue_opts.rq_size = $2;
+                }
+		| WEIGHT number			  {
+			if ($2 < 0 || $2 > 100)  { /* [0..100] is allowed */
+                                yyerror("weight must be in [0..100] range");
+                                YYERROR;
+                        }
+                        
+			dnqueue_opts.weight = $2;
+		}
+                | QUEUE STRING		 {
+                        double   bps;
+                        char    *cp;
+
+			bps = strtod($2, &cp);
+                        if (bps < 16 || bps > 65535) {
+                                yyerror("qlimit out of range [16..65535]");
+                                YYERROR;
+                        }
+
+                        if (cp != NULL) {
+                                if (!strcmp(cp, "B") || !strcmp(cp, "Byte"))
+					dnqueue_opts.flags_fs |= 
+						DN_QSIZE_IS_BYTES;
+                                else if (!strcmp(cp, "KB") || !strcmp(cp, "KByte")) {
+                                        bps *= 1024;
+					dnqueue_opts.flags_fs |= 
+						DN_QSIZE_IS_BYTES;
+                                } else if (*cp != '\0') {
+                                        yyerror("unknown unit %s", cp);
+                                        free($2);
+                                        YYERROR;
+                                }
+			} else 
+				dnqueue_opts.flags_fs &= 
+					~DN_QSIZE_IS_BYTES;
+                        free($2);
+
+                        dnqueue_opts.qsize = (u_int32_t)bps;
+                }
+                | PLR number                            {
+                        dnqueue_opts.plr = (int)$2*0x7fffffff ;
+                }
+                | MASK mask_specifier   {
+                        memcpy(&dnqueue_opts, &$2,
+                                sizeof(dnqueue_opts));
+                }
+                | DNRED string '/' string '/' string '/' string       {
+			/*
+                         * the format for parameters is w_q/min_th/max_th/max_p
+                         */
+			char *end;
+			int error = 0;
+		
+                        double w_q = strtod($2, NULL);
+                        if (w_q > 1 || w_q <= 0) {
+                         	yyerror("0 < w_q <= 1");
+				error = 1;
+			}
+                        dnqueue_opts.w_q = (int) (w_q * (1 << SCALE_RED));
+                        
+                        dnqueue_opts.min_th = strtoul($4, &end, 0); 
+                        if (*end == 'K' || *end == 'k')
+                        	dnqueue_opts.min_th *= 1024;
+                        
+                        dnqueue_opts.max_th = strtoul($6, &end, 0);
+                        if (*end == 'K' || *end == 'k')
+                        	dnqueue_opts.max_th *= 1024;
+                       
+                        double max_p = strtod($8, NULL);
+                        if (max_p > 1 || max_p <= 0) {
+				yyerror("max_p moust be between 0 and 1");
+				error = 1;
+			}
+                        dnqueue_opts.max_p = (int)(max_p * (1 << SCALE_RED));
+
+			dnqueue_opts.flags_fs |= DN_IS_RED;
+			
+			if (dnqueue_opts.min_th >= dnqueue_opts.max_th) {
+        	        	yyerror("min_th %d must be < than max_th %d",
+                        		dnqueue_opts.min_th, dnqueue_opts.max_th);
+				error = 1;
+			}
+                	if (dnqueue_opts.max_th == 0) {
+                    		yyerror("max_th must be > 0");
+				error = 1;
+			}
+
+			free($2), free($4), free($6), free($8);
+			if (error > 0) {
+				YYERROR;
+			}
+                }
+                ;
+
+mask_specifier  : ALL                   {
+
+                        memset(&$$, 0, sizeof($$));
+
+                        $$.flow_mask.dst_ip = ~0;
+                        $$.flow_mask.src_ip = ~0;
+                        $$.flow_mask.dst_port = ~0;
+                        $$.flow_mask.src_port = ~0;
+                        $$.flow_mask.proto = ~0;
+                        n2mask(&$$.flow_mask.dst_ip6, 128);
+                        n2mask(&$$.flow_mask.src_ip6, 128);
+                        $$.flow_mask.flow_id6 = ~0;
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+                }
+                | DSTIP number             	{
+			$$.flow_mask.dst_ip = (uint32_t)$2;
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+                }
+                | SRCIP number	             {
+                        $$.flow_mask.src_ip = (uint32_t)$2;
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+                }
+                | DSTPORT number	           {
+                        $$.flow_mask.dst_port = (uint16_t)$2;
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+                }
+                | SRCPORT number	           {
+                        $$.flow_mask.src_port = (uint16_t)$2;
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+                }
+                | DSTIP6 '/' number 	           {
+                        n2mask(&$$.flow_mask.dst_ip6, $3);
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+                }
+                | SRCIP6 '/' number	            {
+                        n2mask(&$$.flow_mask.src_ip6, $3);
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+                }
+                | FLOWID number	            {
+                        $$.flow_mask.flow_id6 = (uint32_t)$2;
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+
+                }
+                | PROTO number 	             {
+                        $$.flow_mask.proto = (uint8_t)$2;
+                        $$.flags_fs |= DN_HAVE_FLOW_MASK;
+                }
+                | NOERROR       { $$.flags_fs |= DN_NOERROR; }
+                ;
+
 pfrule		: action dir logquick interface route af proto fromto
 		    filter_opts
 		{
@@ -2105,6 +2379,15 @@
 				free($9.queues.pqname);
 			}
 
+			if ($9.dnpipe) {
+                                r.dnpipe = $9.dnpipe;
+				if ($9.free_flags & PFRULE_DN_IS_PIPE)
+					r.free_flags |= PFRULE_DN_IS_PIPE;
+				else
+					r.free_flags |= PFRULE_DN_IS_QUEUE;
+				r.pdnpipe = $9.pdnpipe;
+			}
+
 			expand_rule(&r, $4, $5.host, $7, $8.src_os,
 			    $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
 			    $9.uid, $9.gid, $9.icmpspec, "");
@@ -2202,6 +2485,32 @@
 			}
 			filter_opts.queues = $1;
 		}
+		| DNPIPE number			        {
+			filter_opts.dnpipe = $2;
+			filter_opts.free_flags |= PFRULE_DN_IS_PIPE;
+		}
+		| DNPIPE '(' number ')'			{
+			filter_opts.dnpipe = $3;
+			filter_opts.free_flags |= PFRULE_DN_IS_PIPE;
+		}
+		| DNPIPE '(' number comma number ')' {
+			filter_opts.pdnpipe = $5;
+			filter_opts.dnpipe = $3;
+			filter_opts.free_flags |= PFRULE_DN_IS_PIPE;
+		}
+		| DNQUEUE number			{
+			filter_opts.dnpipe = $2;
+			filter_opts.free_flags |= PFRULE_DN_IS_QUEUE;
+		}
+		| DNQUEUE '(' number comma number ')'	{
+			filter_opts.pdnpipe = $5;
+			filter_opts.dnpipe = $3;
+			filter_opts.free_flags |= PFRULE_DN_IS_QUEUE;
+		}
+		| DNQUEUE '(' number ')'		{
+			filter_opts.dnpipe = $3;
+			filter_opts.free_flags |= PFRULE_DN_IS_QUEUE;
+		}
 		| TAG string				{
 			filter_opts.tag = $2;
 		}
@@ -4230,6 +4539,15 @@
 		yyerror("tos and dscp cannot be used together");
 		problems++;
 	}
+	if (r->dnpipe && r->pdnpipe && !r->direction) {
+		yyerror("dummynet cannot be specified without direction");
+		problems++;
+	}
+	if (r->dnpipe && !r->keep_state) {
+		yyerror("dummynet cannot be specified withtout keep state");
+		problems++;
+	}
+
 	return (-problems);
 }
 
@@ -5022,9 +5340,17 @@
 		{ "code",		CODE},
 		{ "crop",		FRAGCROP},
 		{ "debug",		DEBUG},
+		{ "delay",              DELAY},
+		{ "dngred",             DNGRED},
+		{ "dnpipe",             DNPIPE},
+                { "dnqueue",            DNQUEUE},
+		{ "dnred",		DNRED},
 		{ "drop",		DROP},
 		{ "drop-ovl",		FRAGDROP},
 		{ "dscp",		DSCP},
+		{ "dst-ip",             DSTIP},
+                { "dst-ip6",            DSTIP6},
+                { "dst-port",           DSTPORT},
 		{ "dup-to",		DUPTO},
 		{ "fairq",		FAIRQ},
 		{ "fastroute",		FASTROUTE},
@@ -5032,6 +5358,7 @@
 		{ "fingerprints",	FINGERPRINTS},
 		{ "flags",		FLAGS},
 		{ "floating",		FLOATING},
+		{ "flow-id",            FLOWID},
 		{ "flush",		FLUSH},
 		{ "for",		FOR},
 		{ "fragment",		FRAGMENT},
@@ -5054,6 +5381,7 @@
 		{ "load",		LOAD},
 		{ "log",		LOG},
 		{ "loginterface",	LOGINTERFACE},
+		{ "mask",		MASK},
 		{ "max",		MAXIMUM},
 		{ "max-mss",		MAXMSS},
 		{ "max-src-conn",	MAXSRCCONN},
@@ -5068,12 +5396,14 @@
 		{ "no-df",		NODF},
 		{ "no-route",		NOROUTE},
 		{ "no-sync",		NOSYNC},
+		{ "noerror",		NOERROR},
 		{ "on",			ON},
 		{ "optimization",	OPTIMIZATION},
 		{ "os",			OS},
 		{ "out",		OUT},
 		{ "overload",		OVERLOAD},
 		{ "pass",		PASS},
+		{ "plr",		PLR},
 		{ "port",		PORT},
 		{ "priority",		PRIORITY},
 		{ "priq",		PRIQ},
@@ -5105,6 +5435,9 @@
 		{ "skip",		SKIP},
 		{ "source-hash",	SOURCEHASH},
 		{ "source-track",	SOURCETRACK},
+		{ "src-ip",		SRCIP},
+		{ "src-ip6", 		SRCIP6},
+		{ "src-port",		SRCPORT},
 		{ "state",		STATE},
 		{ "state-policy",	STATEPOLICY},
 		{ "static-port",	STATICPORT},
@@ -5121,6 +5454,7 @@
 		{ "upperlimit",		UPPERLIMIT},
 		{ "urpf-failed",	URPFFAILED},
 		{ "user",		USER},
+		{ "weight",		WEIGHT},
 	};
 	const struct keywords	*p;
 
@@ -5649,3 +5983,80 @@
 
 	return (0);
 }
+
+/* n2mask sets n bits of the mask */
+static void
+n2mask(struct in6_addr *mask, int n)
+{
+        static int      minimask[9] =
+            { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
+        u_char          *p;
+
+        memset(mask, 0, sizeof(struct in6_addr));
+        p = (u_char *) mask;
+        for (; n > 0; p++, n -= 8) {
+                if (n >= 8)
+                        *p = 0xff;
+                else
+                        *p = minimask[n];
+        }
+        return;
+}
+
+static void
+calculate_dnred(struct dn_flow_set *flow, int bandwidth) 
+{
+	struct clockinfo ck;
+	size_t len;
+	double s, idle, weight, w_q;
+	int lookup_depth, avg_pkt_size;
+	int t;
+
+	len = sizeof(int);
+        if (sysctlbyname("net.inet.ip.dummynet.red_lookup_depth",
+        	&lookup_depth, &len, NULL, 0) == -1) 
+                err(1, "sysctlbyname(\"%s\")",
+                	"net.inet.ip.dummynet.red_lookup_depth");
+
+        if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size",
+        	&avg_pkt_size, &len, NULL, 0) == -1) 
+                err(1, "sysctlbyname(\"%s\")",
+                	"net.inet.ip.dummynet.red_avg_pkt_size");
+		
+
+	len = sizeof(struct clockinfo);
+        if (sysctlbyname("kern.clockrate", &ck, &len, NULL, 0) == -1) 
+        	err(1, "sysctlbyname(\"%s\")", "kern.clockrate");
+
+        /*
+         * Ticks needed for sending a medium-sized packet.
+         * Unfortunately, when we are configuring a WF2Q+ queue, we
+         * do not have bandwidth information, because that is stored
+         * in the parent pipe, and also we have multiple queues
+         * competing for it. So we set s=0, which is not very
+         * correct. But on the other hand, why do we want RED with
+         * WF2Q+ ?
+         */
+         if (bandwidth==0) /* this is a WF2Q+ queue */
+	         s = 0;
+         else
+         	 s = ck.hz * avg_pkt_size * 8 / bandwidth;
+
+         /*
+          * max idle time (in ticks) before avg queue size becomes 0.
+          * NOTA:  (3/w_q) is approx the value x so that
+          * (1-w_q)^x < 10^-3.
+          */
+         w_q = ((double)flow->w_q) / (1 << SCALE_RED);
+         idle = s * 3 / w_q;
+         flow->lookup_step = (int)idle / lookup_depth;
+         if (!flow->lookup_step)
+         	flow->lookup_step = 1;
+         weight = 1 - w_q;
+         for (t = flow->lookup_step; t > 0; --t)
+         	weight *= weight;
+	 flow->lookup_weight = (int)(weight * (1 << SCALE_RED));
+	
+	 return;
+}
+
Index: contrib/pf/pfctl/pfctl.c
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/contrib/pf/pfctl/pfctl.c,v
retrieving revision 1.2
diff -u -r1.2 pfctl.c
--- contrib/pf/pfctl/pfctl.c	28 Oct 2008 20:02:24 -0000	1.2
+++ contrib/pf/pfctl/pfctl.c	28 Oct 2008 20:02:52 -0000
@@ -46,6 +46,9 @@
 #include <altq/altq.h>
 #include <sys/sysctl.h>
 
+#include <netinet/ip_fw.h>
+#include <netinet/ip_dummynet.h>
+
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -71,6 +74,7 @@
 int	 pfctl_clear_rules(int, int, char *);
 int	 pfctl_clear_nat(int, int, char *);
 int	 pfctl_clear_altq(int, int);
+int	 pfctl_clear_dummynet(int, int);
 int	 pfctl_clear_src_nodes(int, int);
 int	 pfctl_clear_states(int, const char *, int);
 void	 pfctl_addrprefix(char *, struct pf_addr *);
@@ -96,6 +100,7 @@
 int	 pfctl_show_limits(int, int);
 void	 pfctl_debug(int, u_int32_t, int);
 int	 pfctl_test_altqsupport(int, int);
+int	 pfctl_test_dummynetsupport(int, int);
 int	 pfctl_show_anchors(int, int, char *);
 int	 pfctl_ruleset_trans(struct pfctl *, char *, struct pf_anchor *);
 int	 pfctl_load_ruleset(struct pfctl *, char *,
@@ -125,6 +130,9 @@
 int		 loadopt;
 int		 altqsupport;
 
+int 		 dummynetsupport;
+int 		 dnsock;
+
 int		 dev = -1;
 int		 first_title = 1;
 int		 labels = 0;
@@ -210,12 +218,12 @@
 };
 
 static const char *clearopt_list[] = {
-	"nat", "queue", "rules", "Sources",
+	"nat", "queue", "dummynet", "rules", "Sources",
 	"state", "info", "Tables", "osfp", "all", NULL
 };
 
 static const char *showopt_list[] = {
-	"nat", "queue", "rules", "Anchors", "Sources", "state", "info",
+	"nat", "queue", "dummynet", "rules", "Anchors", "Sources", "state", "info",
 	"Interfaces", "labels", "timeouts", "memory", "Tables", "osfp",
 	"all", NULL
 };
@@ -286,6 +294,8 @@
 			if (errno != ENOENT)
 				err(1, "DIOCSTOPALTQ");
 
+	pfctl_clear_dummynet(0, opts);
+
 	return (0);
 }
 
@@ -370,6 +380,21 @@
 }
 
 int
+pfctl_clear_dummynet(int __unused socket, int opts)
+{
+       if (!dummynetsupport)
+               return (-1);
+       if (setsockopt(dnsock, IPPROTO_IP, IP_DUMMYNET_FLUSH, NULL, 0) < 0) {
+               err(1,"setsockopt(IP_DUMMYNET_FLUSH)");
+               return (1);
+       }
+
+       if ((opts & PF_OPT_QUIET) == 0)
+               fprintf(stderr, "DUMMYNET cleared\n");
+       return (0);
+}
+
+int
 pfctl_clear_src_nodes(int dev, int opts)
 {
 	if (ioctl(dev, DIOCCLRSRCNODES))
@@ -804,6 +829,10 @@
 
 		printf("  [ queue: qname=%s qid=%u pqname=%s pqid=%u ]\n",
 		    rule->qname, rule->qid, rule->pqname, rule->pqid);
+
+		printf("  [ %s: in id=%d out id=%d  ]\n",
+			rule->free_flags & PFRULE_DN_IS_PIPE ? "dnpipe" : "dnqueue",
+			rule->dnpipe, rule->pdnpipe);
 	}
 	if (opts & PF_OPT_VERBOSE) {
 		printf("  [ Evaluations: %-8llu  Packets: %-8llu  "
@@ -1413,6 +1442,24 @@
 }
 
 int
+pfctl_add_dummynet(struct pfctl *pf, struct dn_pipe *p)
+{
+       if (dummynetsupport &&
+           (loadopt & PFCTL_FLAG_DUMMYNET) != 0) {
+               if ((pf->opts & PF_OPT_NOACTION) == 0) {
+                       if (setsockopt(dnsock, IPPROTO_IP, IP_DUMMYNET_CONFIGURE,
+                               p, sizeof(*p)) < 0) {
+                               errx(1, "DUMMYNET configure");
+                       }
+               }
+        }
+	if (pf->opts & PF_OPT_VERBOSE) 
+	       print_dummynet(p);
+
+       return (0);
+}
+
+int
 pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
     char *anchorname, struct pfr_buffer *trans)
 {
@@ -1979,6 +2026,23 @@
 }
 
 int
+pfctl_test_dummynetsupport(int __unused socket, int opts)
+{
+       void *data = NULL;
+       socklen_t       len;
+
+       if (getsockopt(dnsock, IPPROTO_IP, IP_DUMMYNET_GET, data,
+                       &len) < 0) {
+#if 0
+               if (!(opts & (PF_OPT_QUIET|PF_OPT_NOACTION)))
+                       fprintf(stderr, "DUMMYNET not loaded\n");
+#endif
+               return (0);
+       }
+       return (1);
+}
+
+int
 pfctl_show_anchors(int dev, int opts, char *anchorname)
 {
 	struct pfioc_ruleset	 pr;
@@ -2043,7 +2107,7 @@
 		usage();
 
 	while ((ch = getopt(argc, argv,
-	    "a:AdD:eqf:F:ghi:b:k:K:mnNOo::p:rRs:t:T:vx:z")) != -1) {
+	    "a:AdDP:eqf:F:ghi:b:k:K:mnNOo::p:rRs:t:T:vx:z")) != -1) {
 		switch (ch) {
 		case 'a':
 			anchoropt = optarg;
@@ -2125,6 +2189,9 @@
 		case 'A':
 			loadopt |= PFCTL_FLAG_ALTQ;
 			break;
+		case 'P':
+			loadopt |= PFCTL_FLAG_DUMMYNET;
+			break;
 		case 'R':
 			loadopt |= PFCTL_FLAG_FILTER;
 			break;
@@ -2239,6 +2306,11 @@
 		if (dev == -1)
 			err(1, "%s", pf_device);
 		altqsupport = pfctl_test_altqsupport(dev, opts);
+
+		dnsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+		if (dnsock < 0)
+			err(1, "socket");
+		dummynetsupport = pfctl_test_dummynetsupport(dnsock, opts);
 	} else {
 		dev = open(pf_device, O_RDONLY);
 		if (dev >= 0)
@@ -2251,6 +2323,10 @@
 #else
 		altqsupport = 1;
 #endif
+		dnsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+                if (dnsock < 0)
+                        err(1, "socket");
+                dummynetsupport = pfctl_test_dummynetsupport(dnsock, opts);
 	}
 
 	if (opts & PF_OPT_DISABLE)
@@ -2262,6 +2338,9 @@
 		case 'A':
 			pfctl_show_anchors(dev, opts, anchorname);
 			break;
+		case 'd':
+                        pfctl_show_dummynet(dnsock, opts);
+                        break;
 		case 'r':
 			pfctl_load_fingerprints(dev, opts);
 			pfctl_show_rules(dev, path, opts, PFCTL_SHOW_RULES,
@@ -2302,6 +2381,7 @@
 			pfctl_show_nat(dev, opts, anchorname);
 			pfctl_show_rules(dev, path, opts, 0, anchorname, 0);
 			pfctl_show_altq(dev, ifaceopt, opts, 0);
+			pfctl_show_dummynet(dnsock, opts);
 			pfctl_show_states(dev, ifaceopt, opts);
 			pfctl_show_src_nodes(dev, opts);
 			pfctl_show_status(dev, opts);
@@ -2334,6 +2414,9 @@
 			    "be modified from the command line");
 
 		switch (*clearopt) {
+		case 'd':
+			pfctl_clear_dummynet(dnsock, opts);
+			break;
 		case 'r':
 			pfctl_clear_rules(dev, opts, anchorname);
 			break;
@@ -2358,6 +2441,7 @@
 			pfctl_clear_tables(anchorname, opts);
 			if (!*anchorname) {
 				pfctl_clear_altq(dev, opts);
+				pfctl_clear_dummynet(dnsock, opts);
 				pfctl_clear_states(dev, ifaceopt, opts);
 				pfctl_clear_src_nodes(dev, opts);
 				pfctl_clear_stats(dev, opts);
@@ -2454,5 +2538,8 @@
 		}
 	}
 
+	if (dummynetsupport)
+		close(dnsock);
+
 	exit(error);
 }
Index: contrib/pf/pfctl/pfctl.h
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/contrib/pf/pfctl/pfctl.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 pfctl.h
--- contrib/pf/pfctl/pfctl.h	21 Oct 2008 15:18:37 -0000	1.1.1.1
+++ contrib/pf/pfctl/pfctl.h	28 Oct 2008 20:02:52 -0000
@@ -85,6 +85,7 @@
 int	 pfctl_command_tables(int, char *[], char *, const char *, char *,
 	    const char *, int);
 int	 pfctl_show_altq(int, const char *, int, int);
+int	 pfctl_show_dummynet(int, int);
 void	 warn_namespace_collision(const char *);
 int	 pfctl_show_ifaces(const char *, int);
 FILE	*pfctl_fopen(const char *, const char *);
Index: contrib/pf/pfctl/pfctl_dn.c
===================================================================
RCS file: contrib/pf/pfctl/pfctl_dn.c
diff -N contrib/pf/pfctl/pfctl_dn.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ contrib/pf/pfctl/pfctl_dn.c	28 Oct 2008 20:02:52 -0000
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2007 Ermal Luçi
+ * Copyright (c) 2002-2003 Luigi Rizzo
+ * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
+ * Copyright (c) 1994 Ugen J.S.Antsilevich
+ *
+ * Idea and grammar partially left from:
+ * Copyright (c) 1993 Daniel Boulet
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * NEW command line interface for IP firewall facility
+ *
+ */
+
+/*
+ * Most of this is derived from ipfw(8) code.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <net/pfvar.h>
+
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#include <netinet/ip_fw.h>
+#include <netinet/ip_dummynet.h>
+
+#include "pfctl_parser.h"
+#include "pfctl.h"
+
+static int do_sort,
+	   verbose;
+
+static int sort_q(const void *, const void *);
+static void
+list_queues(struct dn_flow_set *, struct dn_flow_queue *);
+static void
+print_flowset_parms(struct dn_flow_set *, char *);
+static void
+list_pipes(void *, uint );
+
+static int
+sort_q(const void *pa, const void *pb)
+{
+        int rev = (0);
+        int field = rev ? -do_sort : do_sort;
+        long long res = 0;
+        const struct dn_flow_queue *a = pa;
+        const struct dn_flow_queue *b = pb;
+
+        switch (field) {
+        case 1: /* pkts */
+                res = a->len - b->len;
+                break;
+        case 2: /* bytes */
+                res = a->len_bytes - b->len_bytes;
+                break;
+
+        case 3: /* tot pkts */
+                res = a->tot_pkts - b->tot_pkts;
+                break;
+
+        case 4: /* tot bytes */
+                res = a->tot_bytes - b->tot_bytes;
+                break;
+        }
+        if (res < 0)
+                res = -1;
+        if (res > 0)
+                res = 1;
+        return (int)(rev ? res : -res);
+}
+
+static void
+list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
+{
+        int l;
+        int index_printed, indexes = 0;
+        char buff[255];
+        struct protoent *pe;
+
+        if (fs->rq_elements == 0)
+                return;
+
+        if (do_sort != 0)
+                heapsort(q, fs->rq_elements, sizeof *q, sort_q);
+
+        /* Print IPv4 flows */
+        index_printed = 0;
+        for (l = 0; l < fs->rq_elements; l++) {
+                struct in_addr ina;
+
+                /* XXX: Should check for IPv4 flows */
+                if (IS_IP6_FLOW_ID(&(q[l].id)))
+                        continue;
+
+                if (!index_printed) {
+                        index_printed = 1;
+                        if (indexes > 0)        /* currently a no-op */
+                                printf("\n");
+                        indexes++;
+                        printf("    "
+                            "mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
+                            fs->flow_mask.proto,
+                            fs->flow_mask.src_ip, fs->flow_mask.src_port,
+                            fs->flow_mask.dst_ip, fs->flow_mask.dst_port);
+
+                        printf("BKT Prot ___Source IP/port____ "
+                            "____Dest. IP/port____ "
+                            "Tot_pkt/bytes Pkt/Byte Drp\n");
+                }
+
+                printf("%3d ", q[l].hash_slot);
+                pe = getprotobynumber(q[l].id.proto);
+                if (pe)
+                        printf("%-4s ", pe->p_name);
+                else
+                        printf("%4u ", q[l].id.proto);
+                ina.s_addr = htonl(q[l].id.src_ip);
+                printf("%15s/%-5d ",
+                    inet_ntoa(ina), q[l].id.src_port);
+                ina.s_addr = htonl(q[l].id.dst_ip);
+                printf("%15s/%-5d ",
+                    inet_ntoa(ina), q[l].id.dst_port);
+                printf("%4qu %8qu %2u %4u %3u\n",
+                    q[l].tot_pkts, q[l].tot_bytes,
+                    q[l].len, q[l].len_bytes, q[l].drops);
+                if (verbose)
+                        printf("   S %20qd  F %20qd\n",
+                            q[l].S, q[l].F);
+        }
+
+        /* Print IPv6 flows */
+        index_printed = 0;
+        for (l = 0; l < fs->rq_elements; l++) {
+                if (!IS_IP6_FLOW_ID(&(q[l].id)))
+                        continue;
+
+                if (!index_printed) {
+                        index_printed = 1;
+                        if (indexes > 0)
+                                printf("\n");
+                       indexes++;
+                        printf("\n        mask: proto: 0x%02x, flow_id: 0x%08x,  ",
+                            fs->flow_mask.proto, fs->flow_mask.flow_id6);
+                        inet_ntop(AF_INET6, &(fs->flow_mask.src_ip6),
+                            buff, sizeof(buff));
+                        printf("%s/0x%04x -> ", buff, fs->flow_mask.src_port);
+                        inet_ntop( AF_INET6, &(fs->flow_mask.dst_ip6),
+                            buff, sizeof(buff) );
+                        printf("%s/0x%04x\n", buff, fs->flow_mask.dst_port);
+
+                        printf("BKT ___Prot___ _flow-id_ "
+                            "______________Source IPv6/port_______________ "
+                            "_______________Dest. IPv6/port_______________ "
+                            "Tot_pkt/bytes Pkt/Byte Drp\n");
+                }
+                printf("%3d ", q[l].hash_slot);
+                pe = getprotobynumber(q[l].id.proto);
+                if (pe != NULL)
+                        printf("%9s ", pe->p_name);
+                else
+                        printf("%9u ", q[l].id.proto);
+                printf("%7d  %39s/%-5d ", q[l].id.flow_id6,
+                    inet_ntop(AF_INET6, &(q[l].id.src_ip6), buff, sizeof(buff)),
+                    q[l].id.src_port);
+                printf(" %39s/%-5d ",
+                    inet_ntop(AF_INET6, &(q[l].id.dst_ip6), buff, sizeof(buff)),
+                    q[l].id.dst_port);
+                printf(" %4qu %8qu %2u %4u %3u\n",
+                    q[l].tot_pkts, q[l].tot_bytes,
+                    q[l].len, q[l].len_bytes, q[l].drops);
+                if (verbose)
+                        printf("   S %20qd  F %20qd\n", q[l].S, q[l].F);
+        }
+}
+
+static void
+print_flowset_parms(struct dn_flow_set *fs, char *prefix)
+{
+        int l;
+        char qs[30];
+        char plr[30];
+        char red[90];   /* Display RED parameters */
+
+        l = fs->qsize;
+        if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
+                if (l >= 8192)
+                        sprintf(qs, "%d KB", l / 1024);
+                else
+                        sprintf(qs, "%d B", l);
+        } else
+                sprintf(qs, "%3d sl.", l);
+        if (fs->plr)
+                sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
+        else
+                plr[0] = '\0';
+        if (fs->flags_fs & DN_IS_RED)   /* RED parameters */
+                sprintf(red,
+                    "\n\t  %cRED w_q %f min_th %d max_th %d max_p %f",
+                    (fs->flags_fs & DN_IS_GENTLE_RED) ? 'G' : ' ',
+                    1.0 * fs->w_q / (double)(1 << SCALE_RED),
+                    SCALE_VAL(fs->min_th),
+                    SCALE_VAL(fs->max_th),
+                    1.0 * fs->max_p / (double)(1 << SCALE_RED));
+        else
+                sprintf(red, "droptail");
+
+        printf("%s %s%s %d queues (%d buckets) %s\n",
+            prefix, qs, plr, fs->rq_elements, fs->rq_size, red);
+}
+
+
+static void
+list_pipes(void *data, uint nbytes)
+{
+        void *next = data;
+        struct dn_pipe *p = (struct dn_pipe *) data;
+        struct dn_flow_set *fs;
+        struct dn_flow_queue *q;
+        int l;
+
+        for (; nbytes >= sizeof *p; p = (struct dn_pipe *)next) {
+                double b = p->bandwidth;
+                char buf[30];
+                char prefix[80];
+
+                if (SLIST_NEXT(p, next) != (struct dn_pipe *)DN_IS_PIPE)
+                        break;  /* done with pipes, now queues */
+
+                /*
+                 * compute length, as pipe have variable size
+                 */
+                l = sizeof(*p) + p->fs.rq_elements * sizeof(*q);
+                next = (char *)p + l;
+                nbytes -= l;
+
+                /*
+                 * Print rate (or clocking interface)
+                 */
+                if (p->if_name[0] != '\0')
+                       sprintf(buf, "%s", p->if_name);
+                else if (b == 0)
+                        sprintf(buf, "unlimited");
+                else if (b >= 1000000)
+                        sprintf(buf, "%7.3f Mbit/s", b/1000000);
+                else if (b >= 1000)
+                        sprintf(buf, "%7.3f Kbit/s", b/1000);
+                else
+                        sprintf(buf, "%7.3f bit/s ", b);
+
+                sprintf(prefix, "%05d: %s %4d ms ",
+                    p->pipe_nr, buf, p->delay);
+                print_flowset_parms(&(p->fs), prefix);
+                if (verbose)
+                        printf("   V %20qd\n", p->V >> MY_M);
+
+                q = (struct dn_flow_queue *)(p+1);
+                list_queues(&(p->fs), q);
+        }
+        for (fs = next; nbytes >= sizeof *fs; fs = next) {
+                char prefix[80];
+
+                if (SLIST_NEXT(fs, next) != (struct dn_flow_set *)DN_IS_QUEUE)
+                        break;
+                l = sizeof(*fs) + fs->rq_elements * sizeof(*q);
+                next = (char *)fs + l;
+                nbytes -= l;
+#if 0
+                if (rulenum != 0 && ((rulenum != fs->fs_nr && do_pipe == 2) ||
+                    (rulenum != fs->parent_nr && do_pipe == 1))) {
+                        continue;
+                }
+#endif
+                q = (struct dn_flow_queue *)(fs+1);
+                sprintf(prefix, "q%05d: weight %d pipe %d ",
+                    fs->fs_nr, fs->weight, fs->parent_nr);
+                print_flowset_parms(fs, prefix);
+                list_queues(fs, q);
+        }
+}
+
+void
+print_dummynet(struct dn_pipe *p)
+{
+	if (p->pipe_nr != 0) { /* This is a pipe */
+		printf("dnpipe %d", p->pipe_nr);
+		if (p->bandwidth >= 1000000) 
+			printf(" bandwidth %dMb", p->bandwidth/1000000);
+	        else if (p->bandwidth >= 1000)
+         	        printf(" bandwidth %dKb", p->bandwidth/1000);
+	        else 
+                       	printf(" bandwidth %db ", p->bandwidth);
+		if (p->delay > 0)
+			printf(" delay %d", p->delay);
+	} else {
+		printf("dnqueue %d dnpipe %d", p->fs.fs_nr, p->fs.parent_nr);
+		if (p->fs.weight)
+			printf(" weight %d", p->fs.weight);
+	}
+
+	if (p->fs.rq_size > 15)
+		printf(" buckets %d", p->fs.rq_size);
+	if (p->fs.flags_fs & DN_QSIZE_IS_BYTES) {
+                if (p->fs.qsize >= 8192)
+                        printf(" queue %dKB",  p->fs.qsize / 1024);
+                else if (p->fs.qsize > 0)
+                        printf(" queue %dB", p->fs.qsize);
+        } else
+		if (p->fs.qsize > 0)
+	                printf(" queue %3d", p->fs.qsize);
+        if (p->fs.plr > 0)
+                printf(" plr %f", 1.0 * p->fs.plr / (double)(0x7fffffff));
+
+	if (p->fs.flow_mask.proto && p->fs.flow_mask.dst_ip && 
+		p->fs.flow_mask.src_ip && p->fs.flow_mask.dst_port && 
+		p->fs.flow_mask.src_port &&
+		p->fs.flow_mask.flow_id6)
+		printf(" mask all");
+	else  if (p->fs.flow_mask.proto || p->fs.flow_mask.dst_ip || 
+		p->fs.flow_mask.src_ip || p->fs.flow_mask.dst_port || 
+		p->fs.flow_mask.src_port ||
+		p->fs.flow_mask.flow_id6) {
+		printf("\n\t mask: ");
+	if (p->fs.flow_mask.proto)
+		printf(" proto 0x%02x", p->fs.flow_mask.proto);
+	if (p->fs.flow_mask.src_ip)
+		printf(" src-ip 0x%08x", p->fs.flow_mask.src_ip);
+	if (p->fs.flow_mask.src_port)
+		printf(" src-port 0x%04x", p->fs.flow_mask.src_port);
+	if (p->fs.flow_mask.dst_ip)
+		printf(" dst-ip 0x%08x", p->fs.flow_mask.dst_ip);
+	if (p->fs.flow_mask.dst_port)
+		printf(" dst-port 0x%04x", p->fs.flow_mask.dst_port);
+	if (p->fs.flow_mask.flow_id6)
+		printf(" dst-port 0x%08x", p->fs.flow_mask.flow_id6);
+	}
+	if (p->fs.flags_fs & DN_NOERROR)
+		printf(" noerror");
+
+	printf("\n");	
+}
+
+int
+pfctl_show_dummynet(int dnsock, int opts)
+{
+        void *data = NULL;
+        int nbytes, nalloc = 1024;
+
+	if (opts & PF_OPT_VERBOSE)
+		verbose = 1;
+	else 
+		verbose = 0;
+	
+	nbytes = nalloc;
+        while (nbytes >= nalloc) {
+                nalloc = nalloc * 2 + 200;
+                nbytes = nalloc;
+                if ((data = realloc(data, nbytes)) == NULL)
+                        err(1, "realloc");
+                if (getsockopt(dnsock, IPPROTO_IP, IP_DUMMYNET_GET, data,
+                        (socklen_t *)&nbytes) < 0) {
+                        free(data);
+                        err(1, "getsockopt(IP_DUMMYNET_GET)");
+		}
+        }
+	
+        list_pipes(data, nbytes);
+	
+	return (0);
+
+}
Index: contrib/pf/pfctl/pfctl_parser.c
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/contrib/pf/pfctl/pfctl_parser.c,v
retrieving revision 1.2
diff -u -r1.2 pfctl_parser.c
--- contrib/pf/pfctl/pfctl_parser.c	21 Oct 2008 15:23:00 -0000	1.2
+++ contrib/pf/pfctl/pfctl_parser.c	28 Oct 2008 20:02:52 -0000
@@ -48,6 +48,9 @@
 #include <net/pfvar.h>
 #include <arpa/inet.h>
 
+#include <netinet/ip_fw.h>
+#include <netinet/ip_dummynet.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -983,6 +986,14 @@
 	}
 	if (r->label[0])
 		printf(" label \"%s\"", r->label);
+	if (r->dnpipe && r->pdnpipe)
+	       printf(" %s(%d, %d)", 
+			r->free_flags & PFRULE_DN_IS_PIPE ? "dnpipe" : "dnqueue",
+			r->dnpipe, r->pdnpipe);
+	else if (r->dnpipe)	
+		printf(" %s %d", 
+			r->free_flags & PFRULE_DN_IS_PIPE ? "dnpipe" : "dnqueue",
+			r->dnpipe);
 	if (r->qname[0] && r->pqname[0])
 		printf(" queue(%s, %s)", r->qname, r->pqname);
 	else if (r->qname[0])
Index: contrib/pf/pfctl/pfctl_parser.h
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/contrib/pf/pfctl/pfctl_parser.h,v
retrieving revision 1.2
diff -u -r1.2 pfctl_parser.h
--- contrib/pf/pfctl/pfctl_parser.h	21 Oct 2008 15:19:34 -0000	1.2
+++ contrib/pf/pfctl/pfctl_parser.h	28 Oct 2008 20:02:52 -0000
@@ -67,6 +67,7 @@
 }
 
 struct pfr_buffer;	/* forward definition */
+struct dn_pipe;
 
 
 struct pfctl {
@@ -232,6 +233,7 @@
 
 int	pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *);
 int	pfctl_add_altq(struct pfctl *, struct pf_altq *);
+int 	pfctl_add_dummynet(struct pfctl *, struct dn_pipe *);
 int	pfctl_add_pool(struct pfctl *, struct pf_pool *, sa_family_t);
 void	pfctl_move_pool(struct pf_pool *, struct pf_pool *);
 void	pfctl_clear_pool(struct pf_pool *);
@@ -259,6 +261,7 @@
 int	eval_pfqueue(struct pfctl *, struct pf_altq *, struct node_queue_bw *,
 	    struct node_queue_opt *);
 
+void	 print_dummynet(struct dn_pipe *);
 void	 print_altq(const struct pf_altq *, unsigned, struct node_queue_bw *,
 	    struct node_queue_opt *);
 void	 print_queue(const struct pf_altq *, unsigned, struct node_queue_bw *,
@@ -301,6 +304,7 @@
 #define PFCTL_FLAG_OPTION	0x08
 #define PFCTL_FLAG_ALTQ		0x10
 #define PFCTL_FLAG_TABLE	0x20
+#define	PFCTL_FLAG_DUMMYNET	0x40
 
 extern const struct pf_timeout pf_timeouts[];
 
Index: sbin/pfctl/Makefile
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sbin/pfctl/Makefile,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Makefile
--- sbin/pfctl/Makefile	21 Oct 2008 15:18:37 -0000	1.1.1.1
+++ sbin/pfctl/Makefile	28 Oct 2008 20:02:52 -0000
@@ -11,6 +11,7 @@
 SRCS+= pfctl_osfp.c pfctl_radix.c pfctl_table.c pfctl_qstats.c
 SRCS+= pfctl_optimize.c
 SRCS+= pf_ruleset.c
+SRCS+= pfctl_dn.c
 
 CFLAGS+= -Wall -Wmissing-prototypes -Wno-uninitialized
 CFLAGS+= -Wstrict-prototypes -I${.CURDIR}/../../contrib/pf/pfctl
Index: sys/contrib/pf/net/pf.c
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/contrib/pf/net/pf.c,v
retrieving revision 1.3
diff -u -r1.3 pf.c
--- sys/contrib/pf/net/pf.c	21 Oct 2008 15:23:00 -0000	1.3
+++ sys/contrib/pf/net/pf.c	28 Oct 2008 20:02:52 -0000
@@ -136,6 +136,9 @@
 #include <netinet/icmp6.h>
 #include <netinet6/nd6.h>
 #ifdef __FreeBSD__
+#include <netinet/ip_fw.h>
+#include <netinet/ip_dummynet.h>
+
 #include <netinet6/ip6_var.h>
 #include <netinet6/in6_pcb.h>
 #endif
@@ -375,6 +378,13 @@
 		s->rule.ptr->states--;			\
 	} while (0)
 
+#define PF_DUMMYNET() 								\
+	do {									\
+		r = (*state)->rule.ptr;						\
+        	if (r->dnpipe && !(pd->pf_mtag->flags & PF_DN_TAG_PRESENT))	\
+                	return (PF_PASS);					\
+	} while (0)
+
 struct pf_src_tree tree_src_tracking;
 
 struct pf_state_tree_id tree_id;
@@ -4670,6 +4680,7 @@
 {
 	struct pf_state_cmp	 key;
 	struct tcphdr		*th = pd->hdr.tcp;
+	struct pf_rule		*r = NULL;
 	u_int16_t		 win = ntohs(th->th_win);
 	u_int32_t		 ack, end, seq, orig_seq;
 	u_int8_t		 sws, dws;
@@ -4693,6 +4704,15 @@
 
 	STATE_LOOKUP();
 
+	PF_DUMMYNET();
+
+        /*
+         * First state is created by the rules checking code and if we reloop
+         * the first packet that hit the rule pf will not like it.
+         */
+        if ((th->th_flags & TH_SYN) && (pd->pf_mtag->flags & PF_DN_TAG_PRESENT))
+                return (PF_PASS);
+
 	if (direction == (*state)->direction) {
 		src = &(*state)->src;
 		dst = &(*state)->dst;
@@ -4700,7 +4720,7 @@
 		src = &(*state)->dst;
 		dst = &(*state)->src;
 	}
-
+	
 	if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
 		if (direction != (*state)->direction) {
 			REASON_SET(reason, PFRES_SYNPROXY);
@@ -5180,6 +5200,7 @@
 {
 	struct pf_state_peer	*src, *dst;
 	struct pf_state_cmp	 key;
+	struct pf_rule		*r;
 	struct udphdr		*uh = pd->hdr.udp;
 
 	key.af = pd->af;
@@ -5198,6 +5219,8 @@
 
 	STATE_LOOKUP();
 
+	PF_DUMMYNET();
+
 	if (direction == (*state)->direction) {
 		src = &(*state)->src;
 		dst = &(*state)->dst;
@@ -5240,6 +5263,7 @@
     struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
 {
 	struct pf_addr	*saddr = pd->src, *daddr = pd->dst;
+	struct pf_rule          *r;
 	u_int16_t	 icmpid = 0;		/* make the compiler happy */
 	u_int16_t	*icmpsum = NULL;	/* make the compiler happy */
 	u_int8_t	 icmptype = 0;		/* make the compiler happy */
@@ -5298,6 +5322,8 @@
 
 		STATE_LOOKUP();
 
+		PF_DUMMYNET();
+
 		(*state)->expire = time_second;
 		(*state)->timeout = PFTM_ICMP_ERROR_REPLY;
 
@@ -5830,6 +5856,7 @@
 {
 	struct pf_state_peer	*src, *dst;
 	struct pf_state_cmp	 key;
+	struct pf_rule          *r;
 
 	key.af = pd->af;
 	key.proto = pd->proto;
@@ -5847,6 +5874,8 @@
 
 	STATE_LOOKUP();
 
+	PF_DUMMYNET();
+
 	if (direction == (*state)->direction) {
 		src = &(*state)->src;
 		dst = &(*state)->dst;
@@ -6798,6 +6827,9 @@
 	int			 off, dirndx, pqid = 0;
 
 #ifdef __FreeBSD__
+	struct m_tag *dn_tag;
+	struct ip_fw_args	 dnflow;
+
 	PF_LOCK();
 #endif
 	if (!pf_status.running)
@@ -6868,8 +6900,15 @@
 		goto done;
 	}
 
+	dn_tag = m_tag_find(m, PACKET_TAG_DUMMYNET, NULL);
+        if (dn_tag != NULL &&
+                ((struct dn_pkt_tag *)(dn_tag+1))->dn_client == DN_CLIENT_PF) {
+		pd.pf_mtag->flags |= PF_DN_TAG_PRESENT;
+                m_tag_delete(m, dn_tag);
+        }
+
 	/* We do IP header normalization and packet reassembly here */
-	if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
+	else if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
 		action = PF_DROP;
 		goto done;
 	}
@@ -6907,6 +6946,11 @@
 		struct tcphdr	th;
 
 		pd.hdr.tcp = &th;
+#ifdef __FreeBSD__
+                dnflow.f_id.flags = th.th_flags;
+                dnflow.f_id.dst_port = th.th_dport;
+                dnflow.f_id.src_port = th.th_sport;
+#endif
 		if (!pf_pull_hdr(m, off, &th, sizeof(th),
 		    &action, &reason, AF_INET)) {
 			log = action != PF_PASS;
@@ -6948,6 +6992,10 @@
 		struct udphdr	uh;
 
 		pd.hdr.udp = &uh;
+#ifdef __FreeBSD__
+                dnflow.f_id.dst_port = uh.uh_dport;
+                dnflow.f_id.src_port = uh.uh_sport;
+#endif
 		if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
 		    &action, &reason, AF_INET)) {
 			log = action != PF_PASS;
@@ -7068,6 +7116,40 @@
 	}
 #endif /* ALTQ */
 
+#ifdef __FreeBSD__
+        if (r->dnpipe && DUMMYNET_LOADED &&
+                !(pd.pf_mtag->flags & PF_DN_TAG_PRESENT)) {
+                        struct ip_fw dummyrule;
+
+                        dummyrule.cmd->opcode =
+                                r->free_flags & PFRULE_DN_IS_PIPE ? O_PIPE : O_QUEUE;
+                        dummyrule.act_ofs = 0;
+                        dummyrule.cmd_len = 1;
+                        if (dir != r->direction && r->pdnpipe) {
+                                dnflow.cookie = r->pdnpipe;
+                        } else if (dir == r->direction) {
+                                dnflow.cookie = r->dnpipe;
+                        } else
+                                goto continueprocessing;
+
+                        dnflow.rule = &dummyrule;
+                        dnflow.f_id.addr_type = 4; /* IPv4 type */
+                        dnflow.f_id.proto = pd.proto;
+
+                        PF_UNLOCK();
+
+                        h = mtod(*m0, struct ip *);
+                        NTOHS(h->ip_len);
+                        NTOHS(h->ip_off);
+                        ip_dn_io_ptr(m0,
+                                dir == PF_IN ? DN_TO_IP_IN : DN_TO_IP_OUT,
+                                &dnflow, DN_CLIENT_PF);
+                        *m0 = NULL;
+                        return (action);
+        }
+continueprocessing:
+#endif
+
 	/*
 	 * connections redirected to loopback should not match sockets
 	 * bound specifically to loopback due to security implications,
@@ -7156,7 +7238,6 @@
 			    tr->dst.neg);
 	}
 
-
 	if (action == PF_SYNPROXY_DROP) {
 		m_freem(*m0);
 		*m0 = NULL;
@@ -7194,6 +7275,9 @@
 	int			 off, terminal = 0, dirndx, rh_cnt = 0;
 
 #ifdef __FreeBSD__
+	struct m_tag *dn_tag;
+	struct ip_fw_args	 dnflow;
+
 	PF_LOCK();
 #endif
 
@@ -7262,8 +7346,15 @@
 		goto done;
 	}
 
+	dn_tag = m_tag_find(m, PACKET_TAG_DUMMYNET, NULL);
+        if (dn_tag != NULL &&
+                ((struct dn_pkt_tag *)(dn_tag+1))->dn_client == DN_CLIENT_PF) {
+                pd.pf_mtag->flags |= PF_DN_TAG_PRESENT;
+                m_tag_delete(m, dn_tag);
+        }
+
 	/* We do IP header normalization and packet reassembly here */
-	if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
+	else if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
 		action = PF_DROP;
 		goto done;
 	}
@@ -7369,6 +7460,11 @@
 		struct tcphdr	th;
 
 		pd.hdr.tcp = &th;
+#ifdef __FreeBSD__
+                dnflow.f_id.flags = th.th_flags;
+                dnflow.f_id.dst_port = th.th_dport;
+                dnflow.f_id.src_port = th.th_sport;
+#endif
 		if (!pf_pull_hdr(m, off, &th, sizeof(th),
 		    &action, &reason, AF_INET6)) {
 			log = action != PF_PASS;
@@ -7409,6 +7505,10 @@
 		struct udphdr	uh;
 
 		pd.hdr.udp = &uh;
+#ifdef __FreeBSD__
+                dnflow.f_id.dst_port = uh.uh_dport;
+                dnflow.f_id.src_port = uh.uh_sport;
+#endif
 		if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
 		    &action, &reason, AF_INET6)) {
 			log = action != PF_PASS;
@@ -7531,6 +7631,37 @@
 	}
 #endif /* ALTQ */
 
+#ifdef __FreeBSD__
+        if (r->dnpipe && DUMMYNET_LOADED &&
+                !(pd.pf_mtag->flags & PF_DN_TAG_PRESENT)) {
+                        struct ip_fw dummyrule;
+
+                        dummyrule.cmd->opcode =
+                                r->free_flags & PFRULE_DN_IS_PIPE ? O_PIPE : O_QUEUE;
+                        dummyrule.act_ofs = 0;
+                        dummyrule.cmd_len = 1;
+                        if (dir != r->direction && r->pdnpipe) {
+                                dnflow.cookie = r->pdnpipe;
+                        } else if (dir == r->direction) {
+                                dnflow.cookie = r->dnpipe;
+                        } else
+                                goto continueprocessing;
+
+                        dnflow.rule = &dummyrule;
+                        dnflow.f_id.addr_type = 6; /* IPv4 type */
+                        dnflow.f_id.proto = pd.proto;
+
+                        PF_UNLOCK();
+
+                        ip_dn_io_ptr(m0,
+                                dir == PF_IN ? DN_TO_IP6_IN : DN_TO_IP6_OUT,
+                                &dnflow, DN_CLIENT_PF);
+                        *m0 = NULL;
+                        return (action);
+        }
+continueprocessing:
+#endif
+
 	if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
 	    pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
 	    (s->nat_rule.ptr->action == PF_RDR ||
@@ -7614,7 +7745,6 @@
 			    tr->dst.neg);
 	}
 
-
 	if (action == PF_SYNPROXY_DROP) {
 		m_freem(*m0);
 		*m0 = NULL;
Index: sys/contrib/pf/net/pf_mtag.h
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/contrib/pf/net/pf_mtag.h,v
retrieving revision 1.2
diff -u -r1.2 pf_mtag.h
--- sys/contrib/pf/net/pf_mtag.h	21 Oct 2008 15:19:34 -0000	1.2
+++ sys/contrib/pf/net/pf_mtag.h	28 Oct 2008 20:02:52 -0000
@@ -37,6 +37,7 @@
 #define	PF_TAG_GENERATED		0x01
 #define	PF_TAG_FRAGCACHE		0x02
 #define	PF_TAG_TRANSLATE_LOCALHOST	0x04
+#define PF_DN_TAG_PRESENT	        0x08
 
 struct pf_mtag {
 	void		*hdr;		/* saved hdr pos in mbuf, for ECN */
Index: sys/contrib/pf/net/pfvar.h
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/contrib/pf/net/pfvar.h,v
retrieving revision 1.4
diff -u -r1.4 pfvar.h
--- sys/contrib/pf/net/pfvar.h	28 Oct 2008 20:02:24 -0000	1.4
+++ sys/contrib/pf/net/pfvar.h	28 Oct 2008 20:02:52 -0000
@@ -632,6 +632,11 @@
 	}			 max_src_conn_rate;
 	u_int32_t		 qid;
 	u_int32_t		 pqid;
+	u_int32_t                dnpipe;
+        u_int32_t                pdnpipe;
+#define	PFRULE_DN_IS_PIPE	0x00000010
+#define	PFRULE_DN_IS_QUEUE	0x00000020	
+	u_int32_t                free_flags;
 	u_int32_t		 rt_listid;
 	u_int32_t		 nr;
 	u_int32_t		 prob;
Index: sys/net/if_bridge.c
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/net/if_bridge.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 if_bridge.c
--- sys/net/if_bridge.c	21 Oct 2008 15:18:37 -0000	1.1.1.1
+++ sys/net/if_bridge.c	28 Oct 2008 20:02:52 -0000
@@ -3034,7 +3034,7 @@
 			 * packet will return to us via bridge_dummynet().
 			 */
 			args.oif = ifp;
-			ip_dn_io_ptr(mp, DN_TO_IFB_FWD, &args);
+			ip_dn_io_ptr(mp, DN_TO_IFB_FWD, &args, DN_CLIENT_IPFW);
 			return (error);
 		}
 
Index: sys/net/if_ethersubr.c
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/net/if_ethersubr.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 if_ethersubr.c
--- sys/net/if_ethersubr.c	21 Oct 2008 15:18:37 -0000	1.1.1.1
+++ sys/net/if_ethersubr.c	28 Oct 2008 20:02:52 -0000
@@ -491,7 +491,7 @@
 			 */
 			*m0 = NULL ;
 		}
-		ip_dn_io_ptr(&m, dst ? DN_TO_ETH_OUT: DN_TO_ETH_DEMUX, &args);
+		ip_dn_io_ptr(&m, dst ? DN_TO_ETH_OUT: DN_TO_ETH_DEMUX, &args,DN_CLIENT_IPFW);
 		return 0;
 	}
 	/*
Index: sys/netinet/ip_dummynet.c
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/netinet/ip_dummynet.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip_dummynet.c
--- sys/netinet/ip_dummynet.c	21 Oct 2008 15:18:37 -0000	1.1.1.1
+++ sys/netinet/ip_dummynet.c	28 Oct 2008 20:02:59 -0000
@@ -86,6 +86,8 @@
 #include <netinet/ip6.h>       /* for ip6_input, ip6_output prototypes */
 #include <netinet6/ip6_var.h>
 
+static struct ip_fw default_rule;
+
 /*
  * We keep a private variable for the simulation time, but we could
  * probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
@@ -238,8 +240,8 @@
 static void	dummynet_flush(void);
 static void	dummynet_send(struct mbuf *);
 void		dummynet_drain(void);
+static ip_dn_ruledel_t dn_rule_delete;
 static ip_dn_io_t dummynet_io;
-static void	dn_rule_delete(void *);
 
 /*
  * Heap management functions.
@@ -1252,7 +1254,7 @@
  * rule		matching rule, in case of multiple passes
  */
 static int
-dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa)
+dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa, u_int16_t client)
 {
 	struct mbuf *m = *m0, *head = NULL, *tail = NULL;
 	struct dn_pkt_tag *pkt;
@@ -1336,6 +1338,7 @@
 	 */
 	pkt->rule = fwa->rule;
 	pkt->dn_dir = dir;
+	pkt->dn_client = client;
 
 	pkt->ifp = fwa->oif;
 
@@ -1556,7 +1559,6 @@
 	DUMMYNET_UNLOCK();
 }
 
-extern struct ip_fw *ip_fw_default_rule ;
 static void
 dn_rule_delete_fs(struct dn_flow_set *fs, void *r)
 {
@@ -1569,14 +1571,14 @@
 	    for (m = q->head ; m ; m = m->m_nextpkt ) {
 		struct dn_pkt_tag *pkt = dn_tag_get(m) ;
 		if (pkt->rule == r)
-		    pkt->rule = ip_fw_default_rule ;
+			pkt->rule = &default_rule ;
 	    }
 }
 /*
  * when a firewall rule is deleted, scan all queues and remove the flow-id
  * from packets matching this rule.
  */
-void
+static void
 dn_rule_delete(void *r)
 {
     struct dn_pipe *pipe;
@@ -1602,7 +1604,7 @@
 		for (m = pipe->head ; m ; m = m->m_nextpkt ) {
 			pkt = dn_tag_get(m);
 			if (pkt->rule == r)
-				pkt->rule = ip_fw_default_rule;
+				pkt->rule = &default_rule ;
 		}
 	}
     DUMMYNET_UNLOCK();
@@ -2201,6 +2203,20 @@
 	ip_dn_io_ptr = dummynet_io;
 	ip_dn_ruledel_ptr = dn_rule_delete;
 
+	bzero(&default_rule, sizeof default_rule);
+
+        default_rule.act_ofs = 0;
+        default_rule.rulenum = IPFW_DEFAULT_RULE;
+        default_rule.cmd_len = 1;
+        default_rule.set = RESVD_SET;
+
+        default_rule.cmd[0].len = 1;
+        default_rule.cmd[0].opcode =
+#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
+                                1 ? O_ACCEPT :
+#endif
+                                O_DENY;
+
 	TASK_INIT(&dn_task, 0, dummynet_task, NULL);
 	dn_tq = taskqueue_create_fast("dummynet", M_NOWAIT,
 	    taskqueue_thread_enqueue, &dn_tq);
@@ -2267,5 +2283,4 @@
 	NULL
 };
 DECLARE_MODULE(dummynet, dummynet_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
-MODULE_DEPEND(dummynet, ipfw, 2, 2, 2);
 MODULE_VERSION(dummynet, 1);
Index: sys/netinet/ip_dummynet.h
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/netinet/ip_dummynet.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip_dummynet.h
--- sys/netinet/ip_dummynet.h	21 Oct 2008 15:18:37 -0000	1.1.1.1
+++ sys/netinet/ip_dummynet.h	28 Oct 2008 20:02:52 -0000
@@ -123,6 +123,9 @@
 #define DN_TO_IP6_OUT	7
 #define DN_TO_IFB_FWD	8
 
+    u_int16_t dn_client;	/* which filter has created the tag */
+#define DN_CLIENT_IPFW	1
+#define DN_CLIENT_PF	2
     dn_key output_time;		/* when the pkt is due for delivery	*/
     struct ifnet *ifp;		/* interface, for ip_output		*/
     struct _ip6dn_args ip6opt;	/* XXX ipv6 options			*/
@@ -343,7 +346,7 @@
 #ifdef _KERNEL
 typedef	int ip_dn_ctl_t(struct sockopt *); /* raw_ip.c */
 typedef	void ip_dn_ruledel_t(void *); /* ip_fw.c */
-typedef	int ip_dn_io_t(struct mbuf **m, int dir, struct ip_fw_args *fwa);
+typedef	int ip_dn_io_t(struct mbuf **m, int dir, struct ip_fw_args *fwa, u_int16_t);
 extern	ip_dn_ctl_t *ip_dn_ctl_ptr;
 extern	ip_dn_ruledel_t *ip_dn_ruledel_ptr;
 extern	ip_dn_io_t *ip_dn_io_ptr;
Index: sys/netinet/ip_fw_pfil.c
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/netinet/ip_fw_pfil.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip_fw_pfil.c
--- sys/netinet/ip_fw_pfil.c	21 Oct 2008 15:18:37 -0000	1.1.1.1
+++ sys/netinet/ip_fw_pfil.c	28 Oct 2008 20:02:52 -0000
@@ -72,9 +72,6 @@
 
 int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
 
-/* Dummynet hooks. */
-ip_dn_ruledel_t	*ip_dn_ruledel_ptr = NULL;
-
 /* Divert hooks. */
 ip_divert_packet_t *ip_divert_ptr = NULL;
 
@@ -160,9 +157,9 @@
 		if (!DUMMYNET_LOADED)
 			goto drop;
 		if (mtod(*m0, struct ip *)->ip_v == 4)
-			ip_dn_io_ptr(m0, DN_TO_IP_IN, &args);
+			ip_dn_io_ptr(m0, DN_TO_IP_IN, &args, DN_CLIENT_IPFW);
 		else if (mtod(*m0, struct ip *)->ip_v == 6)
-			ip_dn_io_ptr(m0, DN_TO_IP6_IN, &args);
+			ip_dn_io_ptr(m0, DN_TO_IP6_IN, &args, DN_CLIENT_IPFW);
 		if (*m0 != NULL)
 			goto again;
 		return 0;		/* packet consumed */
@@ -287,9 +284,9 @@
 		if (!DUMMYNET_LOADED)
 			break;
 		if (mtod(*m0, struct ip *)->ip_v == 4)
-			ip_dn_io_ptr(m0, DN_TO_IP_OUT, &args);
+			ip_dn_io_ptr(m0, DN_TO_IP_OUT, &args, DN_CLIENT_IPFW);
 		else if (mtod(*m0, struct ip *)->ip_v == 6)
-			ip_dn_io_ptr(m0, DN_TO_IP6_OUT, &args);
+			ip_dn_io_ptr(m0, DN_TO_IP6_OUT, &args, DN_CLIENT_IPFW);
 		if (*m0 != NULL)
 			goto again;
 		return 0;		/* packet consumed */
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /home/ermal/tmprepoDSCP/src/sys/netinet/ip_input.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip_input.c
--- sys/netinet/ip_input.c	21 Oct 2008 15:18:37 -0000	1.1.1.1
+++ sys/netinet/ip_input.c	28 Oct 2008 20:02:52 -0000
@@ -202,6 +202,7 @@
  */
 ip_fw_chk_t *ip_fw_chk_ptr = NULL;
 ip_dn_io_t *ip_dn_io_ptr = NULL;
+ip_dn_ruledel_t *ip_dn_ruledel_ptr = NULL;
 int fw_one_pass = 1;
 
 static void	ip_freef(struct ipqhead *, struct ipq *);

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>