| |

LFCE 17 ๐Ÿง Policy Routing โ€” Concepts

โฑ๏ธ Estimated read: 15 min | |

Classic routing makes a decision based solely on the destination address. A packet arrives, the kernel searches its routing table for the longest matching prefix, and forwards the packet accordingly. This model assumes that every packet destined for the same network should follow the same path. Policy routing breaks that assumption. It allows the administrator to route packets differently based on their source address, the incoming interface, the protocol, the firewall mark, or other packet attributes. The mechanism is not a second routing table replacing the first; it is a routing policy database (RPDB) that selects which routing table to consult for each packet, based on rules the administrator defines .

For the LFCE candidate, policy routing is the tool that solves problems the main routing table cannot express. A VPN client that must send only its own traffic through the tunnel while other traffic uses the default gateway. A router with two uplinks that must route traffic from different internal subnets through different providers. A host that must respond to connections from a specific source address through the interface that received them. None of these are possible with destination-only routing. All of them are routine applications of ip rule.

Key point: Policy routing replaces the single routing table lookup with a database of rules. Each rule has a selector (what to match) and an action (which table to consult). The kernel evaluates rules in priority order, lowest number first. The first rule whose selector matches the packet determines the table that is searched. If that table yields a route, the decision is final. If the table has no matching route, evaluation continues to the next rule.


Why policy routing exists

The source-address problem.

The main routing table cannot distinguish between two packets with the same destination but different sources. If a host has two interfacesโ€”one connected to a corporate network and one connected to the internetโ€”and both have a route to 8.8.8.8, the kernel selects one based on metric. It cannot say “traffic from the corporate subnet goes out the corporate interface, and traffic from the guest subnet goes out the internet interface.” Policy routing makes this possible with a rule that matches from 10.0.0.0/8 and directs those packets to a table whose default route points to the corporate gateway .

The multiple-uplink problem.

A router with two ISP connections faces a similar limitation. The main table can hold two default routes with different metrics, but only one is active. The second is a standby that the kernel never uses unless the first is removed. Policy routing allows both to be active simultaneously for different traffic classes. A rule matching fwmark 0x1 can send marked packets to a table with ISP A’s default route, while unmarked packets follow the main table to ISP B. The firewall mark is applied by iptables based on criteria the routing layer cannot see, such as destination port or application .

The interface-separation problem.

A host that forwards traffic between multiple networks must often route return traffic back through the interface it arrived on. The main table knows only destinations, not incoming interfaces. A rule matching iif eth1 can direct packets that arrived on eth1 to a table whose routes point back out eth1, regardless of what the main table says. This is essential for routers that sit between networks with overlapping address space or asymmetric paths .

The policy-as-code problem.

Firewall rules describe what traffic is permitted. Policy routing describes where permitted traffic goes. Without policy routing, these two concerns are tangled: a firewall rule that permits traffic cannot influence the routing decision. With policy routing, the firewall can mark packets, and the routing policy can act on those marks. The separation allows each layer to do what it does best: the firewall classifies, and the routing policy directs .


a. The routing policy database and default rules

At boot, the kernel installs three rules in the RPDB. These rules are always present unless the administrator removes them, and they define the fallback behavior that every packet follows when no custom rule matches.

# Display the current routing policy database
ip rule show

# Default output:
# 0:      from all lookup local
# 32766:  from all lookup main
# 32767:  from all lookup default

The first rule, priority 0, matches every packet and directs it to the local table. This table contains routes for local and broadcast addressesโ€”traffic destined for the host itself. It is evaluated first because local delivery must always take precedence over forwarding. This rule cannot be deleted or overridden .

The second rule, priority 32766, directs unmatched packets to the main table. This is the table that ip route show displays by default. It contains all the routes the administrator has configured: connected networks, static routes, and the default gateway. This rule can be modified or deleted, but doing so without providing an alternative would leave the system unable to route most traffic .

The third rule, priority 32767, directs packets to the default table. This table is empty by default. It exists as a final fallback for post-processing, and like the main rule, it can be removed or overridden .

