# PIM-SM (Sparse Mode)

The previous article covered PIM-DM, in which multicast traffic is flooded and pruned. Routers that have no interested receivers or other downstream PIM neighbors send Prune messages in order to stop the flow of unnecessary traffic. The Prune state has a 3 minute expiration timer, so every 3 minutes traffic is flooded and pruned again.



In PIM-SM, traffic is only forwarded based on explicit PIM Join messages. An LHR, upon receiving an IGMP Join (Membership Report) from a host, sends a PIM Join upstream towards the RP (rendezvous point). This builds a shared tree from the RP down to the receivers. PIM-DM is a “push” model while PIM-SM is a “pull” model. PIM-DM uses (S, G) entries (for a sourced-based tree), and PIM-SM uses (\*, G) entries (for a shared tree, in which the root is the RP).



PIM-SM requires an RP. When a receiver sends an IGMP Membership Report for a group address, such as 239.1.1.1, the LHR would need to somehow build a tree towards the source. However, the source is unknown. The receiver doesn’t care which source is sending to 239.1.1.1, it simply wants to receive any traffic destined for 239.1.1.1. This is called “any source multicast (ASM).” PIM-SM uses (\*, G) entries, which means “any source” to multicast group G.



The RP is used as the “meeting point” for sources and their receivers. The RP connects the sources to the receivers. The LHR uses the RP address to determine the upstream interface, instead of using a particular source IP. This builds a distribution tree from the RP down to the receivers, where the RP is the root of the tree.



When the source sends traffic, the FHR unicasts it directly to the RP, and the RP forwards it down the existing (\*, G) tree towards the receviers. When the FHR unicasts the multicast traffic directly to the RP, this is called Source Registration.



If the above description doesn’t completely make sense yet, don’t worry too much. We will cover this process in detail in the lab below. You can now see how understanding the fundamental terminology we covered the article titled “Tree Formation and Packet Forwarding” is key to understanding PIM operations.



### Lab <a href="#b7d8b811-f5ea-445a-b307-96466bfd1e1f" id="b7d8b811-f5ea-445a-b307-96466bfd1e1f"></a>

We will re-use the previous topology from PIM-DM, wtih an additional router, R6, as the RP, and a link connecting R4 to R5. There is also a second Source connected to R3.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FU4dlOBDOEVq3iORRMhGe%2FUntitled.png?alt=media&#x26;token=6b270cf8-3532-4a68-8508-b0fcc256b2f2" alt=""><figcaption></figcaption></figure>



Here is the additional config:

```
#R6
hostname R6
!
int Gi1
 ip address 10.1.6.6 255.255.255.0
 ip ospf network point-to-point
 no shut
!
int Gi2
 ip address 10.2.6.6 255.255.255.0 
 ip ospf network point-to-point
 no shut
!
int Gi3
 ip address 10.4.6.6 255.255.255.0
 ip ospf network point-to-point
 no shut
!
int Lo0
 ip address 6.6.6.6 255.255.255.255
!
router ospf 1
 network 0.0.0.0 255.255.255.255 area 0

#R1
int Gi4
 ip address 10.1.6.1 255.255.255.0
 ip ospf network point-to-point
 no shut

#R2
int Gi4
 ip address 10.2.6.2 255.255.255.0
 ip ospf network point-to-point
 no shut

#R3
int Gi3
 ip address 10.10.11.1 255.255.255.0
 no shut
!
router ospf 1
 passive-interface Gi3

#R4
int Gi3
 ip address 10.4.6.4 255.255.255.0
 ip ospf network point-to-point
 no shut
!
int Gi4
 ip address 10.4.5.4 255.255.255.0
 ip ospf network point-to-point
 no shut

#R5
int Gi3
 ip address 10.4.5.5 255.255.255.0
 ip ospf network point-to-point
 no shut

#Source2
hostname Source2
!
no ip domain lookup
!
int Gi1
 ip address 10.10.11.10 255.255.255.0
 no shut
!
ip route 0.0.0.0 0.0.0.0 10.10.11.1
```



### Enabling PIM-SM

