altq + nat on 2 interfaces

Hi,

I have an old machine on which I've installed FreeBSD to use it as home router. This box has two NICs - one to the Intenet with a "normal" IP address and one to my home LAN with a private IP address.
I want to impose traffic limits, so all hosts get equal share of the traffic but I'm having trouble pointing the traffic to the proper queues.


Code:
# LAN interface
altq on $int_if bandwidth 100% qlimit 1000 \
  cbq (ecn) queue { all_i, local_t }

  # LAN traffic has (almost) no limits
  queue  local_t bandwidth 90% \
   cbq (ecn, borrow, default) 

 # Internet download. Should share equally
 # between all hosts
  queue all_i bandwidth 10% \
    cbq (borrow, ecn) { all_i_bulk, all_i_int }

# Interactive incoming traffic
      queue all_i_int bandwidth 30% \
        priority 7 cbq (borrow, ecn)

# Bulk download
      queue all_i_bulk bandwidth 70% \
        priority 0 cbq (borrow, ecn)

#External interface
 
altq on $ext_if bandwidth 100% qlimit 1000 \
  cbq (ecn) queue { all_o, local_t }

  queue all_o  bandwidth 100% cbq \
    (borrow, ecn, default) { all_o_bulk, all_o_int }

    queue all_o_int bandwidth 30% \
    priority 7 cbq (borrow, ecn)

    queue all_o_bulk bandwidth 70% \
   priority 0 cbq (borrow, ecn)



# NAT
nat on $ext_if inet from <localnet> to any \
  tag NAT -> $ext_addr port 1024:65535

# FILTERS

block log all
block in  quick from no-route to any
block in  quick log from urpf-failed
block in  quick on $ext_if from any to 255.255.255.255
block quick to   <blocked>
block quick from <blocked>

# Allow traffic initiated from the LAN
pass out on $ext_if tagged NAT queue (all_o_bulk, all_o_int)

# Allow DNS queries
pass out on $ext_if proto udp to any \
  port 53 queue ( all_o_bulk, all_o_int )

# Allow ICMP
pass out on $ext_if inet proto icmp to any \
  queue (all_o_bulk, all_o_int)
pass in on $ext_if inet proto icmp from any \
  queue (all_i_bulk, all_i_int)

# This one has no matches and I don't know how to
# point this traffic. If it was "any to $ext_addr"
# I believe it would match the traffic initiated
# from The Internet to the router itself 
# (as if there was a web server for instance)
pass out on $int_if from any to <localnet> \
  queue (all_i_bulk, all_i_int)

# All incoming traffic goes here,
# which is not the idea
pass out from <localnet> to <localnet> \
  queue (local_t)

# I'm not sure if I can do this:

pass in on $int_if from <localnet> to any \
  queue (all_o_bulk, all_o_int)

pass in on $int_if from <localnet> to <localnet> \
  queue (local_t)

So, as the comments show, all download traffic goes in the "local_t" queue instead of going into "all_i_bulk" and "all_i_int". How should I direct the "response" traffic to the correct queues?
 
[solved]

I believe I've figured the problem out. The trick is to send the packets from <localnet> to the outgoing queue of the internal interface. Sounds a litle bit crazy at first glance, but later makes sense - PF uses the states and puts the response/return packets in the correct queue.

Code:
pass in on $int_if to any (all_i_bulk, all_i_int)

instead of:

pass in on $int_if to any (all_o_bulk, all_o_int)
 
Back
Top