Throttling/QoS with Traffic Control (tc)

This guide demonstrates how to throttle selected application traffic using the Flow Actions Plugin, Linux IP Sets, iptables, and tc.

It also highlights one of the most useful Flow Actions patterns: criteria loaded from "dot-d" configlet folders, which makes policy updates simple to automate.

Requirements

  • Netify Agent v5 with the Flow Actions Plugin installed
  • A Linux system with ipset , iptables , and tc installed
  • Privileges to restart netifyd and manage IP set / firewall / tc state
  • CAP_NET_ADMIN permissions for managing kernel networking controls

Configuration

With the plugin enabled, the next step is to modify the configuration file, /etc/netifyd/netify-proc-flow-actions.json . For this example, we'll drop in a full sample config and review each line and its purpose.

Target

Start with the target definition. A target defines what to do when an action matches. In this example, matching traffic is written to the nfa.throttle IP set.

Actions

The actions block defines when the target is applied. Here, the criteria does not use inline expressions; instead, it points to a configlet folder.

Configlets

In this example, notice how the criteria are not hardcoded into the JSON file. Instead, they are loaded from a configlet directory, defined in a folder, in this case, /etc/netifyd/nfa-throttle.d.

During startup, or after a reload signal, the agent parses configlets in this folder. This model is powerful for automation because individual policy files can be added, updated, enabled, or disabled without replacing the full Flow Actions configuration.

/etc/netifyd/netify-proc-flow-actions.json

{
   "version": 1,
   "targets": {
      "ipset.throttle": {
         "target_type": "ipset",
         "set_name": "nfa.throttle",
         "set_family": "ipv4",
         "type": "hash:ip,port,ip",
         "managed": true,
         "ttl": 60,
         "auto_expire": true,
         "flush_on_destroy": true
      }
   },
   "actions": {
      "throttled": {
         "enabled": true,
         "interface": "*",
         "criteria": [
            "${path_state_persistent}/nfa-throttle.d"
         ],
         "targets": [
            "ipset.throttle"
         ]
      }
   }
}

Connection Tracking in Action

During startup or on receiving a HUP command, the agent will parse any configlets found in this folder. The convenience and power this model provides should not be underestimated, especially when making modifications programmatically. A developer can simply drop and remove (or disable) individual configlet files to tailor a solution. To see how that would work, run:

Terminal - Netify
×
echo "app == 'netify.netflix';" > /etc/netifyd/nfa-throttle.d/10-netflix.conf
systemctl reload netifyd

This writes a valid expression for netify.netflix into a clearly named configlet. After reload, the Flow Actions engine includes the new policy. If you then run:

Terminal - Netify
×
echo "app == 'netify.youtube';" > /etc/netifyd/nfa-throttle.d/10-youtube.conf
systemctl reload netifyd

the policy matches both Netflix and YouTube traffic. To remove or disable a policy, you can do either of the following:

Terminal - Netify
×
rm -f /etc/netifyd/nfa-throttle.d/10-netflix.conf
systemctl reload netifyd

or

Terminal - Netify
×
mv /etc/netifyd/nfa-throttle.d/10-netflix.conf /etc/netifyd/nfa-throttle.d/10-netflix.conf.disabled
systemctl reload netifyd

At this point, the agent is populating nfa.throttle.v4 , but no Layer 3 shaping policy is acting on it yet. Next, create a script named netify-throttle with the following commands:

Terminal - Netify
×
#!/bin/bash
export LAN=eth1
tc qdisc add dev $LAN root handle 1: htb default 20
tc class add dev $LAN parent 1: classid 1:1 htb rate 500kbit burst 500k
tc filter add dev $LAN protocol ip parent 1: prio 1 handle 6 fw flowid 1:1
tc -p -s -d  qdisc show dev $LAN
iptables -t filter -A FORWARD -m set --match-set nfa.throttle.v4 dst,dst,src  -j MARK --set-mark 6
iptables -t filter -A OUTPUT -m set --match-set nfa.throttle.v4 dst,dst,src  -j MARK --set-mark 6

The OUTPUT rule above is only needed when evaluating this policy on a non-gateway host. It applies to packets originating from local processes.

Update the LAN interface name for your environment. For example, on a standard OpenWRT installation this is often export LAN=br-lan .

This creates a 500 kbps throttling policy using HTB in a traffic control class. The iptables rules mark packets, and tc applies shaping based on those marks. You can confirm shaping activity by inspecting tc statistics:

Terminal - Netify
×
export LAN=eth1
tc -p -s -d  qdisc show dev $LAN

You can also validate behavior functionally: throttled services such as Netflix or YouTube should show reduced quality or slower load performance.

As matching traffic flows, entries are inserted into nfa.throttle.v4 and consumed by your firewall and tc rules. Together, Flow Actions and standard Linux tools provide a complete Layer 7 to Layer 3 QoS pipeline.