Policy based routing MICRO-HOWTO Horacio J. Peņa, horape@compendium.com.ar v0.02 29/Nov/1998 1. Preface and disclaimer and help request. This is my attempt to recopilate some info on how to use the advanced routing capabilities of the 2.1.x Linux kernels. As each time i've asked for help in linux-(kernel|net|router|es) instead of getting answers i received lots of mail saying "You seem to know how to use iproute, could you explain me it?" i'm writing that so i can send them an URL :-) I DON'T KNOW NOTHING OF POLICY ROUTING FOR SURE. All of these notes are based on my guesses about how that works. I HAVEN'T READ THE CODE (i tried, but i got lost very quickly, i promise retry when i wake up) ALL OF WHAT YOU DO BASED ON THIS DOCUMENT IS YOUR AND ONLY YOUR RESPONSABILITY. I wasn't. You haven't seen me. You cannot prove it. I'll be very glad receiving all types of advice, being it technical corrections, additions, wishlists, english corrections (i'm not a native speaker), etc. This micro HOWTO will probably vanish with somebody that knows really about this issue writing the corresponding section of the NET-3 HOWTO. I'll assume you know enough of tcp/ip and the standard routing principles. If you don't please read before the NET-3 HOWTO and the NAG. 2. Required software. You'll need a recent 2.1.x kernel (i've a pair of production machines running 2.1.119 from some weeks ago and my work devel machine runs 2.1.129) compiled with policy routing. (depends on Networking Options/ IP: advanced router) You will need too the iproute2 package. You can get it from ftp.inr.ac.ru:/ip-routing (there are lots of interesting things there), but it can be hairy to compile, so if your distro has it as package use it. (i know for sure that Debian has it) You probably will want to use ipchains. And read its wonderful HOWTO (at least for the ASCII art ;). You can find ipchains in http://www.adelaide.net.au/~rustcorp/. 3. Basics. In the traditional (2.0) routing you had a routing table. Now you have a rules table that point to multiple routing tables. The rules let you select the routes based not only on the destination address, but in the source address, TOS, and incoming device. 4. Rules. Rules are defined by the "ip rule" command. Let's see its syntax: Usage: ip rule [ list | add | del ] SELECTOR ACTION SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ dev STRING ] [ pref NUMBER ] ACTION := [ table TABLE_ID ] [ nat ADDRESS ] [ prohibit | reject | unreachable ] TABLE_ID := [ local | main | default | NUMBER ] (I haven't played yet with NAT, and don't understand what "[ prohibit | reject | unreachable ]" does here (isn't it an ipchains work?), so, by now, the only ACTION will be using is table.) 4.1. Listing rules. The command to list the rules table is "ip rule list", more often abbreviate as "ip ru ls". Look at its output: 0: from all lookup local 32766: from all lookup main 32767: from all lookup default (default output) 0: from all lookup local 2000: from all lookup 2 3000: from all lookup 3 3500: from all tos 04 lookup 32 4000: from 192.168.0.14 lookup 4 4000: from 192.168.0.3 lookup 4 4000: from 192.168.0.121 lookup 4 4000: from 192.168.0.30 lookup 4 32000: from all lookup 32 32766: from all lookup main 32767: from all lookup default (output in my main router) The number at the left of the colon is the preference. When a packet arrives to the system it gets compared with the SELECTOR of each rule in preference order, (don't know what happens with equal preference rules), if it matches then the ACTION is done. 4.2. Adding a rule. The command to add a rule is "ip ru add SELECTOR ACTION". Some examples: 4.2.1. Routing by TOS. ip ru add tos 4 pref 3500 table 32 generates the rule 3500: from all tos 04 lookup 32 That means: For all packets with the IP header TOS field == 4 use the routing table 32. 4.2.2. Routing by source This is probably the most used feature of policy routing. ip ru add from 10.20.30.40 table 5 generates the rule 1: from 10.20.30.40 lookup 5 (preference can differ, it assigns the first unused one) That means: for all packets originated from the IP 10.20.30.40 use routing table 5. 4.3. Deleting a rule. Some syntax than for adds but using "ip ru del" 5. Routing tables. These are handled by "ip route" ("ip ro" for the friends) The syntax is very similar to the good old route's one: Usage: ip route list SELECTOR ip route { change | del | add | append | replace | monitor } ROUTE SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ] [ table TABLE_ID ] [ proto RTPROTO ] [ type TYPE ] [ scope SCOPE ] ROUTE := NODE_SPEC [ INFO_SPEC ] NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ] [ table TABLE_ID ] [ proto RTPROTO ] [ type TYPE ] [ scope SCOPE ] INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]... NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS OPTIONS := FLAGS [ mtu NUMBER ] [ rtt NUMBER ] [ window NUMBER ] TYPE := [ unicast | local | broadcast | multicast | throw | unreachable | prohibit | blackhole | nat ] TABLE_ID := [ local | main | default | all | NUMBER ] SCOPE := [ host | link | global | NUMBER ] NHFLAGS := [ onlink | pervasive ] RTPROTO := [ kernel | boot | static | NUMBER ] Oops, it seems a bit more complex than route's one... :-) But, for now, just use it as route. 5.1 Listing routing tables. ip ro ls [table N] The output will be similar to: 192.168.0.0/24 dev eth1 scope link 10.10.0.0./16 via 192.168.0.5 dev eth1 default via 192.168.0.15 dev eth1 5.2. Adding routes. ip ro add destination/dstmsk [dev DEV] [via GATEWAY] [table TABLE] Examples: ip ro add 192.168.0.0/24 dev eth1 table 3 ip ro add 0.0.0.0/0 via 200.16.189.211 table 32 5.3. Deleting routes. ip ro del destination/dstmsk [dev DEV] [via GATEWAY] [table TABLE] ip ro del 192.168.0.0/24 dev eth1 table 3 ip ro del 0.0.0.0/0 table 32 6. More info. The existent documentation about this issue is almost null. Here is a list of what i could find: - The iproute2 documentation. It's OLD. Don't look at the details. Try to catch the general concepts. (it's what i based this howto on) - The "ip" util "usage" messages are very useful (if you have enough imagination :-) - Use the Source, Luke! But after understanding it come back and explain it to us. 7. Wishlist. My first wish is somebody reading this. My second wish is somebody correcting this. ;-) A bit more seriously, i've some things in mind for next versions: - More clear text. Now this HOWTO is too much spartan. - Examples of real world scenarios. - Reading the corresponding RFCs (previous identificating it :-) and the source, so i can start to understand how this really works. - NAT (it seems easy, i'll play with it in the week) - Expanding it to cover some other interesting new routing features (CBQ!) - Translation to Spanish. (in progress) - Make the language more formal? - SGMLization and integration into LDP. 8. Credits and legalities. 8.1. Thanks. To Linus, _Anarchy_, Alexey, Paul, David, etc. for his great work on my preferred TCP/IP stack. :-) To Arne Kuhlmann, JOshua, Enrique I.R. and Lindsay Allen, that have convinced me to write that. To the UniNet crowd, MJ, Mapi, pukka, pask, ciberio, etc. for their patience. To the PuntoAr people that pay me for working on something i enjoy. 8.2 Legalities. This document is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the: Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.