#!/bin/bash
# Global definitions
. /home/andres/src/tcscripts/vif

# Create ifb0, idempotent
modprobe ifb
ip link set ${IFB} up

# Redirect inbound and outbound traffic to an ifb0 pseudo-interface, where it will all be shaped
# according to rule
#RULE="netem delay 50ms"
#RULE="rrc fachdchmu 50ms fachdchsigma 10ms"
RULE="rrc drop 0 delay 50ms dchdlrate 500kbit dchulrate 500kbit"

${TC} qdisc add dev ${IF} ingress
${TC} qdisc add dev ${IF} root handle 1: prio
${TC} qdisc add dev ${IFB} root ${RULE}

# - The proper handle for the ingress qdisc is ffff:fff1. In kernel, the minor gets masked out.
# - Without a classid the filter is not bound, and therefore not activated. But for ingress,
# classid's are meaningless. 
# - classid and flowid are synonimous.
# - u32 is a classifier that matches on actual octets. match u32 0 0 means take the first u32 
# (i.e. 4 bytes) of the packet, and it with 0, if it matches 0, filter succeeds. Effectively a 
# tautology rule that will match all packets
# - The parent is very important. The reason we put a prio qdisc on root is to obtain a qdisc 
# with a handle that we can later refer to. The default qdisc is *not* at root. Notice that due to 
# the filter rule we chose, all packets match, all packets are redirected, no packet actually hits 
# the prio qdisc
# - protocol all is important to also make non ip traffic (arp, etc) go through the filter
# - action tells the filter what to do on success, beyond giving it a classid. for mirred, egress 
# is a nop (ingress not supported/makes no sense) and redirect dev is (finally!) self-explanatory 
${TC} filter add dev ${IF} parent ffff:fff1 protocol all u32 match u32 0 0 classid 25:25 action mirred egress redirect dev ${IFB}
${TC} filter add dev ${IF} parent 1: protocol all u32 match u32 0 0 flowid 25:25 action mirred egress redirect dev ${IFB}

# When you look at the egress filter (tc -s filter show dev ${IF} parent 1:) you'll see the
# number of filter matches doubles the actual number of packets. Apparently a packet hits 
# filter, is redirected ifb0, once out of ifb0 comes back to ${IF}, hits the filter again,
# but is not redirected twice. Number of sent packets for the filter is half of number
# of successful rule evals. This doesn't happen for ingress (who knows....)

