====== Difference between ingress/egress qdisc ====== | Feature | Ingress Qdisc | egress Qdisc | | Direction | Incoming traffic | Outgoing traffic | | Common Usage | Policing (rate limiting) | Shaping, scheduling | | Handle | ffff: | Custom (e.g., 1:) | | Parent Keyword | parent ffff: | parent : | | Shaping Support | ❌ Not supported | ✅ Supported | | Example Qdisc | ingress | htb, fq_codel, tbf, etc. | | create qdisc | tc qdisc add dev **handle ffff:** ingress | tc qdisc add dev **root handle** 1: htb default 10 | | create filter | tc filter add dev **parent ffff:** \ \\ protocol ip prio 1 u32 match ip src 0.0.0.0/0 \ \\ police rate 1mbit burst 10k drop flowid :1 | tc class add dev **parent 1:** classid 1:10 htb rate 1mbit \\ tc filter add dev protocol ip **parent 1:** prio 1 u32 \ \\ match ip dst 0.0.0.0/0 flowid 1:10 | Note: * **handle ffff:** is a reserved handle for ingress and **parent ffff:** refers to the ingress qdisc. * **root** refers to the egress qdisc. * **police** is used to enforce rate limits. * **htb** is a **hierarchical** token bucket used for shaping. * **flowid** assigns traffic to **a specific class**. * **tc class** is only for egress qdisc, not ingress qdisc * **lowid :1** in this ingress command is a label or tag used for accounting and statistics: tc filter add dev parent ffff: protocol ip prio 1 u32 match ip src 0.0.0.0/0 police rate 1mbit burst 10k drop **flowid :1** ====== Example to create below queue structures ====== Queue 1 ─┐ Queue 2 ─┘→ Scheduler 1 → Scheduler 2 → Root Egress Qdisc (eth1) Queue 3 ─┐ Queue 4 ─┘→ Scheduler 3 → Scheduler 4 → Root Egress Qdisc (eth1) Note: * use **tc class** to create queue/scheduler structure * use **tc filter** to map traffic to queue # Step 1: Add root HTB qdisc to eth1 tc qdisc add dev eth1 root handle 1: htb default 100 # Step 2: Create top-level classes (Scheduler 2 and Scheduler 4) tc class add dev eth1 parent 1: classid 1:10 htb rate 10mbit # Scheduler 2 tc class add dev eth1 parent 1: classid 1:20 htb rate 10mbit # Scheduler 4 # Step 3: Create second-level classes (Scheduler 1 and Scheduler 3) tc class add dev eth1 parent 1:10 classid 1:11 htb rate 5mbit # Scheduler 1 tc class add dev eth1 parent 1:20 classid 1:21 htb rate 5mbit # Scheduler 3 # Step 4: Create leaf classes (Queues) tc class add dev eth1 parent 1:11 classid 1:111 htb rate 2mbit # Queue 1 tc class add dev eth1 parent 1:11 classid 1:112 htb rate 3mbit # Queue 2 tc class add dev eth1 parent 1:21 classid 1:211 htb rate 2mbit # Queue 3 tc class add dev eth1 parent 1:21 classid 1:212 htb rate 3mbit # Queue 4 # Step 5: Attach filters to classify traffic into queues # You can change IPs or match conditions as needed # Queue 1: traffic from 192.168.1.1 tc filter add dev eth1 protocol ip parent 1: prio 1 u32 \ match ip src 192.168.1.1/32 flowid 1:111 # Queue 2: traffic from 192.168.1.2 tc filter add dev eth1 protocol ip parent 1: prio 1 u32 \ match ip src 192.168.1.2/32 flowid 1:112 # Queue 3: traffic from 192.168.1.3 tc filter add dev eth1 protocol ip parent 1: prio 1 u32 \ match ip src 192.168.1.3/32 flowid 1:211 # Queue 4: traffic from 192.168.1.4 tc filter add dev eth1 protocol ip parent 1: prio 1 u32 \ match ip src 192.168.1.4/32 flowid 1:212 Delete filter example: * filter del dev eth1 protocol ip parent 1: prio 1 Delete class example: * tc class del dev eth1 classid 1:111 # Queue 1 * tc class del dev eth1 classid 1:112 # Queue 2 * tc class del dev eth1 classid 1:211 # Queue 3 * tc class del dev eth1 classid 1:212 # Queue 4 * tc class del dev eth1 classid 1:11 # Scheduler 1 * tc class del dev eth1 classid 1:21 # Scheduler 3 * tc class del dev eth1 classid 1:10 # Scheduler 2 * tc class del dev eth1 classid 1:20 # Scheduler 4 Delete qdisc example: * tc qdisc del dev eth1 root ====== example to create multiple chains in the ingress qdisc ====== ====== example to create multiple chains in the egress qdisc ======