RFC 6559

A Reliable Transport Mechanism for PIM

๐Ÿ“… published March 2012, from ietf

A Reliable Transport Mechanism for PIM ๐Ÿฆ‹

Part 1 of 7 โœจ

Okay bestie, let's get the basics down first. This is RFC 6559 ๐Ÿ’–, and it was written by D. Farinacci, IJ. Wijnands, S. Venaas (all from Cisco Systems) and M. Napierala (from AT&T Labs). It's an Experimental doc, with ISSN 2070-1721, and it was published in March 2012 ๐ŸŒธ. The header doesn't list any RFCs it obsoletes or updates, so it's not replacing or patching anything else. Iconic, honestly ๐Ÿ‘‘.

Abstract โœจ

Okay so this doc defines a reliable transport mechanism for PIM, used to send Join/Prune messages ๐Ÿ’…. The big win is that it gets rid of the need to send and process Join/Prune messages on a periodic basis ๐Ÿซถ. The mechanism can use either TCP or SCTP as its transport protocol ๐Ÿฆ‹.

Status of This Memo ๐ŸŒธ

Not gonna lie, this part is a lot of formal vibes, but here's the tea. This document is not an Internet Standards Track specification ๐Ÿ’€. It's published so people can examine it, try it out in experimental implementations, and evaluate it ๐Ÿงช.

That said, it does define an Experimental Protocol for the Internet community ๐ŸŒˆ. It's a product of the IETF (Internet Engineering Task Force) and it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). But being approved by the IESG doesn't mean it's a candidate for any level of Internet Standard. See Section 2 of RFC 5741 for more on that ๐Ÿ’….

For info on the current status of this doc, any errata, and how to give feedback, check out http://www.rfc-editor.org/info/rfc6559 โœจ.

Copyright (c) 2012 IETF Trust and the persons identified as the document authors. All rights reserved ๐Ÿ”ฅ.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info), as in effect on the date of publication. Please read these carefully, because they describe your rights and restrictions for this document ๐Ÿ™ˆ. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License ๐ŸŽ€.

Table of Contents ๐Ÿงš

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
  1.1.  Requirements Notation  . . . . . . . . . . . . . . . . . .  4
  1.2.  Definitions  . . . . . . . . . . . . . . . . . . . . . . .  4
2.  Protocol Overview  . . . . . . . . . . . . . . . . . . . . . .  5
3.  PIM Hello Options  . . . . . . . . . . . . . . . . . . . . . .  6
  3.1.  PIM over the TCP Transport Protocol  . . . . . . . . . . .  6
  3.2.  PIM over the SCTP Transport Protocol . . . . . . . . . . .  7
  3.3.  Interface ID . . . . . . . . . . . . . . . . . . . . . . .  8
4.  Establishing Transport Connections . . . . . . . . . . . . . .  9
  4.1.  Connection Security  . . . . . . . . . . . . . . . . . . . 11
  4.2.  Connection Maintenance . . . . . . . . . . . . . . . . . . 11
  4.3.  Actions When a Connection Goes Down  . . . . . . . . . . . 13
  4.4.  Moving from PORT to Datagram Mode  . . . . . . . . . . . . 14
  4.5.  On-Demand versus Pre-Configured Connections  . . . . . . . 14
  4.6.  Possible Hello Suppression Considerations  . . . . . . . . 15
  4.7.  Avoiding a Pair of TCP Connections between Neighbors . . . 15
5.  PORT Message Definitions . . . . . . . . . . . . . . . . . . . 16
  5.1.  PORT Join/Prune Message  . . . . . . . . . . . . . . . . . 18
  5.2.  PORT Keep-Alive Message  . . . . . . . . . . . . . . . . . 19
  5.3.  PORT Options . . . . . . . . . . . . . . . . . . . . . . . 20
    5.3.1.  PIM IPv4 Join/Prune Option . . . . . . . . . . . . . . 21
    5.3.2.  PIM IPv6 Join/Prune Option . . . . . . . . . . . . . . 21
6.  Explicit Tracking  . . . . . . . . . . . . . . . . . . . . . . 22
7.  Support of Multiple Address Families . . . . . . . . . . . . . 23
8.  Miscellany . . . . . . . . . . . . . . . . . . . . . . . . . . 23
9.  Transport Considerations . . . . . . . . . . . . . . . . . . . 23
10. Manageability Considerations . . . . . . . . . . . . . . . . . 24
11. Security Considerations  . . . . . . . . . . . . . . . . . . . 25
12. IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 25
  12.1. PORT Port Number . . . . . . . . . . . . . . . . . . . . . 25
  12.2. PORT Hello Options . . . . . . . . . . . . . . . . . . . . 25
  12.3. PORT Message Type Registry . . . . . . . . . . . . . . . . 26
  12.4. PORT Option Type Registry  . . . . . . . . . . . . . . . . 26
13. Contributors . . . . . . . . . . . . . . . . . . . . . . . . . 26
14. Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 27
15. References . . . . . . . . . . . . . . . . . . . . . . . . . . 27
  15.1. Normative References . . . . . . . . . . . . . . . . . . . 27
  15.2. Informative References . . . . . . . . . . . . . . . . . . 28

1. Introduction ๐Ÿฆ‹

Okay so the goals of this spec are super simple ๐Ÿ’…:

  • Create a simple incremental mechanism that gives reliable PIM Join/Prune message delivery in PIM version 2, for use with PIM Sparse-Mode (PIM-SM) [RFC4601], including PIM Source-Specific Multicast (PIM-SSM), and Bidirectional PIM [RFC5015] ๐ŸŒท.
  • When a router supports this spec, it doesn't have to use the reliable transport mechanism with every neighbor. It can be negotiated on a per-neighbor basis โœจ.

The explicit non-goals (aka the stuff this doc is NOT trying to do) are:

  • Making changes to the PIM message formats defined in [RFC4601] ๐Ÿ™…โ€โ™€๏ธ.
  • Providing support for automatic switching between the reliable transport mechanism and the regular PIM mechanism defined in [RFC4601]. Two routers that are PIM neighbors on a link will always use the reliable transport mechanism if and only if both have enabled support for it ๐Ÿซถ.

This doc will explain how periodic Join/Prune message transmission can be eliminated by using TCP [RFC0793] or SCTP [RFC4960] as the reliable transport mechanism for Join/Prune messages ๐Ÿ”ฅ. The destination port number is 8471 for both TCP and SCTP ๐Ÿ“.

This spec gets greater scalability in terms of control-traffic overhead, which is so iconic ๐Ÿ‘‘. However, for routers connected to multi-access links, that scalability comes at the price of increased PIM state and the overhead needed to maintain that state ๐Ÿฅฒ.

Now, in lots of networks (especially wireless and mobile satellite systems), link degradation from weather, interference, and other impairments can cause temporary spikes in the packet loss rate โ›ˆ๏ธ. In those environments, periodic PIM joining can cause join latency when messages get lost, because the retransmission only happens 60 seconds later ๐Ÿ˜ญ. With a reliable transport, a lost Join gets retransmitted rapidly ๐Ÿš€. And when the last user leaves a multicast group, any lost Prune is repaired in the same way, so the multicast stream is quickly removed from the wireless/satellite link ๐Ÿงš. Without a reliable transport, the multicast transmission could keep going until it timed out, roughly 3 minutes later ๐Ÿ’€. Network resources are a premium in these environments, so rapid termination of the multicast stream is critical for using bandwidth efficiently ๐Ÿ’œ.

This is an experimental extension to PIM, so it's giving "new and still being tested" energy ๐Ÿงช. It makes some fundamental changes to how PIM works, because Join/Prune state no longer needs periodic updates, and it partly turns PIM into a hard-state protocol ๐Ÿซฃ. Using reliable delivery for PIM messages is also a new concept, so it's likely that experiences from early implementations and deployments will lead to at least minor changes in the protocol. Once there's some deployment experience, making this a Standards Track protocol should be considered ๐ŸŒˆ. Experiments using this protocol only require support by pairs of PIM neighbors, and they don't need to be constrained to isolated networks โœจ.

1.1. Requirements Notation ๐Ÿ’…

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] ๐Ÿ“–.

1.2. Definitions ๐ŸŽ€

Here's the glossary, bestie ๐Ÿง :

  • PORT: Stands for PIM Over Reliable Transport, which is the short form for describing the mechanism in this specification, where PIM can use the TCP or SCTP transport protocol ๐Ÿ’–.
  • Periodic Join/Prune message: A Join/Prune message sent periodically to refresh state ๐Ÿ”.
  • Incremental Join/Prune message: A Join/Prune message sent as a result of state creation or deletion events. Also known as a triggered message โšก.
  • Native Join/Prune message: A Join/Prune message that is carried with an IP protocol type of PIM ๐Ÿฆ‹.
  • PORT Join/Prune message: A Join/Prune message using TCP or SCTP for transport ๐ŸŒธ.
  • Datagram Mode: The procedures whereby PIM encapsulates triggered or periodic Join/Prune messages in IP packets ๐Ÿ“ฆ.
  • PORT Mode: The procedures used by PIM, and defined in this specification, for sending Join/Prune messages over the TCP or SCTP transport layer ๐Ÿงš.

2. Protocol Overview โœจ

okay so PORT (PIM Over Reliable Transport) is a simple extension to PIMv2 that cuts down on refresh traffic for PIM Join/Prune messages ๐Ÿ’…. Instead of sending Join/Prune messages over and over on a timer, it sends incremental ones over a TCP or SCTP connection between PIM neighbors ๐Ÿฆ‹.

PORT only applies to PIM Sparse-Mode [RFC4601] and Bidirectional PIM [RFC5015] Join/Prune messages. Nothing else gets the PORT treatment ๐ŸŒธ.

This document doesn't tie PORT to any specific link type ๐ŸŒˆ. Still, using PORT on something like a multi-access LAN with lots of PIM neighbors needs a careful look, e.g. ... ngl this one is important ๐Ÿ‘€. You could end up with a full mesh of PORT connections, and you have to keep explicit track of every PIM neighbor, so it can get messy fast ๐Ÿ’€.

PORT can be rolled out incrementally on a link between PORT-capable neighbors โœจ. Routers that aren't PORT-capable can keep using PIM in Datagram mode, no drama ๐Ÿซถ. PORT capability gets detected through the new PORT-Capable PIM Hello Options ๐Ÿ”.

Once PORT is enabled on an interface and a PIM neighbor also says it's PORT enabled, only PORT Join/Prune messages get used. Like, only PORT Join/Prune messages are accepted from that neighbor, and only those are sent to it ๐ŸŽฏ. Native Join/Prune messages still stick around for neighbors that aren't PORT enabled ๐Ÿ™ˆ.

PORT Join/Prune messages get sent over a TCP/SCTP connection ๐Ÿงš. When two PIM neighbors are PORT enabled, both for TCP or both for SCTP, they'll establish a connection right away or on demand โšก. If the connection drops, they'll try to reconnect right away or on demand too ๐Ÿ”. While there's no connection, no Join/Prune messages go out at all, Native or PORT ๐Ÿšซ. Also, any native Join/Prune messages received from that neighbor get thrown out, even when the connection is down ๐Ÿ—‘๏ธ.

When PORT is in use, only incremental Join/Prune messages go from downstream routers to upstream routers ๐Ÿ’œ. So downstream routers don't generate periodic Join/Prune messages for state whose RPF neighbor is PORT-capable ๐ŸŒท. (RPF = Reverse Path Forwarding, btw ๐Ÿ™ƒ.)

For Joins and Prunes received over a TCP/SCTP connection, the upstream router doesn't start or maintain timers on the outgoing interface entry ๐ŸŽ€. Instead, it keeps track of which downstream routers have shown interest ๐Ÿ‘‘. An interface only gets removed from the outgoing interface list when every downstream router on that interface no longer wants traffic ๐Ÿ“. If there are also native Joins/Prunes from a non-PORT neighbor, a router can keep timers on the outgoing interface entry like usual, while also tracking each downstream PORT Join/Prune at the same time ๐Ÿง โœจ.

This document does not update the PIM Join/Prune packet format ๐Ÿ™Œ. In the procedures described here, each PIM Join/Prune message rides inside the payload of a PORT message carried over TCP/SCTP ๐Ÿ“ฆ. Check out Section 5 for the details on the PORT message ๐Ÿ’–.


3. PIM Hello Options ๐ŸŽ€

3.1. PIM over the TCP Transport Protocol ๐ŸŒŠ

Option Type: PIM-over-TCP-Capable

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           Type = 27           |         Length = 4 + X        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |     TCP Connection ID AFI     |        Reserved       |  Exp  |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                       TCP Connection ID                       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Assigned Hello Type values can be found in [HELLO-OPT] ๐Ÿ”Ž.

When a router is set up to use PIM over TCP on a given interface, it MUST include the PIM-over-TCP-Capable Hello Option in its Hello messages for that interface ๐Ÿ“ฃ. If a router is explicitly disabled from using PIM over TCP, it MUST NOT include the PIM-over-TCP-Capable Hello Option in its Hello messages ๐Ÿšซ.

All Hello messages carrying the PIM-over-TCP-Capable Hello Option MUST also contain the Interface ID Hello Option, see Section 3.3 ๐Ÿ†”.

Implementations MAY provide a configuration option to enable or disable PORT functionality ๐ŸŽ›๏ธ. It is RECOMMENDED that this capability be disabled by default ๐ŸŒ™.

Length: the length in bytes for the value part of the Type/Length/Value encoding, where X is the number of bytes in the Connection ID field ๐Ÿ“. X is 4 when AFI value 1 (IPv4) [AFI] is used, 16 when AFI value 2 (IPv6) [AFI] is used, and 0 when AFI value 0 is used ๐Ÿงฎ.

TCP Connection ID AFI: the AFI value describing the address family of the TCP Connection ID field ๐Ÿท๏ธ. Heads up, this value doesn't have to match the address family of the PIM Hello message that carries it ๐Ÿ™ƒ. When this field is 0, a mechanism outside the scope of this document is used to get the addresses for setting up the TCP connection ๐Ÿคทโ€โ™€๏ธ.

Reserved: set to zero on transmission and ignored on receipt ๐Ÿซง.

Exp: for experimental use [RFC3692] ๐Ÿงช. One expected use of these bits is signaling experimental capabilities ๐Ÿ”ฌ. For example, if a router supports an experimental feature, it may set a bit to indicate this ๐Ÿ’ซ. The default behavior, unless a router supports a particular experiment, is to ignore the bits on receipt ๐Ÿ˜Œ.

TCP Connection ID: an IPv4 or IPv6 address used to establish the TCP connection ๐Ÿ“. This field is omitted (length 0) for Connection ID AFI 0 ๐Ÿซฅ.

3.2. PIM over the SCTP Transport Protocol ๐Ÿš

Option Type: PIM-over-SCTP-Capable

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           Type = 28           |         Length = 4 + X        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |    SCTP Connection ID AFI     |        Reserved       |  Exp  |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                       SCTP Connection ID                      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Assigned Hello Type values can be found in [HELLO-OPT] ๐Ÿ”Ž.

When a router is set up to use PIM over SCTP on a given interface, it MUST include the PIM-over-SCTP-Capable Hello Option in its Hello messages for that interface ๐Ÿ“ฃ. If a router is explicitly disabled from using PIM over SCTP, it MUST NOT include the PIM-over-SCTP-Capable Hello Option in its Hello messages ๐Ÿšซ.

All Hello messages carrying the PIM-over-SCTP-Capable Hello Option MUST also contain the Interface ID Hello Option; see Section 3.3 ๐Ÿ†”.

Implementations MAY provide a configuration option to enable or disable PORT functionality ๐ŸŽ›๏ธ. It is RECOMMENDED that this capability be disabled by default ๐ŸŒ™.

Length: the length in bytes for the value part of the Type/Length/Value encoding, where X is the number of bytes in the Connection ID field ๐Ÿ“. X is 4 when AFI value 1 (IPv4) [AFI] is used, 16 when AFI value 2 (IPv6) [AFI] is used, and 0 when AFI value 0 is used ๐Ÿงฎ.

SCTP Connection ID AFI: the AFI value describing the address family of the SCTP Connection ID field ๐Ÿท๏ธ. Note that this value doesn't have to match the address family of the PIM Hello message that carries it ๐Ÿ™ƒ. When this field is 0, a mechanism outside the scope of this document is used to get the addresses for setting up the SCTP connection ๐Ÿคทโ€โ™€๏ธ.

Reserved: set to zero on transmission and ignored on receipt ๐Ÿซง.

Exp: for experimental use [RFC3692] ๐Ÿงช. One expected use of these bits is signaling experimental capabilities ๐Ÿ”ฌ. For example, if a router supports an experimental feature, it may set a bit to indicate this ๐Ÿ’ซ. The default behavior, unless a router supports a particular experiment, is to ignore the bits on receipt ๐Ÿ˜Œ.

SCTP Connection ID: an IPv4 or IPv6 address used to establish the SCTP connection ๐Ÿ“. This field is omitted (length 0) for Connection ID AFI 0 ๐Ÿซฅ.

3.3. Interface ID ๐Ÿชช

All Hello messages carrying PIM-over-TCP-Capable or PIM-over-SCTP-Capable Hello Options MUST also contain the Interface ID Hello Option [RFC6395] ๐Ÿ’Œ.

The Interface ID is how a PORT Join/Prune message gets linked to the PIM neighbor it came from ๐Ÿ”—. When unnumbered interfaces are used, or when a single transport connection handles sending and receiving Join/Prune messages over multiple interfaces, the Interface ID carries the interface from the Join/Prune message sender to the Join/Prune message receiver ๐Ÿšš. The value of the Interface ID Hello Option in Hellos sent on an interface MUST be the same as the Interface ID value in all PORT Join/Prune messages sent to a PIM neighbor on that interface ๐ŸŽฏ.

The Interface ID only needs to uniquely identify an interface of a router ๐ŸŒŸ. It doesn't have to identify which router the interface belongs to ๐Ÿ™Œ. This means the Router ID part of the Interface ID MAY be 0 ๐Ÿซถ. For details on the Router ID and the value 0, see [RFC6395] ๐Ÿ“š.

4. Establishing Transport Connections โœจ

Okay bestie, so while a router interface is PORT enabled, a PIM-over-TCP-Capable or a PIM-over-SCTP-Capable Option MUST be included in the PIM Hello messages sent on that interface ๐Ÿ’–. When a router on a PORT-enabled interface gets a Hello with a PIM-over-TCP-Capable/PIM-over-SCTP-Capable Option from a new neighbor, or from an existing neighbor that didn't include the option before, it switches to PORT mode for that particular neighbor ๐Ÿฆ‹.

When a router switches to PORT mode for a neighbor, it stops sending and accepting Native Join/Prune messages for that neighbor ๐Ÿ™ˆ. Any state from previous Native Join/Prune messages just gets left to expire as normal. It will also try to establish a transport connection (TCP or SCTP) with the neighbor ๐Ÿงš. If both the router and its neighbor have announced both PIM-over-TCP-Capable and PIM-over-SCTP-Capable Options, SCTP MUST be used. This resolves the issue where two transports are both offered ๐ŸŽ€. The method prefers SCTP over TCP, because SCTP has benefits such as handling of call collisions and support for multiple streams, as discussed later in this document โœจ.

When the router is using TCP, it compares the TCP Connection ID it announced in the PIM-over-TCP-Capable Option with the TCP Connection ID in the Hello received from the neighbor. Unless connections are opened on demand (see below), the router with the lower Connection ID MUST do an active transport open to the neighbor Connection ID. The router with the higher Connection ID MUST do a passive transport open. An implementation MAY open connections only on demand; in that case, it may be that the neighbor with the higher Connection ID does the active open (see Section 4.5). If the router with the lower Connection ID chooses to only do an active open on demand, it MUST do a passive open, allowing for the neighbor to initiate the connection ๐ŸŒธ. Note that the source address of the active open MUST be the announced Connection ID ๐Ÿ‘‘.

When the router is using SCTP, the IP address comparison doesn't need to be done, since the SCTP protocol can handle call collision ๐Ÿ’….

The decisions about whether to use PORT, which transport to use, and which Connection IDs to use are made independently for IPv4 and IPv6. So if PORT is used for both IPv4 and IPv6, both IPv4 and IPv6 PIM Hello messages MUST be sent, and both must contain PORT Hello Options ๐ŸŒˆ. If two neighbors announce the same transport (TCP or SCTP) and the same Connection IDs in the IPv4 and IPv6 Hello messages, then only one connection is established and shared ๐Ÿซถ. Otherwise, two connections are established and used separately.

The PIM router that performs the active open starts the connection with a locally generated source transport port number and a well-known destination transport port number. The PIM router that performs the passive open listens on the well-known local transport port number and does not qualify the remote transport port number ๐Ÿฆ‹. See Section 5 for the well-known port number assignment for PORT.

When a transport connection is established (or reestablished), the two routers MUST both send a full set of Join/Prune messages for state for which the other router is the upstream neighbor. This is needed so the upstream neighbor has the correct state ๐Ÿ˜ญ. When moving from Datagram mode, or when the connection has gone down, the router can't be sure that all the previous Join/Prune state was received by the neighbor. Any state that was created before the connection was established (or reestablished) and that is not refreshed MUST be left to expire and be deleted. Once the non-refreshed state has expired and been deleted, the two neighbors will be in sync โœจ.

When not running PORT, a full update is only needed when a router restarts. With PORT, it has to be done every time a connection is established. This can be costly, although a PORT connection is expected to go up and down rarely ๐Ÿ’€. There may be a need for extensions to handle this better.

It's possible that a router starts sending Hello messages with a new Connection ID, for example due to configuration changes. A router MUST always use the last announced and last seen Connection IDs ๐Ÿ“. A connection is identified by the local Connection ID (the one we're announcing on a particular interface) and the remote Connection ID (the one we're receiving from a neighbor on the same interface). When either the local or remote ID changes, the Connection ID pair we need a connection for changes too. There may be an existing connection with the same pair, in which case the router shares that connection. Otherwise, a new connection may need to be established. Also, for link-local addresses, the interface should be regarded as part of the ID, so connection sharing isn't attempted when the same link-local addresses are seen on different interfaces ๐Ÿงš.

When a Connection ID changes, if the previously used connection isn't needed anymore (meaning there are no other PIM neighborships using the same Connection ID pair), both peers MUST attempt to reset the transport connection. Next, they MUST, unless a connection already exists with the new Connection ID pair, immediately or on demand attempt to establish a new connection with the new Connection ID pair. This happens even if the old connection is still needed ๐Ÿ”ฅ.

Normally the Interface ID wouldn't change while a connection is up. If it does, though, the change doesn't affect the connection. It just means that when subsequent PORT Join/Prune messages are received, they should be matched against the last seen Interface ID ๐ŸŒธ.

A Join sent over a transport connection will only be seen by the upstream router, so it won't cause non-PORT routers on the link with the upstream router to delay refreshing Join state for the same state ๐Ÿ’œ. Similarly, a Prune sent over a transport connection will only be seen by the upstream router, so it will never cause non-PORT routers on the link with the upstream router to send a Join to override this Prune.

Also, a datagram PIM Join/Prune message for a said (S,G) or (*,G) sent by some router on a link will not cause routers on the same link that use a transport connection with the upstream router for that state to suppress refreshing that state to the upstream router (because they don't need to periodically refresh this state), or to send a Join to override a Prune. The latter won't happen, because the upstream router only stops forwarding the traffic when all joined routers that use a transport connection have explicitly sent a Prune for this state, as explained in Section 6 ๐Ÿ™ˆ.

4.1. Connection Security ๐Ÿ”’

TCP/SCTP packets used for PORT MUST be sent with a TTL/Hop Limit of 255, to make it possible to enable the Generalized TTL Security Mechanism (GTSM) [RFC5082] ๐Ÿ›ก๏ธ. Implementations SHOULD provide a configuration option to enable the GTSM check at the receiver. This means checking that inbound packets from directly connected neighbors have a TTL/Hop Limit of 255. Implementations MAY also allow for a different TTL/Hop Limit threshold to check that the sender is within a certain number of router hops. The GTSM check SHOULD be disabled by default.

Implementations SHOULD support the TCP Authentication Option (TCP-AO) [RFC5925] and SCTP Authenticated Chunks [RFC4895] ๐Ÿ”.

4.2. Connection Maintenance ๐Ÿ’ž

TCP is designed to keep connections up indefinitely during a period of network disconnection. If a PIM-over-TCP router fails, the TCP connection may stay up until the neighbor actually reboots, and even then it may keep staying up until PORT tries to send the neighbor some information. This is especially relevant to PIM, since the flow of Join/Prune messages might only go in one direction, and the downstream neighbor might never get any indication via TCP that the other end of the connection isn't really there ๐Ÿ˜ฑ.

SCTP has a heartbeat mechanism that can be used to detect that a connection isn't working, even when no data is sent. Many TCP implementations also support sending keep-alives for this purpose. Implementations MAY make use of TCP keep-alives, but the PORT keep-alive mechanism defined below gives more control and flexibility โœจ.

You can detect that a PORT connection isn't working by regularly sending PORT messages. This applies to both TCP and SCTP. For example, with TCP, the connection will be reset if no TCP ACKs are received after several retries. PORT by itself doesn't require any periodic signaling. PORT Join/Prune messages are only sent when there's a state change. If the state changes aren't frequent enough, a PORT Keep-Alive message (defined in Section 5.2) can be sent instead. For example, if an implementation wants to send a PORT message to check that the connection is working at least every 60 seconds, then whenever 60 seconds have passed since the previous message, a Keep-Alive message could be sent. If there were less than 60 seconds between each Join/Prune, no Keep-Alive messages would be needed ๐ŸŒท. Implementations SHOULD support the use of PORT Keep-Alive messages. It is RECOMMENDED that a configuration option be available to network administrators to enable it when needed. Note that Keep-Alives can be used by a peer, independently of whether the other peer supports it.

An implementation that supports Keep-Alive messages acts as follows when processing a received PORT message. When processing a Keep-Alive message with a non-zero Holdtime value, it MUST set a timer to the value. We call this timer the Connection Expiry Timer (CET). If the CET is already running, it MUST be reset to the new value. When processing a Keep-Alive message with a zero Holdtime value, the CET (if running) MUST be stopped. When processing a PORT message other than a Keep-Alive, the CET MUST be reset to the last received Holdtime value if running. If the CET isn't running, no action is taken. If the CET expires, the connection SHOULD be shut down ๐Ÿงฏ.

This specification does not mandate a specific default Holdtime value. However, the dynamic congestion and flow control in TCP and SCTP can result in variable transit delay between the endpoints. When capacity varies, there may be loss in the network or variable link performance. Consistent behavior therefore requires a sufficiently large Holdtime value, e.g., 60 seconds, to prevent premature termination โณ.

It's possible that a router receives Join/Prune messages for an interface/link that is down. As long as the neighbor hasn't expired, it is RECOMMENDED to process those messages as usual. If they are ignored, the router SHOULD ensure it gets a full update for that interface when it comes back up. This can be done by changing the GenID (Generation Identifier; see [RFC4601]) or by terminating and reestablishing the connection ๐Ÿ”„.

If a PORT neighbor changes its GenID and a connection is established or is in the process of being established, the local side should generally tear down the connection and do as described in Section 4.3. However, if the connection is shared by multiple interfaces and the GenID changes for only one of them, the local side SHOULD simply send a full update, similar to other cases when a GenID changes for an upstream neighbor ๐ŸŽ€.

4.3. Actions When a Connection Goes Down โœจ

okay so a connection can go down for all kinds of reasons ๐Ÿ’”, like an error popped up or someone changed the config ๐Ÿ™ˆ. A connection SHOULD be shut down as soon as there are no more PIM neighbors using it. Specifically, for that connection (and its local and remote Connection IDs), if there's no PIM neighbor with that remote Connection ID on any interface where we announce the local Connection ID, the connection SHOULD be shut down. This can happen when a new Connection ID gets configured, PORT gets disabled, or a PIM neighbor expires. ๐Ÿงน

If a PIM neighbor expires, you should free the connection state and the downstream oif-list state for that neighbor. ๐Ÿซถ For downstream routers, when an upstream neighbor has expired, they just update the RPF neighbor for the matching state to a new neighbor, and that's where they would trigger Join/Prune messages. This follows [RFC4601], which defines the term "RPF neighbor", so that's the source of truth ๐Ÿ’…. It is required of a PIM router to clear its neighbor table for a neighbor who has timed out due to neighbor Holdtime expiration.

When a connection is no longer available between two PORT-enabled PIM neighbors, they MUST immediately, or on demand, try to reestablish the connection, following the normal rules for connection establishment. The neighbors MUST also start expiry timers so that all oif-list state for the neighbor using the connection gets expired after J/P_Holdtime, unless it later gets refreshed by receiving new Join/Prunes. โฐ

The value of J/P_Holdtime is 210 seconds. This value is based on Section 4.11 of [RFC4601], which says that J/P_HoldTime should be 3.5 * t_periodic, where the default for t_periodic is 60 seconds. ๐ŸŒธ

4.4. Moving from PORT to Datagram Mode ๐Ÿฆ‹

there might be times when an administrator decides to stop using PORT ๐Ÿฅบ. If PORT is disabled on a router interface, or a previously PORT-enabled neighbor no longer announces any of the PORT Hello Options, the router follows the rules in Section 4.3 for taking down connections and starting timers. Next, the router SHOULD trigger a full state update, similar to what would be done if the GenID changed in Datagram mode. The router SHOULD send Join/Prune messages for any state where the router switched from PORT to Datagram mode for the upstream neighbor. ๐Ÿ”

4.5. On-Demand versus Pre-Configured Connections ๐Ÿ“

transport connections could be established when they're needed, or when a router interface to other PIM neighbors comes up. The big win for on-demand establishment is saving router resources, especially when there's no need for a full mesh of connections on a network interface. The tradeoff is extra delay and queueing when a Join/Prune message needs to go out and a transport connection isn't established yet. ๐Ÿ˜ค

If a router interface has become operational and PIM neighbors are learned from Hello messages, transport connections may be established at that time. The upside is that a connection is ready to carry data by the time a Join/Prune message needs to be sent. The downside is that there can be more connections established than needed. This can happen when there's a small set of RPF neighbors for the active distribution trees compared to the total number of neighbors. Even when transport connections are pre-established, a connection can still go down, and the implementation will have to deal with an on-demand situation anyway ๐Ÿ’€.

Note that for TCP, it's the router with the lower Connection ID that decides whether to open a connection immediately or on demand. The router with the higher Connection ID SHOULD only initiate a connection on demand, which means it only does so if it needs to send a Join/Prune message and there is no currently established connection. ๐Ÿง

So, this specification recommends, but does not mandate, the use of on-demand transport connection establishment. โœจ

4.6. Possible Hello Suppression Considerations ๐Ÿ™ˆ

based on this specification, a transport connection can't be established until a Hello message is received. The reasons are to figure out whether the PIM neighbor supports this specification, and to work out the remote address to use for establishing the transport connection. ๐Ÿ”

There are cases where it's desirable to suppress the transmission of Hello messages entirely. In that case, how to determine if the PIM neighbor supports this specification, and how to determine the remote address out-of-band (that is, outside of the PIM protocol) for establishing the transport connection, are outside the scope of this document. To put it plainly, the following is outside the scope of this document: how to determine if the PIM neighbor supports this specification, as well as an out-of-band (outside of the PIM protocol) method to determine the remote address to establish the transport connection. ๐Ÿซ 

4.7. Avoiding a Pair of TCP Connections between Neighbors ๐Ÿ‘ฏโ€โ™€๏ธ

okay this one is so important ๐Ÿ˜ญ. To make sure there's only one TCP connection between a pair of PIM neighbors, the following set of rules MUST be followed. Note that this section applies only to TCP. For SCTP, this isn't an issue ๐Ÿ™Œ. Let nodes A and B be two PIM neighbors where A's Connection ID is numerically smaller than B's Connection ID, and each is known to the other as having a potential PIM adjacency relationship. ๐Ÿ’œ

At node A:

  • If there is already an established TCP connection to B, on the PIM-over-TCP port, then A MUST NOT attempt to establish a new connection to B. Instead, it uses the established connection to send Join/Prune messages to B. (This is independent of which node initiated the connection.) ๐Ÿ”—
  • If A has initiated a connection to B, but the connection is still in the process of being established, then A MUST refuse any connection on the PIM-over-TCP port from B. ๐Ÿšซ
  • At any time when A does not have a connection to B (which is either established or in the process of being established), A MUST accept connections from B. ๐Ÿค

At node B:

  • If there is already an established TCP connection to A on the PIM-over-TCP port, then B MUST NOT attempt to establish a new connection to A. Instead, it uses the established connection to send Join/Prune messages to A. (This is independent of which node initiated the connection.) ๐Ÿ”—
  • If B has initiated a connection to A, but the connection is still in the process of being established, then if A initiates a connection too, B MUST accept the connection initiated by A and release the connection that it (B) initiated. ๐Ÿ‘‘

5. PORT Message Definitions ๐Ÿ’Œ

for scaling purposes, it may be desirable to allow Join/Prune messages from different PIM protocol families to be sent over the same transport connection. It may also be desirable to have a set of Join/Prune messages for one address family sent over a transport connection that is established over a different address-family network layer. ๐ŸŒˆ

To make this work, we need a common PORT message format. This gives us both record boundary and demux points when sending over a stream protocol like TCP or SCTP. ๐Ÿงฉ

A PORT message may contain PORT Options. See Section 5.3. We will define two PORT Options for carrying PIM Join/Prune messages, one for IPv4 and one for IPv6. For each PIM Join/Prune message sent over the transport connection, we send a PORT Join/Prune message containing exactly one such option. ๐Ÿ’–

Each PORT message uses the Type/Length/Value format. Multiple different TLV types can be sent over the same transport connection. ๐ŸŽ€

To make sure PIM Join/Prune messages are delivered as soon as the TCP transport layer receives the Join/Prune buffer, the TCP Push flag will be set in all outgoing Join/Prune messages sent over a TCP transport connection. โšก

PORT messages will be sent using destination TCP port number 8471. When using SCTP as the reliable transport, destination port number 8471 will be used. See Section 12 for IANA considerations. ๐Ÿ“ฎ

PORT messages are error checked. This includes unknown or illegal type fields, or a truncated message. If the PORT message contains a PIM Join/Prune Message, then that is subject to the normal PIM error checks, including checksum verification. If any parsing errors occur in a PORT message, it is skipped, and we proceed to any following PORT messages. ๐Ÿ”

When an unknown type field is encountered, that message MUST be ignored. As specified above, one then proceeds as usual when processing further PORT messages. This is important so that new message types can be specified in the future without breaking existing implementations. However, if only unknown or invalid messages are received for a longer period of time, an implementation MAY alert the operator. For example, if a message is sent with a wrong length, the receiver is likely to see only unknown or invalid messages after that. ๐Ÿšจ

The checksum of the PIM Join/Prune message MUST be calculated exactly as specified in Section 4.9 of [RFC4601]. For IPv6, [RFC4601] specifies the use of a pseudo-header. For PORT, the exact same pseudo-header MUST be used, but its source and destination address fields MUST be set to 0 when calculating the checksum. ๐Ÿงฎ

The TLV type field is 16 bits. The range 65532 - 65535 is for experimental use [RFC3692]. ๐Ÿงช

This document defines two message types. ๐Ÿฆ‹

5.1. PORT Join/Prune Message โœจ

Okay bestie, this is the message that carries a PIM Join/Prune ๐Ÿฆ‹ Here's the layout:

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |          Type = 1             |        Message Length         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                            Reserved                           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                           Interface                           |
       |                               ID                              |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |    PORT Option Type           |      Option Value Length      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                             Value                             |
       |                               .                               |
       |                               .                               |
       |                               .                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       \                               .                               \
       /                               .                               /
       \                               .                               \
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |    PORT Option Type           |      Option Value Length      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                             Value                             |
       |                               .                               |
       |                               .                               |
       |                               .                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                          PORT Join/Prune Message
  • Message Length: this is the length in bytes of the value part of the Type/Length/Value encoding ๐Ÿ’… If no PORT Options are included, the length is 12. If n PORT Options with Option Value lengths L1, L2, ..., Ln are included, the message length is 12 + 4*n + L1 + L2 + ... + Ln.
  • Reserved: set to zero on transmission and ignored on receipt ๐ŸŒธ
  • Interface ID: this MUST be the Interface ID of the Interface ID Hello Option that's inside the PIM Hello messages the PIM router sends to the PIM neighbor. It tells the neighbor which interface to link the Join/Prune to, and it's what lets us do connection sharing ๐Ÿซถ
  • PORT Options: the message MUST contain exactly one PIM Join/Prune PORT Option, either one PIM IPv4 Join/Prune or one PIM IPv6 Join/Prune. It MUST NOT contain both. It MAY contain additional options that aren't defined in this document. What happens when you receive a message with unknown options depends on the option type. See Section 5.3 for option definitions โœจ

5.2. PORT Keep-Alive Message ๐Ÿ’œ

Here's the keep-alive layout:

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |          Type = 2             |        Message Length         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                            Reserved                           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           Holdtime            |       PORT Option Type        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |      Option Value Length      |            Value              |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+              .                +
       |                                              .                |
       |                                              .                |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       \                               .                               \
       /                               .                               /
       \                               .                               \
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |    PORT Option Type           |      Option Value Length      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                             Value                             |
       |                               .                               |
       |                               .                               |
       |                               .                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                          PORT Keep-Alive Message

The keep-alive is how you regularly send PORT messages to check that a connection is still alive ๐Ÿฆ‹ It comes in handy when the other PORT messages aren't going out as often as you'd like.

  • Message Length: this is the length in bytes of the value part of the Type/Length/Value encoding. If no PORT Options are included, the length is 6. If n PORT Options with Option Value lengths L1, L2, ..., Ln are included, the message length is 6 + 4*n + L1 + L2 + ... + Ln.
  • Reserved: set to zero on transmission and ignored on receipt ๐ŸŒธ
  • Holdtime: this is a Holdtime in seconds for the connection โฐ A non-zero value means the connection SHOULD be gracefully shut down if no further PORT messages arrive within that time. The receiver measures it from when one PORT message has been processed until the next one has been processed. This MUST be done for any PORT message, not just keep-alives, so pay attention bestie ๐Ÿ‘€ A Holdtime of 0 disables the keep-alive mechanism ๐Ÿ’€
  • PORT Options: a keep-alive message MUST NOT contain any of the options defined in this document. It MAY contain other options that aren't defined here. What happens with unknown options depends on the option type. See Section 5.3 for option definitions ๐ŸŽ€

5.3. PORT Options ๐Ÿงš

Every PORT Option is a TLV, and the type is 16 bits ๐Ÿซถ The type space gets split into two ranges. Types from 0 to 32767 (where the most significant bit is not set) are for Critical Options. Types from 32768 to 65535 (where the most significant bit is set) are for Non-Critical Options.

So what happens when a router gets a message with an unknown PORT Option? It depends on whether the option is Critical ๐Ÿ˜ค If the message has an unknown Critical Option, the entire message must be ignored. If the option is Non-Critical, only that one option gets ignored, and the message is processed as if the option was never there โœจ

PORT Option types are assigned by IANA, except for the ranges 32764 - 32767 and 65532 - 65535, which are reserved for experimental use [RFC3692]. The length tells you how many bytes long the value is. Here are the two options defined in this document ๐Ÿ‘‘

5.3.1. PIM IPv4 Join/Prune Option ๐ŸŒˆ

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |      PORT Option Type = 1     |      Option Value Length      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                   PIMv2 Join/Prune Message                    |
       |                               .                               |
       |                               .                               |
       |                               .                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                     PIM IPv4 Join/Prune Option Format

This option carries a PIMv2 Join/Prune message where every address in the PIM payload is IPv4-encoded ๐Ÿ’–

  • Option Value Length: the number of bytes that make up the PIMv2 Join/Prune message.
  • PIMv2 Join/Prune Message: the PIMv2 Join/Prune message and its payload, with no IP header in front of it.

5.3.2. PIM IPv6 Join/Prune Option ๐Ÿ’œ

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |      PORT Option Type = 2     |      Option Value Length      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                   PIMv2 Join/Prune Message                    |
       |                               .                               |
       |                               .                               |
       |                               .                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                     PIM IPv6 Join/Prune Option Format

This one is the same idea, but it carries a PIMv2 Join/Prune message where every address in the PIM payload is IPv6-encoded ๐ŸŒธ

  • Option Value Length: the number of bytes that make up the PIMv2 Join/Prune message.
  • PIMv2 Join/Prune Message: the PIMv2 Join/Prune message and its payload, with no IP header in front of it.

6. Explicit Tracking โœจ

okay so explicit tracking is when a router keeps tabs on Join state for each individual downstream neighbor on a given interface ๐Ÿ‘€. This MUST be done for all PORT Joins and Prunes ๐Ÿ’…. It may also be done for native Join/Prune messages, but only if every neighbor on the LAN has set the T bit of the LAN Prune Delay Option (the definition lives in Section 4.9.2 of [RFC4601]) ๐Ÿซถ. The bits below talk about ET (explicit tracking) neighbors and non-ET neighbors. The set of ET neighbors MUST include the PORT neighbors. The non-ET neighbors are all the non-PORT neighbors, unless every neighbor has set the LAN Prune Delay T bit. In that case, the ET neighbors set just contains everyone ๐ŸŒˆ.

For some link types, like point-to-point, tracking neighbors is basically the same thing as tracking interfaces ๐Ÿฆ‹. An implementation can also treat different downstream neighbors as living on different logical interfaces, even when they're on the same physical link. How that gets done, and which link types it works for, is up to the implementer ๐Ÿงš.

For (*,G) and (S,G) state, the router starts forwarding traffic on an interface once a Join comes in from a neighbor on that interface ๐Ÿ”ฅ. When a non-ET neighbor sends a Prune (as specified in [RFC4601]), the upstream router waits. If no Join goes out to override that Prune before the Override Timer expires, the upstream router concludes that no non-ET neighbor is interested ๐Ÿ™ˆ. If no ET neighbors are interested either, the interface can be removed from the oif-list. When an ET neighbor sends a Prune, the router removes the Join state for that neighbor. If no other ET or non-ET neighbors are interested, the interface can be removed from the oif-list too. When a PORT neighbor sends a Prune, there can be no Prune Override, because that Prune isn't visible to the other neighbors ๐Ÿ’€.

For (S,G,rpt) state, the router needs to track Prune state on the shared tree. It needs to know which ET neighbors have sent Prunes, and whether any non-ET neighbors have sent Prunes too ๐Ÿง . Normally, a packet from a source S to a group G gets forwarded out an interface if a (,G) Join is received but no (S,G,rpt) Prune is. With ET, that check has to happen per ET neighbor. The packet should be forwarded, except in two cases: when all the ET neighbors that have sent (,G) Joins have also sent (S,G,rpt) Prunes, and when a non-ET neighbor has sent a (*,G) Join while there's also non-ET (S,G,rpt) Prune state ๐Ÿ’œ.


7. Support of Multiple Address Families ๐ŸŒธ

to save router resources (efficiency is everything ๐Ÿ˜ค), you can mux Join/Prune messages from different address families onto the same transport connection. There are two ways to pull this off: using a common message format over a TCP connection, or using multiple streams over a single SCTP connection ๐ŸŽ€.

Using the common message format described in this specification, plus different PORT Options, both IPv4-based and IPv6-based Join/Prune messages can be encoded within the same transport connection โœจ.

When SCTP multi-streaming is in use, the common message format still carries the address-family information. But an SCTP association gets used on a per-family basis, so data for multiple families can be sent concurrently. Sending concurrently means head-of-line blocking (which can happen with TCP) gets avoided ๐Ÿฆ‹.

8. Miscellany ๐Ÿงš

there are no changes to how other PIM messages get processed. That covers PIM Asserts, Grafts, Graft-Acks, Registers, and Register-Stops ๐Ÿ’…. The same goes for Bootstrap Router (BSR) and Auto-RP type messages ๐Ÿซถ.

This extension only applies to PIM-SM, PIM-SSM, and Bidirectional PIM. It doesn't take requirements for PIM Dense Mode (PIM-DM) into consideration ๐Ÿ™…โ€โ™€๏ธ.

9. Transport Considerations ๐ŸŒˆ

as noted in the introduction, this is an experimental extension to PIM, and using reliable delivery for PIM messages is a brand-new concept ๐Ÿ”ฌ. There are a few potential transport-related concerns. Hopefully, experience from early implementations and deployments will reveal which concerns actually matter and how to fix them ๐Ÿคž.

One consideration is keep-alive mechanisms. We defined an optional keep-alive mechanism for PORT (see Section 4.2). SCTP and plenty of TCP implementations also come with keep-alive mechanisms that could be used. When to send keep-alive messages and which mechanism to pick are both unclear. We do think the PORT Keep-alive gives you better application control though ๐Ÿ‘‘. It's also unclear which Holdtimes are preferred for PORT Keep-alives. For now, it is RECOMMENDED that administrators be able to configure whether to use keep-alives, which Holdtimes to use, and so on โญ.

In a stable state, only occasional small messages are expected over a PORT connection. How often those go out depends on how often PIM Join/Prune state changes ๐Ÿ“. So over a long stretch of time, there may be only small messages that never fill up the entire TCP congestion window, and that window may grow very large. That becomes a problem if a state change makes PORT send a very large message ๐Ÿ˜ฌ. It may be good if the TCP stack provides some rate-limiting or burst-limiting. The congestion control mechanism defined in [RFC3465] may be of help ๐Ÿ’œ.

With PORT, it's possible that only occasional small messages get sent (as we just discussed). That can cause problems for the TCP retransmit mechanism. In particular, the TCP Fast Retransmit algorithm may never get triggered ๐Ÿ™ƒ. For more on this and a possible solution, check out [RFC3042] ๐Ÿ“š.

There may be SCTP issues similar to the TCP issues covered in the two paragraphs above ๐ŸŒธ.

10. Manageability Considerations ๐ŸŽ€

this document defines using TCP or SCTP transports between pairs of PIM neighbors. It is recommended that this mechanism be disabled by default. An administrator can then enable PORT TCP and/or SCTP on PIM-enabled interfaces ๐Ÿ› ๏ธ. If two neighbors both have PORT SCTP (or both have PORT TCP), they'll only use SCTP (or, alternatively, TCP) for PIM Join/Prune messages. That's still true even when the connection is down, because there's no fallback to native Join/Prune messages ๐Ÿ˜ค.

When PORT support is enabled, a router sends PIM Hello messages announcing support for TCP and/or SCTP, plus Connection IDs. It should be possible to configure a local Connection ID, and also to see which PORT capabilities and Connection IDs PIM neighbors are announcing ๐Ÿ‘€. Based on those advertisements, pairs of PIM neighbors will decide whether to try establishing a PORT connection. There should be a way for an operator to check the current connection state ๐Ÿซถ. Statistics on the number of PORT messages sent and received (including the number of invalid messages) may also be helpful ๐Ÿ“Š.

For connection security (see Section 4.1), it should be possible to enable a GTSM check. That way, connections (TCP/SCTP packets) are only accepted when the sender is within a certain number of router hops ๐Ÿ›ก๏ธ. You should also be able to configure the use of TCP-AO ๐Ÿ”.

For connection maintenance (see Section 4.2), it is recommended to support Keep-Alive messages. It should be configurable whether to send Keep-Alives, and if so, whether to use a Holdtime and which Holdtime to use ๐Ÿ’–.

There should be some way to alert an operator when PORT connections go down or when establishing a PORT connection fails ๐Ÿšจ. Info like the number of connection failures, and how long a connection has been up or down, is useful too ๐Ÿ•ฐ๏ธ.

11. Security Considerations ๐Ÿ”ฅ

there are several security issues tied to using TCP or SCTP transports, and they're kind of a big deal ๐Ÿ˜ฑ. By sending packets with a spoofed source address, off-path attackers might establish a connection or inject packets into an existing one. That could let an attacker send spoofed Join/Prune messages and/or reset a connection ๐Ÿ’€. Mechanisms that help protect against this are discussed in Section 4.1 ๐Ÿ›ก๏ธ.

For authentication, TCP-AO [RFC5925] may be used with TCP, and Authenticated Chunks [RFC4895] may be used with SCTP ๐Ÿ”‘. GTSM [RFC5082] can also be used to help prevent spoofing ๐Ÿšซ.

12. IANA Considerations ๐ŸŒท

this specification uses a TCP port number and an SCTP port number for the pim-port service, both assigned by IANA. It also makes use of IANA PIM Hello Options assignments that have been made permanent ๐Ÿงพ.

12.1. PORT Port Number ๐Ÿ”ข

IANA previously assigned a port number that serves as the destination port for pim-port TCP and SCTP transports. The assigned number is 8471. References to this document have been added to the Service Name and Transport Protocol Port Number Registry for pim-port ๐Ÿ“.

12.2. PORT Hello Options ๐Ÿ‘‹

in the "PIM-Hello Options" registry, the following options have been added for PORT ๐Ÿ’Œ.

    Value    Length      Name                    Reference
   -------  ----------  -----------------------  ---------------
    27       Variable    PIM-over-TCP-Capable     this document
    28       Variable    PIM-over-SCTP-Capable    this document

12.3. PORT Message Type Registry ๐Ÿ“ฎ

a registry for PORT message types has been created ๐ŸŽ‰. The message type is a 16-bit integer, with values from 0 to 65535. An RFC is required for assignments in the range 0 - 65531. This document defines two PORT message types: Type 1 (Join/Prune) and Type 2 (Keep-alive). The type range 65532 - 65535 is for experimental use [RFC3692] ๐Ÿงช.

The initial content of the registry is as follows:

    Type           Name                             Reference
   -------------  -------------------------------  ---------------
    0              Reserved                         this document
    1              Join/Prune                       this document
    2              Keep-alive                       this document
    3-65531        Unassigned
    65532-65535    Experimental                     this document

12.4. PORT Option Type Registry ๐Ÿ—‚๏ธ

a registry for PORT Option types. The option type is a 16-bit integer, with values from 0 to 65535. The type space is split in two ranges: 0 - 32767 for Critical Options and 32768 - 65535 for Non-Critical Options. Option types are assigned by IANA, except for the ranges 32764 - 32767 and 65532 - 65535, which are for experimental use [RFC3692]. An RFC is required for IANA assignments. An RFC defining a new option type must specify whether the option is Critical or Non-Critical, so that IANA can assign a type ๐Ÿงฉ. This document defines two Critical PORT Option types: Type 1 (PIM IPv4 Join/Prune) and Type 2 (PIM IPv6 Join/Prune) ๐ŸŒŸ.

The initial content of the registry is as follows:

    Type           Name                               Reference
   -------------  ----------------------------------  ---------------
    0              Reserved                            this document
    1              PIM IPv4 Join/Prune                 this document
    2              PIM IPv6 Join/Prune                 this document
    3-32763        Unassigned Critical Options
    32764-32767    Experimental                        this document
    32768-65531    Unassigned Non-Critical Options
    65532-65535    Experimental                        this document

13. Contributors ๐Ÿซถ๐Ÿ’–

in addition to the people listed as authors, significant contributions came from Apoorva Karan and Arjen Boers ๐ŸŒˆโœจ

14. Acknowledgments โœจ

okay bestie, the authors want to give a special thank you to Nidhi Bhaskar ๐Ÿซถ for her initial design and early prototype of this idea. obsessed with that origin story, honestly ๐Ÿ’œ

Appreciation also goes to Randall Stewart ๐Ÿ‘‘ for his authoritative review and recommendation for using SCTP. literally iconic.

Thanks also goes to the following for their ideas and review of this specification ๐ŸŒธ: Mike McBride, Toerless Eckert, Yiqun Cai, Albert Tian, Suresh Boddapati, Nataraj Batchu, Daniel Voce, John Zwiebel, Yakov Rekhter, Lenny Giuliano, Gorry Fairhurst, Sameer Gulrajani, Thomas Morin, Dimitri Papadimitriou, Bharat Joshi, Rishabh Parekh, Manav Bhatia, Pekka Savola, Tom Petch, and Joe Touch. so many brilliant people, the group chat is stacked ๐Ÿฆ‹

A very special thank you goes to Eric Rosen ๐ŸŒˆ for his very detailed review and commentary. Many of his comments are reflected as text in this specification. he really did the most, and the spec is better for it ๐Ÿ’…


15. References

15.1. Normative References

These are the must-read ones ๐Ÿ“–

[RFC0793]    Postel, J., "Transmission Control Protocol", STD 7,
             RFC 793, September 1981.

[RFC2119]    Bradner, S., "Key words for use in RFCs to Indicate
             Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC4601]    Fenner, B., Handley, M., Holbrook, H., and I. Kouvelas,
             "Protocol Independent Multicast - Sparse Mode (PIM-SM):
             Protocol Specification (Revised)", RFC 4601,
             August 2006.

[RFC4895]    Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
             "Authenticated Chunks for the Stream Control
             Transmission Protocol (SCTP)", RFC 4895, August 2007.

[RFC4960]    Stewart, R., "Stream Control Transmission Protocol",
             RFC 4960, September 2007.

[RFC5015]    Handley, M., Kouvelas, I., Speakman, T., and L.
             Vicisano, "Bidirectional Protocol Independent Multicast
             (BIDIR-PIM)", RFC 5015, October 2007.

[RFC5082]    Gill, V., Heasley, J., Meyer, D., Savola, P., and C.
             Pignataro, "The Generalized TTL Security Mechanism
             (GTSM)", RFC 5082, October 2007.

[RFC5925]    Touch, J., Mankin, A., and R. Bonica, "The TCP
             Authentication Option", RFC 5925, June 2010.

[RFC6395]    Gulrajani, S. and S. Venaas, "An Interface Identifier
             (ID) Hello Option for PIM", RFC 6395, October 2011.

15.2. Informative References

these ones are the extra reading for the curious ๐Ÿงš

[AFI]        IANA, "Address Family Numbers",
             <http://www.iana.org/assignments/
             address-family-numbers>.

[HELLO-OPT]  IANA, "PIM-Hello Options",
             <http://www.iana.org/assignments/pim-parameters>.

[RFC3042]    Allman, M., Balakrishnan, H., and S. Floyd, "Enhancing
             TCP's Loss Recovery Using Limited Transmit", RFC 3042,
             January 2001.

[RFC3465]    Allman, M., "TCP Congestion Control with Appropriate
             Byte Counting (ABC)", RFC 3465, February 2003.

[RFC3692]    Narten, T., "Assigning Experimental and Testing Numbers
             Considered Useful", BCP 82, RFC 3692, January 2004.

Authors' Addresses ๐ŸŽ€

meet the authors! ๐Ÿ’–

Dino Farinacci
Cisco Systems
Tasman Drive
San Jose, CA  95134
USA

EMail: dino@cisco.com


IJsbrand Wijnands
Cisco Systems
Tasman Drive
San Jose, CA  95134
USA

EMail: ice@cisco.com


Stig Venaas
Cisco Systems
Tasman Drive
San Jose, CA  95134
USA

EMail: stig@cisco.com


Maria Napierala
AT&T Labs
200 Laurel Drive
Middletown, New Jersey  07748
USA

EMail: mnapierala@att.com
๐Ÿ“ฆ where this page comes from