RFC 9262

Tree Engineering for Bit Index Explicit Replication (BIER-TE)

๐Ÿ“… published October 2022, from ietf

RFC 9262: Tree Engineering for Bit Index Explicit Replication (BIER-TE) ๐Ÿฆ‹

Okay bestie, this one is from the IETF (the Internet Engineering Task Force, the crew that writes the rules for how the internet talks to itself) ๐Ÿ’… It's published as RFC 9262 and dated October 2022. The editor is T. Eckert from Futurewei, with M. Menth from the University of Tuebingen and G. Cauchie from KOEVOO as co-authors. It's a Standards Track document, so it's an official internet standard and not just a suggestion ๐ŸŒˆ The header doesn't list anything it obsoletes or updates. Its ISSN is 2070-1721 โœจ

Abstract โœจ

okay so this memo describes per-packet stateless strict and loose path steered replication and forwarding for "Bit Index Explicit Replication" (BIER) packets (RFC 8279) ๐Ÿ”ฅ The name is "Tree Engineering for Bit Index Explicit Replication" (BIER-TE), and it's meant to be the path steering mechanism for Traffic Engineering with BIER. It's giving main character energy ๐Ÿ‘‘

BIER-TE gives "bit positions" (BPs) a brand new meaning. In regular (non-TE) BIER, a BP points to a "Bit-Forwarding Egress Router" (BFER). In BIER-TE, a BP points to an adjacency in the network topology instead ๐Ÿฆ‹ So a BIER-TE "packets BitString" tells you exactly which edges of the (loop-free) tree the packet gets forwarded across. It's so clean ๐Ÿ˜ญ

The good news is that BIER-TE can use BIER forwarding engines with only small changes ๐Ÿซถ It can also live in the same domain as BIER, for example by using separate BIER "subdomains" (SDs) ๐ŸŒธ Except for the optional routed adjacencies, BIER-TE doesn't need a BIER routing underlay, so it can work without a routing protocol like the "Interior Gateway Protocol" (IGP). No IGP drama needed ๐Ÿ’–


Status of This Memo โœจ

This is an Internet Standards Track document. ๐ŸŽ€

This document is a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community. It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). If you want more info on Internet Standards, check out Section 2 of RFC 7841 ๐Ÿงš

You can find the current status of this document, any errata, and a place to give feedback at https://www.rfc-editor.org/info/rfc9262 ๐Ÿ’œ