To enable PIM-SM, we must have three commands. **ip multicast-routing** must be enabled globally, **ip pim sparse-mode** must be enabled under every interface, and the router must know the IP address of the RP. The RP address can be configured manually or discovered dynamically. In this lab we will simply configure the RP manually on every router, and explore RP discovery mechanisms in another article.



Let’s enable PIM-SM on every router. The command **ip pim sparse-mode** will override **ip pim dense-mode** if it is still configured on the interface in your lab. Additionally I will set the spt-threshold to infinity. By default the threshold is zero, which means the router will immediately switch from the RP tree to the source-specific tree once the source is seen. We will cover this feature in a future article.

```
#Every router
ip multicast-routing distributed  ! If not configured already
ip pim rp-address 6.6.6.6  ! Even R6 needs this config so it "knows" it is an RP
ip pim spt-threshold infinity ! Disables SPT switchover so we can focus on basic PIM-SM

! Every interface
int Gi*
 ip pim sparse-mode
```



As with PIM-DM, enabling PIM-SM on an interface will trigger automatic PIM neighbor discovery. For example, R2 should have four PIM neighbors:

```
R2#show ip pim neighbor 
PIM Neighbor Table
Mode: B - Bidir Capable, DR - Designated Router, N - Default DR Priority,
      P - Proxy Capable, S - State Refresh Capable, G - GenID Capable,
      L - DR Load-balancing Capable
Neighbor          Interface                Uptime/Expires    Ver   DR
Address                                                            Prio/Mode
10.1.2.1          GigabitEthernet1         23:24:02/00:01:33 v2    1 / S P G
10.2.3.3          GigabitEthernet2         23:24:15/00:01:33 v2    1 / DR S P G
10.2.4.4          GigabitEthernet3         23:22:04/00:01:29 v2    1 / DR S P G
10.2.6.6          GigabitEthernet4         00:00:09/00:01:34 v2    1 / DR S P G
```



### Building the Shared Tree

Before we examine the tree formation process, ensure that every host has removed any **igmp join-group** config. All LHRs should have no state for 239.1.1.1 right now.

```
R3#show ip mroute 239.1.1.1
Group 239.1.1.1 not found

R4#show ip mroute 239.1.1.1
Group 239.1.1.1 not found

R5#show ip mroute 239.1.1.1
Group 239.1.1.1 not found
```



On Host1, join the 239.1.1.1 group. This will create state for (\*, 239.1.1.1) on R3 with Gi2 added to the OIL.

```
R3#show ip mroute 239.1.1.1

(*, 239.1.1.1), 00:00:28/00:02:31, RP 6.6.6.6, flags: SC
  Incoming interface: GigabitEthernet1, RPF nbr 10.2.3.2
  Outgoing interface list:
    GigabitEthernet2, Forward/Sparse, 00:00:28/00:02:31
```



Notice that the entry lists the RP as 6.6.6.6, and the RPF neighbor as 10.2.3.2. The RPF neighbor is the PIM neighbor on the shortest path to the RP, which is R2 in this case. R3 sends a PIM join out Gi1, the upstream interface which connects to its RPF neighbor.



The _RPF neighbor_ is used instead of the generic RPF interface facing the RP, because if the RPF interface does not have a PIM neighborship, the PIM Join will not have any effect. The PIM Join needs to be sent to another PIM neighbor which will “understand” the PIM Join, therefore the RPF neighbor is used.



Here is a pcap taken on the link between R3 and R2. R3 sends a PIM Join to the PIM all routers address of 224.0.0.13. The PIM Join specifies the RP address as the source. There is also a flag which specifies that this is an RPT (Rendezvous Point Tree), which refers to the fact that the RP is the root of the shared tree.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FPe7hDnMykrUMSayfdJSS%2FUntitled%201.png?alt=media&#x26;token=b95256ca-7f2d-49b5-a600-2833457fd6db" alt=""><figcaption></figcaption></figure>



The received PIM Join on R2 causes the router to create state for (\*, 239.1.1.1) with Gi2 added to the OIL.