# Inspect the main table specifically
ip route show table main

# Inspect the local table
ip route show table local
# Output includes routes for 127.0.0.0/8, the host's own addresses, and broadcast addresses

The priority numbers matter. Lower numbers are evaluated first. A custom rule with priority 100 is checked before the main table rule at 32766. If the custom rule matches and its table yields a route, the main table is never consulted. If the custom rule matches but its table has no route for the packet, evaluation continues to the next rule in the database .


b. Rule selectors and actions

A policy routing rule consists of a selector and an action. The selector determines which packets the rule applies to. The action determines what happens when a packet matches.

# A rule that matches packets from a specific source and sends them to a custom table
ip rule add from 192.168.1.50 table vpn priority 100

# A rule that matches packets arriving on a specific interface
ip rule add iif eth1 table 200 priority 200

# A rule that matches packets marked by the firewall
ip rule add fwmark 0x1 table 300 priority 150

The available selectors include from (source prefix), to (destination prefix), iif (incoming interface), oif (outgoing interface, for locally generated packets), fwmark (firewall mark), tos (type of service), and uidrange (user ID range) . The most commonly used selectors in LFCE contexts are from, iif, and fwmark. The from selector is the simplest: it matches packets whose source address falls within the specified prefix. The iif selector matches packets that arrived on the named interface. The fwmark selector matches packets that have been marked by iptables or nftables, which allows the routing layer to act on criteria the firewall can see but the routing layer cannot, such as destination port or connection state .

The action is almost always table TABLE_ID, which tells the kernel to look up the route in the named table. The table can be one of the built-in tables (local, main, default) or a custom table identified by a number or a name registered in /etc/iproute2/rt_tables .

# Register a custom table name for readability
echo "100 vpn" >> /etc/iproute2/rt_tables

# Populate the custom table with routes
ip route add default via 10.8.0.1 dev tun0 table vpn
ip route add 192.168.1.0/24 dev eth0 table vpn

A custom table is not automatically populated. It starts empty. The administrator must add routes to it before the rule that points to it can produce a result. A rule pointing to an empty table matches but yields no route, and evaluation continues to the next rule .


c. The lookup algorithm and rule evaluation

The kernel evaluates the RPDB from the lowest priority number to the highest. For each rule, it applies the selector to the packet. If the selector matches, the kernel searches the table named by the action. If the table contains a matching route, that route is selected and the lookup terminates. If the table contains no matching route, the kernel continues to the next rule .

# Example RPDB with a custom rule
# 0:      from all lookup local
# 100:    from 192.168.1.50 lookup vpn
# 32766:  from all lookup main
# 32767:  from all lookup default

# Packet from 192.168.1.50 to 8.8.8.8:
# Rule 0 matches (all packets) โ†’ local table has no route โ†’ continue
# Rule 100 matches (source is 192.168.1.50) โ†’ vpn table has a default route โ†’ selected

# Packet from 192.168.1.60 to 8.8.8.8:
# Rule 0 matches โ†’ no route in local โ†’ continue
# Rule 100 does not match (source is not .50) โ†’ continue
# Rule 32766 matches โ†’ main table has a default route โ†’ selected

The ip route get command verifies the policy routing decision for a specific packet. The from option specifies the source address, which is essential when the rule selector depends on the source.

# Verify which route is selected for a packet from a specific source
ip route get 8.8.8.8 from 192.168.1.50
# Output: 8.8.8.8 from 192.168.1.50 via 10.8.0.1 dev tun0 table vpn

Without the from option, ip route get reports the route for a packet originating from the host’s default source address, which may not match the policy rule. The source address is part of the packet that the rule selector examines, so it must be part of the verification .


Complete Example Session

# ============================================
# PART 1: INSPECT THE DEFAULT RPDB
# ============================================
ip rule show
# Output confirms the three default rules:
# 0:      from all lookup local
# 32766:  from all lookup main
# 32767:  from all lookup default

