Blame doc/actions/actions-general

Packit d3f73b
Packit d3f73b
This documented is slightly dated but should give you idea of how things
Packit d3f73b
work.
Packit d3f73b
Packit d3f73b
What is it?
Packit d3f73b
-----------
Packit d3f73b
Packit d3f73b
An extension to the filtering/classification architecture of Linux Traffic
Packit d3f73b
Control.
Packit d3f73b
Up to 2.6.8 the only action that could be "attached" to a filter was policing.
Packit d3f73b
i.e you could say something like:
Packit d3f73b
Packit d3f73b
-----
Packit d3f73b
tc filter add dev lo parent ffff: protocol ip prio 10 u32 match ip src \
Packit d3f73b
127.0.0.1/32 flowid 1:1 police mtu 4000 rate 1500kbit burst 90k
Packit d3f73b
-----
Packit d3f73b
Packit d3f73b
which implies "if a packet is seen on the ingress of the lo device with
Packit d3f73b
a source IP address of 127.0.0.1/32 we give it a classification id  of 1:1 and
Packit d3f73b
we execute a policing action which rate limits its bandwidth utilization
Packit d3f73b
to 1.5Mbps".
Packit d3f73b
Packit d3f73b
The new extensions allow for more than just policing actions to be added.
Packit d3f73b
They are also fully backward compatible. If you have a kernel that doesn't
Packit d3f73b
understand them, then the effect is null i.e if you have a newer tc
Packit d3f73b
but older kernel, the actions are not installed. Likewise if you
Packit d3f73b
have a newer kernel but older tc, obviously the tc will use current
Packit d3f73b
syntax which will work fine. Of course to get the required effect you need
Packit d3f73b
both newer tc and kernel. If you are reading this you have the
Packit d3f73b
right tc ;->
Packit d3f73b
Packit d3f73b
A side effect is that we can now get stateless firewalling to work with tc.
Packit d3f73b
Essentially this is now an alternative to iptables.
Packit d3f73b
I won't go into details of my dislike for iptables at times, but
Packit d3f73b
scalability is one of the main issues; however, if you need stateful
Packit d3f73b
classification - use netfilter (for now).
Packit d3f73b
Packit d3f73b
This stuff works on both ingress and egress qdiscs.
Packit d3f73b
Packit d3f73b
Features
Packit d3f73b
--------
Packit d3f73b
Packit d3f73b
1) new additional syntax and actions enabled. Note old syntax is still valid.
Packit d3f73b
Packit d3f73b
Essentially this is still the same syntax as tc with a new construct
Packit d3f73b
"action". The syntax is of the form:
Packit d3f73b
tc filter add <DEVICE> parent 1:0 protocol ip prio 10 <Filter description>
Packit d3f73b
flowid 1:1 action <ACTION description>*
Packit d3f73b
Packit d3f73b
You can have as many actions as you want (within sensible reasoning).
Packit d3f73b
Packit d3f73b
In the past the only real action was the policer; i.e you could do something
Packit d3f73b
along the lines of:
Packit d3f73b
tc filter add dev lo parent ffff: protocol ip prio 10 u32 \
Packit d3f73b
match ip src 127.0.0.1/32 flowid 1:1 \
Packit d3f73b
police mtu 4000 rate 1500kbit burst 90k
Packit d3f73b
Packit d3f73b
Although you can still use the same syntax, now you can say:
Packit d3f73b
Packit d3f73b
tc filter add dev lo parent 1:0 protocol ip prio 10 u32 \
Packit d3f73b
match ip src 127.0.0.1/32 flowid 1:1 \
Packit d3f73b
action police mtu 4000 rate 1500kbit burst 90k
Packit d3f73b
Packit d3f73b
" generic Actions" (gact) at the moment are:
Packit d3f73b
{ drop, pass, reclassify, continue}
Packit d3f73b
(If you have others, no listed here give me a reason and we will add them)
Packit d3f73b
+drop says to drop the packet
Packit d3f73b
+pass and ok (are equivalent) says to accept it
Packit d3f73b
+reclassify requests for reclassification of the packet
Packit d3f73b
+continue requests for next lookup to match
Packit d3f73b
Packit d3f73b
2)In order to take advantage of some of the targets written by the
Packit d3f73b
iptables people, a classifier can have a packet being massaged by an
Packit d3f73b
iptable target. I have only tested with mangler targets up to now.
Packit d3f73b
(infact anything that is not in the mangling table is disabled right now)
Packit d3f73b
Packit d3f73b
In terms of hooks:
Packit d3f73b
*ingress is mapped to pre-routing hook
Packit d3f73b
*egress is mapped to post-routing hook
Packit d3f73b
I don't see much value in the other hooks, if you see it and email me good
Packit d3f73b
reasons, the addition is trivial.
Packit d3f73b
Packit d3f73b
Example syntax for iptables targets usage becomes:
Packit d3f73b
tc filter add ..... u32 <u32 syntax> action ipt -j <iptables target syntax>
Packit d3f73b
Packit d3f73b
example:
Packit d3f73b
tc filter add dev lo parent ffff: protocol ip prio 8 u32 \
Packit d3f73b
match ip dst 127.0.0.8/32 flowid 1:12 \
Packit d3f73b
action ipt -j mark --set-mark 2
Packit d3f73b
Packit d3f73b
NOTE: flowid 1:12 is parsed flowid 0x1:0x12.  Make sure if you want flowid
Packit d3f73b
decimal 12, then use flowid 1:c.
Packit d3f73b
Packit d3f73b
3) A feature i call pipe
Packit d3f73b
The motivation is derived from Unix pipe mechanism but applied to packets.
Packit d3f73b
Essentially take a matching packet and pass it through
Packit d3f73b
action1 | action2 | action3 etc.
Packit d3f73b
You could do something similar to this with the tc policer and the "continue"
Packit d3f73b
operator but this rather restricts it to just the policer and requires
Packit d3f73b
multiple rules (and lookups, hence quiet inefficient);
Packit d3f73b
Packit d3f73b
as an example -- and please note that this is just an example _not_ The
Packit d3f73b
Word Youve Been Waiting For (yes i have had problems giving examples
Packit d3f73b
which ended becoming dogma in documents and people modifying them a little
Packit d3f73b
to look clever);
Packit d3f73b
Packit d3f73b
i selected the metering rates to be small so that i can show better how
Packit d3f73b
things work.
Packit d3f73b
Packit d3f73b
The script below does the following:
Packit d3f73b
- an incoming packet from 10.0.0.21 is first given a firewall mark of 1.
Packit d3f73b
Packit d3f73b
- It is then metered to make sure it does not exceed its allocated rate of
Packit d3f73b
1Kbps. If it doesn't exceed rate, this is where we terminate action execution.
Packit d3f73b
Packit d3f73b
- If it does exceed its rate, its "color" changes to a mark of 2 and it is
Packit d3f73b
then passed through a second meter.
Packit d3f73b
Packit d3f73b
-The second meter is shared across all flows on that device [i am surpised
Packit d3f73b
that this seems to be not a well know feature of the policer; Bert was telling
Packit d3f73b
me that someone was writing a qdisc just to do sharing across multiple devices;
Packit d3f73b
it must be the summer heat again; weve had someone doing that every year around
Packit d3f73b
summer  -- the key to sharing is to use a operator "index" in your policer
Packit d3f73b
rules (example "index 20"). All your rules have to use the same index to
Packit d3f73b
share.]
Packit d3f73b
Packit d3f73b
-If the second meter is exceeded the color of the flow changes further to 3.
Packit d3f73b
Packit d3f73b
-We then pass the packet to another meter which is shared across all devices
Packit d3f73b
in the system. If this meter is exceeded we drop the packet.
Packit d3f73b
Packit d3f73b
Note the mark can be used further up the system to do things like policy
Packit d3f73b
or more interesting things on the egress.
Packit d3f73b
Packit d3f73b
------------------ cut here -------------------------------
Packit d3f73b
#
Packit d3f73b
# Add an ingress qdisc on eth0
Packit d3f73b
tc qdisc add dev eth0 ingress
Packit d3f73b
#
Packit d3f73b
#if you see an incoming packet from 10.0.0.21
Packit d3f73b
tc filter add dev eth0 parent ffff: protocol ip prio 1 \
Packit d3f73b
u32 match ip src 10.0.0.21/32 flowid 1:15 \
Packit d3f73b
#
Packit d3f73b
# first give it a mark of 1
Packit d3f73b
action ipt -j mark --set-mark 1 index 2 \
Packit d3f73b
#
Packit d3f73b
# then pass it through a policer which allows 1kbps; if the flow
Packit d3f73b
# doesn't exceed that rate, this is where we stop, if it exceeds we
Packit d3f73b
# pipe the packet to the next action
Packit d3f73b
action police rate 1kbit burst 9k pipe \
Packit d3f73b
#
Packit d3f73b
# which marks the packet fwmark as 2 and pipes
Packit d3f73b
action ipt -j mark --set-mark 2 \
Packit d3f73b
#
Packit d3f73b
# next attempt to borrow b/width from a meter
Packit d3f73b
# used across all flows incoming on eth0("index 30")
Packit d3f73b
# and if that is exceeded we pipe to the next action
Packit d3f73b
action police index 30 mtu 5000 rate 1kbit burst 10k pipe \
Packit d3f73b
# mark it as fwmark 3 if exceeded
Packit d3f73b
action ipt -j mark --set-mark 3 \
Packit d3f73b
# and then attempt to borrow from a meter used by all devices in the
Packit d3f73b
# system. Should this be exceeded, drop the packet on the floor.
Packit d3f73b
action police index 20 mtu 5000 rate 1kbit burst 90k drop
Packit d3f73b
---------------------------------
Packit d3f73b
Packit d3f73b
Now lets see the actions installed with
Packit d3f73b
"tc filter show parent ffff: dev eth0"
Packit d3f73b
Packit d3f73b
-------- output -----------
Packit d3f73b
jroot# tc filter show parent ffff: dev eth0
Packit d3f73b
filter protocol ip pref 1 u32
Packit d3f73b
filter protocol ip pref 1 u32 fh 800: ht divisor 1
Packit d3f73b
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:15
Packit d3f73b
Packit d3f73b
   action order 1: tablename: mangle  hook: NF_IP_PRE_ROUTING