```
R2#show ip mroute 239.1.1.1

(*, 239.1.1.1), 00:03:34/00:02:51, RP 6.6.6.6, flags: S
  Incoming interface: GigabitEthernet4, RPF nbr 10.2.6.6
  Outgoing interface list:
    GigabitEthernet2, Forward/Sparse, 00:03:34/00:02:51
```



You’ve now seen the two situations which cause an interface to be added to an OIL: a received IGMP Join, and a received PIM Join.



Notice that the entry will time out within 3 minutes. This forces R3 to periodically send a PIM Join to refresh the state of its neighbor’s entry. A PIM-SM router sends a PIM Join every 60 seconds.



R2, upon creating the (\*, 239.1.1.1) entry, sends its own PIM Join towards R6. R2’s RPF neighbor is R6 itself. This continues the process of building the shared tree.



R6 is the root of the tree, so it has no incoming interface for the (\*, 239.1.1.1) entry. R6 adds the interface facing R2 to the OIL because it received a PIM Join on that interface.

```
R6#show ip mroute 239.1.1.1

(*, 239.1.1.1), 00:19:30/00:02:55, RP 6.6.6.6, flags: S
  Incoming interface: Null, RPF nbr 0.0.0.0
  Outgoing interface list:
    GigabitEthernet2, Forward/Sparse, 00:05:27/00:02:55
```



### Source Registration <a href="#id-1a2b3c82-9b10-4262-bffc-2fc15aa5b01c" id="id-1a2b3c82-9b10-4262-bffc-2fc15aa5b01c"></a>

Up to this point, we only have the “receiver side” setup. We have a shared tree built from the receiver (Host1) to the RP (R6).



In order to deliver traffic from the source to the R6, the FHR encapsulates packets in a PIM Register message and unicasts it directly to the RP. The source simply starts sending traffic to the multicast address. The source doesn’t actually need to do any signaling, such as use IGMP. IGMP is only used by the receivers.



To see this in action we’ll send a ping from the Source to 239.1.1.1 and repeat it four times.

```
Source#ping 239.1.1.1 repeat 4           
Type escape sequence to abort.
Sending 4, 100-byte ICMP Echos to 239.1.1.1, timeout is 2 seconds:

Reply to request 0 from 10.10.0.10, 9 ms
Reply to request 1 from 10.10.0.10, 6 ms
Reply to request 1 from 10.10.0.10, 46 ms
Reply to request 2 from 10.10.0.10, 6 ms
Reply to request 3 from 10.10.0.10, 5 ms
```



While this happens, we’ll examine a pcap on the link between R1 and R6. Note that while the FHR and RP are directly connected in our lab, this does not need to be the case. The FHR unicasts the Register message to the RP, so routers in the middle would simply preform IP forwarding.



#### First ping

The FHR encapsulates the multicast ping in a PIM Register message and unicasts it to the RP. The RP, in response, sends a PIM Join for (S, G), which is (10.10.10.10, 239.1.1.1). The FHR creates an entry for (10.10.10.10, 239.1.1.1) with Gi4 in the OIL.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FiCNznkxsGSlgtRiDfPdE%2FUntitled%202.png?alt=media&#x26;token=02b1ff7a-9394-4711-bbea-b7c236c44cbb" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FpvYJWdq8A2I3thoDTlsR%2FUntitled%203.png?alt=media&#x26;token=b147b5e4-a3c7-4c41-8157-055190e222e1" alt=""><figcaption></figcaption></figure>



#### Second ping

The FHR encapsulates the ping in a PIM Register message to the RP again (frame 7), and also forwards a duplicate copy down the (S, G) tree (frame 8). The FHR does not know whether the (S, G) tree was successfully built yet, so it preforms both actions. The host will see two copies of the traffic, hence the two replies to ICMP sequence 1 we saw above.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2Fd7lJwWkBis74BnHxQUNP%2FUntitled%204.png?alt=media&#x26;token=b2a8e071-5319-4a60-bf23-3e3901efefc5" alt=""><figcaption></figcaption></figure>



For some reason, which I can’t quite explain, the RP sends another Join for (10.10.10.10, 239.1.1.1). This doesn’t seem necessary.