Copyright (c) 2022 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 (https://trustee.ietf.org/license-info) as they stood on the publication date. Please read these carefully, because they spell out your rights and restrictions for this document ๐Ÿ™ˆ Code Components pulled out of this document must include Revised BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as described in the Revised BSD License ๐Ÿ”ฅ


Table of Contents ๐Ÿ“

1.  Overview
2.  Introduction
  2.1.  Requirements Language
  2.2.  Basic Examples
  2.3.  BIER-TE Topology and Adjacencies
  2.4.  Relationship to BIER
  2.5.  Accelerated Hardware Forwarding Comparison
3.  Components
  3.1.  The Multicast Flow Overlay
  3.2.  The BIER-TE Control Plane
    3.2.1.  The BIER-TE Controller
      3.2.1.1.  BIER-TE Topology Discovery and Creation
      3.2.1.2.  Engineered Trees via BitStrings
      3.2.1.3.  Changes in the Network Topology
      3.2.1.4.  Link/Node Failures and Recovery
  3.3.  The BIER-TE Forwarding Plane
  3.4.  The Routing Underlay
  3.5.  Traffic Engineering Considerations
4.  BIER-TE Forwarding
  4.1.  The BIER-TE Bit Index Forwarding Table (BIFT)
  4.2.  Adjacency Types
    4.2.1.  Forward Connected
    4.2.2.  Forward Routed
    4.2.3.  ECMP
    4.2.4.  Local Decap(sulation)
  4.3.  Encapsulation / Co-existence with BIER
  4.4.  BIER-TE Forwarding Pseudocode
  4.5.  BFR Requirements for BIER-TE Forwarding
5.  BIER-TE Controller Operational Considerations
  5.1.  Bit Position Assignments
    5.1.1.  P2P Links
    5.1.2.  BFERs
    5.1.3.  Leaf BFERs
    5.1.4.  LANs
    5.1.5.  Hub and Spoke
    5.1.6.  Rings
    5.1.7.  Equal-Cost Multipath (ECMP)
    5.1.8.  Forward Routed Adjacencies
      5.1.8.1.  Reducing Bit Positions
      5.1.8.2.  Supporting Nodes without BIER-TE
    5.1.9.  Reuse of Bit Positions (without DNC)
    5.1.10. Summary of BP Optimizations
  5.2.  Avoiding Duplicates and Loops
    5.2.1.  Loops
    5.2.2.  Duplicates
  5.3.  Managing SIs, Subdomains, and BFR-ids
    5.3.1.  Why SIs and Subdomains?
    5.3.2.  Assigning Bits for the BIER-TE Topology
    5.3.3.  Assigning BFR-ids with BIER-TE
    5.3.4.  Mapping from BFRs to BitStrings with BIER-TE
    5.3.5.  Assigning BFR-ids for BIER-TE
    5.3.6.  Example Bit Allocations
      5.3.6.1.  With BIER
      5.3.6.2.  With BIER-TE
    5.3.7.  Summary
6.  Security Considerations
7.  IANA Considerations
8.  References
  8.1.  Normative References
  8.2.  Informative References
Appendix A.  BIER-TE and Segment Routing (SR)
Acknowledgements
Authors' Addresses

1. Overview ๐ŸŒธ

"Tree Engineering for Bit Index Explicit Replication" (BIER-TE) is built on the regular (non-TE) BIER architecture, terminology, and packet formats from [RFC8279] and [RFC8296]. This doc assumes you already know those two, so read them first, bestie ๐Ÿ“š

Same vibe as before: BIER-TE gives "bit positions" (BPs) a new semantic. They point to adjacencies in the network topology instead of "Bit-Forwarding Egress Routers" (BFERs), which is what they do in non-TE BIER ๐Ÿฆ‹ A BIER-TE "packets BitString" marks the edges of the (loop-free) tree the packet travels across. Each "Bit-Forwarding Router" (BFR) only fills its "Bit Index Forwarding Table" (BIFT) with the BPs next to it in the BIER-TE topology, and every other BP is empty in that table โœจ The BFR then replicates and forwards BIER packets to the adjacent BPs that are set. BPs usually get cleared on forwarding too, which keeps duplicates and loops away ๐Ÿ™…โ€โ™€๏ธ

BIER-TE can use BIER forwarding engines with little or no changes ๐Ÿ’… It can also hang out in the same domain as BIER, for example with separate BIER subdomains ๐ŸŽ€ Except for the optional routed adjacencies, BIER-TE doesn't need a BIER routing underlay, so it can run without something like the "Interior Gateway Protocol" (IGP) ๐Ÿ’–

This document is laid out like this:

  • Section 2 gives you BIER-TE with two forwarding examples. Then it introduces the new BIER-TE (overlay) topology concepts, and wraps up with how BIER and BIER-TE relate plus a look at accelerated hardware forwarding ๐ŸŒˆ
  • Section 3 covers the parts of the BIER-TE architecture: the multicast flow overlay, the BIER-TE layer with its control plane (including the BIER-TE controller), the BIER-TE forwarding plane, and the routing underlay ๐Ÿงš
  • Section 4 specifies how the BIER-TE forwarding plane behaves with the different adjacency types, possible variations of the BIER-TE forwarding pseudocode, and the mandatory and optional requirements ๐Ÿ”ฅ
  • Section 5 is for operational considerations for the BIER-TE controller. It mainly looks at how the controller can optimize BP usage by picking specific BIER-TE adjacency types for different topologies, and how to assign bits so you avoid loops and duplicates (which, in BIER-TE, does NOT come "for free" ๐Ÿ˜ญ). Last, it covers how the BIER-TE controller can manage "Set Identifiers" (SIs), "subdomains" (SDs), and BFR-ids, with examples and a summary ๐Ÿ“
  • Appendix A wraps things up and talks about how BIER-TE relates to "Segment Routing" (SR) ๐Ÿซถ

Quick heads-up on related work: [CONSTRAINED-CAST] uses Bloom filters [Bloom70] to represent the leaves or edges of the intended delivery tree ๐Ÿ™ˆ Bloom filters can handle bigger trees and topologies with fewer addressing bits than explicit BitStrings. The catch is that they carry the heuristic risk of false positives, and they can't clear bits during forwarding to avoid loops ๐Ÿ’€ That's why BIER-TE, just like BIER, uses explicit BitStrings. Still, explicit BitStrings as used by BIER-TE can be seen as a special type of Bloom filter, and that's how other related work [ICC] describes them ๐ŸŒธ

2. Introduction ๐Ÿ’œ

2.1. Requirements Language ๐ŸŽ€

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. ๐Ÿ“–โœจ

2.2. Basic Examples ๐ŸŽ€

okay so BIER-TE forwarding is way easier to get once you see a few simple examples ๐Ÿ’– These examples use formal terms that get defined later in this document (Figure 4 in Section 4.1), including forward_connected(), forward_routed(), and local_decap().

Let's start with the simple network from the BIER-TE overview example in Figure 1, which has six BFRs. The bit positions in use are p1...p15. Every BFR can act as a "Bit-Forwarding Ingress Router" (BFIR), and BFR1, BFR3, BFR4, and BFR6 can also be BFERs ๐ŸŒธ Forward_connected() is the name for adjacencies that stand for the subnet adjacencies of the network. Local_decap() is the name for the adjacency that decapsulates BIER-TE packets and hands their payload off to higher-layer processing ๐Ÿงš

      BIER-TE Topology:

      Diagram:

                       p5    p6
                     --- BFR3 ---
                  p3/    p13     \p7          p15
      BFR1 ---- BFR2              BFR5 ----- BFR6
         p1   p2  p4\    p14     /p10 p11   p12
                     --- BFR4 ---
                       p8    p9

      (simplified) BIER-TE Bit Index Forwarding Tables (BIFTs):

      BFR1:   p1  -> local_decap()
              p2  -> forward_connected() to BFR2

      BFR2:   p1  -> forward_connected() to BFR1
              p5  -> forward_connected() to BFR3
              p8  -> forward_connected() to BFR4

      BFR3:   p3  -> forward_connected() to BFR2
              p7  -> forward_connected() to BFR5
              p13 -> local_decap()

      BFR4:   p4  -> forward_connected() to BFR2
              p10 -> forward_connected() to BFR5
              p14 -> local_decap()

      BFR5:   p6  -> forward_connected() to BFR3
              p9  -> forward_connected() to BFR4
              p12 -> forward_connected() to BFR6

      BFR6:   p11 -> forward_connected() to BFR5
              p15 -> local_decap()

                      Figure 1: BIER-TE Basic Example

Say a packet from BFR1 needs to go via BFR4 to BFR6. For that you need a BitString of (p2,p8,p10,p12,p15) ๐Ÿ“ When BIER-TE on BFR1 looks at this packet, the only bit position from the BitString that's also set in the BIFT is p2. So BFR1 sends the one and only copy of the packet to BFR2. Then BFR2 forwards to BFR4 because of p8, BFR4 goes to BFR5 because of p10, and BFR5 goes to BFR6 because of p12. Finally p15 makes BFR6 receive and decapsulate the packet โœจ

Now, if you want a copy sent to BFR6 via BFR4 and a copy to BFR3, the BitString becomes (p2,p5,p8,p10,p12,p13,p15). When BFR2 examines the packet, p5 sends one copy to BFR3 and p8 sends one copy to BFR4. When BFR3 gets the packet, p13 makes it receive and decapsulate it ๐Ÿ’…

If the BitString were instead (p2,p6,p8,p10,p12,p13,p15), then BFR5 would copy the packet toward BFR3 because of p6, instead of BFR2 copying it to BFR3 because of p5 like in the previous case. This shows how the BIER-TE topology in Figure 1 can send traffic across any possible path and replicate it wherever you want ๐Ÿฆ‹

BIER-TE has a bunch of options for minimizing BP assignments. Lots of them depend on out-of-band knowledge about the multicast traffic paths you need and the bandwidth the network will use, e.g., from predeployment planning ๐Ÿ“‹

Figure 2 shows a modified example where Rtr2 and Rtr5 are assumed not to support BIER-TE, so the traffic has to be unicast encapsulated across them ๐ŸŒˆ To clearly tell routed/tunneled forwarding of BIER-TE packets apart from Layer 2 forwarding (forward_connected()), these adjacencies are called "forward_routed()" adjacencies. Other than that, there's no difference in how they get processed compared to the forward_connected() adjacencies we just talked about ๐Ÿซถ

In this example, bits are saved by assuming that BFR1 only needs to be a BFIR, not a BFER or a transit BFR ๐Ÿ’œ

      BIER-TE Topology:

      Diagram:

                      p1  p3  p7
                   ....> BFR3 <....       p5
           ........                ........>
      BFR1       (Rtr2)          (Rtr5)      BFR6
           ........                ........> p9
                   ....> BFR4 <....       p6
                      p2  p4  p8

      (simplified) BIER-TE Bit Index Forwarding Tables (BIFTs):

      BFR1:   p1  -> forward_routed() to BFR3
              p2  -> forward_routed() to BFR4

      BFR3:   p3  -> local_decap()
              p5  -> forward_routed() to BFR6

      BFR4:   p4  -> local_decap()
              p6  -> forward_routed() to BFR6

      BFR6:   p7  -> forward_routed() to BFR3
              p8  -> forward_routed() to BFR4
              p9  -> local_decap()

                  Figure 2: BIER-TE Basic Overlay Example

To send a BIER-TE packet from BFR1 via BFR3 so that BFR6 receives it, the BitString is (p1,p5,p9) ๐ŸŒธ A packet from BFR1 via BFR4 to be received by BFR6 uses (p2,p6,p9). A packet from BFR1 to be received by BFR3 and BFR4, and from BFR3 to be received by BFR6, uses (p1,p2,p3,p4,p5,p9). A packet from BFR1 to be received by BFR3 and BFR4, and from BFR4 to be received by BFR6, uses (p1,p2,p3,p4,p6,p9). A packet from BFR1 to be received by BFR4, then from BFR4 to be received by BFR6, and finally from BFR6 to be received by BFR3, uses (p2,p3,p4,p6,p7,p9). And a packet from BFR1 to be received by BFR3, then from BFR3 to be received by BFR6, and finally from BFR6 to be received by BFR4, uses (p1,p3,p4,p5,p8,p9) ๐Ÿงšโœจ

2.3. BIER-TE Topology and Adjacencies ๐Ÿฆ‹

The big new piece in BIER-TE, compared to (non-TE) BIER, is the BIER-TE topology. We met it through the two examples in Section 2.2 ๐Ÿ’… It's what controls where replication can or should happen, and how to keep the number of BPs needed for adjacencies as low as possible.

The BIER-TE topology is made up of the BIFTs of all the BFRs. You can also picture it as a directed graph, where the edges are the adjacencies between the BFRs, labeled with the BP used for each adjacency. Adjacencies are naturally unidirectional ๐ŸŒˆ A BP can be reused across several adjacencies, as long as that doesn't cause undesired duplicates or loops. Section 5.2 explains this in more detail ๐Ÿซถ

If the BIER-TE topology represents (a subset of) the underlying (Layer 2) topology of the network, like in the first example, it may be called an "underlay" BIER-TE topology. A topology made up only of "forward_routed()" adjacencies, like the second example, may be called an "overlay" BIER-TE topology. And a BIER-TE topology with both forward_connected() and forward_routed() adjacencies may be called a "hybrid" BIER-TE topology ๐Ÿ’œ

2.4. Relationship to BIER ๐ŸŒˆ

BIER-TE is designed so its forwarding plane is a simple extension of the (non-TE) BIER forwarding plane. That means it can be added to BIER deployments where it can be beneficial โœจ

BIER-TE is also meant as an option for expanding the BIER architecture into deployments where (non-TE) BIER may not be the best fit, such as statically provisioned networks that need path steering but don't want distributed routing protocols ๐ŸŽ€

  1. BIER-TE inherits the following aspects from BIER unchanged:
    • 1.a The fundamental purpose of per-packet signaled replication and delivery via a BitString ๐Ÿ’–
    • 1.b The overall architecture, which has three layers: the flow overlay, the BIER(-TE) layer, and the routing underlay ๐Ÿฆ‹
    • 1.c The supported encapsulations [RFC8296] ๐ŸŒธ
    • 1.d The semantics of all BIER header elements [RFC8296] used by the BIER-TE forwarding plane, other than the semantic of the BP in the BitString ๐Ÿงš
    • 1.e The BIER forwarding plane, except for how bits have to be cleared during replication ๐Ÿ’…
  2. BIER-TE has the following key changes with respect to BIER:
    • 2.a In BIER, bits in the BitString of a BIER packet header indicate a BFER, and bits in the BIFT indicate the BIER control plane's calculated next hop toward that BFER. In BIER-TE, a bit in the BitString of a BIER packet header indicates an adjacency in the BIER-TE topology, and only the BFR that is the upstream of that adjacency has its BP populated with the adjacency in its BIFT ๐Ÿซถ
    • 2.b In BIER, the implied reference options for the core part of the BIER layer control plane are the BIER extensions for distributed routing protocols. These include IS-IS and OSPF extensions for BIER, as specified in [RFC8401] and [RFC8444], respectively ๐ŸŒˆ
    • 2.c The reference option for the core part of the BIER-TE control plane is the BIER-TE controller. Nevertheless, both the BIER and BIER-TE BIFTs' forwarding plane state could equally be populated by any mechanism โœจ
    • 2.d Assuming the reference options for the control plane, BIER-TE replaces in-network autonomous path calculations with explicit paths calculated by the BIER-TE controller ๐Ÿ‘‘
  3. The following elements/functions described in the BIER architecture are not required by the BIER-TE architecture:
    • 3.a "Bit Index Routing Tables" (BIRTs) are not required on BFRs for BIER-TE when using a BIER-TE controller, because the controller can directly populate the BIFTs. In BIER, BIRTs are populated by the distributed routing protocol support for BIER, which lets BFRs populate their BIFTs locally from their BIRTs. Other BIER-TE control plane or management plane options may introduce requirements for BIRTs for BIER-TE BFRs ๐Ÿ’€
    • 3.b The BIER-TE layer forwarding plane does not require BFRs to have a unique BP; see Section 5.1.3. Therefore, BFRs may not have a unique BFR-id; see Section 5.3.3 ๐Ÿ™ˆ
    • 3.c Identification of BFRs by the BIER-TE control plane is outside the scope of this specification. Whereas the BIER control plane uses BFR-ids in its BFR-to-BFR signaling, a BIER-TE controller may choose any form of identification deemed appropriate ๐Ÿ“
    • 3.d BIER-TE forwarding does not require the BFIR-id field of the BIER packet header ๐ŸŒธ
  4. Co-existence of BIER and BIER-TE in the same network requires the following:
    • 4.a The BIER/BIER-TE packet header needs to allow the addressing of both BIER and BIER-TE BIFTs. Depending on the encapsulation option, the same SD may or may not be reusable across BIER and BIER-TE. See Section 4.3. In either case, a packet is always forwarded only end to end via BIER or via BIER-TE ("ships in the night" forwarding) ๐ŸŒˆ
    • 4.b BIER-TE deployments will have to assign BFR-ids to BFRs and insert them into the BFIR-id field of BIER packet headers, as does BIER, whenever the deployment uses (unchanged) components developed for BIER that use BFR-ids, such as multicast flow overlays or BIER layer control plane elements. See also Section 5.3.3 ๐Ÿ’–

2.5. Accelerated Hardware Forwarding Comparison

okay so the whole goal here is for BIER-TE to be as close to BIER as humanly possible ๐Ÿ’… because that makes life way easier for anyone programming BIER-TE forwarding code or BIER-TE forwarding hardware on platforms that already do BIER ๐Ÿซถ. Its BitString parsing is basically the same, no cap.

The pseudocode in Section 4.4 shows how existing (non-TE) BIER/BIFT forwarding can be tweaked to support the BIER-TE forwarding functionality you need (Section 4.5), using the BIER BIFT's "Forwarding Bit Mask" (F-BM). The only thing that gets skipped in BIER-TE forwarding is clearing bits to avoid sending duplicate packets to a BFR's neighbor ๐Ÿ˜ญ. That's because it isn't necessary, and it couldn't be done with a BIER F-BM anyway ๐Ÿ™ˆ.

Whether you're doing BIER or BIER-TE forwarding is just a choice of which mode the BIFT indicated by the packet is in (BIER BIFT or BIER-TE BIFT) ๐Ÿฆ‹. The BFR configuration for the encapsulation decides that, so check Section 4.3 for the details โœจ.

3. Components

BIER-TE is giving the same three-layer lineup as BIER ๐Ÿ‘‘: the "multicast flow overlay", the "BIER layer", and the "routing underlay". Figure 3 also shows how the BIER layer is made up of the "BIER-TE forwarding plane" and the "BIER-TE control plane", which is represented by the "BIER-TE controller" ๐Ÿงš.

                   <------BGP/PIM----->
      |<-IGMP/PIM->  multicast flow   <-PIM/IGMP->|
                        overlay

          BIER-TE  [BIER-TE Controller] <=> [BIER-TE Topology]
          control     ^      ^     ^
          plane      /       |      \   BIER-TE control protocol
                    |        |       |  (e.g., YANG/NETCONF/RESTCONF
                    |        |       |       PCEP/...)
                    v        v       v
    Src -> Rtr1 -> BFIR-----BFR-----BFER -> Rtr2 -> Rcvr

                   |<----------------->|
                 BIER-TE forwarding plane

                   |<- BIER-TE domain->|

                 |<--------------------->|
                     Routing underlay

                       Figure 3: BIER-TE Architecture

3.1. The Multicast Flow Overlay

The multicast flow overlay has the same role it has in BIER, as described in [RFC8279], Section 4.3 ๐ŸŽ€. Also peep Section 3.2.1.2 โœจ.

When you're using a BIER-TE controller, it may also be preferable for multicast flow overlay signaling to go through a central point of control ๐ŸŒธ. For BGP-based overlay flow services like "Multicast VPN Using Bit Index Explicit Replication (BIER)" [RFC8556], you can make the BIER-TE controller act as a BGP Route Reflector [RFC4456] and combine that with signaling, through BGP or some other protocol, for the BIER-TE controller's calculated BitStrings. See Sections 3.2.1.2 and 5.3.4 for more ๐Ÿ’œ.

3.2. The BIER-TE Control Plane

In the (non-TE) BIER architecture [RFC8279], the BIER layer is summarized in Section 4.2 of [RFC8279] ๐Ÿงš. That summary covers both the BIER-layer control plane and forwarding plane, it just doesn't use those terms. Some example standardized options for the BIER control plane are IS-IS and OSPF extensions for BIER, specified in [RFC8401] and [RFC8444], respectively ๐ŸŒˆ.

For BIER-TE, the control plane includes, at a minimum, the following functionality ๐Ÿ’–.

  1. BIER-TE topology control: During initial provisioning of the network and/or when its topology and/or services get modified, the protocols and/or procedures establish BIER-TE BIFTs ๐Ÿ“:
    • 1.a Determine the desired BIER-TE topology for BIER-TE subdomains: the adjacencies that are assigned to BPs. Topology discovery is discussed in Section 3.2.1.1, and the different aspects of the BIER-TE controller's topology decisions are discussed throughout Section 5 ๐Ÿ”ฅ.
    • 1.b Determine the per-BFR BIFT from the BIER-TE topology. This is done by simply extracting the adjacencies of the BFR from the BIER-TE topology and populating the BFR's BIFT with them ๐Ÿซถ.
    • 1.c Optionally assign BFR-ids to BFIRs for later insertion into BIER headers on BFIRs as BFIR-ids. Alternatively, BFIR-ids in BIER packet headers may be managed solely by the flow overlay layer and/or be unused. This is discussed in Section 5.3.3 โœจ.
    • 1.d Install/update the BIFTs into the BFRs and, optionally, BFR-ids into BFIRs. This is discussed in Section 3.2.1.1 ๐Ÿฆ‹.
  2. BIER-TE tree control: During network operations, protocols and/or procedures support creating, changing, and removing overlay flows on BFIRs ๐ŸŒธ:
    • 2.a Process the BIER-TE requirements for the multicast overlay flow: the BFIRs and BFERs of the flow, as well as policies for the path selection of the flow. This is discussed in Section 3.5 ๐Ÿ’….
    • 2.b Determine the BitStrings and, optionally, entropy. BitStrings are discussed in Sections 3.2.1.2, 3.5, and 5.3.4. Entropy is discussed in Section 4.2.3 ๐Ÿ”ฅ.
    • 2.c Install state on the BFIR to impose the desired BIER packet header(s) for packets of the overlay flow. Different aspects of this point, as well as the next point, are discussed throughout Section 3.2.1 and in Section 4.3. The main component responsible for these two points is the multicast flow overlay (Section 3.1), which is architecturally inherited from BIER ๐Ÿ‘‘.
    • 2.d Install the necessary state on the BFERs to decapsulate the BIER packet header and properly dispatch its payload ๐Ÿงš.

3.2.1. The BIER-TE Controller

This architecture describes the BIER-TE control plane, as shown in Figure 3, as consisting of ๐Ÿ’œ:

  • A BIER-TE controller.
  • BFR data models and protocols to communicate between the controller and BFRs in support of BIER-TE topology control (see the list under "BIER-TE topology control"), such as YANG/NETCONF/RESTCONF [RFC7950] [RFC6241] [RFC8040] ๐ŸŒˆ.
  • BFR data models and protocols to communicate between the controller and BFIRs in support of BIER-TE tree control (see Section 3.2, point 2.), such as BIER-TE extensions for [RFC5440] ๐Ÿ“.

The single, centralized BIER-TE controller is used in this document as the reference option for the BIER-TE control plane, but other options are equally feasible ๐Ÿฆ‹. The BIER-TE control plane could just as easily be implemented without automated configuration/protocols, with an operator using a CLI on the BFRs. In that case, operator-configured local policy on the BFIR would have to decide how to set the appropriate BIER header fields ๐Ÿ™ˆ. The BIER-TE control plane could also be decentralized and/or distributed. This document doesn't consider any additional protocols and/or procedures that would then be needed to coordinate its (distributed/decentralized) entities to achieve the functionality described above ๐Ÿ˜ญ.

3.2.1.1. BIER-TE Topology Discovery and Creation

The first item listed for BIER-TE topology control (Section 3.2, point 1.a.) covers network topology discovery and BIER-TE topology creation ๐Ÿ”. Creation is the process where a controller figures out which routers are going to be configured as BFRs, and the adjacencies between them ๐Ÿงš.

In statically managed networks, like industrial environments, both discovery and creation can be a manual/offline process ๐ŸŒธ.

In other networks, topology discovery may rely on protocols like those that extend a link-state IGP into the BIER-TE controller itself, for example BGP-LS [RFC7752] or YANG topology [RFC8345]. It can also use methods specific to BIER-TE, for example via [BIER-TE-YANG] โœจ. These options aren't exhaustive ๐Ÿ’….

Dynamic creation of the BIER-TE topology can be as easy as mapping the network topology 1:1 to the BIER-TE topology by assigning a BP for every network subnet adjacency ๐ŸŽ€. In larger networks it likely involves more complex policy and optimization decisions ๐Ÿ”ฅ. Those include how to minimize the number of BPs required, and how to assign BPs across different BitStrings to minimize the number of duplicate packets across links when delivering an overlay flow to BFERs using different SIs:BitStrings ๐Ÿซถ. These topics are discussed in Section 5 ๐Ÿ’–.

When the BIER-TE topology has been determined, the BIER-TE controller pushes the BPs/adjacencies to the BIFT of the BFRs. On each BFR, only those SIs:BPs that are adjacencies to other BFRs in the BIER-TE topology get populated ๐Ÿฆ‹.

Communications between the BIER-TE controller and BFRs for both BIER-TE topology control and BIER-TE tree control are ideally done via standardized protocols and data models, such as NETCONF/RESTCONF/YANG/PCEP ๐ŸŒˆ. A vendor-specific CLI on the BFRs is also an option, as in many other "Software-Defined Network" (SDN) solutions that lack standardized data model definitions ๐Ÿ™ˆ.

3.2.1.2. Engineered Trees via BitStrings

In BIER, the same set of BFERs in a single subdomain is always encoded as the same BitString. In BIER-TE, though, the BitString used to reach the same set of BFERs in the same subdomain can be different for different overlay flows ๐Ÿ‘‘. That's because the BitString encodes the paths towards the BFERs, so BitStrings from different BFIRs to the same set of BFERs will often be different ๐Ÿ’…. Likewise, the BitString from the same BFIR to the same set of BFERs can be different for different overlay flows if different policies should apply to those flows ๐Ÿ”ฅ. Examples of those policies are shortest path trees, Steiner trees (minimum cost trees), diverse path trees for redundancy, and so on ๐Ÿงš.

See also [BIER-MCAST-OVERLAY] for an application that leverages BIER-TE engineered trees ๐Ÿ’œ.

3.2.1.3. Changes in the Network Topology

If the network topology changes (not because of a failure) so that adjacencies assigned to bit positions are no longer needed, the BIER-TE controller can reuse those bit positions for new adjacencies ๐Ÿ“. First, those bit positions need to be removed from any BFIR flow state and BFR BIFT state. After that, they can be repopulated, first into the BIFT and then into the BFIR โœจ.

When links or nodes fail or recover in the topology, BIER-TE could respond quickly with "Fast Reroute" (FRR) procedures such as those described in [BIER-TE-PROTECTION] ๐Ÿš€. The details of those are out of scope for this document ๐Ÿ™ˆ. It can also react more slowly by recalculating the BitStrings of affected multicast flows ๐Ÿข. This reaction is slower than the FRR procedure because the BIER-TE controller needs to receive link/node up/down indications, recalculate the desired BitStrings, and push them down into the BFIRs ๐Ÿ˜ญ. With FRR, all of that is performed locally on a BFR that receives the adjacency up/down notification ๐ŸŒˆ.

3.3. The BIER-TE Forwarding Plane โœจ

okay so the BIER-TE forwarding plane is made of three main jobs, bestie ๐ŸŽ€ each one is a whole vibe:

  1. On a BFIR, imposition of the BIER header for packets from overlay flows. This is driven by state established by the BIER-TE control plane, the multicast flow overlay as explained in Section 3.1, or a combination of both.
  2. On BFRs (including BFIRs and BFERs), forwarding/replication of BIER packets according to their SD, SI, BitStringLength (BSL), BitString, and, optionally, entropy fields as explained in Section 4. Processing of other BIER header fields, such as the "Differentiated Services Code Point" (DSCP) field, is outside the scope of this document. ๐Ÿ’–
  3. On BFERs, removal of the BIER header and dispatching of the payload according to state created by the BIER-TE control plane and/or overlay layer. ๐Ÿฆ‹

okay now the main event ๐Ÿ‘‘ when the BIER-TE forwarding plane gets a packet, it just looks up the bit positions that are set in the packet's BitString in the BIFT that the BIER-TE controller filled in. For every BP that is set and has one or more adjacencies in the BIFT, a copy gets made based on the types of adjacencies for that BP.

And here's the part I'm obsessed with ๐Ÿ˜ญ before sending any copies, the BFR clears every BP in the packet's BitString that it has one or more adjacencies for in the BIFT. Clearing these bits is what stops packets from looping when a BitString accidentally includes a forwarding loop. It's literally the safety net. ๐Ÿซถ

One exception: when a forward_connected() adjacency has the "DoNotClear" (DNC) flag set, that BP gets reset for the copy sent to that adjacency. See Section 4.2.1. ๐ŸŒธ

3.4. The Routing Underlay ๐ŸŒˆ

for forward_connected() adjacencies, BIER-TE sends BIER packets to directly connected BIER-TE neighbors as L2 (unicast) BIER packets, and it doesn't need a routing underlay for that. ๐Ÿงš

for forward_routed() adjacencies, BIER-TE forwarding encapsulates a copy of the BIER packet so the forwarding plane of the routing underlay can deliver it to the routable destination address listed in the adjacency. See Section 4.2.2 for details on forward_routed() adjacencies.

ok so BIER relies on the routing underlay to figure out paths toward BFERs and to derive next-hop BFR adjacencies for those paths. Those two steps usually lean on BIER-specific extensions to the routing protocols of the underlay, but a controller can establish them too. ๐Ÿ’… In BIER-TE though, the next hops for a packet are decided by the BitString, using the adjacencies the BIER-TE controller set up on each BFR for the BPs in that BitString. So there's no need for BFR-specific routing underlay extensions to forward BIER packets with BIER-TE semantics. Iconic, honestly. ๐Ÿ‘‘

Encapsulation parameters can be provisioned by the BIER-TE controller straight into the forward_connected() or forward_routed() adjacencies, no routing underlay required. โœจ

one more thing ๐Ÿ™ˆ if the BFR wants to support FRR for BIER-TE, the BIER-TE forwarding plane needs to receive fast adjacency up/down notifications, like link up/down or neighbor up/down. An example source is "Bidirectional Forwarding Detection" (BFD). Providing these notifications is considered part of the routing underlay in this document.

3.5. Traffic Engineering Considerations ๐Ÿ“

okay Traffic Engineering [TE-OVERVIEW] is all about optimizing the performance of operational IP networks while using network resources economically and reliably. ๐ŸŒธ The key elements are policy, path steering, and resource management. These need support at the control/controller level and inside the forwarding plane too.

Policy decisions are made in the BIER-TE control plane, which means inside the BIER-TE controllers. Controllers use policy when composing BitStrings and BFR BIFT state. The mapping of user/IP traffic to specific BitStrings / BIER-TE flows is also based on policy. The specific details of BIER-TE policies and how a controller uses them are out of scope for this document. ๐Ÿซถ

Path steering is supported through the definition of a BitString. BitStrings used in BIER-TE are composed based on policy and resource management considerations. For example, when composing BIER-TE BitStrings, a controller has to take into account the resources available at each BFR and for each BP if it's providing congestion-loss-free services like Rate-Controlled Service Disciplines [RCSD94]. ๐Ÿ’œ Resource availability could come from routing protocol information, for example, but it can also be gathered through a BIER-TE control protocol such as NETCONF, or any other protocol a controller commonly uses to understand the resources of the network it operates on.

The resource usage of the BIER-TE traffic admitted by the BIER-TE controller can be tracked solely on the controller, using local accounting, as long as no forward_routed() adjacencies are used (see Section 4.2.2 for the definition of forward_routed() adjacencies). When forward_routed() adjacencies are used, the paths selected by the underlying routing protocol need to be tracked as well. ๐Ÿ”ฅ

Resource management has effects on the forwarding plane beyond the BIER-TE-defined steering of packets. This includes allocating buffers to guarantee the worst-case requirements for admitted RCSD traffic, and potentially policing and/or rate-shaping mechanisms, which are typically done with various forms of queuing. This level of resource control is optional, but it's important for networks that want to support congestion management policies, control or regulate offered traffic to deliver different levels of service and ease congestion problems, or control the latencies experienced by specific traffic flows. โญ

4. BIER-TE Forwarding ๐Ÿฆ‹

4.1. The BIER-TE Bit Index Forwarding Table (BIFT) ๐Ÿ’–

the BIER-TE BIFT is equivalent to the (non-TE) BIER BIFT. It exists on every BFR running BIER-TE. For every BIER "subdomain" (SD) in use for BIER-TE, the BIFT is built following the example in Figure 4. The BIFT in the figure assumes a BSL of 8 "bit positions" (BPs) in the packet's BitString. As in [RFC8279], this BSL is purely an example and is not a BSL supported by BIER/BIER-TE (the minimum BSL is 64). ๐ŸŒˆ

A BIER-TE BIFT compares to a BIER BIFT as shown in [RFC8279], like this:

In both BIER and BIER-TE, BIFT rows/entries are indexed in their respective BIER pseudocode ([RFC8279], Section 6.5) and BIER-TE pseudocode (Section 4.4). The index comes from the packet's SI, BSL, and the one bit position of the packet's BitString (BP) that addresses the BIFT row: BIFT-index = SI * BSL + BP - 1. BPs within a BitString are numbered from 1 to BSL, which is why there's the - 1 offset when converting to a BIFT-index. ๐Ÿงš This document also uses the notion SI:BP to indicate BIFT rows. [RFC8279] uses the equivalent notion SI:BitString, where the BitString is filled with only the BPs for the BIFT row.

In BIER, each BIFT-index addresses one BFER by its BFR-id = BIFT-index + 1, and it's populated on each BFR with the next-hop "BFR Neighbor" (BFR-NBR) toward that BFER.

In BIER-TE, each BIFT-index, and therefore each SI:BP, indicates one adjacency between BFRs in the topology, or more than one in the case of SI:BP reuse. ๐Ÿ“ The SI:BP is populated with the adjacency on the upstream BFR of the adjacency. The BIFT entries are empty on all other BFRs.

In BIER, each BIFT row also needs a "Forwarding Bit Mask" (F-BM) entry for BIER forwarding rules. In BIER-TE forwarding, an F-BM is not required, but it can be used when implementing BIER-TE on forwarding hardware derived from BIER forwarding that must use an F-BM. This is discussed in the first variation of BIER-TE forwarding pseudocode shown in Section 4.4. ๐Ÿ’œ

Here's Figure 4, the BIFT with different adjacencies, in all its glory:

    -------------------------------------------------------------------
    | BIFT-index |      | Adjacencies:                                |
    | (SI:BP)    |(F-BM)| <empty> or one or more per entry            |
    ===================================================================
    |               BIFT indices for Packets with SI=0                |
    -------------------------------------------------------------------
    | 0 (0:1)    | ...  | forward_connected(interface,neighbor{,DNC}) |
    -------------------------------------------------------------------
    | 1 (0:2)    | ...  | forward_connected(interface,neighbor{,DNC}) |
    |            | ...  | forward_connected(interface,neighbor{,DNC}) |
    -------------------------------------------------------------------
    |  ...       | ...  | ...                                         |
    -------------------------------------------------------------------
    | 4 (0:5)    | ...  | local_decap({VRF})                          |
    -------------------------------------------------------------------
    | 5 (0:6)    | ...  | forward_routed({VRF,}l3-neighbor)           |
    -------------------------------------------------------------------
    | 6 (0:7)    | ...  | <empty>                                     |
    -------------------------------------------------------------------
    | 7 (0:8)    | ...  | ECMP((adjacency1,...adjacencyN){,seed})     |
    -------------------------------------------------------------------
    |           BIFT indices for BitString/Packet with SI=1           |
    -------------------------------------------------------------------
    | 9 (1:1)    |      | ...                                         |
    |  ...       | ...  | ...                                         |
    -------------------------------------------------------------------

          Figure 4: BIER-TE Bit Index Forwarding Table (BIFT) with
                           Different Adjacencies

The BIER-TE controller configures the BIFT for a BFR's BIER-TE data plane through an appropriate protocol and data model. The BIFT is then used to forward packets, following the BIER-TE forwarding plane procedures in Section 3.3. โœจ

Note that a BIFT-index (SI:BP) may be populated in the BIFT of more than one BFR to save BPs. See Section 5.1.6 for an example of how a BIER-TE controller could assign BPs to (logical) adjacencies shared across multiple BFRs, Section 5.1.3 for an example of assigning the same BP to different adjacencies, and Section 5.1.9 for general guidelines on reusing BPs across different adjacencies. ๐Ÿซถ

{VRF} indicates the Virtual Routing and Forwarding context into which the BIER payload is to be delivered. This is optional and depends on the multicast flow overlay. ๐ŸŒธ

4.2. Adjacency Types ๐ŸŒธ

4.2.1. Forward Connected ๐ŸŽ€

a forward_connected() adjacency is an adjacency toward a directly connected BFR-NBR, using an interface address of that BFR on the connecting interface. A forward_connected() adjacency doesn't route packets; it only does L2 forwarding to the neighbor. ๐Ÿ’…

Packets sent to an adjacency with "DoNotClear" (DNC) set in the BIFT MUST NOT have the bit position for that adjacency cleared when the BFR creates a copy for it. The bit position will still be cleared for copies of a packet made toward other adjacencies. This can be used, for example, in ring topologies, as explained in Section 5.1.6. ๐Ÿ’–

For protection against loops caused by misconfiguration (see Section 5.2.1), DNC is only permissible for forward_connected() adjacencies. No need or benefit of DNC for other types of adjacencies was identified, and the associated risks were not analyzed. ๐Ÿ™ˆ

4.2.2. Forward Routed ๐Ÿฆ‹

okay bestie, so a forward_routed() adjacency is basically a tunnel ๐Ÿš‡. You wrap the BIER-TE packet in some encapsulation so the routing underlay carries it over to the adjacent BFR named in the l3-neighbor parameter. Any encapsulation that works is fair game, like MPLS or tunneling over IP/IPv6 ๐ŸŒธ, as long as the BIER-TE packet can be recognised as a payload. That recognition can come from the BIER/BIER-TE co-existence mechanisms in Section 4.3, or from an explicit BIER-TE payload type in the tunnel encapsulation โœจ.

So why would anyone even want this? ngl it's super useful ๐Ÿ’…. forward_routed() lets BIER-TE traffic hop across routers that aren't BIER-TE capable. It also lets you cut down on how many BPs you need by tunneling over BIER-TE routers where you don't want replication or path steering ๐Ÿงš. Or you just want to borrow the routing underlay's path redundancy and FRR to reach the next BFR ๐Ÿ”ฅ. It can even help a multi-subnet adjacent BFR use the routing underlay's ECMP separately from BIER-TE ECMP (Section 4.2.3) ๐Ÿ’œ. Main character energy, fr fr ๐Ÿ‘‘.

4.2.3. ECMP ๐ŸŽ€

okay so (Non-TE) BIER ECMP is tied to the BIER BIFT processing semantic ๐Ÿ™ˆ, which means you can't just use it with BIER-TE. Not the vibe ๐Ÿ’€.

Instead, BIER-TE has an "Equal-Cost Multipath" adjacency, written ECMP() โœจ. Figure 4 shows one for BIFT-index 7. It takes a list of two or more non-ECMP() adjacencies as parameters, plus an optional seed parameter ๐ŸŒˆ. When a BIER-TE packet gets copied onto an ECMP() adjacency, a hash function picks one adjacency from the list to send it on. This hash is implementation-specific, so every vendor gets to pick their own flavour ๐Ÿ“.

If the packet's encapsulation has an entropy field, the entropy field SHOULD be respected ๐Ÿซถ. Two packets with the same entropy field value SHOULD be sent on the same adjacency ๐Ÿ”ฅ. The seed parameter is there so you can design hash functions that are easy to run at high speed without polarization issues piling up across multiple consecutive ECMP hops ๐Ÿ˜ญ. For the details, check out Section 5.1.7 ๐Ÿ“–.

4.2.4. Local Decap(sulation) ๐ŸŒธ

A local_decap() adjacency takes a copy of the BIER-TE packet's payload and hands it up to the protocol ("NextProto") inside the BFR that's responsible for that payload, like IP/IPv6 or Ethernet ๐Ÿงš. The header fields decide which protocol that is ๐Ÿ’–. So a local_decap() adjacency basically turns the BFR into a BFER for matching packets ๐Ÿฆ‹.

Heads up: local_decap() adjacencies need the BFER to support routing or switching for NextProto, so it knows how to process the packets from there ๐Ÿ™ˆ.

4.3. Encapsulation / Co-existence with BIER ๐ŸŒˆ

Specs for BIER-TE encapsulation are out of scope for this document ๐Ÿ’…. This section just gives explanations and guidelines, bestie ๐ŸŽ€.

Maximum Transmission Unit (MTU) limitations are also out of scope here, and [RFC8279] doesn't cover them either ๐Ÿ™ˆ. Instead, that process lives in the BIER-TE packet encapsulation and/or flow overlay. For example, see [RFC8296], Section 3 โœจ. It works the same way for BIER-TE and BIER ๐Ÿ”ฅ.

Here's the lowkey tricky part ๐Ÿ˜ญ. A BFR has to read the BitString of a BIER-TE packet differently from a (non-TE) BIER packet ๐Ÿ’œ. So it's necessary to tell BIER packets apart from BIER-TE packets ๐Ÿ‘‘. In BIER encapsulation [RFC8296], the BIFT-id field tells you which BIFT the packet belongs to ๐Ÿ“. That means BIER and BIER-TE can run at the same time ๐ŸŒธ, as long as the BIFT-id address space is shared between BIER BIFTs and BIER-TE BIFTs ๐Ÿงš. Splitting up the BIFT-id address space is handled by BIER-TE/BIER control plane procedures ๐Ÿฆ‹.

When [RFC8296] is used for BIER with MPLS, BIFT-id address ranges can be dynamically allocated from the MPLS label space โœจ. This only covers the SD:BSL BIFTs that are actually in use ๐Ÿ’…. It also allows non-overlapping label ranges for the BIFT-ids used with BIER-TE BIFTs ๐ŸŽ€.

With MPLS, you can also reuse the same SD for both BIER-TE and BIER ๐ŸŒˆ. That way the same SD can have a BIER BIFT with its own range of BIFT-ids, plus disjoint BIER-TE BIFTs with a non-overlapping range of BIFT-ids ๐Ÿ’–.

Now, suppose there's a fixed mapping from BSL, SD, and SI to a BIFT-id ๐Ÿ™ˆ. It doesn't explicitly split the BIFT-id space between BIER and BIER-TE. That's the case for non-MPLS forwarding with BIER encapsulation [RFC8296], as proposed in [NON-MPLS-BIER-ENCODING], Section 5 ๐Ÿ“–. Then you have to give BIER and BIER-TE BIFTs disjoint SDs, so that the BIFT-ids can address both ๐Ÿ˜ญ. The encoding in Section 6 of [NON-MPLS-BIER-ENCODING] doesn't statically encode the BSL or SD into the BIFT-id ๐Ÿซถ. But it does allow a mapping, so it can give you the same freedom you'd get with MPLS (the same SD, or different SDs for BIER/BIER-TE) โœจ.

forward_routed() needs an encapsulation that can send unicast encapsulated BIER-TE packets to a specific interface address on a target BFR ๐Ÿฆ‹. With MPLS encapsulation, you can do this with a label stack whose top label is that address's label, followed by the label assigned to the (BSL,SD,SI) BitString ๐Ÿงš. With non-MPLS encapsulation, you'd need some form of IP encapsulation, like IP/GRE ๐ŸŒธ.

Last but not least, the encapsulation used for forward_routed() adjacencies can also support existing advanced adjacency information, like "loose source routes" ๐Ÿ’œ. You can do that with MPLS label stacks or with the right header extensions, like for IPv6 ๐Ÿ‘‘. Iconic ๐Ÿ”ฅ.

4.4. BIER-TE Forwarding Pseudocode โœจ

okay bestie, so the BIER-TE forwarding pseudocode (Figure 5 ๐ŸŽ€) is basically the regular non-TE BIER one from [RFC8279], Section 6.5, with exactly one tweak ๐Ÿ’…

void ForwardBitMaskPacket_withTE (Packet)
{
    SI=GetPacketSI(Packet);
    Offset=SI*BitStringLength;
    for (Index = GetFirstBitPosition(Packet->BitString); Index ;
         Index = GetNextBitPosition(Packet->BitString, Index)) {
        F-BM = BIFT[Index+Offset]->F-BM;
        if (!F-BM) continue;                            [3]
        BFR-NBR = BIFT[Index+Offset]->BFR-NBR;
        PacketCopy = Copy(Packet);
        PacketCopy->BitString &= F-BM;                  [2]
        PacketSend(PacketCopy, BFR-NBR);
        // The following must not be done for BIER-TE:
        // Packet->BitString &= ~F-BM;                  [1]
    }
}

Figure 5: BIER-TE Forwarding Pseudocode for Required Functions, Based on BIER Pseudocode

In step [2], the F-BM is used to clear one or more bits in PacketCopy. This step exists in both BIER and BIER-TE, but the F-BMs need to be populated differently for BIER-TE than for BIER to get the clearing you want ๐Ÿฆ‹

In BIER, multiple bits of a BitString can have the same BFR-NBR ๐ŸŒธ So when a received packet's BitString has more than one of those bits set, BIER's replication logic has to stop more than one PacketCopy from going to that BFR-NBR ([1]). The PacketCopy sent to a BFR-NBR also has to clear every bit in its BitString that isn't routed across that BFR-NBR. That's what stops BIER's replication from making duplicates on any possible further BFRs ([2]).

To solve both [1] and [2] for BIER, the F-BM of each bit index needs to have all the bits set that this BFR wants to route across a BFR-NBR. [2] clears all other bits in PacketCopy->BitString, and [1] clears those bits from Packet->BitString after the first PacketCopy.

In BIER-TE, a BFR-NBR in this pseudocode is an adjacency: forward_connected(), forward_routed(), or local_decap() โœจ There's no need for [2] to suppress duplicates the way BIER does, because in general, different BPs would never have the same adjacency. If a BIER-TE controller actually finds some optimization where that would be desirable, then the controller is also responsible for making sure that only one of those bits is set in any Packet->BitString, unless the controller explicitly wants duplicates to be created ๐Ÿงš

The following points describe how the F-BM for each BP is configured in the BIFT and how that impacts the BitString of the packet being processed with that BIFT:

  • 1. The F-BMs of all BIFT BPs without an adjacency have all their bits clear. This will cause [3] to skip further processing of such a BP.
  • 2. All BIFT BPs with an adjacency (with the DNC flag clear) have an F-BM that has only those BPs set for which this BFR does not have an adjacency. This causes [2] to clear all bits from PacketCopy->BitString for which this BFR does have an adjacency.
  • 3. [1] is not performed for BIER-TE. All bit clearing required by BIER-TE is performed by [2].

This forwarding pseudocode can support the required BIER-TE forwarding functions (see Section 4.5): forward_connected(), forward_routed(), and local_decap(). It can't support the recommended functions (the DNC flag and multiple adjacencies per bit) or the optional function (i.e., ECMP() adjacencies) ๐Ÿ˜ญ The DNC flag cannot be supported when using only [1] to mask bits.

The modified and expanded forwarding pseudocode in Figure 6 specifies how to support all BIER-TE forwarding functions (required, recommended, and optional) ๐Ÿ‘‘

  • 1. This pseudocode eliminates per-bit F-BMs, which reduces the size of BIFT state by SI*BSL^2 and removes the need for per-packet-copy BitString masking operations, except for adjacencies with the DNC flag set:
    • 1.a AdjacentBits[SI] are bit positions with a non-empty list of adjacencies in this BFR BIFT. This can be computed whenever the BIER-TE controller updates (adds/removes) adjacencies in the BIFT.
    • 1.b The BFR needs to create packet copies for these adjacent bits when they are set in the packet's BitString. This set of bits is calculated in PktAdjacentBits.
    • 1.c All bit positions for which the BFR creates copies have to be cleared in packet copies to avoid loops. This is done by masking the BitString of the packet with ~AdjacentBits[SI]. When an adjacency has DNC set, this bit position is set again only for the packet copy towards that bit position.
  • 2. BIFT entries may contain more than one adjacency in support of specific configurations, such as a hub and multiple spokes (Section 5.1.5). The code therefore includes a loop over these adjacencies.
  • 3. The ECMP() adjacency is also shown in the figure. Its parameters are a seed and "ListOfAdjacencies", from which one is picked.
  • 4. The forward_connected(), forward_routed(), and local_decap() adjacencies are shown with their parameters.
void ForwardBitMaskPacket_withTE (Packet)
{
    SI = GetPacketSI(Packet);
    Offset = SI * BitStringLength;
    // Determine adjacent bits in the packets BitString
    PktAdjacentBits = Packet->BitString & AdjacentBits[SI];

    // Clear adjacent bits in the packet header to avoid loops
    Packet->BitString &= ~AdjacentBits[SI];

    // Loop over PktAdjacentBits to create packet copies
    for (Index = GetFirstBitPosition(PktAdjacentBits); Index ;
         Index = GetNextBitPosition(PktAdjacentBits, Index)) {
        for adjacency in BIFT[Index+Offset]->Adjacencies {
            if(adjacency.type == ECMP(ListOfAdjacencies,seed) ) {
                I = ECMP_hash(sizeof(ListOfAdjacencies),
                              Packet->Entropy,seed);
                adjacency = ListOfAdjacencies[I];
            }
            PacketCopy = Copy(Packet);
            switch(adjacency.type) {
                case forward_connected(interface,neighbor,DNC):
                    if(DNC)
                        PacketCopy->BitString |= 1<<(Index-1);
                    SendToL2Unicast(PacketCopy,interface,neighbor);

                case forward_routed({VRF,}l3-neighbor):
                    SendToL3(PacketCopy,{VRF,}l3-neighbor);

                case local_decap({VRF},neighbor):
                    DecapBierHeader(PacketCopy);
                    PassTo(PacketCopy,{VRF,}Packet->NextProto);
            }
        }
    }
}

Figure 6: Complete BIER-TE Forwarding Pseudocode for Required, Recommended, and Optional Functions


4.5. BFR Requirements for BIER-TE Forwarding ๐Ÿ’–

BFRs that support BIER-TE and BIER MUST support a configuration that enables BIER-TE instead of (non-TE) BIER forwarding rules for all BIFTs of one or more BIER subdomains. Every BP in a BIER-TE BIFT MUST support having zero or one adjacency. BIER-TE forwarding MUST support the adjacency types forward_connected() with the DNC flag not set, forward_routed(), and local_decap(). As explained in Section 4.4, these required BIER-TE forwarding functions can be implemented via the same forwarding pseudocode as that used for BIER forwarding, except for one modification (skipping one masking with an F-BM).

BIER-TE forwarding SHOULD support forward_connected() adjacencies with the DNC flag set, as this is very useful for saving bits in rings (see Section 5.1.6) ๐ŸŒˆ

BIER-TE forwarding SHOULD support more than one adjacency on a bit. This allows bits to be saved in hub-and-spoke scenarios (see Section 5.1.5) ๐Ÿซถ

BIER-TE forwarding MAY support ECMP() adjacencies to save bits in ECMP scenarios; see Section 5.1.7 for an example. This is an optional requirement, because for ECMP deployments using BIER-TE, one can also leverage the routing underlay ECMP via forward_routed() adjacencies and/or might prefer to have more explicit control of the path chosen via explicit BPs/adjacencies for each ECMP path alternative ๐Ÿ“

5. BIER-TE Controller Operational Considerations ๐ŸŽ€

5.1. Bit Position Assignments ๐Ÿฆ‹

This section describes how the BIER-TE controller can use the different BIER-TE adjacency types to define the bit positions of a BIER-TE domain.

Because the size of the BitString limits the size of the BIER-TE domain, many of the options described here exist to support larger topologies with fewer bit positions ๐Ÿ’…

On a "point-to-point" (P2P) link that connects two BFRs, the same bit position can be used on both BFRs for the adjacency to the neighboring BFR. A P2P link therefore requires only one bit position ๐ŸŒธ

5.1.2. BFERs

Every non-leaf BFER is given a unique bit position with a local_decap() adjacency โœจ

5.1.3. Leaf BFERs ๐Ÿ“

okay so a leaf BFER is a BFER where incoming BIER-TE packets never need to get forwarded onward to another BFR. They just get sent to that BFER so they can exit the BIER-TE domain ๐Ÿšชโœจ. Think of PE routers as spokes hanging off P routers ๐Ÿงš. Those PEs are leaf BFERs, unless there's a U-turn between two PEs ๐Ÿ”„.

Now look at how redundant, disjoint traffic can reach BFER1/BFER2 in Figure 7 ๐Ÿ’…. If BFER1/BFER2 are non-leaf BFERs (the right side of the picture), then one copy can go from BFR1 straight to BFER1, but the other copy can only reach BFER1 by going through BFER2. So BFER2 is a non-leaf BFER ๐Ÿ˜ญ. It works the same way in reverse, so BFER1 is a non-leaf BFER when it's forwarding traffic to BFER2 ๐Ÿซถ. The BFERs on the left side are only guaranteed to be leaf BFERs if you correctly apply a routing config that stops transit traffic from going through the BFERs. That's super common in these topologies, so it's usually fine, but it's a config thing, not magic ๐Ÿ™ˆ.

        BFR1(P) BFR2(P)             BFR1(P)  BFR2(P)
          |  \ /  |                    |       |
          |   X   |                    |       |
          |  / \  |                    |       |
     BFER1(PE)  BFER2(PE)        BFER1(PE)----BFER2(PE)

                                           ^ U-turn link

         Leaf BFER /               Non-leaf BFER /
          PE router                  PE router

               Figure 7: Leaf vs. Non-Leaf BFER Example

Here's the slay part ๐Ÿ’–. In most situations, leaf BFERs that are addressed through the same BitString can share a single bit position for their local_decap() adjacency in that BitString, which saves bit positions ๐ŸŒธ. A non-leaf BFER is different. A received BIER-TE packet might just need to transit through it, or it might also need to be decapsulated, so the decision to decapsulate has to be signaled by a unique bit position. That bit position only shows up on this BFER's BIFT, and it carries a local_decap() adjacency ๐ŸŽ€. On a leaf BFER, packets never pass through anyway, so any packet that arrives is usually meant to be decapsulated. That means one shared bit position can be filled with a local_decap() adjacency on every leaf BFER that the BitString addresses ๐Ÿง.

There are some possible exceptions to this leaf BFER bit position optimization. One is when the bit position on the prior BIER-TE BFR (the one that made the packet copy for that leaf BFER) has multiple adjacencies stuffed in as an optimization. Sections 5.1.4 and 5.1.5 show examples of that ๐Ÿ‘€. With either of those two optimizations, the sender can only explicitly control whether the packet gets decapsulated on that leaf BFER if the leaf has its own unique bit position for local_decap() ๐Ÿ’œ.

BUT, sharing the bit position across a leaf BFER does mean packets might get decapsulated when they didn't really need to. That can still be totally fine, though, if the decapsulated payload itself says whether it needs further processing or receiving ๐Ÿ™Œ. This is usually true when the payload is IP multicast, because the BFER knows the membership state of that multicast payload and can toss it if BIER-TE delivered it by accident ๐Ÿ—‘๏ธโœจ. If the payload has no membership indication and the BFIR wants explicit control over which BFERs receive and decapsulate a packet, then those two optimizations can't be combined with the shared bit position optimization on a leaf BFER ๐Ÿšซ. Not me being picky, just how it works ๐Ÿ’….

5.1.4. LANs ๐ŸŒˆ

In a LAN, every neighboring BFR gets its own unique bit position ๐Ÿซง. The adjacency on that bit position is a forward_connected() adjacency pointing toward that BFR, and this bit position gets populated into the BIFT of all the other BFRs on that LAN ๐Ÿ’ซ.

                                 BFR1
                                  |p1
                           LAN1-+-+---+-----+
                              p3|   p4|   p2|
                              BFR3  BFR4  BFR7

                        Figure 8: LAN Example

Now, if bandwidth on the LAN isn't a concern and most BIER-TE traffic should get copied to all the neighbors on the LAN, you can save bit positions ๐Ÿง . Just assign a single bit position to the whole LAN, then fill that bit position in each BFR's BIFT on the LAN with a list of forward_connected() adjacencies to all the other neighbors on the LAN ๐ŸŽ‰.

This optimization does NOT work when BFRs are redundantly connected to more than one LAN ๐Ÿ˜ฌ. Those BFRs would receive duplicates and then forward those duplicates into the other LANs, which is a mess ๐Ÿ’€. Those BFRs need a separate bit position for each LAN they connect to ๐Ÿ“.

5.1.5. Hub and Spoke ๐Ÿงš

In a setup with one hub and multiple spokes, each connected to the hub by its own P2P link, all the P2P adjacencies from the hub toward the spokes' links can share the same bit position ๐Ÿฆ‹. The hub's BIFT gets that bit position set up with a list of forward_connected() adjacencies, one for each spoke ๐ŸŒธ.

This is kind of like the LAN optimization ๐Ÿ’…. Redundantly connected spokes still need their own bit positions, unless they're themselves leaf BFERs ๐Ÿซถ.

This type of optimized bit position could be used, for example, when all traffic is "broadcast" traffic (very dense receiver sets), like live TV or many-to-many telemetry, including situational awareness ๐Ÿ“บโœจ. This bit position optimization can then be used to explicitly steer different traffic flows across different ECMP paths in data-center or broadband-aggregation networks, all with minimal use of bit positions ๐Ÿ‘‘.

5.1.6. Rings ๐Ÿ’

In L3 rings, instead of assigning a single bit position to every P2P link in the ring, you can save bit positions by setting the "DoNotClear" (DNC) flag on forward_connected() adjacencies ๐ŸŒ€. The DNC flag is the secret sauce here ๐Ÿคซ๐Ÿ”ฅ.

For the ring in Figure 9, one single bit position is enough to forward traffic that enters the ring at BFRa or BFRb all the way up to BFR1 ๐ŸŽฏ. Here's how it goes. On BFRa, BFRb, BFR30,... BFR3, the bit position gets populated with a forward_connected() adjacency pointing to the clockwise neighbor on the ring, and DNC is set โœ…. On BFR2, the adjacency also points to the clockwise neighbor BFR1, but this time DNC is NOT set ๐Ÿ™ƒ.

Handling DNC this way makes sure that copies forwarded from any BFR in the ring to a BFR outside the ring won't have the ring bit position set, which keeps the risk of creating loops really low ๐Ÿ”๐Ÿšซ.

              v        v
              |        |
       L1     |   L2   |   L3
   /-------- BFRa ---- BFRb --------------------\
   |                                            |
   \- BFR1 - BFR2 - BFR3 - ... - BFR29 - BFR30 -/
       |      |    L4               |      |
    p33|                         p15|
       BFRd                       BFRc

                       Figure 9: Ring Example

Heads up, this example only allows packets that are supposed to make it all the way around the ring to enter at BFRa and BFRb โš ๏ธ. Also, packets always travel clockwise ๐Ÿ”„. If you want packets to be allowed to enter the ring at any of the ring's BFRs, then you'd need two ring bit positions, one for each direction: clockwise and counterclockwise ๐Ÿงญโœจ.

Both of those would be set up to stop rotating on the same link, e.g., L1 ๐Ÿ›‘. When the ring's BFIR creates the clockwise copy, it clears the counterclockwise bit position, because the DNC bit only applies to the bit the replication was done for. (It works the same way the other direction, for the clockwise bit position on the counterclockwise copy ๐Ÿ™Œ.) So the ring's BFIR ends up sending a copy in both directions, serving BFRs on either side of the ring up to L1 ๐ŸŒˆ๐Ÿ’–.

5.1.7. Equal-Cost Multipath (ECMP) ๐ŸŽ€

okay so ECMP() adjacencies let you use just ONE BP to deliver packets to one of N adjacencies, instead of giving every adjacency its own BP ๐Ÿซถ in the super common example in Figure 10, there's a link bundle of three links (L1, L2, L3) connecting BFR1 and BFR2, and only one BP gets used instead of three to send packets from BFR1 to BFR2. it's giving efficiency ๐Ÿ’…

            --L1-----
       BFR1 --L2----- BFR2
            --L3-----

 BIFT entry in BFR1:
 ------------------------------------------------------------------
 | Index |  Adjacencies                                           |
 ==================================================================
 | 0:6   |  ECMP({forward_connected(L1, BFR2),                    |
 |       |        forward_connected(L2, BFR2),                    |
 |       |        forward_connected(L3, BFR2)}, seed)             |
 ------------------------------------------------------------------

 BIFT entry in BFR2:
 ------------------------------------------------------------------
 | Index |  Adjacencies                                           |
 ==================================================================
 | 0:6   |  ECMP({forward_connected(L1, BFR1),                    |
 |       |        forward_connected(L2, BFR1),                    |
 |       |        forward_connected(L3, BFR1)}, seed)             |
 ------------------------------------------------------------------

Figure 10: ECMP Example ๐ŸŒธ

okay so this document doesn't standardize any ECMP algorithm ๐Ÿ™ˆ it's enough for implementations to document whichever ECMP algorithm they pick freely. BUT Figure 11 shows an example ECMP algorithm, and it doubles as documentation for that. basically a BIER-TE controller could figure out which adjacency gets chosen, based on the seed and adjacencies parameters, plus packet entropy โœจ

   forward(packet, ECMP(adj(0), adj(1),... adj(N-1), seed)):
      i = (packet(bier-header-entropy) XOR seed) % N
      forward packet to adj(i)

Figure 11: ECMP Algorithm Example ๐Ÿงš

in the example in Figure 12, all traffic from BFR1 towards BFR10 is meant to be ECMP load-split equally across the topology ๐Ÿฆ‹ this setup isn't meant to be a likely one, ngl. it's more about showing that ECMP can share BPs not only across link bundles but also across alternative paths through different transit BFRs. it also explains why the seed parameter exists ๐Ÿ’œ

                 BFR1         (BFIR)
               /L11  \L12
              /       \
          BFR2         BFR3
         /L21 \L22    /L31 \L32
        /      \     /      \
       BFR4  BFR5   BFR6  BFR7
        \      /     \      /
         \    /       \    /
          BFR8         BFR9
              \       /
               \     /
                BFR10         (BFER)

 BIFT entry in BFR1:
 ------------------------------------------------------------------
 | 0:6   |  ECMP({forward_connected(L11, BFR2),                   |
 |       |        forward_connected(L12, BFR3)}, seed1)           |
 ------------------------------------------------------------------

 BIFT entry in BFR2:
 ------------------------------------------------------------------
 | 0:7   |  ECMP({forward_connected(L21, BFR4),                   |
 |       |        forward_connected(L22, BFR5)}, seed1)           |
 ------------------------------------------------------------------

 BIFT entry in BFR3:
 ------------------------------------------------------------------
 | 0:7   |  ECMP({forward_connected(L31, BFR6),                   |
 |       |        forward_connected(L32, BFR7)}, seed1)           |
 ------------------------------------------------------------------

 BIFT entry in BFR4, BFR5:
 ------------------------------------------------------------------
 | 0:8   |  forward_connected(Lxx, BFR8)  |xx differs on BFR4/BFR5|
 ------------------------------------------------------------------

 BIFT entry in BFR6, BFR7:
 ------------------------------------------------------------------
 | 0:8   |  forward_connected(Lxx, BFR9)  |xx differs on BFR6/BFR7|
 ------------------------------------------------------------------

 BIFT entry in BFR8, BFR9:
 ------------------------------------------------------------------
 | 0:9   |  forward_connected(Lxx, BFR10) |xx differs on BFR8/BFR9|
 ------------------------------------------------------------------

Figure 12: Polarization Example ๐Ÿ“

quick heads up: for the ECMP chat below, only the BIFT ECMP() adjacencies on BFR1, BFR2, and BFR3 matter ๐Ÿ‘€ how BPs get reused across BFRs in this example is explained more in Section 5.1.9 below.

with the ECMP setup in that topology, traffic would NOT be equally load-split ๐Ÿ˜ญ instead, links L22 and L31 would see zero traffic. here's why: BFR2 only sees traffic from BFR1, and the ECMP hash in BFR1 picked the first of its two adjacencies, which was link L11-to-BFR2. then BFR2 does ECMP with two adjacencies on that subset of traffic using the same seed1, so it picks the first of its two adjacencies again: L21-to-BFR4. so L22 and BFR5 see no traffic (same deal for L31 and BFR6) ๐Ÿ’€

this issue in BFR2/BFR3 is called "polarization" ๐Ÿ”ฅ it happens because the same hash function gets reused across multiple consecutive hops in topologies like these. the fix is to set up the ECMP() adjacency on BFR1 with a different seed2 than the ECMP() adjacencies on BFR2/BFR3. BFR2/BFR3 can keep using the same hash, because packets won't pass through both of them one after the other. that means they can also use the same BP (i.e., 0:7) ๐Ÿ‘‘

one more thing ๐ŸŒˆ ECMP solutions outside of BIER often hide the seed by auto-selecting it from local entropy, like unique local or next-hop identifiers. letting the BIER-TE controller set the seed explicitly gives it the power to control whether consecutive ECMP hops pick the same path or different paths โœจ

5.1.8. Forward Routed Adjacencies ๐Ÿฆ‹

5.1.8.1. Reducing Bit Positions ๐Ÿงš

okay so forward_routed() adjacencies can cut down on the number of bit positions needed when path steering isn't hop-by-hop explicit path selection, and is loose-hop selection instead ๐Ÿ’– they can also allow BIER-TE operation across intermediate-hop routers that don't support BIER-TE ๐Ÿซถ

say the requirement in Figure 13 is to explicitly steer traffic flows that arrived at BFR1 or BFR4 via a path in the routing underlay "Network Area 1" towards one of these three next segments: (1) BFR2 via link L1, (2) BFR2 via link L2, or (3) via BFR3, without caring whether the packet goes out via L3 or L4 ๐Ÿ’…

                  ...............
        ...BFR1--...           ...--L1-- BFR2...
                 ... .Routers. ...--L2--/
        ...BFR4--...           ...--L3-- BFR3...
                 ...           ...--L4--/ |
                  ...............         |
                                         LO
                   Network Area 1

Figure 13: Forward Routed Adjacencies Example ๐ŸŒธ

to make this work, both BFR1 and BFR4 get set up with a forward_routed() adjacency bit position pointing at BFR2's address on link L1, another forward_routed() bit position pointing at BFR2's address on link L2, and a third forward_routed() bit position pointing at BFR3's node address LO ๐ŸŽ€

5.1.8.2. Supporting Nodes without BIER-TE ๐ŸŒˆ

forward_routed() adjacencies also make incremental BIER-TE deployment possible ๐Ÿฅน only the nodes that BIER-TE traffic actually needs to be steered through (with or without replication) need to support BIER-TE. where those nodes aren't directly connected to each other, forward_routed() adjacencies get used to pass over nodes that aren't BIER-TE enabled ๐Ÿ“

5.1.9. Reuse of Bit Positions (without DNC) โ™ป๏ธ

okay so BPs can be reused across multiple BFRs, which means the controller needs fewer BPs overall ๐Ÿ’… This happens when adjacencies on multiple BFRs use the DNC flag as described above, but it can also be done for non-DNC adjacencies. This section only talks about the non-DNC case.

Because a given BP is cleared when a packet passes a BFR with an adjacency for that BP, reusing BPs across multiple BFRs does not cause any problems with duplicates or loops that wouldn't also exist when every adjacency has a unique BP ๐Ÿซถ So the real challenge when reusing BPs is whether the desired Tree Engineering goals can still be achieved. ๐ŸŽฏ

A BP cannot be reused across two BFRs that would need to be passed sequentially for some path, because the first BFR will clear the BP and those paths cannot be built ๐Ÿ™ˆ A BP can be set across BFRs that would only occur across (A) different paths or (B) different branches of the same tree.

An example of (A) was given in Figure 12, where BP 0:7, BP 0:8, and BP 0:9 are each reused across multiple BFRs, because a single packet/path would never be able to reach more than one BFR sharing the same BP โœจ

Now imagine the example was changed: BFR1 has no ECMP() adjacency for BP 0:6, but instead has BP 0:5 with forward_connected() to BFR2 and BP 0:6 with forward_connected() to BFR3. Packets with both BP 0:5 and BP 0:6 would now be able to reach both BFR2 and BFR3 ๐Ÿฆ‹ The still-existing reuse of BP 0:7 between BFR2 and BFR3 is a case of (B), and it's perfect there because it doesn't limit the set of useful path choices, as in the following example.

If, instead of reusing BP 0:7, BFR3 used a separate BP 0:10 for its ECMP() adjacency, no useful additional path steering options would be enabled ๐Ÿ™„ If duplicates at BFR10 were undesirable, this would be handled by not setting BP 0:5 and BP 0:6 for the same packet. If the duplicates were desirable (e.g., resilient transmission), the additional BP 0:10 would also not add any value.

Reuse can also save BPs in bigger topologies ๐ŸŒˆ Check out the topology shown in Figure 14.

                      area1
                  BFR1a BFR1b
                    /    \
       ....................................
       .                Core              .
       ....................................
       |    /       \    /           \  |
     BFR2a BFR2b  BFR3a BFR3b      BFR6a BFR6b
      /-------\   /---------\      /--------\
      | area2 |   |  area3  | ...  | area6  |
      | ring  |   |  ring   |      | ring   |
      \-------/   \---------/      \--------/
      more BFRs    more BFRs        more BFRs

                      Figure 14: Reuse of BPs

So here's the vibe: a BFIR/sender (e.g., video headend) is attached to area 1, and areas 2...6 are full of receivers/BFERs ๐Ÿ’– Each area has a distribution ring, and each ring has two BPs to indicate the direction (as explained before). Those same two BPs could be reused across all five areas. Packets get replicated through other BPs from the core to the desired subset of areas, and once a packet copy reaches an area's ring, the two ring BPs come into play. This reuse is a case of (B), but it does limit the topology choices: packets can only flow around the same direction in the rings of all areas ๐Ÿ‘€ Whether that's okay depends on the desired path steering options. If resilient transmission is the path engineering goal, it's likely a good optimization. But if the bandwidth of each ring were to be optimized separately, it would not be a good limitation. ๐Ÿ’…

5.1.10. Summary of BP Optimizations ๐Ÿ

In this section, we went over a bunch of techniques a BIER-TE controller can use to build a BIER-TE topology in a way that minimizes the number of BPs it needs ๐Ÿงš

Without any optimization, a BIER-TE controller would try to map the network subnet topology 1:1 into the BIER-TE topology. Every adjacent neighbor in the subnet would need a forward_connected() BP, and every BFER would need a local_decap() BP ๐Ÿ˜ญ

The optimizations described in this document are as follows:

  1. P2P links require only one BP (Section 5.1.1).
  2. All leaf BFERs can share a single local_decap() BP (Section 5.1.3).
  3. A LAN with N BFRs needs at most N BPs (one for each BFR). It only needs one BP for all those BFRs that are not redundantly connected to multiple LANs (Section 5.1.4).
  4. A hub with P2P connections to multiple non-leaf BFER spokes can share one BP with all of the spokes if traffic can be flooded to all of those spokes, e.g., because of no bandwidth concerns or dense receiver sets (Section 5.1.5).
  5. Rings of BFRs can be built with just two BPs (one for each direction), except for BFRs with multiple ring connections -- similar to LANs (Section 5.1.6).
  6. ECMP() adjacencies to N neighbors can replace N BPs with one BP. Multihop ECMP can avoid polarization through different seeds of the ECMP algorithm (Section 5.1.7).
  7. Forward_routed() adjacencies permit "tunneling" across routers that are either BIER-TE capable or not BIER-TE capable, where no traffic steering or replications are required (Section 5.1.8).
  8. A BP can generally be reused across a set of nodes where it can be guaranteed that no path will ever need to traverse more than one node of the set. Depending on the scenario, this may limit the feasible path steering options (Section 5.1.9).

Note that this list of optimizations is not exhaustive โš ๏ธ Further optimizations of BPs are possible, especially when both the set of required path steering choices and the possible subsets of BFERs that should be able to receive traffic are limited. The hub-and-spoke optimization is a simple example of these traffic-pattern-dependent optimizations. ๐Ÿ“

5.2. Avoiding Duplicates and Loops ๐Ÿ”

5.2.1. Loops

Whenever BIER-TE creates a copy of a packet, the BitString of that copy will have all bit positions cleared that are associated with adjacencies on the BFR. This is what stops packets from looping ๐Ÿ™Œ The only exceptions are adjacencies with DNC set.

With DNC set, looping can happen ๐Ÿ˜ฑ Look at Figure 15: link L4 from BFR3 is (inadvertently) plugged into the L1 interface of BFRa (instead of BFR2). This creates a loop where the ring's clockwise bit position is never cleared for copies of the packets traveling clockwise around the ring.

                  v        v
                  |        |
           L1     |   L2   |   L3
       /-------- BFRa ---- BFRb ---------------------\
       |        .                                    |
       |         ......  Wrong link wiring           |
       |               .                             |
       \- BFR1 - BFR2   BFR3 - ... - BFR29 - BFR30 -/
           |      |    L4               |      |
        p33|                         p15|
           BFRd                       BFRc

                  Figure 15: Miswired Ring Example

To stop looping even when the physical wiring is messed up, only forward_connected() adjacencies are permitted to have DNC set. On top of that, the link layer port unique unicast destination address of the adjacency (e.g., "Media Access Control" (MAC) address) protects against closing the loop ๐Ÿ›ก๏ธ Link layers without port unique link layer addresses should not be used with the DNC flag set.

5.2.2. Duplicates

Duplicates happen when the graph expressed by a BitString is not a tree, but is redundantly connecting BFRs with each other ๐Ÿ‘ฏ In Figure 16, a BitString of p2,p3,p4,p5 would result in duplicate packets arriving on BFER4. So the BIER-TE controller must therefore ensure that only BitStrings that are trees are created. ๐ŸŒณ

                BFIR1
               /    \
              / p2   \ p3
             BFR2   BFR3
              \ p4   / p5
               \    /
                BFER4

                   Figure 16: Duplicates Example

If links get incorrectly reconnected physically before the BIER-TE controller updates BitStrings in BFIRs, duplicates can happen. Just like with loops, these can be inhibited by link layer addressing in forward_connected() adjacencies.

If interface or loopback addresses used in forward_routed() adjacencies are moved from one BFR to another, duplicates are equally likely to happen ๐Ÿ˜ฌ Readdressing operations like that must be coordinated with the BIER-TE controller.

5.3. Managing SIs, Subdomains, and BFR-ids ๐ŸŽ€

When the number of bits needed to represent the necessary hops in the topology and BFERs goes over the supported "BitStringLength" (BSL), multiple SIs and/or subdomains must be used. This section explains how that's done.

BIER-TE forwarding doesn't need the concept of BFR-ids, but routing underlay, flow overlay, and BIER headers might. This section also covers how BFR-ids can be assigned to BFIRs/BFERs for BIER-TE.

5.3.1. Why SIs and Subdomains? ๐Ÿค”

For (non-TE) BIER and BIER-TE forwarding, the biggest takeaway about using multiple SIs and/or subdomains is the same: multicast flow overlay packets that need to go to BFERs in different SIs or subdomains need multiple BIER packets, each one with a BitString for a different (SI,subdomain) combination. Each of those BitStrings uses one BSL-sized SI block in the BIFT of the subdomain. We call this a BIFT:SI (block) ๐Ÿงฉ

SIs and subdomains have different purposes in the BIER architecture and also in the BIER-TE architecture. This affects how operators manage them, and especially how flow overlays will likely use them ๐Ÿ’…

By default, every possible BFIR/BFER in a BIER network would likely be given a BFR-id in subdomain 0 (unless there are > 64k BFIRs/BFERs).

If there are different flow services (or service instances) that require replication to different subsets of BFERs, then it will likely not be possible to get the best replication efficiency for all of those service instances via subdomain 0 ๐Ÿ˜ฉ Ideal replication efficiency for N BFERs exists in a subdomain if they are split over no more than ceiling(N/BitStringLength) SIs.

If service instances justify additional BIER:SI state in the network, additional subdomains will be used. BFIRs/BFERs get assigned BFR-ids in those subdomains, and each service instance is configured to use the most appropriate subdomain โœจ This results in improved replication efficiency for different services.

Even if creating subdomains and assigning BFR-ids to BFIRs/BFERs in those subdomains is automated, it is not expected that individual service instances can deal with BFERs in different subdomains. A service instance may only support configuration of a single subdomain, and it should rely on that one ๐Ÿซ 

To be able to easily reuse (and modify as little as possible) existing BIER procedures (including flow overlay and routing underlay) when BIER-TE forwarding is added, we therefore reuse SIs and subdomains logically in the same way they're used in BIER ๐Ÿฆ‹ So all necessary BFIRs/BFERs for a service use a single BIER-TE BIFT and are split across as many SIs as necessary (see Section 5.3.2). Different services may use different subdomains that primarily exist to provide more efficient replication (and, for BIER-TE, desirable path steering) for different subsets of BFIRs/BFERs. ๐ŸŒธ

5.3.2. Assigning Bits for the BIER-TE Topology โœจ

okay so in plain BIER, BitStrings only need bits for the BFERs ๐Ÿ’– which means the model is super clean: every BFR-id maps 1:1 to one bit in a BitString ๐ŸŽ€

in BIER-TE it's a whole different vibe ๐Ÿฆ‹ BitStrings have to carry bits for the receiving BFER AND the intermediate hops/links the packet has to cross ๐Ÿ›ฃ๏ธ so the max number of BFERs you can fit in one BitString or BIFT:SI depends on how many bits you need to describe the topology between them ๐Ÿงš

"desired" topology is the key phrase here, bestie ๐Ÿ‘‘ it depends on the physical topology AND what the operator wants to do with it:

  1. permit explicit path steering across every single hop (which needs more bits) ๐Ÿ”ฅ, or
  2. cut down on the bits you need by using optimizations like unicast (forward_routed()), ECMP(), or flood (DNC) over "uninteresting" sub-parts of the topology ๐ŸŒธ, e.g., parts where, for path steering reasons, different trees don't need to take different paths ๐Ÿ™ˆ

the total number of topology bits vs. the number of BFERs in a BIFT:SI can vary wildly ๐Ÿ’€ it depends on how big the topology is and how many alternative paths it has โœจ and in a BIER-TE topology crafted by a BIER-TE expert, the higher the percentage of non-BFER bits, the more likely those extra bits aren't just BIER-TE overhead with no payoff ๐Ÿ˜ญ they actually unlock desirable path steering alternatives ๐Ÿ’…

5.3.3. Assigning BFR-ids with BIER-TE ๐Ÿฆ‹

BIER-TE forwarding doesn't use BFR-ids ๐Ÿ™…โ€โ™€๏ธ and it doesn't require the BFIR-id field of the BIER header to be set to any particular value ๐ŸŒˆ BUT other parts of a BIER-TE deployment might need a BFR-id, specifically multicast flow overlay signaling and multicast flow overlay packet disposition ๐ŸŽ€ so in that case, BFRs also need BFR-ids for BIER-TE SDs ๐Ÿ’œ

for example, BIER overlay signaling needs BFIRs to have a BFR-id ๐Ÿซถ because that BFIR BFR-id gets carried in the BFIR-id field of the BIER header, and that's how the overlay signaling on the receiving BFER knows which BFIR sent the packet ๐Ÿ“ฌ

in BIER, BFR-id = SI * BSL + BP ๐Ÿงฎ so the SI and BP of a BFER can be calculated from the BFR-id and vice versa โœจ this also means every BFR with a BFR-id has a reserved BP in an SI, even if BIER forwarding doesn't strictly need it ๐Ÿ™ƒ because that BFR might never be a BFER (it'll only ever be a BFIR) ๐Ÿ’…