# ============================================
# PART 2: REGISTER A CUSTOM TABLE NAME
# ============================================
# Table numbers work, but names are readable
echo "100 vpn" >> /etc/iproute2/rt_tables
ip route show table vpn
# Table is empty until routes are added

# ============================================
# PART 3: POPULATE THE CUSTOM TABLE
# ============================================
# The VPN table routes traffic through the tunnel
ip route add default via 10.8.0.1 dev tun0 table vpn
# A route back to the local network keeps return traffic working
ip route add 192.168.1.0/24 dev eth0 table vpn

# ============================================
# PART 4: ADD THE POLICY RULE
# ============================================
# Traffic from 192.168.1.50 uses the vpn table
ip rule add from 192.168.1.50 table vpn priority 100

# ============================================
# PART 5: VERIFY THE RULE EXISTS
# ============================================
ip rule show
# Output includes: 100: from 192.168.1.50 lookup vpn

# ============================================
# PART 6: VERIFY THE ROUTING DECISION
# ============================================
# The source address must be specified
ip route get 8.8.8.8 from 192.168.1.50
# Output: 8.8.8.8 from 192.168.1.50 via 10.8.0.1 dev tun0 table vpn

# ============================================
# PART 7: VERIFY OTHER SOURCES ARE UNAFFECTED
# ============================================
ip route get 8.8.8.8 from 192.168.1.60
# Output: 8.8.8.8 from 192.168.1.60 via 192.168.1.1 dev eth0
# The main table's default route is used for other sources

# ============================================
# PART 8: ADD A SECOND RULE FOR INCOMING INTERFACE
# ============================================
# Packets arriving on eth1 are routed via table 200
ip route add default via 10.0.0.1 dev eth1 table 200
ip rule add iif eth1 table 200 priority 200

# ============================================
# PART 9: TEST THE INTERFACE-BASED RULE
# ============================================
# Forwarded traffic from eth1 follows the iif rule
ip route get 8.8.8.8 iif eth1
# Output: 8.8.8.8 via 10.0.0.1 dev eth1 table 200

# ============================================
# PART 10: CLEAN UP
# ============================================
# Remove the custom rules
ip rule del from 192.168.1.50 table vpn
ip rule del iif eth1 table 200

# Flush the custom table's routes
ip route flush table vpn

The ten parts demonstrate the complete policy routing workflow: inspect the defaults, create a custom table, populate it with routes, add a rule that selects it, and verify the decision with ip route get. The critical verification is Part 6, which shows that the rule is actually being applied to the intended traffic.


Quick Reference

RPDB Commands

TaskCommand
Show all rulesip rule show
Add a ruleip rule add <selector> table <table> priority <n>
Delete a ruleip rule del <selector> table <table>
Add route to custom tableip route add <dest> via <gw> table <name>
Show custom tableip route show table <name>
Verify policy decisionip route get <dest> from <source>
Register table nameecho "100 vpn" >> /etc/iproute2/rt_tables

Rule Selectors

SelectorMatches
from <prefix>Source address
to <prefix>Destination address
iif <interface>Incoming interface
oif <interface>Outgoing interface (local packets only)
fwmark <mark>Firewall mark set by iptables/nftables
tos <value>TOS/DSCP field

Default Rules

PriorityActionTablePurpose
0Lookup locallocalLocal and broadcast addresses
32766Lookup mainmainNormal routing table
32767Lookup defaultdefaultEmpty fallback

Best Practices

โœ… Do This:

# Verify the default RPDB before adding rules
ip rule show                                                  # โœ…

# Use explicit priorities for custom rules
ip rule add from 10.0.0.5 table vpn priority 100              # โœ…

# Populate the custom table before adding the rule
ip route add default via 10.8.0.1 dev tun0 table vpn          # โœ…

# Verify with ip route get and the from option
ip route get 8.8.8.8 from 10.0.0.5                            # โœ…

# Register table names for readability
echo "100 vpn" >> /etc/iproute2/rt_tables                     # โœ…