Packit d3f73b
        target MARK set 0x1  index 2
Packit d3f73b
Packit d3f73b
   action order 2: police 1 action pipe rate 1Kbit burst 9Kb mtu 2Kb
Packit d3f73b
Packit d3f73b
   action order 3: tablename: mangle  hook: NF_IP_PRE_ROUTING
Packit d3f73b
        target MARK set 0x2  index 1
Packit d3f73b
Packit d3f73b
   action order 4: police 30 action pipe rate 1Kbit burst 10Kb mtu 5000b
Packit d3f73b
Packit d3f73b
   action order 5: tablename: mangle  hook: NF_IP_PRE_ROUTING
Packit d3f73b
        target MARK set 0x3  index 3
Packit d3f73b
Packit d3f73b
   action order 6: police 20 action drop rate 1Kbit burst 90Kb mtu 5000b
Packit d3f73b
Packit d3f73b
  match 0a000015/ffffffff at 12
Packit d3f73b
-------------------------------
Packit d3f73b
Packit d3f73b
Note the ordering of the actions is based on the order in which we entered
Packit d3f73b
them. In the future i will add explicit priorities.
Packit d3f73b
Packit d3f73b
Now lets run a ping -f from 10.0.0.21 to this host; stop the ping after
Packit d3f73b
you see a few lines of dots
Packit d3f73b
Packit d3f73b
----
Packit d3f73b
[root@jzny hadi]# ping -f  10.0.0.22
Packit d3f73b
PING 10.0.0.22 (10.0.0.22): 56 data bytes
Packit d3f73b
....................................................................................................................................................................................................................................................................................................................................................................................................................................................
Packit d3f73b
--- 10.0.0.22 ping statistics ---
Packit d3f73b
2248 packets transmitted, 1811 packets received, 19% packet loss
Packit d3f73b
round-trip min/avg/max = 0.7/9.3/20.1 ms
Packit d3f73b
-----------------------------
Packit d3f73b
Packit d3f73b
Now lets take a look at the stats with "tc -s filter show parent ffff: dev eth0"
Packit d3f73b
Packit d3f73b
--------------
Packit d3f73b
jroot# tc -s filter show parent ffff: dev eth0
Packit d3f73b
filter protocol ip pref 1 u32
Packit d3f73b
filter protocol ip pref 1 u32 fh 800: ht divisor 1
Packit d3f73b
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
Packit d3f73b
5
Packit d3f73b
Packit d3f73b
   action order 1: tablename: mangle  hook: NF_IP_PRE_ROUTING