#### Third ping

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FLdbLPESY9a83DpP2nhSs%2FUntitled%205.png?alt=media&#x26;token=b1b8264d-b02a-41bb-bbb1-f2ca9d5b4c9d" alt=""><figcaption></figcaption></figure>



The FHR still continues to send the traffic in a unicasted PIM Register (frame 11) plus the native (S, G) entry (frame 12). The RP now sees that traffic is flowing using the (S, G) entry, so it drops the encapsulated packet in the Register message, and forwards the packet received on the (S, G) entry. The source only sees one ICMP reply from the host for sequence 1.



The RP, now seeing that the traffic arrived natively on the (S, G) tree, as well as via the PIM Register message, sends a PIM Register Stop to the FHR (frame 13). This tells the FHR to stop encapsulating the traffic in PIM Register messages. The RP has now successfully joined the (S, G) tree rooted at the source.



#### Fourth ping

Now traffic is only flowing natively in frame 14.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FikTo9MyIfB0vgfVli8bm%2FUntitled%206.png?alt=media&#x26;token=0093bd40-6968-49ce-98bf-c08b5db0dd3c" alt=""><figcaption></figcaption></figure>



### What happens if there are no receivers yet?

What happens if a source starts sending to a multicast group for which no receivers have sent an IGMP Join? If the RP has no (\*, G) state already (which would be created via the chain of PIM Joins in response to IGMP Joins), the RP will simply send a PIM Register-Stop to the FHR and will not join the (S, G) tree.



We can test this by pinging another group, such as 239.2.2.2 from the source.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FbxB5upzUplC4XCBFA7i0%2FUntitled%207.png?alt=media&#x26;token=27f76735-c182-4059-9666-fc58f7d6e760" alt=""><figcaption></figcaption></figure>



The RP creates state for the received traffic, but the OIL is null for both the (\*, G) and (S, G) entry.

```
R6#show ip mroute 239.2.2.2
(*, 239.2.2.2), 00:00:31/stopped, RP 6.6.6.6, flags: SP
  Incoming interface: Null, RPF nbr 0.0.0.0
  Outgoing interface list: Null

(10.10.10.10, 239.2.2.2), 00:00:31/00:02:28, flags: P
  Incoming interface: GigabitEthernet1, RPF nbr 10.1.6.1
  Outgoing interface list: Null
```



### Multiple sources sending to the same group <a href="#id-9bf2c6d9-388c-445c-bfe3-11c54673c85a" id="id-9bf2c6d9-388c-445c-bfe3-11c54673c85a"></a>

On Host1, remove the igmp join-group command for 239.1.1.1. Join 239.1.1.1 on Host2. Send 3 pings to 239.1.1.1 from both Source1 and Source2. What has changed in terms of PIM state in the network when an additional source sends to the same group?



No matter how many sources send to 239.1.1.1, R4 always has a single entry for (\*, 239.1.1.1). It is the LHR and is not on any path between the RP and the senders.

```
R4#show ip mroute 239.1.1.1    

(*, 239.1.1.1), 00:02:26/00:02:17, RP 6.6.6.6, flags: SC
  Incoming interface: GigabitEthernet3, RPF nbr 10.4.6.6
  Outgoing interface list:
    GigabitEthernet2, Forward/Sparse, 00:02:26/00:02:17
```



To test your knowledge, what state does R2 have?



R2 has the (\*, G) state with nothing in its OIL, and (S, G) state with interface facing the RP in its OIL. The (\*, G) entry has nothing in its OIL becuase the only receiver in the network is on R4. R4’s RPF neighbor is R6. The (S,G) state is created when the RP joins the (S, G) tree towards the source, in order to “pull in” the traffic.

```
R2#show ip mroute 239.1.1.1

(*, 239.1.1.1), 01:16:10/stopped, RP 6.6.6.6, flags: SP
  Incoming interface: GigabitEthernet4, RPF nbr 10.2.6.6
  Outgoing interface list: Null

(10.10.11.10, 239.1.1.1), 00:00:03/00:02:56, flags: T
  Incoming interface: GigabitEthernet2, RPF nbr 10.2.3.3
  Outgoing interface list:
    GigabitEthernet4, Forward/Sparse, 00:00:03/00:03:28
```