in BIER-TE, a non-leaf BFER usually has a single BP with a local_decap() adjacency on the BFER ๐Ÿ“ so its BFR-id can be worked out the same way as non-TE BIER: BFR-id = SI * BSL + BP ๐Ÿ‘‘

as explained in Section 5.1.3, leaf BFERs don't need that unique local_decap() adjacency ๐ŸŒธ and BFIRs that aren't also BFERs might not have a unique local_decap() adjacency either ๐Ÿคทโ€โ™€๏ธ so for all those BFIRs and (leaf) BFERs, the controller needs to figure out unique BFR-ids that don't collide with the ones derived from the non-leaf BFER local_decap() BPs ๐Ÿ”ฅ

this document doesn't put any requirements on how those BFR-ids get allocated ๐Ÿซ  but a simple option is to derive one from the (SI,BP) of an adjacency that's unique to that BFR โœจ for a BFIR, that can be the first adjacency that's only populated on that BFIR ๐Ÿ’– for a leaf BFER, it could be the first BP with an adjacency towards that BFER ๐Ÿงš

5.3.4. Mapping from BFRs to BitStrings with BIER-TE ๐ŸŒˆ

in BIER, applications of the flow overlay on a BFIR can work out the (SI,BP) of a BFER from that BFER's BFR-id ๐Ÿง  so they can easily figure out the BitStrings for a BIER packet going to a set of BFERs with known BFR-ids ๐Ÿ’…