Packit d3f73b
        target MARK set 0x1  index 2
Packit d3f73b
         Sent 188832 bytes 2248 pkts (dropped 0, overlimits 0)
Packit d3f73b
Packit d3f73b
   action order 2: police 1 action pipe rate 1Kbit burst 9Kb mtu 2Kb
Packit d3f73b
         Sent 188832 bytes 2248 pkts (dropped 0, overlimits 2122)
Packit d3f73b
Packit d3f73b
   action order 3: tablename: mangle  hook: NF_IP_PRE_ROUTING
Packit d3f73b
        target MARK set 0x2  index 1
Packit d3f73b
         Sent 178248 bytes 2122 pkts (dropped 0, overlimits 0)
Packit d3f73b
Packit d3f73b
   action order 4: police 30 action pipe rate 1Kbit burst 10Kb mtu 5000b
Packit d3f73b
         Sent 178248 bytes 2122 pkts (dropped 0, overlimits 1945)
Packit d3f73b
Packit d3f73b
   action order 5: tablename: mangle  hook: NF_IP_PRE_ROUTING
Packit d3f73b
        target MARK set 0x3  index 3
Packit d3f73b
         Sent 163380 bytes 1945 pkts (dropped 0, overlimits 0)
Packit d3f73b
Packit d3f73b
   action order 6: police 20 action drop rate 1Kbit burst 90Kb mtu 5000b
Packit d3f73b
         Sent 163380 bytes 1945 pkts (dropped 0, overlimits 437)
Packit d3f73b
Packit d3f73b
  match 0a000015/ffffffff at 12
Packit d3f73b
-------------------------------
Packit d3f73b
Packit d3f73b
Neat, eh?
Packit d3f73b
Packit d3f73b
Packit d3f73b
Want to  write an action module?
Packit d3f73b
------------------------------
Packit d3f73b
Its easy. Either look at the code or send me email. I will document at
Packit d3f73b
some point; will also accept documentation.
Packit d3f73b
Packit d3f73b
TODO
Packit d3f73b
----
Packit d3f73b
Packit d3f73b
Lotsa goodies/features coming. Requests also being accepted.
Packit d3f73b
At the moment the focus has been on getting the architecture in place.
Packit d3f73b
Expect new things in the spurious time i have to work on this
Packit d3f73b
(particularly around end of year when i have typically get time off
Packit d3f73b
from work).