2

I am trying to set up a QoS script in my OpenWRT box so that traffic coming from the Internet is classified into a low prio and a high prio class. The criteria to classify traffic is its destination IP address within my home network, i.e. a private IP address. Specifically if traffic is addressed to IP=192.168.1.22 it should go a low prio and otherwise to high prio.

In order to implement the previous I am redirecting all the Internet traffic arriving at my eth1 interface to an IFB device where I implement the traffic shaping. However, the problem that I am having is that all traffic goes to the high prio class. In order to do the filtering I am using iptables to set marks on the incoming traffic, and I guess there is where I am making the error. I am inserting my filtering rules in the "mangle" table, where I have tried the PREROUTING, FORWARD and POSTROUTING chains, but it does not work in any of these chains.

Any help is appreciated.

Best Regards

Daniel

I attach here the script I am using:

# Variable definition
ETH=eth1
IFB=ifb1
IP_LP="192.168.1.22/32"
DL_RATE="900kbit"
HP_RATE="890kbit"
LP_RATE="10kbit"
TC="tc"
IPTABLES="iptables"

# Loading the required modules
insmod ifb
insmod sch_htb
insmod sch_ingress
insmod ipt_IMQ
insmod act_mirred
insmod act_connmark
insmod cls_u32
insmod cls_fw
insmod em_u32

# Bringing up the $IFB interface, and redirecting all the ingress traffic arriving to the $ETH interface to it
$TC qdisc del dev $ETH ingress
$TC qdisc add dev $ETH ingress
ifconfig $IFB up 
$TC filter add dev $ETH parent ffff: protocol ip prio 1 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev $IFB

# Adding the HTB scheduler to the ingress interface
$TC qdisc add dev $IFB root handle 1: htb default 11

# add main rate limit classes
$TC class add dev $IFB parent 1: classid 1:1 htb rate $DL_RATE

# add leaf classes: set the maximum bandwidth that each priority class can get, and the maximum borrowing they can do
$TC class add dev $IFB parent 1:1 classid 1:10 htb rate $LP_RATE ceil $DL_RATE
$TC class add dev $IFB parent 1:1 classid 1:11 htb rate $HP_RATE ceil $DL_RATE

# filter traffic into classes by fwmark
$TC filter add dev $IFB parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10  # packets with MARK 10 go to classid 1:10
$TC filter add dev $IFB parent 1:0 prio 0 protocol ip handle 11 fw flowid 1:11  # packets with MARK 11 go to classid 1:11

# add MYSHAPER-IN chain to the mangle table in iptables
$IPTABLES -t mangle -N MYSHAPER-IN                      # create a user defined chain in the mangle table
$IPTABLES -t mangle -I PREROUTING -i $ETH -j MYSHAPER-IN            # insert a rule in the PREROUTING chain to jump to our chain

# add fwmark entries to classify different types of traffic - Set fwmark according to the priority.
$IPTABLES -t mangle -A MYSHAPER-IN -d $IP_LP -j MARK --set-mark 10              # rule to mark packets addressed to the low prio host 
$IPTABLES -t mangle -A MYSHAPER-IN -m mark --mark 0 -j MARK --set-mark 11       # rule to mark any unmarked packets as high prio

Here you can see how incoming traffic is successfully redirected to the IFB interface, but it all goes to the high prio class (of course I had the low prio host receiving data when I took this statistic):

:~# tc -s class show dev ifb1
class htb 1:11 parent 1:1 prio 0 rate 890000bit ceil 900000bit burst 1599b cburst 1599b 
 Sent 71763116 bytes 58364 pkt (dropped 7296, overlimits 0 requeues 0) 
 rate 893208bit 84pps backlog 0b 31p requeues 0 
 lended: 57510 borrowed: 823 giants: 0
 tokens: -50586 ctokens: -189649

class htb 1:10 parent 1:1 prio 0 rate 10000bit ceil 900000bit burst 1600b cburst 1599b 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 rate 0bit 0pps backlog 0b 0p requeues 0 
 lended: 0 borrowed: 0 giants: 0
 tokens: 20000000 ctokens: 222218

class htb 1:1 root rate 900000bit ceil 900000bit burst 1599b cburst 1599b 
 Sent 71720770 bytes 58333 pkt (dropped 0, overlimits 0 requeues 0) 
 rate 891776bit 84pps backlog 0b 0p requeues 0 
 lended: 823 borrowed: 0 giants: 0
 tokens: -189649 ctokens: -189649
Dani Camps
  • 301
  • 6
  • 11
  • For the record, this is because IFB is occuring before masq has occured, the destination IP on the packets is still that of the router itself. – Geoffrey Jun 18 '15 at 11:31

1 Answers1

1

I could finally solve the problem, so I document it here in case it can be useful for somebody else. The trick was to use the IMQ device instead of the IFB one. There was no problem then classifying with iptables and using IMQ.

Best Regards

Daniel

This is the working script:

#!/bin/sh

# This script classifies all the Internet traffic addressed to a given IP in our LAN (IP_LP) as low priority. 
# All the rest of traffic is classified as high priority. In the absence of high prio the low prio can grab all the bandwidth. 
# However, when there is high prio traffic the low prio one is limited to 10Kbos. 

INTERNET="eth1"
IMQ="imq1"
IP_LP="192.168.1.22/32"
DL_RATE="900kbit"
HP_RATE="890kbit"
LP_RATE="10kbit"
TC="tc"
IPTABLES="iptables"
IFCONFIG="ifconfig"

# Loading the required modules
insmod ifb
insmod sch_htb
insmod sch_ingress
insmod ipt_IMQ
insmod act_mirred
insmod act_connmark
insmod cls_u32
insmod cls_fw
insmod em_u32

# Bringing up the IMQ device
$IFCONFIG $IMQ up

# Adding the HTB scheduler to the ingress interface
$TC qdisc add dev $IMQ root handle 1: htb default 11

# add main rate limit classes
$TC class add dev $IMQ parent 1: classid 1:1 htb rate $DL_RATE

# add leaf classes: set the maximum bandwidth that each priority class can get, and the maximum borrowing they can do
$TC class add dev $IMQ parent 1:1 classid 1:10 htb rate $LP_RATE ceil $DL_RATE
$TC class add dev $IMQ parent 1:1 classid 1:11 htb rate $HP_RATE ceil $DL_RATE

# Filtering packets according to destination IP address
$TC filter add dev $IMQ parent 1: protocol ip prio 1 u32 match ip dst $IP_LP flowid 1:10

# Sending packets after SNAT has been done into the IMQ device
$IPTABLES -t mangle -A FORWARD -i $INTERNET -j IMQ --todev 1
Dani Camps
  • 301
  • 6
  • 11