in BIER-TE, this mapping needs to be just as well supported for flow overlays ๐Ÿซถ this section lays out two core options, depending on what type of Tree Engineering the BIER-TE controller needs to do for a given application ๐ŸŽ€

"Independent branches": for a given flow overlay instance, the branches from a BFIR to every BFER are calculated by the BIER-TE controller to be independent of the branches to any other BFER ๐Ÿฆ‹ shortest path trees are the most common examples of trees with independent branches ๐Ÿ›ฃ๏ธ

"Interdependent branches": when a BFER gets added to or deleted from a particular distribution tree, the BIER-TE controller has to recalculate the branches to the other BFERs, because they might need to change ๐Ÿ˜ญ Steiner trees are examples of interdependent branch trees ๐ŸŒธ

if "independent branches" are used, the BIER-TE controller can signal to the BFIR flow overlay, for every BFER, a SI:BitString that represents the branch to that BFER ๐Ÿ’œ the flow overlay on the BFIR can then calculate the SI:BitString for all the desired BFERs by ORing their BitStrings, all on its own without asking the controller ๐Ÿ”ฅ this means flow overlay applications can work independently of the controller whenever they need to figure out which subset of BFERs should get a particular packet ๐Ÿ‘‘

if "interdependent branches" are required, an application would need to query the SI:BitString for a given set of BFERs every time that set changes ๐Ÿ™ˆ

