0

I have a Linux server application running on a specific IP and PORT. Incoming packets need to be manipulated and put into an nfqueue based on sources and ports, for example:

iptables -t raw -A PREROUTING -p udp --src 192.168.1.100 --sport 8000 -j NFQUEUE --queue-num 1
iptables -t raw -A PREROUTING -p tcp --src 192.168.1.100 --sport 8001 -j NFQUEUE --queue-num 1

The problem is that nfqueue fills up quickly and starts dropping packages. Packet manipulation is not as fast as inbound speed. I need to limit the bandwidth to a certain rate that doesn't overflow the nfqueue buffer. Only traffic that matches the iptables rules has to be limited, the rest remains unlimited.

What's the best approach? I read that it is possible to use tc. I'm not familiar with this. I need to limit the bandwidth for all incoming packets to this specific (IP, PORT) pair. What's the best approach? I read that it is possible to use tc. I'm not familiar with this.

2

1 Answer 1

1

You can indeed use tc to shape your incoming bandwidth on this ip-port tuple. To shape the incoming packets, you need an ifb virtual interface so you can apply egress filters on it. Then you create the root qdisc on the virtual interface, and a shaping class attached to it. You can then build a filter to direct traffic on the class. It should be something like this:

# Define variables
IP=192.168.1.100/32
PORT=8000
INTERFACE=eth0
VIRTUAL_INTERFACE=ifb0
# Speed unit is Mbits/s
TUPLE_SPEED=100

# Add the virtual interface
modprobe ifb numifbs=1;
ip link set dev "$VIRTUAL_INTERFACE" up;

# Redirect ingress packets to egress virtual interface
tc qdisc add dev "$INTERFACE" handle ffff: ingress
tc filter add dev "$INTERFACE" parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev "$VIRTUAL_INTERFACE";

# Create root qdisc and class for the virtual interface
tc qdisc add dev "$VIRTUAL_INTERFACE" root handle 1: htb;
tc class add dev "$VIRTUAL_INTERFACE" parent 1: classid 1:10 htb rate "${TUPLE_SPEED}mbit";

# Add a filter that match yor tuple 
tc filter add dev "$VIRTUAL_INTERFACE" protocol ip parent 1: prio 1 u32 match ip dst "${IP}" match udp dst"${PORT}" flowid 1:10;

Note you can add multiple tc filter lines to match multiple source tuples.

If you want to start digging, you should read https://blog.csdn.net/mrwangwang/article/details/39080895 first, and start all your google query by site:lartc.org

5
  • The goal is to limit the bandwidth because nfqueue gets full and starts dropping incoming packets. Server is using the following iptable command: iptables -t raw -A PREROUTING -p udp --src 192.168.1.100 --sport 8000 -j NFQUEUE --queue-num 1
    – seq16
    Feb 3 at 12:34
  • 1
    Can you please update your question with this, and give some more informations with an example flow and its path and context? Feb 3 at 13:02
  • Thanks! Are 192.168.1.100 and udp port 8000 the client sources IP and port? Or are they server listening ip and port, and you are nfqueueing the answer from your server? Feb 3 at 14:37
  • I changed the answer so if 192.168.1.100:8000 is the source, it should be good like this. Feb 3 at 14:43
  • IP 192.168.1.100 and port 8000 are client source ip. Server gets UDP and TCP packets from clients.
    – seq16
    Feb 4 at 8:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .