FortiGate
FortiGate Next Generation Firewall utilizes purpose-built security processors and threat intelligence security services from FortiGuard labs to deliver top-rated protection and high performance, including encrypted traffic.
Benoit_Rech_FTNT
Purpose
This article explains why multicast packets can not pass through the FortiGate unit, when a static route was configured to use a VRRP, HSRP or GLBP address to reach a PIM sparse-mode neighbor.


Scope


Diagram

FD34555_IMG01-VRRP.jpg


Expectations, Requirements

FortiGate unit is using PIM-SM (PIM sparse-mode) with ROUTER2 and ROUTER3.

1. The receiver sends an IGMP join to group 239.121.1.1, which is processed by the FortiGate unit (FGT):

FGT # get router info multicast igmp groups 239.121.1.1
IGMP Connected Group Membership
Group Address    Interface            Uptime   Expires  Last Reporter
239.121.1.1      port1                00:00:22 00:04:04 172.31.18.167

2. The rendez-vous point (RP) is reachable from the FortiGate unit (FGT):

FGT # get router info multicast pim sparse-mode rp-mapping
PIM Group-to-RP Mappings
Group(s): 224.0.0.0/4, Static
    RP: 10.10.10.10
         Uptime: 01:30:38
FGT # exec ping 10.10.10.10
PING 10.10.10.10 (10.10.10.10): 56 data bytes
64 bytes from 10.10.10.10: icmp_seq=0 ttl=254 time=0.3 ms
64 bytes from 10.10.10.10: icmp_seq=1 ttl=254 time=0.5 ms
64 bytes from 10.10.10.10: icmp_seq=2 ttl=254 time=0.5 ms
64 bytes from 10.10.10.10: icmp_seq=3 ttl=254 time=0.4 ms
64 bytes from 10.10.10.10: icmp_seq=4 ttl=254 time=0.5 ms
--- 10.10.10.10 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.3/0.4/0.5 ms

3. However, the multicast route table displays only one entry for 239.121.1.1:

FGT # get router info multicast pim sparse-mode table 239.121.1.1
IP Multicast Routing Table
(*,*,RP) Entries: 0
(*,G) Entries: 3
(S,G) Entries: 0
(S,G,rpt) Entries: 0
FCR Entries: 0
(*, 239.121.1.1)
RP: 10.10.10.10
RPF nbr: 0.0.0.0
RPF idx: None
Upstream State: JOINED
 Local:
     port1
 Joined:
 Asserted:
FCR:

This entry is created by the IGMP join messages received on the port1 network interface facing the receiver. There is not a (S,G) entry, which means traffic is not being received from the source.

But the nexthop for the RP is:
FGT # get router info multicast pim sparse-mode next-hop
Flags: N = New, R = RP, S = Source, U = Unreachable
Destination     Type  Nexthop   Nexthop         Nexthop  Nexthop Metric Pref  Refcnt
                        Num     Addr            Ifindex  Name
____________________________________________________________________________________
10.10.10.10     .R..  1         10.120.3.254    5                0      10    3


4. RPF check fails, because the next_hop for the RP is 10.120.3.254, which is not a PIM neighbor, but the VRRP address. The PIM neighbors use the address of the interface, not the VRRP address.

FGT # get router info multicast pim sparse-mode neighbour
Neighbor          Interface          Uptime/Expires    Ver   DR
Address                                                      Priority/Mode
10.120.0.192      port4              01:00:29/00:01:16 v2    1 /
10.120.3.15       port4              00:27:01/00:01:18 v2    255 / DR

- this can be verified if the multicast debug is enabled using the following CLI commands:
#diag ip router pim-sm level info
#diag ip router pim-sm all enable
#diag debug enable
...
id=0 msg="PIM-SM: IGMP message for 239.121.1.1 on port1 received filter mode EXCL, num sources 0"
id=0 msg="PIM-SM: Recv (*, 239.121.1.1) Include on port1"
id=0 msg="PIM-SM: Apply (*, 239.121.1.1) Include on port1"
id=0 msg="PIM-SM: Group 239.121.1.1 SPT threshold set"
id=0 msg="PIM-SM: Nexthop 10.10.10.10: Increment refcnt 3"
id=0 msg="PIM-SM: JoinDesired(*,G) => TRUE event for (*, 239.121.1.1)"
id=0 msg="PIM-SM: MRIB.next_hop_rp(10.10.10.10): nexthop 10.120.3.254"
id=0 msg="PIM-SM: US (*,G): No RPF neighbor for (*, 239.121.1.1)" <-------- RPF failure
id=0 msg="PIM-SM: US (*, 239.121.1.1): NOT JOINED to JOINED, JoinDesired(*,G) => TRUE "
...
#diag debug disable
#diag ip router pim-sm all disable
#diag ip router pim-sl level critical