note that in either case (unlike with BIER), the bits may need to change when links or nodes fail or recover, when the network expands, or when other traffic consumes network resources as part of achieving Traffic Engineering goals (e.g., reoptimizing lower-priority traffic flows) ๐Ÿ’€ so the interactions between those BFIR applications and the BIER-TE controller do need to support dynamic updates to the SIs:BitStrings ๐Ÿ”„โœจ

communication between the BFIR flow overlay and the BIER-TE controller needs some way to identify the BFERs ๐Ÿซถ if BFR-ids are used in the deployment, as outlined in Section 5.3.3, then those are the "natural" BFR-ids ๐ŸŽ€ if BFR-ids aren't used, then any other unique identifier, like a BFR's BFR-prefix [RFC8279], could be used ๐Ÿฆ‹

5.3.5. Assigning BFR-ids for BIER-TE ๐Ÿ’…

it isn't currently decided whether a single subdomain could or should be allowed to forward both (non-TE) BIER and BIER-TE packets ๐Ÿค” if that should be supported, there are two options:

A. BIER and BIER-TE have different BFR-ids in the same subdomain ๐ŸŒˆ this gives BIER higher replication efficiency, because the BIER BFR-ids can be assigned sequentially, while the BitStrings for BIER-TE also have to assign the extra bits for the topology adjacencies ๐Ÿ˜ค there's no relationship between a BFR's BIER BFR-id and its BIER-TE BFR-id ๐Ÿ™…โ€โ™€๏ธ

