# ipfw queue problem



## jishnu (Jan 20, 2012)

I have another little problem with my ipfw queue rules. I have 3 ethernet cards: 1 EXTERNAL and 2 INTERNAL(NAT). My goal is to shape download speed of my two INTERNAL lans.

The problem is: my queue rules works only when I use 'external ip' not 'internal class'.

Here are my configs.

/etc/ipnat.rules

```
map em0 192.168.1.0/24 -> xx.xx.62.20 portmap tcp/udp auto
map em0 192.168.1.0/24 -> xx.xx.62.20 icmp
map em0 192.168.2.0/24 -> xx.xx.62.20 portmap tcp/udp auto
map em0 192.168.2.0/24 -> xx.xx.62.20 icmp
```

/etc/ipfw.rules

```
${fwcmd} pipe 1 config bw 24Mbit/s
${fwcmd} pipe 2 config bw 15Mbit/s
${fwcmd} pipe 3 config bw 24Mbit/s
${fwcmd} pipe 4 config bw 15Mbit/s

${fwcmd} add 10 pipe 3 all from ${lan1} to any in via em1
${fwcmd} add 20 pipe 1 all from any to ${lan1} out via em1
${fwcmd} add 30 pipe 4 all from ${lan2} to any in via rl0
${fwcmd} add 40 pipe 2 all from any to ${lan2} out via rl0

# DOWNLOAD SPEED
${fwcmd} add 21 queue 21 all from any to 192.168.1.0/24
${fwcmd} queue config 21 weight 5 pipe 1 buckets 255 mask dst-ip 0xffffffff
${fwcmd} add 41 queue 41 all from any to 192.168.1.0/24
${fwcmd} queue config 41 weight 5 pipe 2 buckets 255 mask dst-ip 0xffffffff

...
```

When I download things from 192.168.1.0/24 using this config queue is free.

```
q00021  50 sl. 1 flows (255 buckets) sched 9 weight 5 lmax 0 pri 0 droptail
    mask:  0x00 0x00000000/0x0000 -> 0xffffffff/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
```

But when I change ipfw rules to (using EXTERNAL IP):

```
${fwcmd} add 21 queue 21 all from any to xx.xx.62.20/32
${fwcmd} queue config 21 weight 5 pipe 1 buckets 255 mask dst-ip 0xffffffff
${fwcmd} add 41 queue 41 all from any to xx.xx.62.20/32
${fwcmd} queue config 41 weight 5 pipe 2 buckets 255 mask dst-ip 0xffffffff
```
then it works

```
q00065  50 sl. 1 flows (255 buckets) sched 9 weight 5 lmax 0 pri 0 droptail
    mask:  0x00 0x00000000/0x0000 -> 0xffffffff/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
 81 ip           0.0.0.0/0         xx.xx.62.20/0       14     1176  0    0   0
```

Problem is: that way I can't 'cut' 192.168.2.0/24 subnet. Why does queue work with external IP but not the internal class. Is this problem with NAT?


----------



## ecazamir (Jan 20, 2012)

Why don't you use: 

```
/sbin/ipfw add 41 queue 41 all from any to 192.168.1.0/24 out recv ${ext_if} xmit ${int_if}
```
It's a single match for a specific flow, when the packets leave the system, without limiting traffic between subnets connected the two local interfaces.
I suggest the following 'way to do it':
- match only on egress (out keyword)
- specify where the packet came from and where is leaving the system: recv and xmit keywords
- define pipes/queues before creating rules to send traffic to them, to prevent packet loss when loading rules
- try to use 'any' as few times as possible, especially on multi-LAN configurations. A _! <local_ip_space>_ (negation, local_ip_space should be a table of all local subnets) may help

On your example I see the following problems:
- the rule numbered 30 will match packets sent from ${lan2} to ${lan1}, which may not be intended. Also, this rule will match twice: for ingress packets and egress packets, cutting the total usable bandwidth of the pipe because the pipe is used twice for the same traffic.
- if you define queues, use them. I don't see any match rule sending traffic to queue 21 and 41 on the first part of the script, so this traffic is not affected by pipes and queues.
- I see a pipe 65, which is not defined on the code you posted, same for the matching rules sending traffic to pipe 65.


----------



## phoenix (Jan 21, 2012)

jishnu said:
			
		

> I have another little problem with my ipfw queue rules. I have 3 ethernet cards: 1 EXTERNAL and 2 INTERNAL(NAT). My goal is to shape download speed of my two INTERNAL lans.
> 
> The problem is: my queue rules works only when I use 'external ip' not 'internal class'.
> 
> ...



Why are you using ipnat, which is part of IPFilter, with IPFW?  That's running two completely separate packet filters.  Just use IPFW; it includes NAT functionality.



> /etc/ipfw.rules
> 
> ```
> ${fwcmd} pipe 1 config bw 24Mbit/s
> ...


Here you configure 4 separate pipes.



> ```
> ${fwcmd} add 10 pipe 3 all from ${lan1} to any in via em1
> ${fwcmd} add 20 pipe 1 all from any to ${lan1} out via em1
> ${fwcmd} add 30 pipe 4 all from ${lan2} to any in via rl0
> ...


Here you send all traffic to/from LAN1 to one pipe, and all the traffic to/from LAN2 to the other pipe.  These rules right here limit all the traffic to/from the two LANs.  Packets stop going through the ruleset here, unless you've changed sysctls, so no packets ever reach the queues below.



> ```
> ${fwcmd} add 21 queue 21 all from any to 192.168.1.0/24
> ${fwcmd} queue config 21 weight 5 pipe 1 buckets 255 mask dst-ip 0xffffffff
> ${fwcmd} add 41 queue 41 all from any to 192.168.1.0/24
> ...


Yet here you are configuring queues inside of the existing pipes (which you have already sent traffic through), and are trying to send the traffic (again) into the queues.



> When I download things from 192.168.1.0/24 using this config queue is free.


Yeah, because you sent all the traffic through the pipe at the top of the ruleset.



> But when I change ipfw rules to (using EXTERNAL IP):
> 
> ```
> ${fwcmd} add 21 queue 21 all from any to xx.xx.62.20/32
> ...


Yeah, cause this is separate traffic from the stuff you sent through the pipe, as you are doing the queuing on a different interface from the piping.  The packets going out of the firewall on the public interface don't match the pipe rules above, so they fall through the ruleset and match these rules.



> Problem is: that way I can't 'cut' 192.168.2.0/24 subnet. Why does queue work with external IP but not the internal class. Is this problem with NAT?



Remove the rules where you send the traffic into the pipes.

Configure the pipes.
Configure the queues using those pipes.
Then add the rules that send traffic into the queues.

Don't send any traffic directly into the pipes.


----------



## jishnu (Jan 21, 2012)

*thanks*

You showed me my mistakes very clearly.
Thanks guys.


----------