Configuration
The workaround is to have a more specific route to the RP address than the default route.
You can either use a dynamic routing protocol, that announces the RP address, or use a static route with a distance less than the default route. In this case, you need to have multiple routes to the RP, to ensure the redundancy offer through VRRP for the unicast traffic.

FGT # sh router static
config router static
    edit 1
        set device "port4"
        set gateway 10.120.3.254
        set priority 10
    next
    edit 2
        set device "port4"
        set distance 5
        set dst 10.10.10.10 255.255.255.255
        set gateway 10.120.3.15
        set priority 10
    next
    edit 3
        set device "port4"
        set distance 5
        set dst 10.10.10.10 255.255.255.255
        set gateway 10.120.0.192
        set priority 15
    next
end

FGT # get router info routing all
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
       O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
       * - candidate default
S*      0.0.0.0/0 [10/0] via 10.120.3.254, port4, [10/0]
S       10.10.10.10/32 [5/0] via 10.120.3.15, port4, [10/0]
                       [5/0] via 10.120.0.192, port4, [15/0]
C       10.120.0.0/22 is directly connected, port4
C       172.31.16.0/22 is directly connected, port1


Verification
FGT # get router info multicast pim sparse-mode table 239.121.1.1
IP Multicast Routing Table
(*,*,RP) Entries: 0
(*,G) Entries: 3
(S,G) Entries: 1
(S,G,rpt) Entries: 1
FCR Entries: 1
(*, 239.121.1.1)
RP: 10.10.10.10
RPF nbr: 10.120.3.15
RPF idx: port4
Upstream State: JOINED
 Local:
     port1
 Joined:
 Asserted:
FCR:
Source: 10.121.0.21
 Outgoing:
     port1
 KAT timer running, 179 seconds remaining
 Packet count 1
(10.121.0.21, 239.121.1.1)
RPF nbr: 0.0.0.0
RPF idx: None
SPT bit: 0
Upstream State: JOINED
 Local:
 Joined:
 Asserted:
 Outgoing:
     port1
(10.121.0.21, 239.121.1.1, rpt)
RP: 10.10.10.10
RPF nbr: 10.120.3.15
RPF idx: port4
Upstream State: NOT PRUNED
 Local:
 Pruned:
 Outgoing:


id=0 msg="PIM-SM: IGMP message for 239.121.1.1 on port1 received filter mode EXCL, num sources 0"
id=0 msg="PIM-SM: Recv (*, 239.121.1.1) Include on port1"
id=0 msg="PIM-SM: Apply (*, 239.121.1.1) Include on port1"
id=0 msg="PIM-SM: Group 239.121.1.1 SPT threshold set"
id=0 msg="PIM-SM: Nexthop 10.10.10.10: Increment refcnt 3"
id=0 msg="PIM-SM: JoinDesired(*,G) => TRUE event for (*, 239.121.1.1)"
id=0 msg="PIM-SM: MRIB.next_hop_rp(10.10.10.10): nexthop 10.120.3.15"
id=0 msg="PIM-SM: Send Join/Prune message"
id=0 msg="PIM-SM:  Upstream: 10.120.3.15 (Family 1, Type 0)"
id=0 msg="PIM-SM:  Rserved: 0"
id=0 msg="PIM-SM:  Num groups: 1"
id=0 msg="PIM-SM:  Holdtime: 210"
id=0 msg="PIM-SM:  Multicast group: 239.121.1.1/32 (Family 1, Type 0)"
id=0 msg="PIM-SM:   Number of Join: 1"
id=0 msg="PIM-SM:   Number of Prune: 0"
id=0 msg="PIM-SM: Join: (*,G) 10.10.10.10/32 (Family 1, Type 0)"
id=0 msg="PIM-SM: US (*, 239.121.1.1): Starting JT timer with 60 secs timeout"
id=0 msg="PIM-SM: US (*, 239.121.1.1): NOT JOINED to JOINED, JoinDesired(*,G) => TRUE "


Troubleshooting


Internal Notes


Contributors