B. BIER and BIER-TE share the same BFR-id ๐Ÿ’œ the BFR-ids get assigned as explained above for BIER-TE and then just reused for BIER ๐Ÿ” the replication efficiency for BIER ends up being as low as it is for BIER-TE in this approach ๐Ÿ’€

5.3.6. Example Bit Allocations ๐Ÿ“

5.3.6.1. With BIER ๐ŸŒธ

okay picture this: a network setup with a BSL of 256 for the topology in Figure 17 โœจ it has six areas, each with 170 BFERs, all connecting through a core with four (core) BFRs ๐Ÿฐ to address all the BFERs with BIER, you need four SIs ๐Ÿ”ฅ and to send a BIER packet to all BFERs in the network, the BFIR has to send four copies ๐Ÿ“ฆ on the BFIR, it doesn't matter how the BFR-ids are allocated to BFERs, but it totally matters for efficiency further down the network ๐Ÿ˜ญ

Figure 17: Scaling BIER-TE Bits by Reuse

            area1           area2        area3
          BFR1a BFR1b  BFR2a BFR2b   BFR3a BFR3b
            |  \         /    \        /  |
            ................................
            .                Core          .
            ................................
            |    /       \    /        \  |
          BFR4a BFR4b  BFR5a BFR5b   BFR6a BFR6b
           area4          area5        area6

              Figure 17: Scaling BIER-TE Bits by Reuse