# Use iif for forwarded traffic, from for locally originated traffic
ip rule add iif eth1 table 200 priority 200                   # โœ…

โŒ Don’t Do This:

# Add a rule pointing to an empty table
# The rule matches but yields no route; evaluation continues     # โŒ

# Assume the main table is consulted when a custom rule matches
# The first matching rule with a route terminates the lookup     # โŒ

# Forget to specify the source in verification
ip route get 8.8.8.8    # Does not test the policy rule         # โŒ

# Use duplicate priorities without understanding the behavior
# The kernel does not reject duplicate priorities; order is ambiguous # โŒ

# Delete the default rules without providing alternatives
# The system may become unable to route                           # โŒ

# Use policy routing for cases the main table can handle
# Complexity without benefit                                      # โŒ

Common Pitfalls

PitfallWhy It HappensFix
Rule matches but no routeCustom table is emptyPopulate table with ip route add ... table <name>
Policy rule not appliedSource address in verification is wrongUse ip route get <dest> from <source>
Main table ignored unexpectedlyCustom rule matches and table has a default routeVerify rule priority and table contents
Rule order ambiguousDuplicate prioritiesAssign unique priorities
Forwarded traffic not matchedUsed from instead of iifUse iif for incoming interface matching
Custom table routes lost after rebootip route add is not persistentAdd to NetworkManager or startup script

Real-World Examples

1. Source-based routing to VPN

ip rule add from 192.168.1.50 table vpn priority 100
ip route add default via 10.8.0.1 dev tun0 table vpn

2. Interface-based routing for forwarded traffic

ip rule add iif eth1 table 200 priority 200
ip route add default via 10.0.0.1 dev eth1 table 200

3. Firewall-marked routing

iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 1
ip rule add fwmark 0x1 table 300 priority 150
ip route add default via 192.168.2.1 dev eth1 table 300

4. Verify a policy rule

ip route get 8.8.8.8 from 192.168.1.50

5. Show a custom table

ip route show table vpn

6. Register a table name

echo "100 vpn" >> /etc/iproute2/rt_tables

7. Delete a policy rule

ip rule del from 192.168.1.50 table vpn

8. Check rule priority order

ip rule show | head -10

9. Route local traffic differently

ip rule add from 10.0.0.0/8 table 100 priority 50

10. Clean up a custom table

ip route flush table vpn

Visual

