uRPF allows anti-spoofing embedded at forwarding plane level. Junos provides this feature for many years with several modes and options:
- Loose or Strict mode
- Active or Feasible paths uRPF data base
- Discard or not supported in the uRPF data base
I carried out several tests on MX960 version 12.3R2 with DPC or MPC cards to test all the possible combinations of uRPF options.
1/ Explanations of Modes & options
Modes for DPC:
Strict mode:
- Default mode
- Accept a packet if the source of the packet (@IP src of the datagram) is known in the FIB and reachable by the interface that receives the packet.
- For ECMP paths where several interfaces can be used to reach a destination, this case is by default supported by strict mode. (IGP ECMP or BGP multipath)
- Default route with a valid NH is taken into account by default
Loose Mode:
- Configurable mode (interface based config)
- Accept a packet if the source of the packet (@IP src of the datagram) is known in the FIB
- Default route with a valid NH is taken into account by default
Modes for MPC:
Strict mode:
- Default mode
- Accept a packet if the source of the packet (@IP src of the datagram) is known in the FIB and reachable by the interface that receives the packet.
- For ECMP paths where several interfaces can be used to reach a destination, this case is by default supported by strict mode. (IGP ECMP or BGP multipath)
- Default route with a valid NH is taken into account by default
Loose Mode:
- Configurable mode (interface based config)
- Accept a packet if the source of the packet (@IP src of the datagram) is known in the FIB
- Default route with a valid NH is treated as unknown route
Option 1 (for DPC and MPC):
By default uRPF uses only the best path. Indeed, within the FIB only the best paths are available except if you use features like FRR (Fast ReRoute) LFA (Loop Free Alternate). Otherwise, there is no backup path in the FIB, only the RIB keeps those information.
This default behavior is called “active-paths”. To take into account the backup paths at FIB level, known in the RIB, you need to activate the option “feasible-paths”. This feature pushes in the FIB uRPF database, the active path but also the backup path(s) .
Note: this feature requests a little bit more memory at PFE level (adds ifl-list-nh entries)
Option 2 (only for MPC):
Routes with a next-hop set to DISCARD are by default not used on DPC and MPC. But for MPC only you can add to the uRPF database the “discard” routes by using a knog called rpf-loose-mode-discard. This is a global knob that has only a meaning in Loose Mode. (No effect in Strict mode)
Option 3 (for DPC and MPC):
The third option concerns the action applied to packets failing uRPF check. By default those packets are silently discarded but on Junos you can also apply a specific firewall filter to manage those packets (ex. Modify Forwarding Class, rate-limiting, are anything else allowed by a Firewall Filter).
As we can see, there are a lot of combinations. I tried to establish a matrix of tests to cover the entire combinations of Modes, Options, and type of Cards.
2/ uRPF configuration
Modes configuration: This is a per-interface statement.
Strict mode configuration:
edit exclusive
set interfaces aeXX.0 family inet rpf-check
or
set interfaces xe-x/x/x.0 family inet rpf-check
commit
Loose mode configuration:
edit exclusive
set interfaces aeXX.0 family inet rpf-check mode loose
or
set interfaces xe-x/x/x.0 family inet rpf-check mode loose
commit
uRPF failure action: This is a per-interface statement.
edit exclusive
set interfaces aeXX.0 family inet rpf-check fail-filter <MyFilter>
or
set interfaces xe-x/x/x.0 family inet rpf-check fail-filter <MyFilter>
commit
Options configuration: Global configuration.
Take into account only Active Path (default):
edit exclusive
set routing-options forwarding-table unicast-reverse-path active-paths
commit
Take into account Active Path and Backup paths (pushes backup paths to the FIB – actually create new ifl-list-nh):
edit exclusive
set routing-options forwarding-table unicast-reverse-path feasible-paths
commit
For MPC only ; take into account also routes with a Discard NH; (here for inet routes):
edit exclusive
set forwarding-options rpf-loose-mode-discard family inet
commit
3/ uRPF troubleshooting
Verify the uRPF configuration and uRPF counters:
sponge@bob> show interfaces ae40.0 extensive | match rpf
Flags: Sendbcast-pkt-to-re, uRPF, uRPF-loose, Sample-input
RPF Failures: Packets: 9950, Bytes: 11745652
A little bit more info at PFE level:
sponge@bob> show interfaces ae41.0 | match Index
Logical interface ae41.0 (Index 332) (SNMP ifIndex 833)
sponge@bob> start shell pfe network fpc4
NPC4(bob vty)# show route rpf loose-discard-mode proto ip
RPF loose-discard mode for IPv4: Enabled
Platform support: Yes, Walk RTT: No
NPC4(bob vty)# show route rpf iff ifl-index 332 proto ip
RPF mode: Loose
Fail filter index: 0
Bytes: 0
Pkts: 0
To know which RPF interfaces are used to perform Reverse Lookup, let’s take one simple example:
This route has 2 paths, one active path through ae40.0 and a backup path through ae41.0.
sponge@bob> show route 1.0.0.0/30
inet.0: 905188 destinations, 1351252 routes (905178 active, 13 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
1.0.0.0/30 *[BGP/170] 17:29:36, localpref 0, from 192.168.37.1
AS path: I, validation-state: unverified
> to 81.253.193.9 via ae40.0
[BGP/170] 16:35:47, localpref 0, from 192.168.37.2
AS path: I, validation-state: unverified
> to 81.253.193.18 via ae41.0
Strict mode is configured on each interface and only active paths are used by uRPF.
sponge@bob> show route forwarding-table destination 1.0.0.1/32 extensive table default
Routing table: default.inet [Index 0]
Internet:
Destination: 1.0.0.0/30
Route type: user
Route reference: 0 Route interface-index: 0
Flags: sent to PFE
Next-hop type: indirect Index: 1048584 Reference: 200001
Nexthop: 81.253.193.9
Next-hop type: unicast Index: 595 Reference: 16
Next-hop interface: ae40.0
RPF interface: ae40.0
You can see that only ae40.0 is allowed to receive datagrams with @IP Source equal to 1.0.0.1/32. Now we configure the feasible-path feature. The 2 paths (active and backup) should be allowed to receive traffic coming from the 1.0.0.1/32. Let’s check :
sponge@bob> show route forwarding-table destination 1.0.0.1/32 extensive table default
Routing table: default.inet [Index 0]
Internet:
Destination: 1.0.0.0/30
Route type: user
Route reference: 0 Route interface-index: 0
Flags: sent to PFE
Next-hop type: indirect Index: 1048584 Reference: 200001
Nexthop: 81.253.193.9
Next-hop type: unicast Index: 595 Reference: 16
Next-hop interface: ae40.0
RPF interface: ae40.0
RPF interface: ae41.0
Cool, now the backup interface is also allowed to receive traffic coming from 1.0.0.1 (Nice for multi-homing )
4/ uRPF IPv4 test results
The 2 next tabs sumarize the tests carried out on MPC and DPC. Hereafter the explanation of each column:
- Active or Feasible : active-paths or feasible-paths feature
- Mode : loose or strict
- @Src known in FIB : @Src known in FIB via a valid NH, or a Dicard NH or a default route or unknown in FIB
- Packet is coming from : the right interface (to reach the source) or by a backup interface (only for feasible)
- Default route case : Default points either to a Discard NH or to the right interface (to reach the source) or another interface
- In loose mode and for MPC only: the routes with a Discard NH is also included within the RPF database.
- Expected Result: the result expected and described in Juniper technical documentation/KB
- Observed Result: the real result observed during tests.
MPC test results:
DPC test results:
David.