with random allocation of BFR-ids to BFERs, each receiving area would (most likely) have to receive all four copies of the BIER packet ๐Ÿ˜ฉ because there'd be BFR-ids for each of the four SIs in each area ๐Ÿ’€ the duplication would only start to subside further toward each BFER, once each of the four trees runs out of branches ๐ŸŒฟ

if BFR-ids are allocated intelligently, then all the BFERs in an area get BFR-ids with as few different SIs as possible ๐Ÿง โœจ each area would then only have to forward one or two packets instead of four ๐Ÿ™Œ

given how networks grow over time, replication efficiency in an area also goes down over time when BFR-ids are only allocated sequentially, network wide ๐Ÿ“‰ an area that starts out with BFR-ids in just one SI might end up with many SIs after a longer period of growth ๐Ÿ˜ฌ allocating SIs to areas that initially have plenty of spare bits for growth can help with this ๐Ÿซถ alternatively, BFERs can be renumbered after network expansion ๐Ÿ”ข in this example, you could consider using six SIs and assigning one to each area ๐Ÿ’–

this example shows that intelligent BFR-id allocation within at least subdomain 0 can be helpful, or even necessary, in BIER ๐Ÿ‘‘๐ŸŒˆ

5.3.6.2. With BIER-TE โœจ

okay so in BIER-TE, you have to pick out a subset of the physical topology and the attached BFERs so that the "desired" version of that topology and those BFERs fits into one single BitString ๐Ÿงฉ. Then you keep doing this until the whole topology is covered ๐Ÿ’….

Once the bits/SIs are assigned to the topology and BFERs, the BFR-ids are just a derived set of identifiers from the operator / BIER-TE controller, like we talked about above ๐ŸŽ€.

Real talk though: whenever different subtopologies overlap, bits have to get repeated across the BitStrings, so the total number of bits across all BitStrings/SIs goes up ๐Ÿ“ˆ. The worst case is when you assign random subsets of BFERs to different SIs ๐Ÿ’€. That is way worse than in (non-TE) BIER, because it maximizes the unnecessary topology overlap across SIs, which cuts down the number of BFERs you can reach across each individual SI. Smart BFER-to-SI assignment and picking specific "desired" subtopologies can fix most of that ๐Ÿซถ.

To set up BIER-TE efficiently for the topology in Figure 17, you can use the following bit allocation method. It's easy to expand to other, similarly structured larger topologies ๐ŸŒˆ.

Each area gets one or more SIs, depending on the number of future expected BFERs and the number of bits the topology in that area needs. In this example, six SIs are used, one per area ๐Ÿ“.

On top of that, we use four bits in each SI:

  • bia: (b)it (i)ngress (a)
  • bib: (b)it (i)ngress (b)
  • bea: (b)it (e)gress (a)
  • beb: (b)it (e)gress (b)

These bits pass BIER packets from any BFIR, via any combination of ingress area a/b BFRs and egress area a/b BFRs, into a specific target area. Then these bits get set up with the right forward_routed() adjacencies on the BFIRs and area edge BFRs, like so:

On all BFIRs in an area, j|j=1...6, bia in each BIFT:SI is populated with the same forward_routed(BFRja), and bib with forward_routed(BFRjb). On all area edge BFRs, bea in BIFT:SI=k|k=1...6 is populated with forward_routed(BFRka), and beb in BIFT:SI=k with forward_routed(BFRkb).

For BIER-TE forwarding of a packet to a subset of BFERs across all areas, a BFIR would create at most six copies, with SI=1...SI=6. In each packet, the BitString includes bits for one area and the BFERs in that area, plus the four bits that indicate whether to pass the packet via the ingress area a or b border BFR and the egress area a or b border BFR. That gives path steering for those two "unicast" legs: 1) BFIR to ingress area edge and 2) core to egress area edge. Replication only happens inside the egress areas. For BFERs that are in the same area as the BFIR, these four bits are not used ๐Ÿฆ‹.

5.3.7. Summary

BIER-TE can, like BIER, support multiple SIs within a subdomain. This allows the mapping BFR-id = SI * BSL + BP. It also keeps the BIER architecture concept of BFR-ids, so there's minimal BIER-TE-specific stuff needed in possible BIER layer control plane mechanisms with BIER-TE, including flow overlay methods and BIER header fields ๐Ÿงš.

The number of BFIRs/BFERs possible in a subdomain is smaller than in BIER, because BIER-TE uses additional bits for the topology ๐Ÿ˜ญ.

Subdomains in BIER-TE can be used just like they are in BIER, to create more efficient replication to known subsets of BFERs ๐Ÿ’œ.

Assigning bits for BFERs intelligently into the right SI matters more in BIER-TE than in BIER, because of replication efficiency and the overall number of bits required ๐Ÿ‘‘.

6. Security Considerations ๐Ÿ”ฅ

If "Encapsulation for Bit Index Explicit Replication (BIER) in MPLS and Non-MPLS Networks" [RFC8296] is used, its security considerations also apply to BIER-TE.

The security considerations of "Multicast Using Bit Index Explicit Replication (BIER)" [RFC8279] also apply to BIER-TE, with the following overriding or additional considerations.

BIER-TE forwarding explicitly supports unicast "tunneling" of BIER packets via forward_routed() adjacencies. The BIER domain security model is based on a subset of interfaces on a BFR that connect to other BFRs of the same BIER domain. For BIER-TE, this security model applies equally to such unicast "tunneled" BIER packets. That includes the need to filter received unicast "tunneled" BIER packets, to prohibit the injection of such "tunneled" BIER packets from outside the BIER domain, and also the need to prohibit forward_routed() adjacencies from leaking BIER packets out of the BIER domain. It SHOULD be possible to configure interfaces to be part of a BIER domain solely for sending and receiving unicast "tunneled" BIER packets, even if the interface cannot send/receive BIER encapsulated packets ๐Ÿ›ก๏ธ.

In BIER, the standardized methods for the routing underlays are IGPs with extensions to distribute BFR-ids and BFR-prefixes. [RFC8401] specifies the extensions for IS-IS, and [RFC8444] specifies the extensions for OSPF. Attacking the protocols for the BIER routing underlay or the (non-TE) BIER layer control plane, or impairing any BFRs in a domain, may lead to successful attacks against the information that BIER-TE learns from the routing protocol (routes, next hops, BFR-ids, ...). That enables DoS attacks against paths or against the addressing (BFR-ids, BFR-prefixes) used by BIER ๐Ÿšจ.

The reference model for the BIER-TE layer control plane is a BIER-TE controller. When such a controller is used, impairing an individual BFR in a domain causes no impairment of the BIER-TE control plane on other BFRs. If a routing protocol is used to support forward_routed() adjacencies, then this is still an attack vector as in BIER, but only for BIER-TE forward_routed() adjacencies and not other adjacencies ๐Ÿ™ˆ.

Whereas IGP routing protocols are most often not well secured through cryptographic authentication and confidentiality, communications between controllers and routers, such as those to be considered for the BIER-TE controller / control plane, can be, and are, much more commonly secured with those security properties. For example, by using "Secure Shell" (SSH) [RFC4253] for NETCONF [RFC6242], or via "Transport Layer Security" (TLS), such as [RFC8253] for PCEP [RFC5440] or [RFC7589] for NETCONF. BIER-TE controllers SHOULD use security equal to or better than these mechanisms ๐Ÿ”.