R3 and R1 have the same exact state. Both routers are a FHR, and each has a (S, G) entry created by the PIM Join sent by the RP. Both have the parent (\*, G) entry with nothing in the OIL



What happens if Host1 sends an IGMP Join again?



R3 will add Gi2 to the OIL for (\*, 239.1.1.1). Consequently, this causes the (S, G) entry to add Gi2 to the OIL as well. In this case, traffic from Source2 to Host1 will _not_ go through the RP.

```
#Host1
int Gi0/0
 ip igmp join-group 239.1.1.1

R3#show ip mroute 239.1.1.1


(*, 239.1.1.1), 00:05:30/stopped, RP 6.6.6.6, flags: SCF
  Incoming interface: GigabitEthernet1, RPF nbr 10.2.3.2
  Outgoing interface list:
    GigabitEthernet2, Forward/Sparse, 00:00:12/00:02:47

(10.10.11.10, 239.1.1.1), 00:00:07/00:03:26, flags: FT
  Incoming interface: GigabitEthernet3, RPF nbr 0.0.0.0
  Outgoing interface list:
    GigabitEthernet1, Forward/Sparse, 00:00:07/00:03:22
    GigabitEthernet2, Forward/Sparse, 00:00:07/00:02:52
```



It is important to understand the difference between the (\*, G) entry and (S, G) entry. The (\*, G) entry is either created in response to an IGMP Join, a PIM Join, or when a router sees traffic from a source. Interfaces are added to the OIL for the (\*, G) entry due to IGMP Joins or PIM Joins from downstream neighbors.



The (S, G) entry is created when the RP joins the source-based tree routed at the source. The interface Gi1 was added to this OIL as a result. The interfaces from the parent (\*, G) entry are also automatically added to the (S, G) entries, which is why Gi2 is in the (S, G) OIL as well.



### Non-optimal routing of (\*, G) traffic <a href="#id-0685cf5e-b74f-40f5-ba9c-f8f80c6cade3" id="id-0685cf5e-b74f-40f5-ba9c-f8f80c6cade3"></a>

The design behind PIM-SM requires traffic to flow through the RP. This is because a LHR joins a tree rooted at the RP, and a source-based (S, G) tree is built from the source to the RP in order for the RP to “pull in” the traffic and forward it down the shared tree.



This has the potential to create non-optimal traffic flows. To see this in action, configure Host4 to join the group 239.100.100.100.



As an exercise, try to guess which routers currently have state for (\*, 239.100.100.100).



The answer is: R5 (LHR), R4 (R5’s RPF neighbor), and R6 (RP).



Start a ping from the Source to 239.100.100.100. What path must traffic take?



Traffic takes the following path, although a much more efficient path from the FHR (R1) directly to the LHR (R5) exists.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FPcNlsD2pYEBU2Rw26BPF%2FUntitled%208.png?alt=media&#x26;token=3131d15c-5137-4e2f-9f47-344eec159b06" alt=""><figcaption></figcaption></figure>



To solve this issue, PIM-SM allows for SPT switchover. When the LHR learns the source of the traffic, the LHR can join a source-based (S, G) tree and send a PIM Join towards the source instead of towards the RP. We will explore this in the following article.



### Conclusion <a href="#id-46d9dce2-37ed-488a-8e47-f1a54aa3b5f5" id="id-46d9dce2-37ed-488a-8e47-f1a54aa3b5f5"></a>

PIM-SM uses an explicit Join model, in which the multicast distribution tree is built based on PIM Joins. In PIM-SM, an RP is required, due to the fact that the source is unknown by the LHR. So the LHR sends a PIM Join in the direction of the RP.



The RP pulls in the traffic from the source by joining the source-based (S, G) tree rooted at the source. The FHR unicasts the multicast traffic encapsulated in PIM Register messages until the source-based tree is setup.



You could say that the PIM-SM model is a combination of the shared tree on the receiver side, and the source-based tree on the sender side.



This model creates non-optimal traffic paths, because all traffic must flow through the RP. Additionally, this model requires every router to have the RP address statically configured, which is burdensome. In upcoming articles we will learn about features which improve both of these aspects of PIM-SM.