The Routing Policy Database Lookup

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  RPDB EVALUATION: FIRST MATCH WITH A ROUTE WINS              โ”‚
โ”‚                                                              โ”‚
โ”‚  Packet: src=192.168.1.50 dst=8.8.8.8                        โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Priority 0:   from all lookup local                    โ”‚  โ”‚
โ”‚  โ”‚ Match: YES โ†’ local table has no route for 8.8.8.8      โ”‚  โ”‚
โ”‚  โ”‚ Action: CONTINUE                                       โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                           โ”‚                                  โ”‚
โ”‚                           โ–ผ                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Priority 100: from 192.168.1.50 lookup vpn             โ”‚  โ”‚
โ”‚  โ”‚ Match: YES (source matches)                            โ”‚  โ”‚
โ”‚  โ”‚ vpn table: default via 10.8.0.1                        โ”‚  โ”‚
โ”‚  โ”‚ Action: ROUTE FOUND โ†’ TERMINATE                        โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                           โ”‚                                  โ”‚
โ”‚                           โ–ผ                                  โ”‚
โ”‚  Selected: 10.8.0.1 dev tun0 table vpn                       โ”‚
โ”‚                                                              โ”‚
โ”‚  Rules below priority 100 are never evaluated.               โ”‚
โ”‚  The main table (32766) is not consulted.                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Default RPDB and Custom Rule Insertion

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  DEFAULT RULES AND WHERE CUSTOM RULES FIT                    โ”‚
โ”‚                                                              โ”‚
โ”‚  Priority 0      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚                  โ”‚ from all lookup local       โ”‚             โ”‚
โ”‚                  โ”‚ (cannot be deleted)         โ”‚             โ”‚
โ”‚                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  Priority 100    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚  (CUSTOM)        โ”‚ from 192.168.1.50 lookup vpnโ”‚             โ”‚
โ”‚                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  Priority 200    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚  (CUSTOM)        โ”‚ iif eth1 lookup 200         โ”‚             โ”‚
โ”‚                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  Priority 32766  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚                  โ”‚ from all lookup main        โ”‚             โ”‚
โ”‚                  โ”‚ (normal routing table)      โ”‚             โ”‚
โ”‚                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  Priority 32767  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚                  โ”‚ from all lookup default     โ”‚             โ”‚
โ”‚                  โ”‚ (empty fallback)            โ”‚             โ”‚
โ”‚                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  Custom rules sit between local and main.                    โ”‚
โ”‚  They intercept specific traffic before the main table.      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Custom Table Population

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  A RULE POINTS TO A TABLE; THE TABLE HOLDS THE ROUTES        โ”‚
โ”‚                                                              โ”‚
โ”‚  ip rule add from 192.168.1.50 table vpn priority 100        โ”‚
โ”‚       โ”‚                                                      โ”‚
โ”‚       โ”‚ Points to table "vpn"                                โ”‚
โ”‚       โ–ผ                                                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ TABLE vpn (id 100)                                     โ”‚  โ”‚
โ”‚  โ”‚                                                        โ”‚  โ”‚
โ”‚  โ”‚ default via 10.8.0.1 dev tun0                          โ”‚  โ”‚
โ”‚  โ”‚ 192.168.1.0/24 dev eth0                                โ”‚  โ”‚
โ”‚  โ”‚                                                        โ”‚  โ”‚
โ”‚  โ”‚ The rule selects this table.                           โ”‚  โ”‚
โ”‚  โ”‚ The table's default route handles all unmatched        โ”‚  โ”‚
โ”‚  โ”‚ destinations for matched packets.                      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                              โ”‚
โ”‚  If the table were empty:                                    โ”‚
โ”‚  - Rule matches                                             โ”‚
โ”‚  - Table lookup fails (no route)                            โ”‚
โ”‚  - Evaluation continues to next rule                        โ”‚
โ”‚  - Main table may be used                                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Policy routing mechanismRouting Policy Database (RPDB)
Rule componentsSelector + action (table lookup)
Evaluation orderLowest priority number first
Default rules0 (local), 32766 (main), 32767 (default)
First match with routeTerminates lookup
First match without routeContinues to next rule
Common selectorsfrom, iif, fwmark, to
Custom tableMust be populated before use
Verification commandip route get <dest> from <source>
Table name registration/etc/iproute2/rt_tables

Key takeaways:

  • Policy routing replaces destination-only lookup with a rule database. The kernel evaluates rules in priority order, and the first rule whose selector matches and whose table yields a route determines the path .
  • The default RPDB has three rules. Priority 0 handles local delivery, priority 32766 handles the main table, and priority 32767 handles an empty fallback table. Custom rules are inserted between them .
  • The selector determines what traffic is affected. from matches source addresses, iif matches incoming interfaces, and fwmark matches packets marked by the firewall. The choice of selector determines what kind of policy the rule can express .
  • A rule is only as useful as the table it points to. A custom table starts empty. The administrator must add routes before the rule can produce a result. A rule pointing to an empty table matches but does not terminate the lookup .
  • ip route get with the from option verifies the policy decision. Without the source address, the command tests the default source, which may not match the rule being verified .
  • Policy routing separates classification from direction. The firewall classifies packets (by marking them), and the routing policy directs them. This separation allows each layer to operate independently .

Remember: Policy routing is not a replacement for the main routing table. It is a layer above it that decides which table to consult. The default rules ensure that packets follow the main table unless a custom rule intercepts them. A custom rule is a single sentence: “If this packet matches this selector, look in this table.” The table must contain a route, or the sentence has no effect. Configure the rule, populate the table, verify with ip route get and the correct source, and the packet follows the policy the administrator defined.


Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!