When any of these security mechanisms/protocols are used for communications between a BIER-TE controller and BFRs, their security considerations apply to BIER-TE. In addition, the security considerations of "A Path Computation Element (PCE)-Based Architecture" [RFC4655] apply.

The most important attack vector in BIER-TE is misconfiguration, either on the BFRs themselves or via the BIER-TE controller. Forwarding entries with DNC could be set up to create persistent loops, in which packets only expire because of TTL. ๐Ÿ˜ฑ To minimize the impact of such attacks (or, more likely, unintentional misconfiguration by operators and/or bad BIER-TE controller software), the BIER-TE forwarding rules are defined to be as strict in clearing bits as possible. Clearing all bits with an adjacency on a BFR stops a looping packet from creating additional packet amplification through the misconfigured loop on its second or subsequent times around the loop, because all relevant adjacency bits would have been cleared on the first round through the loop. As a result, looping packets can occur in BIER-TE to the same degree as is possible with unintentional or malicious loops in the routing underlay with BIER, or even with unicast traffic ๐ŸŒ€.

Deployments where BIER-TE would likely be beneficial may include operational models where actual configuration changes from the controller are only required during non-production phases of the network's life cycle, e.g., in embedded networks or in manufacturing networks during activities such as plant reworking or repairs. In these types of deployments, configuration changes could be locked out when the network is in production state, and could only be (re-)enabled by reverting the network/installation to non-production state. Such security designs would not only allow a deployment to provide additional layers of protection against configuration attacks, but would, first and foremost, protect the active production process from such configuration attacks ๐Ÿญ.

7. IANA Considerations ๐ŸŒธ

This document has no IANA actions.

8. References ๐Ÿ“š

8.1. Normative References

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119,
           DOI 10.17487/RFC2119, March 1997,
           <https://www.rfc-editor.org/info/rfc2119>.

[RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
           2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
           May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8279]  Wijnands, IJ., Ed., Rosen, E., Ed., Dolganow, A.,
           Przygienda, T., and S. Aldrin, "Multicast Using Bit Index
           Explicit Replication (BIER)", RFC 8279,
           DOI 10.17487/RFC8279, November 2017,
           <https://www.rfc-editor.org/info/rfc8279>.

[RFC8296]  Wijnands, IJ., Ed., Rosen, E., Ed., Dolganow, A.,
           Tantsura, J., Aldrin, S., and I. Meilik, "Encapsulation
           for Bit Index Explicit Replication (BIER) in MPLS and Non-
           MPLS Networks", RFC 8296, DOI 10.17487/RFC8296, January
           2018, <https://www.rfc-editor.org/info/rfc8296>.

8.2. Informative References

[BIER-MCAST-OVERLAY] Trossen, D., Rahman, A., Wang, C., and T. Eckert, "Applicability of BIER Multicast Overlay for Adaptive Streaming Services", Work in Progress, Internet-Draft, draft-ietf-bier-multicast-http-response-06, 10 July 2021, https://datatracker.ietf.org/doc/html/draft-ietf-bier-multicast-http-response-06.

[BIER-TE-PROTECTION] Eckert, T., Cauchie, G., Braun, W., and M. Menth, "Protection Methods for BIER-TE", Work in Progress, Internet-Draft, draft-eckert-bier-te-frr-03, 5 March 2018, https://datatracker.ietf.org/doc/html/draft-eckert-bier-te-frr-03.

[BIER-TE-YANG] Zhang, Z., Wang, C., Chen, R., Hu, F., Sivakumar, M., and H. Chen, "A YANG data model for Tree Engineering for Bit Index Explicit Replication (BIER-TE)", Work in Progress, Internet-Draft, draft-ietf-bier-te-yang-05, 1 May 2022, https://datatracker.ietf.org/doc/html/draft-ietf-bier-te-yang-05.

[Bloom70] Bloom, B. H., "Space/time trade-offs in hash coding with allowable errors", Comm. ACM 13(7):422-6, DOI 10.1145/362686.362692, July 1970, https://dl.acm.org/doi/10.1145/362686.362692.

[CONSTRAINED-CAST] Bergmann, O., Bormann, C., Gerdes, S., and H. Chen, "Constrained-Cast: Source-Routed Multicast for RPL", Work in Progress, Internet-Draft, draft-ietf-roll-ccast-01, 30 October 2017, https://datatracker.ietf.org/doc/html/draft-ietf-roll-ccast-01.

[ICC] Reed, M. J., Al-Naday, M., Thomos, N., Trossen, D., Petropoulos, G., and S. Spirou, "Stateless multicast switching in software defined networks", IEEE International Conference on Communications (ICC), Kuala Lumpur, Malaysia, DOI 10.1109/ICC.2016.7511036, May 2016, https://ieeexplore.ieee.org/document/7511036.

[NON-MPLS-BIER-ENCODING] Wijnands, IJ., Mishra, M., Xu, X., and H. Bidgoli, "An Optional Encoding of the BIFT-id Field in the non-MPLS BIER Encapsulation", Work in Progress, Internet-Draft, draft-ietf-bier-non-mpls-bift-encoding-04, 30 May 2021, https://datatracker.ietf.org/doc/html/draft-ietf-bier-non-mpls-bift-encoding-04.

[RCSD94] Zhang, H. and D. Ferrari, "Rate-Controlled Service Disciplines", Journal of High Speed Networks, Volume 3, Issue 4, pp. 389-412, DOI 10.3233/JHS-1994-3405, October 1994, https://content.iospress.com/articles/journal-of-high-speed-networks/jhs3-4-05.

[RFC4253] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH) Transport Layer Protocol", RFC 4253, DOI 10.17487/RFC4253, January 2006, https://www.rfc-editor.org/info/rfc4253.

[RFC4456] Bates, T., Chen, E., and R. Chandra, "BGP Route Reflection: An Alternative to Full Mesh Internal BGP (IBGP)", RFC 4456, DOI 10.17487/RFC4456, April 2006, https://www.rfc-editor.org/info/rfc4456.

[RFC4655] Farrel, A., Vasseur, J.-P., and J. Ash, "A Path Computation Element (PCE)-Based Architecture", RFC 4655, DOI 10.17487/RFC4655, August 2006, https://www.rfc-editor.org/info/rfc4655.

[RFC5440] Vasseur, JP., Ed. and JL. Le Roux, Ed., "Path Computation Element (PCE) Communication Protocol (PCEP)", RFC 5440, DOI 10.17487/RFC5440, March 2009, https://www.rfc-editor.org/info/rfc5440.

[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., "Network Configuration Protocol (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011, https://www.rfc-editor.org/info/rfc6241.

[RFC6242] Wasserman, M., "Using the NETCONF Protocol over Secure Shell (SSH)", RFC 6242, DOI 10.17487/RFC6242, June 2011, https://www.rfc-editor.org/info/rfc6242.

[RFC7589] Badra, M., Luchuk, A., and J. Schoenwaelder, "Using the NETCONF Protocol over Transport Layer Security (TLS) with Mutual X.509 Authentication", RFC 7589, DOI 10.17487/RFC7589, June 2015, https://www.rfc-editor.org/info/rfc7589.

[RFC7752] Gredler, H., Ed., Medved, J., Previdi, S., Farrel, A., and S. Ray, "North-Bound Distribution of Link-State and Traffic Engineering (TE) Information Using BGP", RFC 7752, DOI 10.17487/RFC7752, March 2016, https://www.rfc-editor.org/info/rfc7752.

[RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", RFC 7950, DOI 10.17487/RFC7950, August 2016, https://www.rfc-editor.org/info/rfc7950.

[RFC7988] Rosen, E., Ed., Subramanian, K., and Z. Zhang, "Ingress Replication Tunnels in Multicast VPN", RFC 7988, DOI 10.17487/RFC7988, October 2016, https://www.rfc-editor.org/info/rfc7988.

[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017, https://www.rfc-editor.org/info/rfc8040.

[RFC8253] Lopez, D., Gonzalez de Dios, O., Wu, Q., and D. Dhody, "PCEPS: Usage of TLS to Provide a Secure Transport for the Path Computation Element Communication Protocol (PCEP)", RFC 8253, DOI 10.17487/RFC8253, October 2017, https://www.rfc-editor.org/info/rfc8253.

[RFC8345] Clemm, A., Medved, J., Varga, R., Bahadur, N., Ananthakrishnan, H., and X. Liu, "A YANG Data Model for Network Topologies", RFC 8345, DOI 10.17487/RFC8345, March 2018, https://www.rfc-editor.org/info/rfc8345.

[RFC8401] Ginsberg, L., Ed., Przygienda, T., Aldrin, S., and Z. Zhang, "Bit Index Explicit Replication (BIER) Support via IS-IS", RFC 8401, DOI 10.17487/RFC8401, June 2018, https://www.rfc-editor.org/info/rfc8401.

[RFC8402] Filsfils, C., Ed., Previdi, S., Ed., Ginsberg, L., Decraene, B., Litkowski, S., and R. Shakir, "Segment Routing Architecture", RFC 8402, DOI 10.17487/RFC8402, July 2018, https://www.rfc-editor.org/info/rfc8402.

[RFC8444] Psenak, P., Ed., Kumar, N., Wijnands, IJ., Dolganow, A., Przygienda, T., Zhang, J., and S. Aldrin, "OSPFv2 Extensions for Bit Index Explicit Replication (BIER)", RFC 8444, DOI 10.17487/RFC8444, November 2018, https://www.rfc-editor.org/info/rfc8444.

[RFC8556] Rosen, E., Ed., Sivakumar, M., Przygienda, T., Aldrin, S., and A. Dolganow, "Multicast VPN Using Bit Index Explicit Replication (BIER)", RFC 8556, DOI 10.17487/RFC8556, April 2019, https://www.rfc-editor.org/info/rfc8556.

[TE-OVERVIEW] Farrel, A., Ed., "Overview and Principles of Internet Traffic Engineering", Work in Progress, Internet-Draft, draft-ietf-teas-rfc3272bis-21, 11 September 2022, https://datatracker.ietf.org/doc/html/draft-ietf-teas-rfc3272bis-21.


Appendix A. BIER-TE and Segment Routing (SR) ๐ŸŽ€

Okay so SR [RFC8402] is all about lightweight path steering using loose source routing ๐Ÿงš. Compared to its heavier older sibling, RSVP-TE, SR doesn't need per-path signaling to each of those hops. Iconic efficiency ๐Ÿ’….

BIER-TE brings that same design philosophy to multicast ๐Ÿฆ‹. Like SR, BIER-TE:

  • relies on source routing (via a BitString), and
  • only requires consideration of the "hops" either (1) on which replication has to happen or (2) across which the traffic should be steered (even without replication).

Any other hops can be skipped by using routed adjacencies โœจ.

BIER-TE "bit positions" (BPs) are basically the BIER-TE version of "forwarding segments" in SR ๐ŸŒธ. The vibe is different though, because forwarding segments in SR are global or local, while BPs in BIER-TE are scoped to one or more BFRs that have adjacencies for those BPs in their BIFTs. These can be called "adjacency-scoped" forwarding segments ๐Ÿ’œ.

Adjacency scope could be global, but then every BFR would need an adjacency for a given BP. For example, that could be a forward_routed() adjacency with encapsulation to the global SR "Segment Identifier" (SID) of the destination. Such a BP would always result in ingress replication, though (as in [RFC7988]) ๐Ÿ˜ญ. The first BFR that encounters this BP would directly replicate traffic on it. Only by using non-global adjacency scope for BPs can traffic be steered and replicated on a non-BFIR ๐Ÿ™ˆ.

SR can naturally be combined with BIER-TE and can help optimize it ๐Ÿ”ฅ. For example, instead of defining bit positions for non-replicating hops, it is equally possible to use SR encapsulations (e.g., SR-MPLS label stacks) for the encapsulation of forward_routed() adjacencies. Very efficient, very chic.

Also, (non-TE) BIER itself can be seen as being similar to SR ๐ŸŒˆ. BIER BPs act as global destination Node-SIDs, and the BIER BitString is simply a highly optimized way to indicate multiple such SIDs and let the network take care of replicating the packet hop by hop to each destination Node-SID. BIER doesn't allow the indication of intermediate hops or, in SR terms, the ability to indicate a sequence of SIDs to reach the destination. BIER-TE and its adjacency-scoped BPs, on the other hand, do provide those capabilities ๐Ÿ‘‘.

Acknowledgements

The authors would like to thank Greg Shepherd, IJsbrand Wijnands, Neale Ranns, Dirk Trossen, Sandy Zheng, Lou Berger, Jeffrey Zhang, Carsten Bormann, and Wolfgang Braun for their reviews and suggestions ๐Ÿซถ.

Special thanks to Xuesong Geng for shepherding this document ๐Ÿ’–. Special thanks also go to the IESG reviewers and their suggestions: Alvaro Retana (responsible AD/RTG), Benjamin Kaduk (SEC), Tommy Pauly (TSV), Zaheduzzaman Sarker (TSV), ร‰ric Vyncke (INT), Martin Vigoureux (RTG), Robert Wilton (OPS), Erik Kline (INT), Lars Eggert (GEN), Roman Danyliw (SEC), Ines Robles (RTGDIR), Robert Sparks (Gen-ART), Yingzhen Qu (RTGDIR), and Martin Duke (TSV) ๐ŸŒŸ.

Authors' Addresses

Toerless Eckert (editor)

Toerless Eckert (editor)
Futurewei Technologies Inc.
2330 Central Expy
Santa Clara, CA 95050
United States of America
Email: tte@cs.fau.de
Michael Menth
University of Tuebingen
Germany
Email: menth@uni-tuebingen.de
Gregory Cauchie
KOEVOO
France
Email: gregory@koevoo.tech

That's the whole thing, bestie ๐ŸŒˆ๐Ÿ’–

๐Ÿ“ฆ where this page comes from