RFC 2022

Support for Multicast over UNI 3.0/3.1 based ATM Networks

๐Ÿ“… published November 1996, from ietf

RFC 2022 ๐ŸŽ€ Support for Multicast over UNI 3.0/3.1 based ATM Networks.

Network Working Group ๐Ÿ’… Author: G. Armitage (Bellcore) ๐ŸŒธ Category: Standards Track ๐Ÿฆ‹ Date: November 1996 โœจ

Obsoletes / Updates: There's no Obsoletes or Updates line in this header, so there's nothing to flag there ๐Ÿ™ˆ

Status of This Memo ๐Ÿ“

Okay so this doc is an Internet standards track protocol for the Internet community, and it's literally asking everyone to discuss it and send suggestions for improvements ๐Ÿซถ. If you want the official standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐Ÿ’…. Distribution of this memo is unlimited, so share away ๐Ÿ’Œ

Abstract โœจ

Mapping the connectionless IP multicast service over the connection oriented ATM services provided by UNI 3.0/3.1 is no small task ๐Ÿ˜ญ. This memo describes a mechanism that supports the multicast needs of Layer 3 protocols in general, and it describes how that applies to IP multicasting in particular.

ATM based IP hosts and routers use a Multicast Address Resolution Server (MARS) to support RFC 1112 style Level 2 IP multicast over the ATM Forum's UNI 3.0/3.1 point to multipoint connection service ๐Ÿงš. Clusters of endpoints share a MARS and use it to track and spread the word about which nodes are receivers for given multicast groups. That lets endpoints set up and manage point to multipoint VCs when they transmit to the group ๐Ÿ‘‘.

The MARS behaviour lets Layer 3 multicasting run on either meshes of VCs or ATM level multicast servers. You can pick this on a per-group basis, and the endpoints don't have to care which one you picked ๐ŸŒˆ

Table of Contents ๐Ÿ“š

   1. Introduction.................................................   4
    1.1 The Multicast Address Resolution Server (MARS).............   5
    1.2 The ATM level multicast Cluster............................   5
    1.3 Document overview..........................................   6
    1.4 Conventions................................................   7
   2. The IP multicast service model...............................   7
   3. UNI 3.0/3.1 support for intra-cluster multicasting...........   8
    3.1 VC meshes..................................................   9
    3.2 Multicast Servers..........................................   9
    3.3 Tradeoffs..................................................  10
    3.4 Interaction with local UNI 3.0/3.1 signalling entity.......  11
   4. Overview of the MARS.........................................  12
    4.1 Architecture...............................................  12
    4.2 Control message format.....................................  12
    4.3 Fixed header fields in MARS control messages...............  13
      4.3.1 Hardware type..........................................  14
      4.3.2 Protocol type..........................................  14
      4.3.3 Checksum...............................................  15
      4.3.4 Extensions Offset......................................  15
      4.3.5 Operation code.........................................  16
      4.3.6 Reserved...............................................  16
   5. Endpoint (MARS client) interface behaviour...................  16
    5.1 Transmit side behaviour....................................  17
      5.1.1 Retrieving Group Membership from the MARS..............  18
      5.1.2 MARS_REQUEST, MARS_MULTI, and MARS_NAK messages........  20
      5.1.3 Establishing the outgoing multipoint VC................  22
      5.1.4 Monitoring updates on ClusterControlVC.................  24
        5.1.4.1 Updating the active VCs............................  24
        5.1.4.2 Tracking the Cluster Sequence Number...............  25
      5.1.5 Revalidating a VC's leaf nodes.........................  26
        5.1.5.1 When leaf node drops itself........................  27
        5.1.5.2 When a jump is detected in the CSN.................  27
      5.1.6 'Migrating' the outgoing multipoint VC.................  27
    5.2. Receive side behaviour....................................  29
      5.2.1 Format of the MARS_JOIN and MARS_LEAVE Messages........  30
        5.2.1.1 Important IPv4 default values......................  32
      5.2.2 Retransmission of MARS_JOIN and MARS_LEAVE messages....  33
      5.2.3 Cluster member registration and deregistration.........  34
    5.3 Support for Layer 3 group management.......................  34
    5.4 Support for redundant/backup MARS entities.................  36
      5.4.1 First response to MARS problems........................  36
      5.4.2 Connecting to a backup MARS............................  37
      5.4.3 Dynamic backup lists, and soft redirects...............  37
    5.5 Data path LLC/SNAP encapsulations..........................  40
      5.5.1 Type #1 encapsulation..................................  40
      5.5.2 Type #2 encapsulation..................................  41
      5.5.3 A Type #1 example......................................  42
   6. The MARS in greater detail...................................  42
    6.1 Basic interface to Cluster members.........................  43
      6.1.1 Response to MARS_REQUEST...............................  43
      6.1.2 Response to MARS_JOIN and MARS_LEAVE...................  43
      6.1.3 Generating MARS_REDIRECT_MAP...........................  45
      6.1.4 Cluster Sequence Numbers...............................  45
    6.2 MARS interface to Multicast Servers (MCSs).................  46
      6.2.1 MARS_REQUESTs for MCS supported groups.................  47
      6.2.2 MARS_MSERV and MARS_UNSERV messages....................  47
      6.2.3 Registering a Multicast Server (MCS)...................  49
      6.2.4 Modified response to MARS_JOIN and MARS_LEAVE..........  49
      6.2.5 Sequence numbers for ServerControlVC traffic...........  51
    6.3 Why global sequence numbers?...............................  52
    6.4 Redundant/Backup MARS Architectures........................  52
   7. How an MCS utilises a MARS...................................  53
    7.1 Association with a particular Layer 3 group................  53
    7.2 Termination of incoming VCs................................  54
    7.3 Management of outgoing VC..................................  54
    7.4 Use of a backup MARS.......................................  54
   8. Support for IP multicast routers.............................  54
    8.1 Forwarding into a Cluster..................................  55
    8.2 Joining in 'promiscuous' mode..............................  55
    8.3 Forwarding across the cluster..............................  56
    8.4 Joining in 'semi-promiscous' mode..........................  56
    8.5 An alternative to IGMP Queries.............................  57
    8.6 CMIs across multiple interfaces............................  58
   9. Multiprotocol applications of the MARS and MARS clients......  59
   10. Supplementary parameter processing..........................  60
    10.1 Interpreting the mar$extoff field.........................  60
    10.2 The format of TLVs........................................  60
    10.3 Processing MARS messages with TLVs........................  62
    10.4 Initial set of TLV elements...............................  62
   11. Key Decisions and open issues...............................  62
   Security Considerations.........................................  65
   Acknowledgments.................................................  65
   Author's Address................................................  65
   References......................................................  66
   Appendix A. Hole punching algorithms............................  67
   Appendix B. Minimising the impact of IGMP in IPv4 environments..  69
   Appendix C. Further comments on 'Clusters'......................  71
   Appendix D. TLV list parsing algorithm..........................  72
   Appendix E. Summary of timer values.............................  73
   Appendix F. Pseudo code for MARS operation......................  74

1. Introduction โœจ

Multicasting is when a source host or protocol entity sends a packet to multiple destinations at once, using a single, local 'transmit' operation ๐Ÿฆ‹. Unicasting and Broadcasting are basically special cases of multicasting, with the packet going to one destination, or to 'all' destinations, respectively ๐Ÿ’–.

Most network layer models, like the one in RFC 1112 [1] for IP multicasting, assume sources can send packets to abstract 'multicast group addresses'. The link layer is assumed to support that abstraction, and technologies like Ethernet do ๐ŸŒธ.

ATM is being used as a new link layer technology for a bunch of protocols, IP included ๐Ÿงš. RFC 1483 [2] gave us a multiprotocol way to encapsulate and send packets over ATM Virtual Channels (VCs) using AAL5. BUT the ATM Forum's current signalling specs, UNI 3.0 [8] and UNI 3.1 [4], don't provide the multicast address abstraction ๐Ÿ’€. Unicast connections are point to point, bidirectional VCs. Multicasting runs on point to multipoint unidirectional VCs. The big limitation is that the sender has to know every intended recipient ahead of time and explicitly set up a VC with itself as the root node and the recipients as the leaf nodes. Not ideal, bestie ๐Ÿ™ˆ

This document has two broad goals:

  • Define a group address registration and membership distribution mechanism that lets UNI 3.0/3.1 based networks support the multicast service of protocols such as IP ๐Ÿ‘‘.
  • Define specific endpoint behaviours for managing point to multipoint VCs so layer 3 packets get multicast ๐Ÿซถ.

The IETF is in the forefront of using wide area multicasting right now, so this document will often focus on the IP service model from RFC 1112 ๐ŸŒˆ. A final chapter will note the multiprotocol application of the architecture.

This document skips one highly non-trivial part of using ATM: specifying the QoS for VCs being set up in response to higher layer needs. Research in this area is still very formative [7], so it's assumed future documents will clarify how QoS requirements map to VC establishment โญ. For now, the default is that VCs are set up with a request for Unspecified Bit Rate (UBR) service, which is what the IETF uses for unicast IP, as described in RFC 1755 [6] ๐Ÿ’….

1.1. The Multicast Address Resolution Server (MARS).

The Multicast Address Resolution Server (MARS) is an extended analog of the ATM ARP Server introduced in RFC 1577 [3] ๐Ÿงš. It acts as a registry, associating layer 3 multicast group identifiers with the ATM interfaces representing the group's members ๐Ÿ“. MARS messages support distributing multicast group membership information between MARS and endpoints (hosts or routers). Endpoint address resolution entities query the MARS when a layer 3 address needs to be resolved to the set of ATM endpoints making up the group at any one time. Endpoints keep the MARS informed when they need to join or leave particular layer 3 groups ๐Ÿ”ฅ. For asynchronous notification of group membership changes, the MARS manages a point to multipoint VC out to all endpoints that want multicast support ๐Ÿ’œ

Valid arguments can be made for two different approaches to ATM level multicasting of layer 3 packets: through meshes of point to multipoint VCs, or through ATM level multicast servers (MCS) ๐Ÿฆ‹. The MARS architecture allows either VC meshes or MCSs to be used on a per-group basis ๐ŸŽ€

1.2. The ATM level multicast Cluster. โ˜๏ธ

Okay so each MARS manages a 'cluster' of ATM-attached endpoints ๐Ÿฆ‹. The official definition is: "The set of ATM interfaces choosing to participate in direct ATM connections to achieve multicasting of AAL_SDUs between themselves." Basically, a Cluster is whoever decides to use the same MARS to register their memberships and get their updates ๐Ÿ’….

By the logic of that definition, traffic between interfaces in different Clusters has to pass through an inter-cluster device ๐Ÿšช. (In the IP world, that's an IP multicast router with logical interfaces into each Cluster ๐ŸŒ.) This document explicitly avoids specifying the nature of inter-cluster (layer 3) routing protocols, so no spoilers there ๐Ÿ™ˆ.

How you map clusters onto other constrained sets of endpoints, like unicast Logical IP Subnets, is up to each network administrator ๐ŸŽ€. BUT for conformance with this document, network administrators MUST ensure that each Logical IP Subnet (LIS) is served by a separate MARS, so you get a one-to-one mapping between cluster and unicast LIS ๐Ÿ’–. IP multicast routers then interconnect each LIS the same way they do with conventional subnets. (Relaxation of this restriction MAY only occur after future research on how existing layer 3 multicast routing protocols interact with unicast subnet boundaries ๐Ÿ”ฌ.)

The term 'Cluster Member' is used in this document for an endpoint that is currently using a MARS for multicast support ๐Ÿซถ. So the potential scope of a cluster might be the entire membership of a LIS, but the actual scope depends on which endpoints are really Cluster Members at any given time โœจ.

1.3. Document overview. ๐Ÿ—บ๏ธ

Quick heads up, this assumes you already know the concepts explained in more depth in RFC 1112, RFC 1577, UNI 3.0/3.1, and RFC 1755 [6] ๐Ÿ“š. Here's the tour:

  • Section 2 gives an overview of IP multicast and what RFC 1112 required from Ethernet ๐ŸŒธ.
  • Section 3 describes the multicast support services offered by UNI 3.0/3.1, and outlines the differences between VC meshes and multicast servers (MCSs) as ways to distribute packets to multiple destinations ๐Ÿงš.
  • Section 4 provides an overview of the MARS and its relationship to ATM endpoints. It also covers the encapsulation and structure of MARS control messages ๐Ÿ“ฆ.
  • Section 5 substantially defines the entire cluster member endpoint behaviour, on both receive and transmit sides. That includes normal operation and error recovery ๐Ÿ› ๏ธ.
  • Section 6 summarises the required behaviour of a MARS ๐Ÿ‘‘.
  • Section 7 looks at how a multicast server (MCS) interacts with a MARS ๐Ÿค.
  • Section 8 discusses how IP multicast routers may make novel use of promiscuous and semi-promiscuous group joins. It also covers a mechanism designed to reduce the amount of IGMP traffic issued by routers ๐Ÿ”ฅ.
  • Section 9 discusses how this document applies in the more general (non-IP) case ๐ŸŒˆ.
  • Section 10 summarises the key proposals, and identifies areas for future research generated by this MARS architecture ๐Ÿ”ฎ.

The appendices get into the implementation side of things ๐Ÿ’œ. Appendix A covers MARS and endpoint algorithms for parsing MARS messages. Appendix B describes the particular problems introduced by the current IGMP paradigms, plus possible interim work-arounds ๐Ÿ™ƒ. Appendix C digs deeper into the 'cluster' concept, while Appendix D briefly outlines an algorithm for parsing TLV lists ๐Ÿงฉ. Appendix E summarises various timer values used in this document, and Appendix F provides example pseudo-code for a MARS entity ๐Ÿ’ป.

1.4. Conventions. ๐Ÿ”ข

In this document, the following coding and packet representation rules are used ๐Ÿ“:

  • All multi-octet parameters are encoded in big-endian form (i.e. the most significant octet comes first) ๐Ÿฅ‡.
  • In all multi-bit parameters, bit numbering begins at 0 for the least significant bit when stored in memory (i.e. the n'th bit has weight of 2^n) ๐Ÿงฎ.
  • A bit that is 'set', 'on', or 'one' holds the value 1 โœ….
  • A bit that is 'reset', 'off', 'clear', or 'zero' holds the value 0 โŒ.

2. Summary of the IP multicast service model. ๐ŸŒ

Under IP version 4 (IPv4), addresses in the range between 224.0.0.0 and 239.255.255.255 (224.0.0.0/4) are termed 'Class D' or 'multicast group' addresses ๐Ÿ’ซ. They abstractly represent all the IP hosts in the Internet (or some constrained subset of it) who have decided to 'join' the specified group ๐Ÿ‘ฏ.

RFC1112 requires that a multicast-capable IP interface must support transmitting IP packets to an IP multicast group address, whether or not the node considers itself a 'member' of that group ๐Ÿ“ค. So group membership is basically irrelevant to the transmit side of the link layer interfaces ๐Ÿคทโ€โ™€๏ธ. When Ethernet is the link layer (the example used in RFC1112), no address resolution is needed to transmit packets. Instead, an algorithmic mapping from IP multicast address to Ethernet multicast address is performed locally, before the packet goes out the local interface in the same 'send and forget' manner as a unicast IP packet ๐Ÿš€.

Joining and leaving an IP multicast group is more explicit on the receive side ๐Ÿ“ฅ. The primitives JoinLocalGroup and LeaveLocalGroup affect which groups the local link layer interface accepts packets from ๐ŸŽง. When the IP layer wants to receive packets from a group, it issues JoinLocalGroup. When it no longer wants them, it issues LeaveLocalGroup. The key thing to note is that changing state is a local issue. It has no effect on other hosts attached to the Ethernet ๐Ÿ™Œ.

IGMP is defined in RFC 1112 to support IP multicast routers attached to a given subnet ๐Ÿ“ก. Hosts issue IGMP Report messages when they perform a JoinLocalGroup, or in response to an IP multicast router sending an IGMP Query. By periodically transmitting queries, IP multicast routers can identify which IP multicast groups have non-zero membership on a given subnet ๐Ÿ”.

A specific IP multicast address, 224.0.0.1, is allocated for transmitting IGMP Query messages ๐Ÿ“ฃ. Host IP layers issue a JoinLocalGroup for 224.0.0.1 when they intend to participate in IP multicasting, and a LeaveLocalGroup for 224.0.0.1 when they've stopped participating ๐Ÿ‘‹.

Each host keeps a list of the IP multicast groups it has JoinLocalGroup'd to ๐Ÿ“‹. When a router issues an IGMP Query on 224.0.0.1, each host begins sending IGMP Reports for each group it's a member of ๐Ÿ’Œ. IGMP Reports are sent to the group address, not 224.0.0.1, "so that other members of the same group on the same network can overhear the Report" and not bother sending one of their own ๐Ÿ‘‚. IP multicast routers conclude that a group has no members on the subnet when IGMP Queries no longer elicit associated replies ๐Ÿ•ต๏ธโ€โ™€๏ธ.


3. UNI 3.0/3.1 support for intra-cluster multicasting. ๐Ÿฆ‹

For the purposes of the MARS protocol, UNI 3.0 and UNI 3.1 provide equivalent support for multicasting ๐Ÿฅฐ. Differences between UNI 3.0 and UNI 3.1 in required signalling elements are covered in RFC 1755 ๐Ÿ“–.

This document describes its operation in terms of 'generic' functions that should be available to clients of a UNI 3.0/3.1 signalling entity in a given ATM endpoint ๐Ÿง . The ATM model broadly describes an 'AAL User' as any entity that establishes and manages VCs and underlying AAL services to exchange data ๐Ÿ’ฌ. An IP over ATM interface is a form of 'AAL User' (although the default LLC/SNAP encapsulation mode specified in RFC1755 really requires that an 'LLC entity' is the AAL User, which in turn supports the IP/ATM interface) ๐Ÿง.

The most fundamental limitations of UNI 3.0/3.1's multicast support are ๐Ÿšง:

  • Only point to multipoint, unidirectional VCs may be established.
  • Only the root (source) node of a given VC may add or remove leaf nodes.

Leaf nodes are identified by their unicast ATM addresses ๐Ÿท๏ธ. UNI 3.0/3.1 defines two ATM address formats: native E.164 and NSAP (although it must be stressed that the NSAP address is so called because it uses the NSAP format. An ATM endpoint is NOT a Network layer termination point ๐Ÿ™…โ€โ™€๏ธ). In UNI 3.0/3.1, an 'ATM Number' is the primary identification of an ATM endpoint, and it may use either format ๐Ÿ”–. Under some circumstances, an ATM endpoint must be identified by both a native E.164 address (identifying the attachment point of a private network to a public network), and an NSAP address ('ATM Subaddress') identifying the final endpoint within the private network ๐Ÿ . For the rest of this document, the term will be used to mean either a single 'ATM Number' or an 'ATM Number' combined with an 'ATM Subaddress' โœจ.

3.1. VC meshes. ๐Ÿ•ธ๏ธ

The most fundamental approach to intra-cluster multicasting is the multicast VC mesh ๐Ÿ’…. Each source establishes its own independent point to multipoint VC (a single multicast tree) to the set of leaf nodes (destinations) it has been told are members of the group it wants to send packets to ๐ŸŒณ.

Interfaces that are both senders and group members (leaf nodes) to a given group will originate one point to multipoint VC, and terminate one VC for every other active sender to the group. This criss-crossing of VCs across the ATM network is where the name 'VC mesh' comes from ๐Ÿงถ.

3.2. Multicast Servers. ๐Ÿ–ฅ๏ธ

An alternative model has each source establish a VC to an intermediate node, the multicast server (MCS) ๐Ÿ™‹โ€โ™€๏ธ. The multicast server itself establishes and manages a point to multipoint VC out to the actual desired destinations ๐Ÿ“ก.

The MCS reassembles AAL_SDUs arriving on all the incoming VCs, then queues them for transmission on its single outgoing point to multipoint VC ๐ŸŽ€. (Reassembly of incoming AAL_SDUs is required at the multicast server, as AAL5 does not support cell level multiplexing of different AAL_SDUs on a single outgoing VC ๐Ÿงฉ.) The leaf nodes of the multicast server's point to multipoint VC must be established prior to packet transmission, and the multicast server requires an external mechanism to identify them ๐Ÿ”Ž. A side-effect of this method is that ATM interfaces that are both sources and group members will receive copies of their own packets back from the MCS ๐Ÿชž. (An alternative method is for the multicast server to explicitly retransmit packets on individual VCs between itself and group members. A benefit of this second approach is that the multicast server can ensure sources do not receive copies of their own packets ๐Ÿ’ก.)

The simplest MCS pays no attention to the contents of each AAL_SDU. It is purely an AAL/ATM level device ๐Ÿค–. More complex MCS architectures (where a single endpoint serves multiple layer 3 groups) are possible, but they're beyond the scope of this document ๐ŸŒŒ. More detailed discussion is provided in section 7 ๐Ÿ’œ.

Keep going, the good stuff is coming! ๐ŸŒธ

3.3. Tradeoffs โœจ

Okay, this debate has been going forever ๐Ÿ’…. VC meshes vs multicast servers is a whole thing, and honestly the answer is "it depends" ๐Ÿ™„. A sysadmin has to balance throughput, latency, congestion, and resource consumption. Even "latency" is slippery: are we talking end to end packet time, or how long a group takes to settle after someone joins or leaves? ๐Ÿค” The right pick comes down to what the apps sending the multicast traffic are actually doing ๐Ÿฆ‹.

If we zoom in on the data path, the VC mesh is the main character ๐ŸŽ€. It doesn't have that one obvious congestion point that an MCS has. Throughput is likely higher and end to end latency lower, because the mesh skips the intermediate AAL_SDU reassembly that has to happen in MCSs โœจ. ATM signalling also has more room to pick optimal branching points at ATM switches along each source's multicast tree ๐ŸŒณ.

But resource consumption is where the mesh gets messy ๐Ÿ˜ญ. Every group member's ATM interface has to terminate a VC per sender. That eats on-board memory for state information, an instance of an AAL service, and buffering, all based on the vendor's particular architecture. With a multicast server, you only need 2 VCs (one out, one in), no matter how many senders there are ๐Ÿ™Œ. VC related resources are also lower inside the ATM cloud when you use an MCS. These points can matter a lot where VCs across the UNI or inside the ATM cloud are valuable (like when the ATM provider charges per VC) ๐Ÿ’ธ, or where AAL contexts are limited in the endpoint's ATM interfaces.

Now signalling load: MCSs win when receivers keep changing ๐Ÿ”„. Whenever group membership changes (a leaf node gets added or dropped), only a single point to multipoint VC has to be modified with an MCS. That creates a single signalling event across the MCS's UNI. In a VC mesh, though, a membership change sets off signalling events at the UNI of every traffic source, so the transient signalling load scales with the number of sources ๐Ÿ“ˆ. That's a big deal if you define latency as the time for a group's connectivity to stabilise after a change, especially as senders multiply ๐Ÿ˜ฉ.

Last one: as noted above, MCSs bring a 'reflected packet' problem ๐Ÿชž. To fix it, extra per-AAL_SDU information has to be carried so layer 3 sources can detect their own AAL_SDUs coming back to them.

The MARS architecture lets system administrators use either approach, decided group by group ๐ŸŒˆ.


3.4. Interaction with local UNI 3.0/3.1 signalling entity. ๐Ÿ’Œ

Local AAL Users are presumed to have these generic signalling functions available:

L_CALL_RQ     - Establish a unicast VC to a specific endpoint.
L_MULTI_RQ    - Establish multicast VC to a specific endpoint.
L_MULTI_ADD   - Add new leaf node to previously established VC.
L_MULTI_DROP  - Remove specific leaf node from established VC.
L_RELEASE     - Release unicast VC, or all Leaves of a multicast VC.

The signalling exchanges and local information passed between the AAL User and the UNI 3.0/3.1 signalling entity for these functions are outside the scope of this document ๐Ÿ™ˆ.

The AAL Users are also assumed to get these indications from the local UNI 3.0/3.1 signalling entity:

L_ACK          - Succesful completion of a local request.
L_REMOTE_CALL  - A new VC has been established to the AAL User.
ERR_L_RQFAILED - A remote ATM endpoint rejected an L_CALL_RQ,
                 L_MULTI_RQ, or L_MULTI_ADD.
ERR_L_DROP     - A remote ATM endpoint dropped off an existing VC.
ERR_L_RELEASE  - An existing VC was terminated.

Same deal as before: the signalling exchanges and local information for these indications are outside the scope of this document ๐Ÿ’….


4. Overview of the MARS. ๐Ÿงš

The MARS can live inside any ATM endpoint that the endpoints it serves can directly address ๐Ÿ“. Endpoints that want to join a multicast cluster must be configured with the ATM address of the node where the cluster's MARS lives. (Section 5.4 explains how backup MARSs can be added to keep a cluster running. In the following sections, 'the MARS' means the acting MARS for the cluster ๐Ÿซถ.)

4.1. Architecture. ๐Ÿ—๏ธ

Architecturally, the MARS is an evolution of the RFC 1577 ARP Server ๐Ÿฆ‹. The ARP Server keeps a table of {IP,ATM} address pairs for every IP endpoint in a LIS. The MARS keeps extended tables of mappings in the form of {layer 3 address, ATM.1, ATM.2, ..... ATM.n}. It can be configured with certain mappings, or it can dynamically 'learn' them. The MARS generally doesn't interpret the format of the {layer 3 address} field ๐Ÿคทโ€โ™€๏ธ.

A single ATM node can support multiple logical MARSs, and each one supports a separate cluster ๐ŸŽ€. The one restriction is that each MARS has a unique ATM address (for example, a different SEL field in the NSAP address of the node where the multiple MARSs reside). By definition, a single instance of a MARS can't support more than one cluster ๐Ÿšซ.

The MARS sends group membership updates to cluster members over a point to multipoint VC called the ClusterControlVC ๐Ÿ“ข. When Multicast Servers (MCSs) are in use, the MARS also sets up a separate point to multipoint VC out to the registered MCSs, called the ServerControlVC. All cluster members are leaf nodes of the ClusterControlVC, and all registered multicast servers are leaf nodes of the ServerControlVC (more on that in section 6) ๐ŸŒธ.

The MARS does NOT take part in the actual multicasting of layer 3 data packets ๐Ÿ™…โ€โ™€๏ธ.

4.2. Control message format. ๐Ÿงฉ

By default, every MARS control message MUST be LLC/SNAP encapsulated, using these codepoints:

[0xAA-AA-03][0x00-00-5E][0x00-03][MARS control message]
    (LLC)       (OUI)     (PID)

(This is a PID from the IANA OUI.) ๐Ÿท๏ธ

MARS control messages have 4 major components:

[Fixed header][Mandatory fields][Addresses][Supplementary TLVs]

The [Fixed header] carries fields that say what operation is happening and which layer 3 protocol it's about (like IPv4, IPv6, AppleTalk, etc). It also has checksum info and hooks so this basic control message structure can be reused by other query/response protocols ๐Ÿ”ง.

The [Mandatory fields] section holds fixed width parameters that depend on the operation type named in [Fixed header] ๐Ÿ“.

The [Addresses] area that follows holds variable length fields for source and target addresses, both hardware (e.g. ATM) and layer 3 (e.g. IPv4) ๐Ÿ . These are the core info that registrations, queries, and updates work with. For the MARS protocol, the fields in [Fixed header] tell you how to read the contents of [Addresses] ๐Ÿ”.

[Supplementary TLVs] is an optional list of TLV (type, length, value) encoded information elements that can be tacked on for extra info. Section 10 has more details on this ๐ŸŽ.

MARS messages have variable length address fields. In every case, null addresses SHALL be encoded as zero length, and they don't get any space allocated in the message ๐Ÿซง.

(Thanks to the unique LLC/SNAP encapsulation, MARS and ARP Server functionality can live in a common entity and share a client-server VC, if the implementor wants to do it that way. Also, the LLC/SNAP codepoint for MARS is different from the codepoint used for ATMARP ๐Ÿ‘€.)

4.3. Fixed header fields in MARS control messages. ๐Ÿ“‹

The [Fixed header] looks like this:

Data:
 mar$afn      16 bits  Address Family (0x000F).
 mar$pro      56 bits  Protocol Identification.
 mar$hdrrsv   24 bits  Reserved. Unused by MARS control protocol.
 mar$chksum   16 bits  Checksum across entire MARS message.
 mar$extoff   16 bits  Extensions Offset.
 mar$op       16 bits  Operation code.
 mar$shtl      8 bits  Type & length of source ATM number. (r)
 mar$sstl      8 bits  Type & length of source ATM subaddress. (q)

mar$shtl and mar$sstl tell you about the source's hardware (ATM) address ๐Ÿชช. In the MARS protocol these fields are always there, because every MARS message carries a non-null source ATM address. In every case, the source ATM address is the first variable length field in the [Addresses] section ๐Ÿฅ‡.

The other fields in [Fixed header] are covered in the subsections below ๐Ÿ‘‡.

4.3.1. Hardware type. ๐Ÿ”Œ

mar$afn says what type of link layer addresses are being carried. MARS messages made under this document SHALL use the value 0x000F. How ATM addresses and subaddresses are encoded when mar$afn = 0x000F is covered in section 5.1.2. Encodings when mar$afn != 0x000F are outside the scope of this document ๐Ÿšง.

4.3.2. Protocol type. ๐Ÿง

The mar$pro field is made up of two subfields:

mar$pro.type 16 bits  Protocol type.
mar$pro.snap 40 bits  Optional SNAP extension to protocol type.

The mar$pro.type field is a 16 bit unsigned integer, and it covers this number space:

0x0000 to 0x00FF  Protocols defined by the equivalent NLPIDs.
0x0100 to 0x03FF  Reserved for future use by the IETF.
0x0400 to 0x04FF  Allocated for use by the ATM Forum.
0x0500 to 0x05FF  Experimental/Local use.
0x0600 to 0xFFFF  Protocols defined by the equivalent Ethertypes.

(This split is based on the observations that valid Ethertypes are never smaller than 0x600, and NLPIDs are never larger than 0xFF ๐Ÿง .)

The NLPID value of 0x80 means a SNAP encoded extension is being used to encode the protocol type. When mar$pro.type == 0x80, the SNAP extension sits in the mar$pro.snap field. This is called the 'long form' protocol ID ๐Ÿ’œ.

If mar$pro.type != 0x80, then the mar$pro.snap field MUST be zero on transmit and ignored on receive. The mar$pro.type field itself identifies the protocol being referred to, and this is called the 'short form' protocol ID โœจ.

In every case where a protocol has an assigned number in the mar$pro.type space (excluding 0x80), the short form MUST be used when transmitting MARS messages. Also, where a protocol has valid short and long forms of identification, receivers MAY choose to recognise the long form ๐Ÿซถ.

mar$pro.type values other than 0x80 MAY have 'long forms' defined in future documents ๐Ÿ”ฎ.

For the rest of this document, references to mar$pro SHALL be interpreted to mean mar$pro.type, or mar$pro.type in combination with mar$pro.snap, as appropriate ๐Ÿงฉ.

The use of different protocol types is described further in section 9 ๐ŸŒˆ.

4.3.3. Checksum ๐Ÿ’–

okay so the mar$chksum field holds a standard IP checksum that's calculated over the whole MARS control message, minus the LLC/SNAP header ๐ŸŽ€ before the checksum runs, the field gets set to zero ๐Ÿงš

the thing is, the entire LLC/SNAP-encapsulated MARS message is already protected by the 32 bit CRC of the AAL5 transport ๐Ÿฆ‹ so implementors MAY choose to skip the checksum facility totally ๐Ÿ’… if no checksum gets calculated, those bits MUST be reset before transmission ๐ŸŒธ and if nobody checks the checksum on reception, this field MUST be ignored ๐Ÿ™ˆ a receiver that can validate a checksum MUST only do it when the received mar$chksum is non-zero โœจ messages that show up with mar$chksum of 0 are always considered valid, no drama ๐Ÿซถ

4.3.4. Extensions Offset ๐ŸŽ€

the mar$extoff field tells you whether there's an optional supplementary parameters list and where it lives ๐Ÿ—บ๏ธ we'll get into how that works in section 10 ๐ŸŒˆ

4.3.5. Operation code ๐Ÿ‘‘

the mar$op field is split into two 8 bit fields ๐Ÿ’œ the leading octet is mar$op.version and the trailing octet is mar$op.type ๐Ÿ’œ together they say what kind of control message you're looking at, and how the [Mandatory fields], [Addresses], and [Supplementary TLVs] should be read ๐Ÿ˜ญ

mar$op.version
   0               MARS protocol defined in this document.
   0x01 - 0xEF     Reserved for future use by the IETF.
   0xF0 - 0xFE     Allocated for use by the ATM Forum.
   0xFF            Experimental/Local use.

mar$op.type
   Value indicates operation being performed, within context of
   the control protocol version indicated by mar$op.version.

for the rest of this doc, any reference to the mar$op value SHALL be read as mar$op.type, with mar$op.version = 0x00 ๐Ÿ“ the values we use are summarised in section 11 ๐Ÿ’…

(fyi this number space is totally separate from the ATMARP operation code number space ๐Ÿ™ˆ)

4.3.6. Reserved ๐Ÿฆ‹

mar$hdrrsv can be split up and given specific meanings by other control protocols whenever mar$op.version != 0 ๐ŸŒธ

5. Endpoint (MARS client) interface behaviour โœจ

okay so an endpoint is basically a 'shim' or 'convergence' layer ๐Ÿ’– it sits between a layer 3 protocol's link layer interface and the UNI 3.0/3.1 service underneath ๐Ÿงš an endpoint can live in a host or a router, honestly anything that needs a generic 'layer 3 over ATM' interface to do layer 3 multicast ๐Ÿ‘‘ it's split into two main subsections, one for transmit and one for receive ๐Ÿซถ

one physical ATM interface can back multiple logical ATM interfaces (like using different SEL values in the NSAP formatted address on that physical interface) ๐ŸŒˆ so implementors MUST allow for multiple independent 'layer 3 over ATM' interfaces too ๐Ÿ”ฅ each one gets its own configured MARS (or a table of MARSs, more on that in section 5.4) and can attach to the same or different clusters ๐Ÿ’…

the initial signalling path between a MARS client and its MARS is a transient point to point, bidirectional VC ๐Ÿฆ‹ the MARS client sets it up, and it's used to send queries to the MARS and get replies back ๐Ÿ’œ it has an idle timer, so it gets torn down if nobody uses it for a configurable amount of time โณ the minimum suggested value is 1 minute, and the RECOMMENDED default is 20 minutes ๐ŸŒธ (if the MARS and ARP Server live in the same place, this VC can carry both ATM ARP traffic and MARS control traffic, iykyk โœจ)

the remaining signalling path is ClusterControlVC, and the MARS client gets added to it as a leaf node when it registers (see section 5.2.3) ๐ŸŽ€

most of this doc is about handing out info so endpoints can set up and manage outgoing point to multipoint VCs, which are the forwarding paths for multicast traffic to particular groups ๐Ÿซถ the actual format of the AAL_SDUs on those VCs is almost totally out of scope here ๐Ÿ™ˆ but endpoints aren't expected to know whether their forwarding path goes straight to a group's members or to an MCS (see section 3) ๐Ÿ˜ญ that's why there's extra per-packet encapsulation (see section 5.5) to help detect reflected AAL_SDUs ๐Ÿ’€

5.1. Transmit side behaviour ๐Ÿ’…

this description is gonna be mostly about an IPv4/ATM interface that can send packets to a Class D address at any time, no warning needed ๐Ÿฆ‹ it should be super easy for an implementor to generalise this to the needs of another layer 3 data protocol ๐Ÿงš

when a local Layer 3 entity hands down a packet for transmission, the endpoint first checks whether an outbound path to that destination multicast group already exists ๐Ÿ‘‘ if it doesn't, it queries the MARS for a set of ATM endpoints that make up an appropriate forwarding path ๐ŸŒˆ (those ATM endpoints might be the actual group members in the cluster, or one or more MCSs, and the endpoint doesn't care which one it is ๐Ÿ’– section 6.2 explains the MARS behaviour that leads to MCSs being handed out as a group's forwarding path โœจ) the query happens by sending a MARS_REQUEST ๐Ÿ’Œ the MARS can reply in one of two ways:

MARS_MULTI - Sequence of MARS_MULTI messages returning the set of
             ATM endpoints that are to be leaf nodes of an
             outgoing point to multipoint VC (the forwarding
             path).

MARS_NAK - No mapping found, group is empty.

the formats of these messages are in section 5.1.2 ๐ŸŽ€

outgoing VCs get set up with a request for Unspecified Bit Rate (UBR) service, which is the same thing IETF uses for unicast IP VCs, see RFC 1755 [6] ๐ŸŒธ future docs might change this and allow different ATM traffic parameters, from locally configured info or from some external source ๐Ÿ”ฅ

5.1.1. Retrieving Group Membership from the MARS. ๐Ÿซถ

if the MARS had no mapping for the Class D address you asked about, it sends back a MARS_NAK ๐Ÿ’€ in that case the IP packet MUST be discarded silently ๐Ÿ™ˆ if there is a match in the MARS's tables, it returns addresses ATM.1 through ATM.n in one or more MARS_MULTIs ๐ŸŒˆ there's a simple mechanism to spot and recover from losing a MARS_MULTI ๐Ÿฆ‹

(so if the client finds out there's no other group member in the cluster, meaning the MARS returns a MARS_NAK or a MARS_MULTI with only the client in it, it MUST delay sending a new MARS_REQUEST for that group for no less than 5 seconds and no more than 10 seconds ๐Ÿ˜ญ)

each MARS_MULTI carries a boolean field x and a 15 bit integer field y, written MARS_MULTI(x,y) ๐Ÿ’œ field y is a sequence number that starts at 1 and goes up by one for each MARS_MULTI sent ๐Ÿงš field x is the 'end of reply' marker, and when x == 1 the MARS response is considered complete ๐Ÿ

each MARS_MULTI can also carry several ATM addresses from the set {ATM.1, ATM.2, .... ATM.n} ๐Ÿ‘‘ a MARS MUST minimise the number of MARS_MULTIs it sends by packing as many group members' addresses into each one as it can ๐Ÿ’… the limit on the length of a single MARS_MULTI MUST be the MTU of the underlying VC ๐Ÿซถ

for example, say n ATM addresses need returning, each MARS_MULTI only fits p ATM addresses, and p << n ๐ŸŒธ that takes a sequence of k MARS_MULTI messages (where k = (n/p)+1, using integer arithmetic) sent like this:

MARS_MULTI(0,1) carries back {ATM.1 ... ATM.p}
MARS_MULTI(0,2) carries back {ATM.(p+1) ... ATM.(2p)}
      [.......]
MARS_MULTI(1,k) carries back { ... ATM.n}

if k == 1 then only MARS_MULTI(1,1) gets sent ๐Ÿ’–

the typical failure mode is losing one or more of MARS_MULTI(0,1) through MARS_MULTI(0,k-1) ๐Ÿ˜ญ you catch this when y jumps by more than one between consecutive MARS_MULTIs ๐Ÿ™ˆ an alternative failure is losing MARS_MULTI(1,k) ๐Ÿ’€ so a timer MUST be implemented to flag when the last MARS_MULTI hasn't shown up ๐ŸŒˆ a default of 10 seconds is RECOMMENDED โฐ

if a 'sequence jump' gets detected, the host MUST wait for MARS_MULTI(1,k), throw out all results, and repeat the MARS_REQUEST ๐Ÿ”ฅ

if a timeout happens, the host MUST discard all results and repeat the MARS_REQUEST ๐Ÿซถ

there's one last failure mode involving the MARS Sequence Number (covered in section 5.1.4.2, and carried in each part of a multi-part MARS_MULTI) ๐Ÿงš if its value changes while a multi-part MARS_MULTI is coming in, the host MUST wait for MARS_MULTI(1,k), discard all results, and repeat the MARS_REQUEST ๐Ÿ’…

(corrupted cell contents will make an AAL5 CPCS_PDU reassembly fail and lose a MARS_MULTI, and the mechanisms above will catch that ๐Ÿฆ‹)

if the MARS is managing a cluster of endpoints spread across different but directly accessible ATM networks, it can't fit all the group members into one MARS_MULTI ๐ŸŒธ the MARS_MULTI format lets you return E.164, ISO NSAP, or (E.164 + NSAP) as ATM addresses ๐Ÿ’œ but each MARS_MULTI can only return ATM addresses of one type and length ๐Ÿ˜ญ so the returned addresses MUST be grouped by type (E.164, ISO NSAP, or both) and sent as a sequence of separate MARS_MULTI parts ๐ŸŽ€

5.1.2. MARS_REQUEST, MARS_MULTI, and MARS_NAK messages. ๐ŸŒˆ

here's the MARS_REQUEST ๐Ÿซถ it's marked with an 'operation type value' (mar$op) of 1 โœจ

the multicast address being resolved goes into the target protocol address field (mar$tpa), and the target hardware address is set to null (mar$thtl and mar$tstl both zero) ๐Ÿ’–

in IPv4 environments the protocol type (mar$pro) is 0x800, and the target protocol address length (mar$tpln) MUST be set to 4 ๐Ÿ”ฅ the source fields MUST contain the ATM number and subaddress of the client sending the MARS_REQUEST (the subaddress MAY be null) ๐Ÿ’…

Data:
 mar$afn      16 bits  Address Family (0x000F).
 mar$pro      56 bits  Protocol Identification.
 mar$hdrrsv   24 bits  Reserved. Unused by MARS control protocol.
 mar$chksum   16 bits  Checksum across entire MARS message.
 mar$extoff   16 bits  Extensions Offset.
 mar$op       16 bits  Operation code (MARS_REQUEST = 1)
 mar$shtl      8 bits  Type & length of source ATM number. (r)
 mar$sstl      8 bits  Type & length of source ATM subaddress. (q)
 mar$spln      8 bits  Length of source protocol address (s)
 mar$thtl      8 bits  Type & length of target ATM number (x)
 mar$tstl      8 bits  Type & length of target ATM subaddress (y)
 mar$tpln      8 bits  Length of target group address (z)
 mar$pad      64 bits  Padding (aligns mar$sha with MARS_MULTI).
 mar$sha      roctets  source ATM number
 mar$ssa      qoctets  source ATM subaddress
 mar$spa      soctets  source protocol address
 mar$tpa      zoctets  target multicast group address
 mar$tha      xoctets  target ATM number
 mar$tsa      yoctets  target ATM subaddress

following the RFC1577 approach, the mar$shtl, mar$sstl, mar$thtl and mar$tstl fields are coded like this ๐Ÿงš

              7 6 5 4 3 2 1 0
             +-+-+-+-+-+-+-+-+
             |0|x|  length   |
             +-+-+-+-+-+-+-+-+

the next bit is the one where things get really juicy ๐ŸŒˆโœจ keep going ๐Ÿ’–

The most significant bit is reserved and MUST be set to zero ๐Ÿ™ˆ The second most significant bit (x) is a flag that tells you whether the ATM address being referred to is in:

  • ATM Forum NSAPA format (x = 0) ๐Ÿ’…
  • Native E.164 format (x = 1) ๐Ÿ“ž

The bottom 6 bits are an unsigned integer that gives the length of the associated ATM address in octets. If this value is zero the flag x is ignored ๐Ÿงš

The mar$spln and mar$tpln fields are unsigned 8 bit integers, giving the length in octets of the source and target protocol address fields respectively ๐ŸŽ€

MARS packets use true variable length fields โœจ A null (non-existant) address MUST be coded as zero length, and no space allocated for it in the message body. No cap, that keeps things tidy ๐ŸŒธ

MARS_NAK is the MARS_REQUEST returned with operation type value of 6 ๐Ÿฆ‹ All other fields are left unchanged from the MARS_REQUEST (e.g. do not transpose the source and target information. In all cases MARS clients use the source address fields to identify their own messages coming back). Don't flip the source and target, bestie, the clients literally rely on those source fields to spot their own messages ๐Ÿ‘‘

The MARS_MULTI message is identified by an mar$op value of 2 ๐Ÿ’œ The message format is:

   Data:
    mar$afn      16 bits  Address Family (0x000F).
    mar$pro      56 bits  Protocol Identification.
    mar$hdrrsv   24 bits  Reserved. Unused by MARS control protocol.
    mar$chksum   16 bits  Checksum across entire MARS message.
    mar$extoff   16 bits  Extensions Offset.
    mar$op       16 bits  Operation code (MARS_MULTI = 2).
    mar$shtl      8 bits  Type & length of source ATM number. (r)
    mar$sstl      8 bits  Type & length of source ATM subaddress. (q)
    mar$spln      8 bits  Length of source protocol address (s)
    mar$thtl      8 bits  Type & length of target ATM number (x)
    mar$tstl      8 bits  Type & length of target ATM subaddress (y)
    mar$tpln      8 bits  Length of target group address (z)
    mar$tnum     16 bits  Number of target ATM addresses returned (N)
    mar$seqxy    16 bits  Boolean flag x and sequence number y.
    mar$msn      32 bits  MARS Sequence Number.
    mar$sha      roctets  source ATM number
    mar$ssa      qoctets  source ATM subaddress
    mar$spa      soctets  source protocol address
    mar$tpa      zoctets  target multicast group address
    mar$tha.1    xoctets  target ATM number 1
    mar$tsa.1    yoctets  target ATM subaddress 1
    mar$tha.2    xoctets  target ATM number 2
    mar$tsa.2    yoctets  target ATM subaddress 2
              [.......]
    mar$tha.N    xoctets  target ATM number N
    mar$tsa.N    yoctets  target ATM subaddress N

The source protocol and ATM address fields are copied directly from the MARS_REQUEST that this MARS_MULTI is in response to (not the MARS itself) ๐Ÿซถ

mar$seqxy is coded with flag x in the leading bit, and sequence number y coded as an unsigned integer in the remaining 15 bits ๐Ÿ”ฅ Here's the vibe:

         |  1st octet    |   2nd octet   |
          7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |x|                 y           |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

mar$tnum is an unsigned integer indicating how many pairs of {mar$tha,mar$tsa} (i.e. how many group member's ATM addresses) are present in the message. mar$msn is an unsigned 32 bit number filled in by the MARS before transmitting each MARS_MULTI. Its use is described further in section 5.1.4 โญ

As an example, assume we have a multicast cluster using 4 byte protocol addresses, 20 byte ATM numbers, and 0 byte ATM subaddresses. For n group members in a single MARS_MULTI we require a (60 + 20n) byte message. If we assume the default MTU of 9180 bytes, we can return a maximum of 456 group member's addresses in a single MARS_MULTI ๐Ÿ“ The math is giving organised, periodt.


5.1.3. Establishing the outgoing multipoint VC. ๐Ÿฆ‹

Following the completion of the MARS_MULTI reply the endpoint may establish a new point to multipoint VC, or reuse an existing one ๐Ÿ’–

If establishing a new VC, an L_MULTI_RQ is issued for ATM.1, followed by an L_MULTI_ADD for every member of the set {ATM.2, ....ATM.n} (assuming the set is non-null). The packet is then transmitted over the newly created VC just as it would be for a unicast VC โœจ

After transmitting the packet, the local interface holds the VC open and marks it as the active path out of the host for any subsequent IP packets being sent to that Class D address ๐ŸŒˆ

When establishing a new multicast VC it is possible that one or more L_MULTI_RQ or L_MULTI_ADD may fail. The UNI 3.0/3.1 failure cause must be returned in the ERR_L_RQFAILED signal from the local signalling entity to the AAL User. If the failure cause is not 49 (Quality of Service unavailable), 51 (user cell rate not available - UNI 3.0), 37 (user cell rate not available - UNI 3.1), or 41 (Temporary failure), the endpoint's ATM address is dropped from the set {ATM.1, ATM.2, ..., ATM.n} returned by the MARS. Otherwise, the L_MULTI_RQ or L_MULTI_ADD should be reissued after a random delay of 5 to 10 seconds. If the request fails again, another request should be issued after twice the previous delay has elapsed. This process should be continued until the call succeeds or the multipoint VC gets released ๐Ÿฅบ

If the initial L_MULTI_RQ fails for ATM.1, and n is greater than 1 (i.e. the returned set of ATM addresses contains 2 or more addresses) a new L_MULTI_RQ should be immediately issued for the next ATM address in the set. This procedure is repeated until an L_MULTI_RQ succeeds, as no L_MULTI_ADDs may be issued until an initial outgoing VC is established ๐Ÿ”ฅ

Each ATM address for which an L_MULTI_RQ failed with cause 49, 51, 37, or 41 MUST be tagged rather than deleted. An L_MULTI_ADD is issued for these tagged addresses using the random delay procedure outlined above ๐Ÿท๏ธ

The VC MAY be considered 'up' before failed L_MULTI_ADDs have been successfully re-issued. An endpoint MAY implement a concurrent mechanism that allows data to start flowing out the new VC even while failed L_MULTI_ADDs are being re-tried. (The alternative of waiting for each leaf node to accept the connection could lead to significant delays in transmitting the first packet.) Nobody wants to wait around for every leaf to pick up, iykyk ๐Ÿ’€

Each VC MUST have a configurable inactivity timer associated with it. If the timer expires, an L_RELEASE is issued for that VC, and the Class D address is no longer considered to have an active path out of the local host. The timer SHOULD be no less than 1 minute, and a default of 20 minutes is RECOMMENDED. Choice of specific timer periods is beyond the scope of this document ๐Ÿ•ฐ๏ธ

VC consumption may also be reduced by endpoints noting when a new group's set of {ATM.1, ....ATM.n} matches that of a pre-existing VC out to another group. With careful local management, and assuming the QoS of the existing VC is sufficient for both groups, a new pt to mpt VC may not be necessary. Under certain circumstances endpoints may decide that it is sufficient to re-use an existing VC whose set of leaf nodes is a superset of the new group's membership (in which case some endpoints will receive multicast traffic for a layer 3 group they haven't joined, and must filter them above the ATM interface). Algorithms for performing this type of optimization are not discussed here, and are not required for conformance with this document ๐Ÿง  Smart reuse is lowkey a flex, but it's not a must-have for conformance.

5.1.4. Tracking subsequent group updates. ๐Ÿ‘€

Once a new VC has been established, the transmit side of the cluster member's interface needs to monitor subsequent group changes - adding or dropping leaf nodes as appropriate. This is achieved by watching for MARS_JOIN and MARS_LEAVE messages from the MARS itself. These messages are described in detail in section 5.2 - at this point it is sufficient to note that they carry:

  • The ATM address of a node joining or leaving a group.
  • The layer 3 address of the group(s) being joined or left.
  • A Cluster Sequence Number (CSN) from the MARS.

MARS_JOIN and MARS_LEAVE messages arrive at each cluster member across ClusterControlVC. MARS_JOIN or MARS_LEAVE messages that simply confirm information already held by the cluster member are used to track the Cluster Sequence Number, but are otherwise ignored ๐Ÿซง

5.1.4.1. Updating the active VCs. ๐Ÿ› ๏ธ

If a MARS_JOIN is seen that refers to (or encompasses) a group for which the transmit side already has a VC open, the new member's ATM address is extracted and an L_MULTI_ADD issued locally. This ensures that endpoints already sending to a given group will immediately add the new member to their list of recipients ๐Ÿฅณ

If a MARS_LEAVE is seen that refers to (or encompasses) a group for which the transmit side already has a VC open, the old member's ATM address is extracted and an L_MULTI_DROP issued locally. This ensures that endpoints already sending to a given group will immediately drop the old member from their list of recipients. When the last leaf of a VC is dropped, the VC is closed completely and the affected group no longer has a path out of the local endpoint (the next outbound packet to that group's address will trigger the creation of a new VC, as described in sections 5.1.1 to 5.1.3) ๐Ÿ‘‹

The transmit side of the interface MUST NOT shut down an active VC to a group for which the receive side has just executed a LeaveLocalGroup. (This behaviour is consistent with the model of hosts transmitting to groups regardless of their own membership status.) Don't kill the VC just because your own receive side walked out, that's not how this works ๐Ÿ™…โ€โ™€๏ธ

If a MARS_JOIN or MARS_LEAVE arrives with mar$pnum == 0 it carries no <min,max> pairs, and is only used for tracking the CSN ๐Ÿงพ

5.1.4.2. Tracking the Cluster Sequence Number. ๐Ÿ”ข

It is important that endpoints do not miss group membership updates issued by the MARS over ClusterControlVC. However, this will happen from time to time ๐Ÿ™ƒ The Cluster Sequence Number is carried as an unsigned 32 bit value in the mar$msn field of many MARS messages (except for MARS_REQUEST and MARS_NAK). It increments once for every transmission the MARS makes on ClusterControlVC, regardless of whether the transmission represents a change in the MARS database or not. By tracking this counter, cluster members can determine whether they have missed a previous message on ClusterControlVC, and possibly a membership change. This is then used to trigger revalidation (described in section 5.1.5) ๐Ÿ•ต๏ธโ€โ™€๏ธ

The current CSN is copied into the mar$msn field of MARS messages being sent to cluster members, whether out ClusterControlVC or on a point to point VC ๐Ÿ’Œ

Calculations on the sequence numbers MUST be performed as unsigned 32 bit arithmetic. Math with the numbers has to be unsigned 32 bit, no exceptions, babe ๐Ÿงฎ

Every cluster member keeps its own 32 bit Host Sequence Number (HSN) to track the MARS's sequence number. Whenever a message is received that carries an mar$msn field the following processing is performed:

      Seq.diff = mar$msn - HSN

      mar$msn -> HSN
      {...process MARS message as appropriate...}

      if ((Seq.diff != 1) && (Seq.diff != 0))
         then {...revalidate group membership information...}

The basic result is that the cluster member attempts to keep locked in step with membership changes noted by the MARS. If it ever detects that a membership change occurred (in any group) without it noticing, it re-validates the membership of all groups it currently has multicast VCs open to ๐Ÿ”’ Stay synced, stay slay.

The mar$msn value in an individual MARS_MULTI is not used to update the HSN until all parts of the MARS_MULTI (if more than 1) have arrived. (If the mar$msn changes the MARS_MULTI is discarded, as described in section 5.1.1.) ๐Ÿ“ฆ

The MARS is free to choose an initial value of CSN ๐ŸŒธ. When a new cluster member starts up, it should initialise HSN to zero ๐Ÿ“. Once the cluster member sends its MARS_JOIN to register (we'll get to that later), HSN gets updated to the current CSN value when the endpoint receives its own MARS_JOIN back from the MARS ๐Ÿ’–.

5.1.5. Revalidating a VC's leaf nodes. ๐Ÿฆ‹

Okay so certain events can tell a cluster member that its info about which leaf nodes it should be sending to is wrong ๐Ÿ˜ญ. If an error happens on a VC tied to a particular group, the cluster member starts revalidation for that group only ๐ŸŽ€. But if a jump is detected in the Cluster Sequence Number, that kicks off revalidation for every group the cluster member currently has open point to multipoint VCs for โœจ.

Each open and active multipoint VC has a flag called VC_revalidate attached to it ๐Ÿ’…. This flag gets checked every time a packet is queued for transmission on that VC. If the flag is false, the packet just gets transmitted and no further action is needed ๐Ÿซถ.

If the VC_revalidate flag is true, though, the packet is still transmitted, but a brand new sequence of events starts locally ๐Ÿ‘‘.

Revalidation begins by re-issuing a MARS_REQUEST for the group being revalidated ๐ŸŒˆ. The returned set of members {NewATM.1, NewATM.2, .... NewATM.n} gets compared with the set already held locally ๐Ÿ”ฅ. L_MULTI_DROPs are issued on the group's VC for each node that appears in the original set but not in the revalidated set ๐Ÿ’€. L_MULTI_ADDs are issued on the group's VC for each node that appears in the revalidated set but not in the original set ๐Ÿงš. The VC_revalidate flag gets reset when revalidation wraps up for that group ๐ŸŒธ. Implementation specific mechanisms will be needed to flag the 'revalidation in progress' state ๐Ÿ™ˆ.

The big difference between constructing a VC (section 5.1.3) and revalidating one is that packet transmission keeps going on the open VC while it's being revalidated ๐Ÿ’œ. That keeps disruption to existing traffic to a minimum โœจ.

The algorithm for initiating revalidation goes like this:

  • When a packet arrives for transmission on a given group, the groups membership is revalidated if VC_revalidate == TRUE. Revalidation resets VC_revalidate.
  • When an event occurs that demands revalidation, every group has its VC_revalidate flag set TRUE at a random time between 1 and 10 seconds.

The benefit? Revalidation of active groups happens quickly, and essentially idle groups only get revalidated as needed ๐Ÿฆ‹. The randomly distributed setting of VC_revalidate also improves the chances that senders stagger their revalidation requests when a sequence number jump is detected ๐Ÿ’–.

5.1.5.1. When leaf node drops itself. ๐Ÿ™ˆ

During the life of a multipoint VC, an ERR_L_DROP may be received, which means a leaf node has ended its participation at the ATM level ๐Ÿ˜ญ. The ATM endpoint associated with that ERR_L_DROP MUST be removed from the locally held set {ATM.1, ATM.2, .... ATM.n} associated with the VC ๐Ÿ’….

After a random period of time between 1 and 10 seconds, the VC_revalidate flag associated with that VC MUST be set true ๐ŸŽ€.

If an ERR_L_RELEASE is received, then the entire set {ATM.1, ATM.2, .... ATM.n} gets cleared and the VC is considered completely shut down ๐Ÿ’€. Any further packet transmission to the group served by that VC will result in a new VC being established, as described in section 5.1.3 ๐ŸŒˆ.

5.1.5.2. When a jump is detected in the CSN. ๐ŸŒŠ

Section 5.1.4.2 describes how a CSN jump is detected ๐Ÿ”. If a CSN jump is detected upon receipt of a MARS_JOIN or a MARS_LEAVE, then every outgoing multicast VC MUST have its VC_revalidate flag set true at some random interval between 1 and 10 seconds from when the CSN jump was detected ๐Ÿ‘‘.

The only exception to this rule: if a sequence number jump is detected during the establishment of a new group's VC (i.e. a MARS_MULTI reply was correctly received, but its mar$msn indicated that some previous MARS traffic had been missed on ClusterControlVC), then every open VC, EXCEPT the one just established, MUST have its VC_revalidate flag set true at some random interval between 1 and 10 seconds from when the CSN jump was detected. The VC being established at the time is considered already validated ๐Ÿซถ.

5.1.6. 'Migrating' the outgoing multipoint VC ๐Ÿฆ‹

On top of the group tracking described in section 5.1.4, the transmit side of a cluster member has to respond to 'migration' requests from the MARS ๐Ÿงš. This gets triggered when a MARS_MIGRATE message comes in from ClusterControlVC ๐Ÿ’œ. The MARS_MIGRATE message is shown below, with an mar$op code of 13 โœจ.

   Data:
    mar$afn      16 bits  Address Family (0x000F).
    mar$pro      56 bits  Protocol Identification.
    mar$hdrrsv   24 bits  Reserved. Unused by MARS control protocol.

    mar$chksum   16 bits  Checksum across entire MARS message.
    mar$extoff   16 bits  Extensions Offset.
    mar$op       16 bits  Operation code (MARS_MIGRATE = 13).
    mar$shtl      8 bits  Type & length of source ATM number. (r)
    mar$sstl      8 bits  Type & length of source ATM subaddress. (q)
    mar$spln      8 bits  Length of source protocol address (s)
    mar$thtl      8 bits  Type & length of target ATM number (x)
    mar$tstl      8 bits  Type & length of target ATM subaddress (y)
    mar$tpln      8 bits  Length of target group address (z)
    mar$tnum     16 bits  Number of target ATM addresses returned (N)
    mar$resv     16 bits  Reserved.
    mar$msn      32 bits  MARS Sequence Number.
    mar$sha      roctets  source ATM number
    mar$ssa      qoctets  source ATM subaddress
    mar$spa      soctets  source protocol address
    mar$tpa      zoctets  target multicast group address
    mar$tha.1    xoctets  target ATM number 1
    mar$tsa.1    yoctets  target ATM subaddress 1
    mar$tha.2    xoctets  target ATM number 2
    mar$tsa.2    yoctets  target ATM subaddress 2
                              [.......]
    mar$tha.N    xoctets  target ATM number N
    mar$tsa.N    yoctets  target ATM subaddress N

A migration gets requested when the MARS decides it no longer wants cluster members forwarding their packets directly to the ATM addresses it had previously specified (through MARS_REQUESTs or MARS_JOINs) ๐ŸŒธ. When a MARS_MIGRATE is received, each cluster member MUST perform the following steps ๐Ÿ”ฅ:

  • Close down any existing outgoing VC associated with the group carried in the mar$tpa field (L_RELEASE), or dissociate the group from any outgoing VC it may have been sharing (as described in section 5.1.3).
  • Establish a new outgoing VC for the specified group, using the algorithm described in section 5.1.3 and taking the set of ATM addresses supplied in the MARS_MIGRATE as the group's new set of members {ATM.1, .... ATM.n}.

The MARS_MIGRATE carries the new set of members {ATM.1, .... ATM.n} in a single message, similar to a single part MARS_MULTI ๐ŸŽ€. As with other messages from the MARS, the Cluster Sequence Number carried in mar$msn gets checked as described in section 5.1.4.2 ๐ŸŒˆ.


5.2. Receive side behaviour. ๐Ÿ‘‘

A cluster member is a 'group member' (in the sense that it receives packets directed at a given multicast group) when its ATM address appears in the MARS's table entry for the group's multicast address ๐Ÿ’–. A key function within each cluster is distributing group membership information from the MARS to cluster members โœจ.

An endpoint may want to 'join a group' in response to a local, higher level request for membership of a group ๐Ÿฆ‹. It might also do so because the endpoint supports a layer 3 multicast forwarding engine that needs to 'see' intra-cluster traffic in order to forward it ๐Ÿงš.

Two messages handle these needs: MARS_JOIN and MARS_LEAVE ๐Ÿ’œ. Endpoints send these to the MARS whenever the local layer 3/ATM interface is asked to join or leave a multicast group ๐Ÿซถ. The MARS then propagates them back out over ClusterControlVC, so that news of the group's membership change reaches other cluster members in a timely fashion ๐ŸŒธ.

Certain models of layer 3 endpoints (e.g. IP multicast routers) expect to receive packet traffic 'promiscuously' across all groups ๐Ÿ‘€. This can be emulated by letting routers ask the MARS to return them as 'wild card' members of all Class D addresses ๐Ÿ”ฅ. The catch is that a problem inherent in the current ATM model is that a completely promiscuous router may exhaust the local reassembly resources in its ATM interface ๐Ÿ˜ญ. So MARS_JOIN supports a generalisation of the notion of 'wild card' entries, letting routers limit themselves to 'blocks' of the Class D address space ๐Ÿ’…. Use of this facility is described in greater detail in Section 8 ๐ŸŽ€.

A block can be as small as 1 (a single group) or as large as the entire multicast address space (e.g. default IPv4 'promiscuous' behaviour) ๐ŸŒˆ. A block is defined as all addresses between, and inclusive of, a <min,max> address pair ๐Ÿ“. A MARS_JOIN or MARS_LEAVE may carry multiple <min,max> pairs ๐Ÿงš.

Cluster members MUST provide ONLY a single <min,max> pair in each JOIN/LEAVE message they issue ๐Ÿ™ˆ. However, they MUST be able to process multiple <min,max> pairs in JOIN/LEAVE messages when performing VC management as described in section 5.1.4 (the interpretation being that the join/leave operation applies to all addresses in the range from <min> to <max> inclusive, for every <min,max> pair) ๐Ÿ’–.

In RFC1112 environments, a MARS_JOIN for a single group is triggered by a JoinLocalGroup signal from the IP layer ๐ŸŒธ. A MARS_LEAVE for a single group is triggered by a LeaveLocalGroup signal from the IP layer ๐ŸŒŠ.

Cluster members with special requirements (e.g. multicast routers) may issue MARS_JOINs and MARS_LEAVEs specifying a single block of 2 or more multicast group addresses ๐Ÿ‘‘. However, a cluster member SHALL NOT issue such a multi-group block join for an address range fully or partially overlapped by multi-group block join(s) that the cluster member has previously issued and not yet retracted ๐Ÿ˜ญ. A cluster member MAY issue combinations of single group MARS_JOINs that overlap with a multi-group block MARS_JOIN โœจ.

An endpoint MUST register with a MARS in order to become a member of a cluster and be added as a leaf to ClusterControlVC ๐Ÿ’…. Registration is covered in section 5.2.3 ๐Ÿฆ‹.

Finally, the endpoint MUST be capable of terminating unidirectional VCs (i.e. act as a leaf node of a UNI 3.0/3.1 point to multipoint VC, with zero bandwidth assigned on the return path) ๐Ÿซถ. RFC 1755 describes the signalling information required to terminate VCs carrying LLC/SNAP encapsulated traffic (discussed further in section 5.5) ๐ŸŒˆ.

5.2.1. Format of the MARS_JOIN and MARS_LEAVE Messages ๐Ÿ’–

okay so the MARS_JOIN message is the one with operation type value 4 ๐ŸŽ€ and MARS_LEAVE has the exact same format but operation type value 5 ๐Ÿซถ. here's the layout, bestie:

   Data:
    mar$afn      16 bits  Address Family (0x000F).
    mar$pro      56 bits  Protocol Identification.
    mar$hdrrsv   24 bits  Reserved. Unused by MARS control protocol.
    mar$chksum   16 bits  Checksum across entire MARS message.
    mar$extoff   16 bits  Extensions Offset.
    mar$op       16 bits  Operation code (MARS_JOIN or MARS_LEAVE).
    mar$shtl      8 bits  Type & length of source ATM number. (r)
    mar$sstl      8 bits  Type & length of source ATM subaddress. (q)
    mar$spln      8 bits  Length of source protocol address (s)
    mar$tpln      8 bits  Length of group address (z)
    mar$pnum     16 bits  Number of group address pairs (N)
    mar$flags    16 bits  layer3grp, copy, and register flags.
    mar$cmi      16 bits  Cluster Member ID
    mar$msn      32 bits  MARS Sequence Number.
    mar$sha      roctets  source ATM number.
    mar$ssa      qoctets  source ATM subaddress.
    mar$spa      soctets  source protocol address
    mar$min.1    zoctets  Minimum multicast group address - pair.1
    mar$max.1    zoctets  Maximum multicast group address - pair.1
              [.......]
    mar$min.N    zoctets  Minimum multicast group address - pair.N
    mar$max.N    zoctets  Maximum multicast group address - pair.N

so mar$spln tells you how many bytes the source endpoint's protocol address is ๐Ÿ“, and that number gets read in the context of whatever protocol mar$pro points to ๐Ÿงš. for example, in IPv4 land, mar$pro is 0x800, mar$spln is 4, and mar$tpln is 4 ๐ŸŒธ.

the mar$flags field is packed with flags, and it's giving bit-level drama ๐Ÿ’…:

   Bit 15  - mar$flags.layer3grp.
   Bit 14  - mar$flags.copy.
   Bit 13  - mar$flags.register.
   Bit 12  - mar$flags.punched.
   Bit 0-7 - mar$flags.sequence.

bits 8 to 11 are reserved and MUST be zero ๐Ÿ™ˆ. no exceptions, no vibes-based bits!

mar$flags.sequence gets set by cluster members, and the MARS MUST always pass it on unmodified when it retransmits a MARS_JOIN or MARS_LEAVE ๐Ÿ”. it's source specific, so other cluster members MUST ignore it ๐Ÿ‘€. the details live in section 5.2.2 โœจ.

mar$flags.punched MUST be zero when a MARS_JOIN or MARS_LEAVE is sent to the MARS ๐Ÿซง. its use is explained in section 5.2.2 and section 6.2.4 ๐Ÿฆ‹.

mar$flags.copy MUST be set to 0 when a MARS client is the one sending the message, and it MUST be set to 1 when the message is coming from a MARS ๐ŸŒˆ. (this flag exists so the MARS function can be integrated with one of the MARS clients in your cluster, and the destination of an incoming MARS_JOIN can be figured out from its value ๐Ÿงฉ. iykyk.)

mar$flags.layer3grp lets the MARS hand out the group membership info from section 5.3 ๐Ÿ“ก. the rules are literally this:

  • mar$flags.layer3grp MUST be set when the cluster member is issuing the MARS_JOIN because a layer 3 multicast group was explicitly joined. (for example, from a JoinHostGroup operation in an RFC1112 compliant host ๐Ÿ–ฅ๏ธ)
  • mar$flags.layer3grp MUST be reset in each MARS_JOIN if the MARS_JOIN is just the local ip/atm interface registering to receive traffic on that group for its own reasons ๐Ÿ™‹โ€โ™€๏ธ.
  • mar$flags.layer3grp is ignored and MUST be treated as reset by the MARS for any MARS_JOIN that specifies a block covering more than a single group (like a block join from a router making sure their forwarding engines "see" all the traffic ๐Ÿšฆ).

mar$flags.register shows whether the MARS_JOIN or MARS_LEAVE is being used to register or deregister a cluster member (described in section 5.2.3) ๐ŸŽŸ๏ธ. when it's used to join or leave specific groups, the mar$register flag MUST be zero ๐Ÿ’œ.

mar$pnum tells you how many <min,max> pairs are in the message ๐Ÿ”ข. it MUST be 1 when the message is sent from a cluster member ๐Ÿ™Œ. a MARS MAY return a MARS_JOIN or MARS_LEAVE with any mar$pnum value, including zero ๐ŸŒ€. this gets explained further in section 6.2.4.

the mar$cmi field MUST be zeroed by cluster members ๐Ÿงผ, and the MARS uses it during cluster member registration, described in section 5.2.3 ๐Ÿชช.

mar$msn MUST be zero when an endpoint transmits it 0๏ธโƒฃ. when the MARS retransmits the MARS_JOIN or MARS_LEAVE, it sets mar$msn to the current value of the Cluster Sequence Number โฑ๏ธ. its use was described in section 5.1.4.

to keep construction and parsing simple, there are some restrictions on the <min,max> pairs โœ‚๏ธ:

   Assume max(N) is the <max> field from the Nth <min,max> pair.
   Assume min(N) is the <min> field from the Nth <min,max> pair.
   Assume a join/leave message arrives with K <min,max> pairs.
   The following must hold:
      max(N) < min(N+1) for 1 <= N < K
      max(N) >= min(N) for 1 <= N <= K

in plain language, the set has to be an ascending sequence of address blocks ๐Ÿ“ˆ. what counts as "greater" or "less than" can depend on the protocol ๐Ÿคทโ€โ™€๏ธ. in IPv4 environments, the addresses are treated as 32 bit, unsigned binary values (most significant byte first) ๐Ÿ”Ÿ.

5.2.1.1. Important IPv4 default values ๐ŸŒŸ

the JoinLocalGroup and LeaveLocalGroup operations are only valid for a single group 1๏ธโƒฃ. for any arbitrary group address X, the associated MARS_JOIN or MARS_LEAVE MUST specify a single pair <X, X> ๐ŸŽฏ. mar$flags.layer3grp MUST be set under these circumstances ๐Ÿ’ซ.

a router that wants to behave strictly in accordance with RFC1112 MUST specify the entire Class D space ๐ŸŒ. the associated MARS_JOIN or MARS_LEAVE MUST specify a single pair <224.0.0.0, 239.255.255.255> ๐Ÿ’Ž. whenever a router issues a MARS_JOIN only in order to forward IP traffic, it MUST reset mar$flags.layer3grp ๐Ÿ”„.

how multicast routers use alternative <min, max> values is discussed in Section 8 ๐Ÿ“š.

5.2.2. Retransmission of MARS_JOIN and MARS_LEAVE messages ๐Ÿ”

okay, so transient problems can cause messages between the MARS and cluster members to get lost ๐Ÿ˜ญ.

the fix is a simple algorithm ๐Ÿงƒ. cluster members retransmit each MARS_JOIN and MARS_LEAVE message at regular intervals until they get a copy back, either on ClusterControlVC or on the VC they sent the message on ๐Ÿ“ฌ. at that point, the local endpoint can be certain the MARS received and processed it ๐Ÿซถ.

the interval should be no shorter than 5 seconds, and a default value of 10 seconds is recommended โฐ. after 5 retransmissions, the attempt should be flagged locally as a failure ๐Ÿšฉ. this MUST be considered a MARS failure, and it triggers the MARS reconnection described in section 5.4 ๐Ÿ’ฅ.

a 'copy' is a received message whose following fields match a previously transmitted MARS_JOIN/LEAVE ๐Ÿ‘ฏโ€โ™€๏ธ:

  • mar$op
  • mar$flags.register
  • mar$flags.sequence
  • mar$pnum
  • Source ATM address
  • First <min,max> pair

on top of that, a valid copy MUST have these field values ๐Ÿ’…:

  • mar$flags.punched = 0
  • mar$flags.copy = 1

mar$flags.sequence is never modified or checked by a MARS ๐Ÿ™…โ€โ™€๏ธ. implementors MAY choose to use locally significant sequence number schemes, which MAY differ from one cluster member to the next ๐ŸŽฒ. without such a scheme, the default value for mar$flags.sequence MUST be zero 0๏ธโƒฃ.

careful implementations MAY have more than one unacknowledged MARS_JOIN/LEAVE outstanding at a time ๐Ÿง โœจ.

5.2.3. Cluster member registration and deregistration ๐Ÿชช

to become a cluster member, an endpoint has to register with the MARS ๐ŸŽ€. this does two things at once ๐Ÿ‘‘: the endpoint gets added as a leaf node of ClusterControlVC, and it gets assigned a 16 bit Cluster Member Identifier (CMI) ๐Ÿ†”. the CMI uniquely identifies each endpoint attached to the cluster ๐Ÿ’–.

registration with the MARS happens when an endpoint issues a MARS_JOIN with mar$flags.register set to one (bit 13 of the mar$flags field) ๐ŸŽŸ๏ธ.

the cluster member MUST include its source ATM address, and it MAY choose to specify a null source protocol address when registering ๐ŸŒท.

no protocol specific group addresses are included in a registration MARS_JOIN ๐Ÿ™…โ€โ™€๏ธ.

the cluster member retransmits this MARS_JOIN in accordance with section 5.2.2 until it confirms the MARS received it ๐Ÿ”.

when the registration MARS_JOIN comes back, it contains a non-zero value in mar$cmi โœจ. the cluster member MUST note this value and use it whenever it needs its CMI ๐Ÿ“.

an endpoint may also choose to deregister, using a MARS_LEAVE with mar$flags.register set ๐Ÿ‘‹. this makes the MARS drop the endpoint from ClusterControlVC, remove all references to the member in the mapping database, and free up its CMI ๐Ÿซง.

same as registration, a deregistration request MUST include the correct source ATM address for the cluster member, but it MAY choose to specify a null source protocol address ๐Ÿงพ.

the cluster member retransmits this MARS_LEAVE in accordance with section 5.2.2 until it confirms the MARS received it ๐Ÿ”๐Ÿ’….

5.3. Support for Layer 3 group management ๐Ÿงš

so the whole point of this spec is to stay independent of layer 3 stuff ๐Ÿ™ˆ, but it does try to help layer 3 multicast routing protocols figure out whether any groups have members inside a cluster ๐Ÿ”.

IP is one example. IGMP (described in section 2) is used just to figure out whether any other cluster members are listening to a group, because they have higher layer applications that want that group's traffic ๐Ÿ“ป.

routers can choose to ask the MARS for this info, instead of multicasting IGMP queries to 224.0.0.1 and paying the cost of setting up a VC to every system in the cluster ๐Ÿ’ธ. slay, efficiency ๐Ÿ’….

the query gets sent as a MARS_GROUPLIST_REQUEST to the MARS ๐Ÿ“จ. the MARS_GROUPLIST_REQUEST is built from a MARS_JOIN, but it has an operation code of 10 ๐Ÿ”Ÿ. the MARS uses the first <min,max> pair to identify the range of groups the querying cluster member is interested in, and any additional <min,max> pairs get ignored ๐Ÿ™…โ€โ™€๏ธ. a request with mar$pnum = 0 will be ignored too ๐Ÿšซ.

the MARS responds with a MARS_GROUPLIST_REPLY, which carries a list of the multicast groups inside the specified <min,max> block that have Layer 3 members ๐Ÿ“‹. a group shows up in this list if one or more of the MARS_JOINs that made its mapping entry in the MARS had a set mar$flags.layer3grp flag ๐Ÿท๏ธ.

MARS_GROUPLIST_REPLYs go back to the querying cluster member on the VC that was used to send the MARS_GROUPLIST_REQUEST ๐Ÿ›ค๏ธ.

the MARS_GROUPLIST_REPLY is derived from the MARS_MULTI, but with mar$op = 11 ๐Ÿงฉ. it may come in multiple parts if needed, and it gets received in a similar manner to a MARS_MULTI ๐Ÿ“ฆโœจ.

Okay so the whole group list reply layout is right here, and it's giving structured ๐Ÿ’…

      Data:
       mar$afn      16 bits  Address Family (0x000F).
       mar$pro      56 bits  Protocol Identification.
       mar$hdrrsv   24 bits  Reserved. Unused by MARS control protocol.
       mar$chksum   16 bits  Checksum across entire MARS message.
       mar$extoff   16 bits  Extensions Offset.
       mar$op       16 bits  Operation code (MARS_GROUPLIST_REPLY).
       mar$shtl      8 bits  Type & length of source ATM number. (r)
       mar$sstl      8 bits  Type & length of source ATM subaddress. (q)
       mar$spln      8 bits  Length of source protocol address (s)
       mar$thtl      8 bits  Unused - set to zero.
       mar$tstl      8 bits  Unused - set to zero.
       mar$tpln      8 bits  Length of target group address (z)
       mar$tnum     16 bits  Number of group addresses returned (N).
       mar$seqxy    16 bits  Boolean flag x and sequence number y.
       mar$msn      32 bits  MARS Sequence Number.
       mar$sha      roctets  source ATM number.
       mar$ssa      qoctets  source ATM subaddress.
       mar$spa      soctets  source protocol address
       mar$mgrp.1   zoctets  Group address 1
                 [.......]
       mar$mgrp.N   zoctets  Group address N

mar$seqxy works the same way as it does for MARS_MULTI, so multi-part MARS_GROUPLIST_REPLY components get sent and received with the same algorithm from section 5.1.1 โœจ The only difference is that you're getting protocol addresses back instead of ATM addresses ๐Ÿฆ‹

Also, if something goes wrong while receiving a multi-part MARS_GROUPLIST_REPLY, the whole thing MUST be discarded and the MARS_GROUPLIST_REQUEST re-issued ๐Ÿ’€ (This includes the mar$msn value staying constant, so yes, it's strict.)

Lowkey important: being able to generate MARS_GROUPLIST_REQUEST messages and receive MARS_GROUPLIST_REPLY messages is not required for general host interface implementations ๐ŸŒธ It's optional for interfaces that are being built to support layer 3 multicast forwarding engines. BUT this functionality MUST be supported by the MARS ๐Ÿ‘‘


5.4. Support for redundant/backup MARS entities. ๐Ÿซถ

Endpoints are assumed to have been configured with the ATM address of at least one MARS. Endpoints MAY choose to keep a table of ATM addresses for alternative MARSs, which get contacted if normal operation with the original MARS is deemed to have failed. It's assumed that this table orders the ATM addresses in descending order of preference ๐Ÿ“

An endpoint will typically decide there are problems with the MARS when:

  • It fails to establish a point to point VC to the MARS.
  • MARS_REQUESTs fail (section 5.1.1).
  • MARS_JOIN/MARS_LEAVEs fail (section 5.2.2).
  • It has not received a MARS_REDIRECT_MAP in the last 4 minutes (section 5.4.3).

(If it can tell which connection is ClusterControlVC, it may also use connection failures on this VC to indicate problems with the MARS ๐Ÿ™ˆ)

5.4.1. First response to MARS problems. ๐Ÿ˜ญ

The first response is to assume it's a transient problem with the MARS being used at the time ๐Ÿงš The cluster member should wait a random period of time between 1 and 10 seconds before trying to reconnect and re-register with the MARS. If the registration MARS_JOIN works out, then:

The cluster member MUST then proceed to rejoin every group that its local higher layer protocol(s) have joined. it is recommended that a random delay between 1 and 10 seconds be inserted before attempting each MARS_JOIN. The cluster member MUST initiate the revalidation of every multicast group it was sending to (as though a sequence number jump had been detected, section 5.1.5). The rejoin and revalidation procedure must not disrupt the cluster member's use of multipoint VCs that were already open at the time of the MARS failure.

If re-registration with the current MARS fails, and there are no backup MARS addresses configured, the cluster member MUST wait for at least 1 minute before repeating the re-registration procedure. It is RECOMMENDED that the cluster member signals an error condition in some locally significant fashion ๐Ÿšจ

This procedure may repeat until network administrators manually step in or the current MARS goes back to normal operation ๐ŸŒˆ

5.4.2. Connecting to a backup MARS. ๐Ÿฆ‹

If re-registration with the current MARS fails, and other MARS addresses have been configured, the next MARS address on the list becomes the current MARS, and the cluster member immediately restarts the re-registration procedure described in section 5.4.1. If that's succesful, the cluster member resumes normal operation using the new MARS โœจ It is RECOMMENDED that the cluster member signals a warning of this condition in some locally significant fashion.

If the attempt at re-registration with the new MARS fails, the cluster member MUST wait for at least 1 minute before choosing the next MARS address in the table and repeating the procedure. If the end of the table has been reached, the cluster member starts again at the top of the table (which should be the original MARS that the cluster member started with) ๐Ÿ”„

In the worst case scenario, cluster members end up looping through their table of possible MARS addresses until network administrators manually step in ๐Ÿ˜ตโ€๐Ÿ’ซ

5.4.3. Dynamic backup lists, and soft redirects. ๐Ÿ’œ

To support some level of autoconfiguration, there's a MARS message that lets the current MARS broadcast a table of backup MARS addresses on ClusterControlVC ๐ŸŽ€ When this message is received, cluster members that keep a list of backup MARS addresses MUST insert this information at the top of their locally held list. (The info the MARS provides has a higher preference than addresses that may have been manually configured into the cluster member, so it's the main character ๐Ÿ‘‘)

The message is MARS_REDIRECT_MAP. It's based on the MARS_MULTI message, with these changes:

  • mar$tpln field replaced by mar$redirf.
  • mar$spln field reserved.
  • mar$tpa and mar$spa eliminated.

MARS_REDIRECT_MAP has an operation type code of 12 decimal.

      Data:
       mar$afn      16 bits  Address Family (0x000F).
       mar$pro      56 bits  Protocol Identification.
       mar$hdrrsv   24 bits  Reserved. Unused by MARS control protocol.
       mar$chksum   16 bits  Checksum across entire MARS message.
       mar$extoff   16 bits  Extensions Offset.
       mar$op       16 bits  Operation code (MARS_REDIRECT_MAP).
       mar$shtl      8 bits  Type & length of source ATM number. (r)
       mar$sstl      8 bits  Type & length of source ATM subaddress. (q)
       mar$spln      8 bits  Length of source protocol address (s)
       mar$thtl      8 bits  Type & length of target ATM number (x)
       mar$tstl      8 bits  Type & length of target ATM subaddress (y)
       mar$redirf    8 bits  Flag controlling client redirect behaviour.
       mar$tnum     16 bits  Number of MARS addresses returned (N).
       mar$seqxy    16 bits  Boolean flag x and sequence number y.
       mar$msn      32 bits  MARS Sequence Number.
       mar$sha      roctets  source ATM number
       mar$ssa      qoctets  source ATM subaddress
       mar$tha.1    xoctets  ATM number for MARS 1
       mar$tsa.1    yoctets  ATM subaddress for MARS 1
       mar$tha.2    xoctets  ATM number for MARS 2
       mar$tsa.2    yoctets  ATM subaddress for MARS 2
                 [.......]
       mar$tha.N    xoctets  ATM number for MARS N
       mar$tsa.N    yoctets  ATM subaddress for MARS N

The source ATM address field(s) MUST identify the originating MARS ๐Ÿซถ A multi-part MARS_REDIRECT_MAP can be sent and reassembled using mar$seqxy in the same way as a multi-part MARS_MULTI (section 5.1.1). If something fails during reassembly of a multi-part MARS_REDIRECT_MAP (a part gets lost, reassembly times out, or there's an illegal MARS Sequence Number jump), the entire message MUST be discarded ๐Ÿ’€

This message is sent regularly by the MARS. It MUST be transmitted at least every 2 minutes, and it is RECOMMENDED that it is transmitted every 1 minute โฐ

MARS_REDIRECT_MAP is also used to force cluster members to shift from one MARS to another. If the ATM address of the first MARS in a MARS_REDIRECT_MAP table is not the address of the cluster member's current MARS, the client MUST 'redirect' to the new MARS. The mar$redirf field controls how that redirection happens ๐Ÿฆ‹

mar$redirf has the following format:

                7 6 5 4 3 2 1 0
               +-+-+-+-+-+-+-+-+
               |x|             |
               +-+-+-+-+-+-+-+-+

If Bit 7 (the most significant bit) of mar$redirf is 1, the cluster member MUST perform a 'hard' redirect. After installing the new table of MARS addresses carried by the MARS_REDIRECT_MAP, the cluster member re-registers with the MARS now at the top of the table, using the mechanism described in sections 5.4.1 and 5.4.2 ๐Ÿš€

If Bit 7 of mar$redirf is 0, the cluster member MUST perform a 'soft' redirect, starting with these actions:

  • open a point to point VC to the first ATM address.
  • attempt a registration (section 5.2.3).

If the registration succeeds, the cluster member shuts down its point to point VC to the current MARS (if it had one open), and then starts using the newly opened point to point VC as its connection to the 'current MARS'. The cluster member does NOT attempt to rejoin the groups it is a member of, or revalidate groups it is currently sending to โœจ

This is called a 'soft redirect' because it skips the extra rejoining and revalidation work that happens when you're recovering from a MARS failure ๐ŸŒธ It assumes some external synchronisation mechanisms exist between the old and new MARS, and those mechanisms are outside the scope of this specification.

Some level of trust is required before starting a soft redirect. A cluster member MUST check that the calling party at the other end of the VC on which the MARS_REDIRECT_MAP arrived (supposedly ClusterControlVC) is actually the node it trusts as the current MARS ๐Ÿ”

Additional applications of this function are for further study ๐Ÿ”ญ

5.5. Data path LLC/SNAP encapsulations. ๐ŸŒˆ

An extended encapsulation scheme is required to support filtering of possible reflected packets (section 3.3) ๐Ÿชž

Two LLC/SNAP codepoints are allocated from the IANA OUI space. These support two different mechanisms for detecting reflected packets, and they're called Type #1 and Type #2 multicast encapsulations ๐Ÿ’–

Type #1

   [0xAA-AA-03][0x00-00-5E][0x00-01][Type #1 Extended Layer 3 packet]
      LLC         OUI        PID

Type #2

   [0xAA-AA-03][0x00-00-5E][0x00-04][Type #2 Extended Layer 3 packet]
      LLC         OUI        PID

For conformance with this document, MARS clients:

  • MUST transmit data using Type #1 encapsulation.
  • MUST be able to correctly receive traffic using Type #1 OR Type #2 encapsulation.
  • MUST NOT transmit using Type #2 encapsulation.

5.5.1 Type #1 encapsulation. โœจ

Okay bestie, the Type #1 Extended layer 3 packet carries a copy of the source's Cluster Member ID (CMI) ๐ŸŽ€ plus either the 'short form' or 'long form' of the protocol type, whichever one fits (section 4.3). ๐Ÿ’…

For protocols with a valid short form, the packet is encoded like this:

      [pkt$cmi][pkt$pro][Original Layer 3 packet]
        2octet   2octet        N octet

The first 2 octets (pkt$cmi) carry the CMI that gets assigned when an endpoint registers with the MARS (section 5.2.3) ๐Ÿฆ‹. The second 2 octets (pkt$pro) tell you the protocol type of the packet in the rest of the payload. It's copied from the mar$pro field used in the MARS control messages ๐Ÿ’–.

For protocols that only have a long form (pkt$pro = 0x80), the overhead SHALL be extended further to carry the 5 byte mar$pro.snap field, with padding for 32 bit alignment. The encoded form SHALL be:

      [pkt$cmi][0x00-80][mar$pro.snap][padding][Original Layer 3 packet]
        2octet   2octet   5 octets   3 octets        N octet

The CMI gets copied into the pkt$cmi field of every outgoing Type #1 packet ๐ŸŒธ. When an endpoint interface receives an AAL_SDU with the LLC/SNAP codepoint for Type #1 encapsulation, it compares the CMI field with its own Cluster Member ID for the protocol in question. If they match, the packet is discarded silently ๐Ÿ™ˆ. Otherwise, the packet is accepted and handed to the local protocol entity identified by the pkt$pro (and possibly SNAP) field(s). No reflections allowed, periodt.

Where a protocol has valid short and long forms of identification, receivers MAY choose to additionally recognise the long form. โœจ

5.5.2 Type #2 encapsulation. ๐Ÿ’Œ

Future developments may enable direct multicasting of AAL_SDUs beyond cluster boundaries ๐ŸŒˆ. Expanding the set of possible sources like that could make the CMI an inadequate way to detect reflected packets. A larger source identification field may be required ๐Ÿ‘€.

The Type #2 Extended layer 3 packet carries an 8 octet source ID field plus either the 'short form' or 'long form' of the protocol type, whichever fits (section 4.3) ๐Ÿงš. The form and content of the source ID field is currently unspecified, and it isn't relevant to any MARS client built in conformance with this document. Received Type #2 encapsulated packets MUST always be accepted and passed up to the higher layer indicated by the protocol identifier. Non-negotiable, iconic behaviour ๐Ÿ‘‘.

For protocols with a valid short form, the packet is encoded as:

      [8 octet sourceID][mar$pro.type][Null pad][Original Layer 3
      packet]
                           2octets     2octets

For protocols that only have a long form (pkt$pro = 0x80), the overhead SHALL be extended further to carry the 5 byte mar$pro.snap field, with padding for 32 bit alignment. The encoded form SHALL be:

      [8 octet sourceID][mar$pro.type][mar$pro.snap][Null pad][Layer 3
      packet]

                           2octets      5octets      1octet

(Quick note ๐Ÿ“: in this case the padding after the SNAP field is 1 octet, not the 3 octets used in Type #1.)

Where a protocol has valid short and long forms of identification, receivers MAY choose to additionally recognise the long form. ๐Ÿฆ‹

(Future documents may specify the contents of the source ID field. This will only matter to implementations sending Type #2 encapsulated packets, since they're the only entities that need to worry about detecting reflected Type #2 packets ๐Ÿซถ.)

5.5.3 A Type #1 example. ๐Ÿ“

An IPv4 packet (fully identified by an Ethertype of 0x800, so it needs 'short form' protocol type encoding) would be transmitted as:

      [0xAA-AA-03][0x00-00-5E][0x00-01][pkt$cmi][0x800][IPv4 packet]

The different LLC/SNAP codepoints for unicast and multicast transmission let a single IPv4/ATM interface support both, just by demuxing on the LLC/SNAP header. Gorgeous design, honestly ๐Ÿ˜ญโœจ.


6. The MARS in greater detail. ๐ŸŒŸ

Section 5 implies a lot about the MARS's basic behaviour as observed by cluster members ๐Ÿ‘€. This section sums up how the MARS behaves for groups that are VC mesh based, and how its behaviour changes when an MCS is registered to support a group ๐Ÿงš.

The MARS is meant to be a multiprotocol entity. All its mapping tables, CMIs, and control VCs MUST be managed within the context of the mar$pro field in incoming MARS messages. For example, a MARS keeps completely separate ClusterControlVCs for each layer 3 protocol it registers members for. If a MARS receives messages with a mar$pro it doesn't support, the message is dropped ๐Ÿ’….

In general, the MARS treats protocol addresses as arbitrary byte strings. For example, the MARS won't apply IPv4 specific 'class' checks to addresses supplied under mar$pro = 0x800. It's enough for the MARS to assume that endpoints know how to interpret the protocol addresses they're establishing and releasing mappings for. Trust the endpoints, bestie ๐Ÿซถ.

The MARS requires control messages to carry the originator's identity in the source ATM address field(s). Messages that arrive with an empty ATM Number field are silently discarded before any other processing by the MARS ๐Ÿ™ˆ. (Only the ATM Number field needs checking. An empty ATM Number field combined with a non-empty ATM Subaddress field does not make a valid ATM address.)

(Some example pseudo-code for a MARS can be found in Appendix F. ๐Ÿ“–)

6.1 Basic interface to Cluster members. ๐ŸŽ€

The following MARS messages are used or required by cluster members:

      1    MARS_REQUEST
      2    MARS_MULTI
      4    MARS_JOIN
      5    MARS_LEAVE
      6    MARS_NAK
      10   MARS_GROUPLIST_REQUEST
      11   MARS_GROUPLIST_REPLY
      12   MARS_REDIRECT_MAP

6.1.1 Response to MARS_REQUEST. ๐Ÿ’Œ

Except as described in section 6.2, if a MARS_REQUEST arrives whose source ATM address doesn't match any registered Cluster member, the message MUST be dropped and ignored. Bye bye, random requests ๐Ÿ‘‹.

6.1.2 Response to MARS_JOIN and MARS_LEAVE. ๐Ÿฆ‹

When a registration MARS_JOIN arrives (described in section 5.2.3), the MARS does the following:

  • Adds the node to ClusterControlVC.
  • Allocates a new Cluster Member ID (CMI).
  • Inserts the new CMI into the mar$cmi field of the MARS_JOIN.
  • Retransmits the MARS_JOIN back privately.

If the node is already a registered member of the cluster for the specified protocol type, its existing CMI is simply copied into the MARS_JOIN, and the MARS_JOIN gets retransmitted back to the node. A single node may register multiple times if it supports multiple layer 3 protocols. The CMIs the MARS allocates for each of those registrations may or may not be the same ๐ŸŒธ.

The retransmitted registration MARS_JOIN must NOT be sent on ClusterControlVC. If a cluster member issues a deregistration MARS_LEAVE, it too gets retransmitted privately ๐Ÿ™ˆ.

Non-registration MARS_JOIN and MARS_LEAVE messages are ignored if they arrive from a node that isn't registered as a cluster member ๐Ÿ’€.

MARS_JOIN or MARS_LEAVE messages MUST arrive at the MARS with mar$flags.copy set to 0. Otherwise the message is silently ignored ๐Ÿ™….

All outgoing MARS_JOIN or MARS_LEAVE messages SHALL have mar$flags.copy set to 1, and mar$msn set to the current Cluster Sequence Number for ClusterControlVC (Section 5.1.4.2) ๐Ÿงพ.

mar$flags.layer3grp (section 5.3) MUST be treated as reset for MARS_JOINs specifying a single <min,max> pair covering more than a single group. If a MARS_JOIN/LEAVE is received that contains more than one <min,max> pair, the MARS MUST silently drop the message ๐Ÿšซ.

If one or more MCSs have registered with the MARS, message processing continues as described in section 6.2.4 โœจ.

The MARS database gets updated to add the node to any indicated group(s) it wasn't already considered a member of, and message processing continues as follows:

If a single group was being joined or left:

mar$flags.punched is set to 0.

If the joining (leaving) node was already (is still) considered a member of the specified group, the message is retransmitted privately back to the cluster member. Otherwise, the message is retransmitted on ClusterControlVC ๐Ÿ’ซ.

If a single block covering 2 or more groups was being joined or left:

A copy of the original MARS_JOIN/LEAVE is made. This copy then has its <min,max> block replaced with a 'hole punched' set of zero or more <min,max> pairs. The 'hole punched' set of <min,max> pairs covers the entire address range specified by the original <min,max> pair, but excludes those addresses/groups which the joining (leaving) node is already (still) a member of due to a previous single group join ๐Ÿ•ณ๏ธ.

If no 'holes' were punched in the specified block, the original MARS_JOIN/LEAVE is retransmitted out on ClusterControlVC. Otherwise, the following happens:

The original MARS_JOIN/LEAVE is transmitted back to the source cluster member unchanged, using the VC it arrived on. The mar$flags.punched field MUST be reset to 0 in this message.

If the hole-punched set contains 1 or more <min,max> pair, the copy of the original MARS_JOIN/LEAVE is transmitted on ClusterControlVC, carrying the new <min,max> list. The mar$flags.punched field MUST be set to 1 in this message. (The mar$flags.punched field is set so the hole-punched copy is ignored by the message's source when it tries to match received MARS_JOIN/LEAVE messages with ones it previously sent (section 5.2.2). Clever, right? ๐Ÿง )

If the MARS receives a deregistration MARS_LEAVE (described in section 5.2.3), that member's ATM address MUST be removed from all groups it may have joined, dropped from ClusterControlVC, and its CMI released ๐Ÿ‘‹.

If the MARS receives an ERR_L_RELEASE on ClusterControlVC indicating that a cluster member has disconnected, that member's ATM address MUST be removed from all groups it may have joined, and its CMI released ๐Ÿฅ€.

6.1.3 Generating MARS_REDIRECT_MAP. ๐Ÿ—บ๏ธ

A MARS_REDIRECT_MAP message (described in section 5.4.3) MUST be regularly transmitted on ClusterControlVC. It is RECOMMENDED that this happens every 1 minute, and it MUST happen at least every 2 minutes. If the MARS has no knowledge of other backup MARSs serving the cluster, it MUST include its own address as the only entry in the MARS_REDIRECT_MAP message (in addition to filling in the source address fields). Main character energy in one message ๐ŸŒˆ๐Ÿ‘‘

The design and use of backup MARS entities is beyond the scope of this document, and will be covered in future work. ๐Ÿ”ฎ

6.1.4. Cluster Sequence Numbers โœจ

okay so the Cluster Sequence Number (CSN) is the thing from section 5.1.4 ๐Ÿ”ข It rides along in the mar$msn field of every MARS message going to cluster members, whether that's out ClusterControlVC or on an individual VC. The MARS bumps the CSN after every transmission on ClusterControlVC, and whatever the current CSN is gets copied into mar$msn on messages to members, whether they're going out ClusterControlVC or on a private VC ๐Ÿ’…

A MARS should be carefully designed to minimise the possibility of the CSN jumping unnecessarily. Under normal operation, only cluster members hit by transient link problems will miss CSN updates and have to revalidate. But if the MARS itself glitches, it gets absolutely flooded with requests for a while, because every cluster member tries to revalidate at once ๐Ÿ˜ญ

Calculations on the CSN MUST be performed as unsigned 32 bit arithmetic. This is a must-do, no exceptions ๐Ÿ”ฅ

One implication of this mechanism is that the MARS should serialize its processing of "simultaneous" MARS_REQUEST, MARS_JOIN and MARS_LEAVE messages. Join and Leave operations get queued up inside the MARS alongside MARS_REQUESTs, and they don't get processed until all the reply packets of a preceding MARS_REQUEST have been transmitted. The transmission of MARS_REDIRECT_MAP should be queued up the same way ๐ŸŽ€

(The regular transmission of MARS_REDIRECT_MAP has a secondary job too: it lets cluster members track the CSN, even if they missed an earlier MARS_JOIN or MARS_LEAVE. iykyk ๐Ÿงš)


6.2. MARS interface to Multicast Servers (MCS) ๐Ÿ’–

When the MARS hands back the actual addresses of group members, the endpoint behaviour described in section 5 means every group ends up supported by meshes of point to multipoint VCs. But when MCSs register to support particular layer 3 multicast groups, the MARS changes how it uses various MARS messages to fool endpoints into using the MCS instead ๐ŸŽญ

The following MARS messages are associated with interaction between the MARS and MCSs:

   3   MARS_MSERV
   7   MARS_UNSERV
   8   MARS_SJOIN
   9   MARS_SLEAVE

The following MARS messages are treated in a slightly different manner when MCSs have registered to support certain group addresses:

   1   MARS_REQUEST
   4   MARS_JOIN
   5   MARS_LEAVE

A MARS must keep two sets of mappings for each layer 3 group using MCS support. The original {layer 3 address, ATM.1, ATM.2, ... ATM.n} mapping (now called the 'host map', even though it includes routers) gets a parallel buddy, the {layer 3 address, server.1, server.2, ... server.K} mapping (the 'server map'). It's assumed that no ATM addresses appear in both the server and host maps for the same multicast group. Typically K will be 1, but it'll be larger if multiple MCSs are configured to support a given group ๐Ÿ“

The MARS also maintains a point to multipoint VC out to any MCSs registered with it, called ServerControlVC (section 6.2.3). This does the same job ClusterControlVC does, letting the MARS update MCSs with group membership changes as they happen. A MARS MUST also send its regular MARS_REDIRECT_MAP transmissions on both ServerControlVC and ClusterControlVC ๐Ÿ“ก

6.2.1. Response to a MARS_REQUEST if MCS is registered. ๐ŸŒธ

When the MARS gets a MARS_REQUEST for an address that has both host and server maps, it builds its response based on who the request came from. If the requestor is a member of the server map for the requested group, the MARS returns the contents of the host map in a sequence of one or more MARS_MULTIs. Otherwise, if the source is a valid cluster member, the MARS returns the contents of the server map in a sequence of one or more MARS_MULTIs. If the source is neither a cluster member nor a member of the server map for the group, the request is dropped and ignored. Not invited, not answered ๐Ÿ™…โ€โ™€๏ธ

Servers use the host map to set up a basic distribution VC for the group. Cluster members establish outgoing multipoint VCs to members of the group's server map, without being aware that their packets won't be going directly to the multicast group's members. Sneaky, but iconic ๐Ÿ‘‘

6.2.2. MARS_MSERV and MARS_UNSERV messages. ๐Ÿฆ‹

MARS_MSERV and MARS_UNSERV are identical to the MARS_JOIN message. An MCS uses a MARS_MSERV with a <min,max> pair of <X,X> to specify the multicast group X that it's willing to support. A single group MARS_UNSERV indicates the group the MCS is no longer willing to support. The operation code for MARS_MSERV is 3 (decimal), and MARS_UNSERV is 7 (decimal) ๐Ÿ”ข

Both of these messages get sent to the MARS over a point to point VC (between the MCS and the MARS). After processing, they're retransmitted on ServerControlVC so other MCSs can note the new node ๐Ÿซถ

When registering or deregistering support for specific groups, the mar$flags.register flag MUST be zero. (This flag is only one when the MCS is registering as a member of ServerControlVC, as described in section 6.2.3 ๐Ÿ’œ)

When an MCS issues a MARS_MSERV for a specific group, the message MUST be dropped and ignored if the source has not already registered with the MARS as a multicast server (section 6.2.3). Otherwise, the MARS adds the new ATM address to the server map for the specified group, possibly constructing a new server map if this is the first MCS for the group.

If a MARS_MSERV represents the first MCS to register for a particular group, and there's a non null host map serving that group, the MARS issues a MARS_MIGRATE (section 5.1.6) on ClusterControlVC. The MARS's own identity goes in the source protocol and hardware address fields of the MARS_MIGRATE. The ATM address of the MCS goes in as the first and only target ATM address. The address of the affected group goes in the target multicast group address field ๐Ÿšš

If a MARS_MSERV is not the first MCS to register for a particular group, the MARS simply changes its operation code to MARS_JOIN and sends a copy of the message on ClusterControlVC. This fools the cluster members into thinking a new leaf node has been added to the group specified ๐ŸŽญ In the retransmitted MARS_JOIN, mar$flags.layer3grp MUST be zero, mar$flags.copy MUST be one, and mar$flags.register MUST be zero.

When an MCS issues a MARS_UNSERV, the MARS removes its ATM address from the server maps for each specified group, deleting any server maps that end up null after the operation ๐Ÿ—‘๏ธ

The operation code is then changed to MARS_LEAVE, and the MARS sends a copy of the message on ClusterControlVC. This fools the cluster members into thinking a leaf node has been dropped from the group specified. In the retransmitted MARS_LEAVE, mar$flags.layer3grp MUST be zero, mar$flags.copy MUST be one, and mar$flags.register MUST be zero ๐Ÿ’…

The MARS retransmits redundant MARS_MSERV and MARS_UNSERV messages directly back to the MCS generating them. MARS_MIGRATE messages are never repeated in response to redundant MARS_MSERVs ๐Ÿ™ˆ

The last or only MCS for a group MAY choose to issue a MARS_UNSERV while the group still has members. When the MARS_UNSERV is processed by the MARS, the 'server map' gets deleted. When the associated MARS_LEAVE is issued on ClusterControlVC, all cluster members with a VC open to the MCS for that group will close the VC (in accordance with section 5.1.4, since the MCS was their only leaf node). When cluster members later find they need to transmit packets to the group, they begin again with the MARS_REQUEST/MARS_MULTI sequence to set up a new VC. Since the MARS has deleted the server map, this results in the host map being returned, and the group reverts to being supported by a VC mesh. Full circle, bestie ๐Ÿ”„

The reverse process is achieved through the MARS_MIGRATE message when the first MCS registers to support a group. This ensures that cluster members explicitly dismantle any VC mesh they may have had up, and re-establish their multicast forwarding path with the MCS as its termination point. main character energy, fr โœจ๐ŸŒˆ๐Ÿ’–

6.2.3. Registering a Multicast Server (MCS) ๐Ÿงš

Okay so 6.2.3 is giving "registration, but make it MCS" ๐Ÿ’… Remember section 5.2.3, where endpoints sign up as cluster members and get added as leaf nodes to ClusterControlVC? Same energy here, bestie. Endpoints that want to provide MCS support use the same approach ๐Ÿซถ

Registration with the MARS happens when an endpoint sends a MARS_MSERV with mar$flags.register set to one โœจ Once it's registered, the endpoint gets added as a leaf node to ServerControlVC, and the MARS_MSERV gets sent back to the MCS privately ๐Ÿฆ‹

The MCS keeps resending that MARS_MSERV until it gets proof the MARS actually received it. That proof is getting a copy back, which works just like the reliable-sending thing from section 5.2.2 for MARS_JOINs ๐Ÿ˜ญ

The mar$cmi field in MARS_MSERVs MUST be set to zero by both MCS and MARS. ๐Ÿ’… Non-negotiable, periodt.

An MCS can also choose to de-register using a MARS_UNSERV with mar$flags.register set to one. When that happens, the MARS MUST remove all references to that MCS in all servermaps tied to the protocol (mar$pro) named in the MARS_UNSERV, and drop the MCS from ServerControlVC. ๐Ÿ—‘๏ธ Bye bye, no cap.

Here's the tea: multiple logical MCSs can share the same physical ATM interface, as long as each one uses its own ATM address (like a different SEL field in the NSAP format address) ๐ŸŒธ Honestly iconic. An MCS can even share the ATM interface of a node that's also a cluster member (host or router), provided each logical entity has a different ATM address ๐Ÿ‘‘

A MARS MUST be capable of handling a multi-entry servermap. ๐Ÿ”ฅ But whether multiple MCSs can register to support the same group? That's still a subject for further study ๐Ÿ™ˆ Until there's an MCS synchronisation protocol, a system administrator MUST NOT let more than one logical MCS register for a given group. Hard no ๐Ÿ’€


6.2.4. Modified response to MARS_JOIN and MARS_LEAVE ๐ŸŽ€

So some groups have MCSs supporting them and some don't, which means the MARS has to change how it hands out single and block join/leave updates to cluster members. The MARS also adds two new messages, MARS_SJOIN and MARS_SLEAVE, for telling MCSs about group changes over ServerControlVC ๐Ÿ“ฃ

MARS_SJOIN and MARS_SLEAVE are identical to MARS_JOIN, just with operation codes 18 and 19 (decimal) respectively ๐Ÿ”ข

When a cluster member sends MARS_JOIN or MARS_LEAVE for a single group, the MARS checks whether that group has an associated server map. If the group doesn't have one, processing carries on like section 6.1.2 says ๐Ÿง 

But if a server map does exist for the group, a whole new set of actions kicks in ๐Ÿš€

  • If the joining (leaving) node was not already (is no longer) considered a member of the specified group, a copy of the MARS_JOIN/LEAVE is made with type MARS_SJOIN or MARS_SLEAVE as appropriate, and transmitted on ServerControlVC. This lets the MCS(s) supporting the group notice the new member and update their data VCs ๐Ÿ‘€
  • The original message is sent back to the source cluster member unchanged, using the VC it arrived on instead of ClusterControlVC. The mar$flags.punched field MUST be reset to 0 in this message. ๐Ÿซง

(Quick aside: section 5.2.2 says cluster members need a way to confirm the MARS got their message. For mesh supported groups, using ClusterControlVC does double duty, confirming receipt AND distributing group update info. When a group is MCS supported, there's no reason for every cluster member to process null join/leave messages on ClusterControlVC, so those get sent back on the private VC between the cluster member and the MARS ๐Ÿ’…)

Now, receiving a block MARS_JOIN (like from a router coming online) or MARS_LEAVE is a bit more complicated ๐Ÿ˜ค The single <min,max> block might cover both mesh supported and MCS supported groups at the same time. But cluster members only need to hear about the mesh supported groups the endpoint has joined, and only the MCSs need to know if the endpoint is joining any MCS supported groups ๐Ÿงฉ

So the fix is to modify the MARS_JOIN or MARS_LEAVE that gets retransmitted on ClusterControlVC. Here's what happens:

  • A copy of the MARS_JOIN/LEAVE is made with type MARS_SJOIN or MARS_SLEAVE as appropriate, with its <min,max> block replaced by a "hole punched" set of zero or more <min,max> pairs. The "hole punched" set covers the entire address range from the original <min,max> pair, but leaves out the addresses/groups which the joining (leaving) node is already (still) a member of due to a previous single group join. ๐Ÿ•ณ๏ธ
  • Before anything goes out on ClusterControlVC, the original MARS_JOIN/LEAVE has its <min,max> block replaced by a "hole punched" set of zero or more <min,max> pairs. This set covers the entire address range from the original <min,max> pair, but leaves out the addresses/groups supported by MCSs, or which the joining (leaving) node is already (still) a member of due to a previous single group join. ๐ŸŽฏ
  • If no "holes" were punched in the specified block, the original MARS_JOIN/LEAVE is retransmitted out on ClusterControlVC unchanged. Otherwise, the following happens:
    • The original MARS_JOIN/LEAVE is transmitted back to the source cluster member unchanged, using the VC it arrived on. The mar$flags.punched field MUST be reset to 0 in this message. ๐Ÿ”
    • If the hole-punched set contains 1 or more <min,max> pair, a copy of the original MARS_JOIN/LEAVE is transmitted on ClusterControlVC, carrying the new <min,max> list. The mar$flags.punched field MUST be set to 1 in this message. ๐Ÿณ๏ธ

The mar$flags.punched field is set so the hole-punched copy gets ignored by the message's source when it's trying to match received MARS_JOIN/LEAVE messages against the ones it sent earlier (section 5.2.2). Big brain move ๐Ÿง โœจ

(Appendix A talks about some algorithms for "hole punching" ๐Ÿง)

It's assumed that MCSs use the MARS_SJOINs and MARS_SLEAVEs to update their own VCs out to the actual group's members ๐Ÿ“ก

mar$flags.layer3grp gets copied over into the messages the MARS transmits. mar$flags.copy MUST be set to one. ๐Ÿ’–


6.2.5. Sequence numbers for ServerControlVC traffic. ๐Ÿ”ข

Just like the Cluster Sequence Number, the MARS keeps a Server Sequence Number (SSN) that goes up by one after every transmission on ServerControlVC ๐Ÿ“ˆ The current SSN value goes into the mar$msn field of every message the MARS sends that it thinks is headed for an MCS. That includes MARS_MULTIs being returned in response to a MARS_REQUEST from an MCS, and MARS_REDIRECT_MAPs being sent on ServerControlVC. The MARS must check the MARS_REQUEST's source. If it's a registered MCS, the SSN gets copied into the mar$msn field. Otherwise, the CSN gets copied in instead ๐Ÿ•ต๏ธโ€โ™€๏ธ

MCSs are expected to track and use SSNs the same way endpoints use the CSN in section 5.1, which means using them to trigger revalidation of group membership info ๐Ÿ”„

A MARS should be carefully designed so the SSN doesn't jump around unnecessarily. Under normal operation, only MCSs hit by transient link problems will miss mar$msn updates and get forced to revalidate. But if the MARS itself glitches, it's going to get inundated with requests for a while, since every MCS tries to revalidate at once ๐Ÿ˜ตโ€๐Ÿ’ซ๐Ÿ’€


6.3. Why global sequence numbers? ๐Ÿค”

The CSN and SSN are global within the context of a given protocol (e.g. IPv4, mar$pro = 0x800). They count ClusterControlVC and ServerControlVC activity without referring to the multicast group(s) involved. People might see this as a limitation, because cluster members or multicast servers have no way to figure out exactly which multicast group they missed an update for. An alternative would have been a per-group sequence number ๐Ÿ’ญ

Unfortunately, per-group sequence numbers just aren't practical ๐Ÿ™…โ€โ™€๏ธ The current mechanism lets sequence info piggy-back onto MARS messages that are already in transit for other reasons. Being able to specify blocks of multicast addresses with a single MARS_JOIN or MARS_LEAVE means one message can refer to membership changes for multiple groups at the same time. A single mar$msn field can't give meaningful info about each group's sequence, and multiple mar$msn fields would have been way too unwieldy ๐Ÿฅด

Any MARS or cluster member that supports different protocols MUST keep separate mapping tables and sequence numbers for each protocol. ๐Ÿ—‚๏ธ Separate lanes, no mixing.


6.4. Redundant/Backup MARS Architectures. ๐Ÿ›Ÿ

If backup MARSs exist for a given cluster, then there need to be mechanisms that keep their mapping tables consistent with those of the active, current MARS ๐Ÿค

(Cluster members will consider backup MARSs to exist if they've been configured with a table of MARS addresses, or if the regular MARS_REDIRECT_MAP messages contain a list of 2 or more addresses.)

Defining a MARS-synchronization protocol is beyond the scope of this document. It's expected to be the subject of further research work ๐Ÿ”ฌ Still, the following observations can be made:

  • MARS_REDIRECT_MAP messages exist, which lets one MARS force endpoints to move to another MARS. For example, after a MARS failure, the chosen backup MARS will eventually want to hand control of the cluster back to the main MARS once it's working properly again ๐Ÿ”™
  • Cluster members and MCSs don't need to start up knowing about more than one MARS, as long as that MARS correctly issues MARS_REDIRECT_MAP messages with the full list of MARSs for that cluster ๐Ÿ“‹

Any mechanism for synchronising backup MARSs (and for coping with the aftermath of MARS failures) should be compatible with the cluster member behaviour described in this document ๐Ÿงฉ


7. How an MCS utilises a MARS. ๐ŸŽค

When an MCS supports a multicast group, it acts as a proxy cluster endpoint for the senders to that group. It also behaves like a sender, managing a single outgoing point to multipoint VC to the real group members ๐ŸŒˆ

Detailed descriptions of possible MCS architectures are beyond the scope of this document. This section will just outline the main issues ๐Ÿ“

7.1. Association with a particular Layer 3 group. ๐Ÿงท

When an MCS issues a MARS_MSERV, it forces all senders to the specified layer 3 group to terminate their VCs on the supplied source ATM address ๐ŸŽฏ

The simplest MCS architecture takes incoming AAL_SDUs and just flips them back out a single point to multipoint VC. An MCS like that can't support more than one group at once, because it has no way to tell apart traffic destined for different groups ๐Ÿ™ƒ So with this architecture, a physical node would provide MCS support for multiple groups by creating multiple logical instances of the MCS, each with a different ATM Address (e.g. a different SEL value in the node's NSAPA) ๐Ÿง

A slightly fancier approach is to add minimal layer 3 specific processing into the MCS. It would look inside the received AAL_SDUs and figure out which layer 3 group they're destined for. A single instance of this kind of MCS might register its ATM Address with the MARS for multiple layer 3 groups, and manage multiple independent outgoing point to multipoint VCs (one for each group) ๐Ÿฆ‹โœจ

When an MCS starts up it MUST register with the MARS as described in section 6.2.3, identifying the protocol it supports with the mar$pro field of the MARS_MSERV. This applies to logical MCSs too, even if they share the same physical ATM interface ๐Ÿซถ It's important because the MARS needs to notice when an MCS drops off ServerControlVC, so it can react. Lowkey, this means "simple" MCS setups end up with one ServerControlVC member per group ๐Ÿงš MCSs doing layer 3 specific processing can support multiple groups and still only register as one member of ServerControlVC ๐Ÿ’…

An MCS MUST NOT share the same ATM address as a cluster member, although it may share the same physical ATM interface โœจ

7.2. Termination of incoming VCs. ๐ŸŽ€

An MCS MUST terminate unidirectional VCs the same way a cluster member does. Think of it like terminating on an LLC entity when LLC/SNAP encapsulation is in use, as described in RFC 1755 for unicast endpoints ๐Ÿ’–

7.3. Management of outgoing VC. ๐Ÿฆ‹

An MCS MUST establish and manage its outgoing point to multipoint VC just like a cluster member does (section 5.1) ๐Ÿ’…

MARS_REQUEST is how the MCS sets up the initial leaf nodes for its outgoing point to multipoint VC. Once the VC is up, the MCS reacts to MARS_SJOIN and MARS_SLEAVE messages the same way a cluster member reacts to MARS_JOIN and MARS_LEAVE ๐ŸŒธ

The MCS keeps track of the Server Sequence Number from the mar$msn fields of messages from the MARS. If a sequence number jump happens, it revalidates its outgoing point to multipoint VC(s) ๐Ÿ”ฅ

7.4. Use of a backup MARS. ๐ŸŒˆ

The MCS handles backup MARSs the same way a cluster member does (section 5.4). It tracks MARS_REDIRECT_MAP messages on ServerControlVC ๐Ÿ‘‘

8. Support for IP multicast routers โœจ

Multicast routers are required to send multicast traffic beyond the limits of a single cluster (inter-cluster traffic). Honestly, they're multicast servers working one layer up, where clusters are the abstract sources and destinations instead of individual endpoints ๐Ÿงš

Multicast routers usually take part in higher layer multicast routing algorithms and policies. Those are outside the scope of this memo, for example DVMRP [5] in the IPv4 environment ๐ŸŒธ

It's assumed that multicast routers are implemented over the same sort of IP/ATM interface a multicast host would use. Their IP/ATM interfaces register with the MARS as cluster members and join and leave multicast groups as needed. Like we said in section 5, multiple logical 'endpoints' can run over a single physical ATM interface, and routers use this to get interfaces into each cluster they route between ๐Ÿ’œ

The rest of this section assumes a simple IPv4 scenario, where a cluster's scope is limited to one particular LIS that's part of an overlaid IP network. Not every LIS member is necessarily a registered cluster member, since you can have unicast-only hosts in the LIS ๐Ÿ™ˆ

8.1. Forwarding into a Cluster. ๐Ÿฆ‹

If a multicast router needs to send a packet to a group inside the cluster, its IP/ATM interface opens a VC the same way a normal host would. Once the VC is open, the router watches for MARS_JOIN and MARS_LEAVE messages and responds to them like a normal host would ๐Ÿซถ

The multicast router's transmit side MUST implement inactivity timers to shut down idle outgoing VCs, just like normal hosts do ๐Ÿ˜ญ

Just like a normal host, the multicast router doesn't need to be a member of a group it's sending to ๐Ÿ’…

8.2. Joining in 'promiscuous' mode. ๐Ÿ‘‘

Once it's registered and initialised, the simplest model of IPv4 multicast router operation is for it to issue a MARS_JOIN covering the entire Class D address space. Effectively it becomes 'promiscuous', since it'll be a leaf node to all present and future multipoint VCs set up for IPv4 groups on the cluster ๐ŸŒˆ

How a router picks which groups to propagate outside the cluster is outside the scope of this document ๐Ÿคทโ€โ™€๏ธ

Consistent with RFC 1112, IP multicast routers may keep using IGMP Query and IGMP Report messages to figure out group membership. There are certain optimisations available, though, and they're covered in section 8.5 โœจ

8.3. Forwarding across the cluster. ๐ŸŒŠ

Sometimes the cluster is just another hop between IP subnets that have participants in a multicast group ๐Ÿ“

      [LAN.1] ----- IPmcR.1 -- [cluster/LIS] -- IPmcR.2 ----- [LAN.2]

LAN.1 and LAN.2 are subnets (such as Ethernet) with attached hosts that are members of group X ๐Ÿงš

IPmcR.1 and IPmcR.2 are multicast routers with interfaces to the LIS ๐Ÿ’–

The old-school solution would be to treat the LIS as a unicast subnet and use tunneling routers. The catch is that this wouldn't let hosts on the LIS join the cross-LIS traffic ๐Ÿ˜ญ

Say IPmcR.1 is receiving packets promiscuously on its LAN.1 interface, and it's set up to propagate multicast traffic to all attached interfaces. In this case, that means the LIS ๐Ÿ‘€

When a packet for group X shows up on its LAN.1 interface, IPmcR.1 just sends it to group X on the LIS interface like a normal host would. That means issuing a MARS_REQUEST for group X, creating the VC, and sending the packet ๐Ÿฆ‹

Since IPmcR.2 initialised itself with the MARS as a member of the entire Class D space, it gets returned as a member of X even when no other nodes on the LIS are members. Every packet for group X received on IPmcR.2's LIS interface may be retransmitted on LAN.2 ๐Ÿ”ฅ

If IPmcR.1 is initialised the same way, the reverse process applies to multicast traffic going from LAN.2 to LAN.1, for any multicast group. The nice part is that cluster members within the LIS can also join and leave group X at any time ๐Ÿ’…

8.4. Joining in 'semi-promiscuous' mode. ๐ŸŒธ

Both unicast and multicast IP routers have a shared problem: they're limited by the number of AAL contexts available at their ATM interfaces. Being 'promiscuous' in the RFC 1112 sense means that for every M hosts sending to N groups, a multicast router's ATM interface ends up with M*N incoming reassembly engines tied up ๐Ÿ˜ฉ

It's easy to picture situations where a bunch of multicast groups are active within the LIS but don't need to go beyond it. A distributed simulation system built specifically for the high speed IP/ATM environment could be one example. Its traffic might have no practical use on the other side of the multicast router, yet under the conventional scheme the router would still have to be a leaf to each participating host ๐Ÿ™ƒ

Since this problem sits below the IP layer, it's worth knowing that 'scoping' mechanisms at the IP multicast routing level don't solve it. An IP level scope would still have the router's ATM interface receiving traffic on the scoped groups, only for the router to drop it ๐Ÿ’€

So in this situation, the network administrator might configure their multicast routers to exclude sections of the Class D address space when issuing MARS_JOIN(s). Groups that will never be propagated beyond the cluster won't list the router as a member, so the router never has to receive (and simply ignore) traffic from them ๐Ÿงน

Another scenario is when the product M*N goes over the capacity of a single router's interface, especially if that same interface also has to support a unicast IP router service ๐ŸŒŠ

A network administrator may choose to add a second node to act as a parallel IP multicast router. Each router is configured to be 'promiscuous' over a separate part of the Class D address space, so each one is exposed to only part of the VC load. IP hosts within the LIS won't notice any of this ๐Ÿซถ

Restricted promiscuous mode doesn't break RFC 1112's use of IGMP Report messages. If the router is configured to serve a given block of Class D addresses, it receives the IGMP Report. If it isn't configured to support a given block, an IGMP Report for a group in that block is irrelevant to the router. Either way, all routers can track membership changes through MARS_JOIN and MARS_LEAVE traffic anyway. (Section 8.5 covers a better alternative to IGMP within a cluster ๐Ÿ’œ)

Mechanisms and reasons for setting up these modes of operation are outside the scope of this document ๐ŸŽ€

8.5. An alternative to IGMP Queries. ๐Ÿงš

Honestly, the unfortunate thing about IGMP is that it assumes multicasting IP packets is a cheap and trivial event at the link layer. So routers regularly multicast IGMP Queries to group 224.0.0.1, and those queries are meant to trigger IGMP Replies from cluster members that have layer 3 members of particular groups ๐Ÿ˜ค

The MARS_GROUPLIST_REQUEST and MARS_GROUPLIST_REPLY messages were designed so routers can skip actually sending IGMP Queries out into a cluster ๐Ÿ™Œ

Whenever the router's forwarding engine wants to send an IGMP query, it can send a MARS_GROUPLIST_REQUEST to the MARS instead. The resulting MARS_GROUPLIST_REPLY(s) (described in section 5.3) from the MARS carry all the information the router would have gotten from IGMP replies ๐Ÿฆ‹

It is RECOMMENDED that multicast routers use this MARS service to cut down on IGMP traffic within the cluster ๐ŸŒˆ

By default, a MARS_GROUPLIST_REQUEST SHOULD specify the entire address space (e.g. <224.0.0.0, 239.255.255.255> in an IPv4 environment). Routers serving part of the address space (as described in section 8.4) MAY choose to issue MARS_GROUPLIST_REQUESTs that only specify the subset they're serving ๐Ÿ’–

(Okay, on the surface it'd also seem useful for multicast routers to track MARS_JOINs and MARS_LEAVEs that arrive with mar$flags.layer3grp set. Those could stand in for IGMP Reports and give the router a timely heads-up that a new layer 3 group member exists in the cluster. But this only works on VC mesh supported groups, so it's NOT recommended ๐Ÿ™…โ€โ™€๏ธ)

Appendix B covers less elegant ways to reduce IGMP traffic within a cluster, on the assumption that the IP/ATM interfaces to the cluster are being used by un-optimised IP multicasting code ๐Ÿ“

8.6. CMIs across multiple interfaces. ๐Ÿ‘ฏโ€โ™€๏ธ

The Cluster Member ID is only unique within the Cluster managed by a given MARS. At first glance, that looks like a problem when a multicast router routes between two or more Clusters over a single physical ATM interface. The router registers with two or more MARSs, so it picks up two or more independent CMIs. Since each MARS has no reason to sync its CMI allocations, a host in one cluster could end up with the same CMI as the router's interface to another Cluster. So how does the router tell its own reflected packets apart from packets sent by that other host? ๐Ÿค”

The answer is that routers (and hosts) actually run logical IP/ATM interfaces over a single physical ATM interface. Each logical interface has a unique ATM Address (eg. an NSAP with different SELector fields, one for each logical interface) ๐Ÿฆ‹

Okay so this is where each logical IP/ATM interface gets its own MARS, and honestly the whole cluster separation thing is giving main character energy ๐Ÿฆ‹. Every logical interface on the router is set up with the address of exactly one MARS, attaches to exactly one cluster, and therefore only has one CMI to keep track of ๐Ÿ’…. Each MARS the router registers with hands back a different ATM Address for each logical interface in its MARS_JOIN registration ๐ŸŽ€.

When hosts in a cluster add the router as a leaf node, they put the ATM Address of the right logical interface on the router into the L_MULTI_ADD message ๐Ÿซถ. That means each logical interface only has to check and filter the CMIs its own MARS assigned ๐Ÿงš. So basically the clusters are kept apart by making sure logical IP/ATM interfaces never share ATM Addresses. Iconic ๐Ÿ‘‘.

9. Multiprotocol applications of the MARS and MARS clients. ๐ŸŒˆ

Bestie, we really tried to describe the MARS and its mechanisms without tying them to any one higher layer protocol running over the ATM cloud ๐Ÿ’œ. The immediate use of this document is an IPv4 environment, which is why most of the key examples look like that ๐Ÿ“. Still, the mar$pro.type and mar$pro.snap fields in every MARS control message let any higher layer protocol with a 'short form' or 'long form' of protocol identification (section 4.3) be supported by a MARS โœจ.

Every MARS MUST implement entirely separate logical mapping tables and support ๐Ÿ”ฅ. Every cluster member has to read messages from the MARS in the context of the protocol type that the MARS message is about ๐Ÿ’….

Every MARS and MARS client MUST treat Cluster Member IDs in the context of the protocol type carried in the MARS message or data packet containing the CMI ๐ŸŽ€.

Let's do an IPv6 example because it's so clean ๐Ÿงš. IPv6 was allocated the Ethertype 0x86DD, so the 'short form' of protocol identification has to be used in the MARS control messages and in the data path encapsulation (section 5.5) ๐Ÿ’–. An IPv6 multicasting client sets the mar$pro.type field of every MARS message to 0x86DD ๐ŸŒธ. When it carries IPv6 addresses, the mar$spln and mar$tpln fields are either 0 (for null or non-existent information) or 16 (for the full IPv6 address) โœจ.

Following the rules in section 5.5, an IPv6 data packet gets encapsulated like this ๐Ÿฆ‹:

   [0xAA-AA-03][0x00-00-5E][0x00-01][pkt$cmi][0x86DD][IPv6 packet]

A host or endpoint interface using the same MARS to support multicasting for multiple protocols MUST not assume their CMI will be the same for each protocol ๐Ÿ™ˆ.

10. Supplementary parameter processing. โญ

The mar$extoff field in the [Fixed header] tells you whether a MARS control message is carrying supplementary parameters ๐ŸŽ€. This is the hook for adding new functionality to the MARS protocol in later documents ๐Ÿ”ฎ.

Supplementary parameters come as a list of TLV (type, length, value) encoded information elements ๐Ÿ’œ. The TLV(s) start on the first 32 bit boundary after the [Addresses] field in the MARS control message (so after mar$tsa.N in a MARS_MULTI, after mar$max.N in a MARS_JOIN, and so on) ๐Ÿซถ.

10.1. Interpreting the mar$extoff field. ๐Ÿง

If mar$extoff is non-zero, it means one or more TLVs have been tacked onto the MARS message ๐Ÿ’–. To find the first TLV, you treat mar$extoff as an unsigned integer giving an offset in octets from the beginning of the MARS message (the MSB of the mar$afn field) ๐Ÿฆ‹.

Since TLVs are 32 bit aligned, the bottom 2 bits of mar$extoff are reserved too ๐ŸŒˆ. A receiver MUST mask off these two bits before it works out the octet offset to the TLV list ๐Ÿ’…. A sender MUST set these two bits to zero ๐ŸŽ€.

If mar$extoff is zero, no TLVs have been appended โœจ.

10.2. The format of TLVs. ๐Ÿงš

When they exist, TLVs start on 32 bit boundaries, are multiples of 32 bits long, and form a sequential list that ends with a NULL TLV ๐Ÿ”ฅ.

The TLV structure looks like this:

   [Type - 2 octets][Length - 2 octets][Value - n*4 octets]

The Type subfield says how the contents of the Value subfield should be read ๐Ÿ“. The Length subfield is the number of VALID octets in the Value subfield, and those valid octets start right after the Length subfield ๐ŸŒธ. To get from the start of one TLV to the start of the next, you use this formula (where % is the modulus operator) ๐Ÿงฎ:

   offset = (length + 4 + ((4-(length & 3)) % 4))

The Value subfield gets padded with 0, 1, 2, or 3 octets so the next TLV stays 32 bit aligned, and the padded locations MUST be set to zero ๐Ÿ’œ.

Example time ๐ŸŽ€: a TLV that only needs 5 valid octets is 12 octets long. Its Length subfield holds 5, and the Value subfield gets padded out to 8 bytes. The 5 valid octets begin at the first octet of the Value subfield โœจ.

The Type subfield is laid out like this ๐Ÿ’–:

          |   1st octet   |   2nd octet   |
           7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | x |               y           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The two most significant bits (Type.x) decide how a recipient behaves when it doesn't recognise the TLV type given by the lower 14 bits (Type.y) ๐Ÿ™ˆ. The required behaviours are:

      Type.x = 0   Skip the TLV, continue processing the list.
      Type.x = 1   Stop processing, silently drop the MARS message.
      Type.x = 2   Stop processing, drop message, give error indication.
      Type.x = 3   Reserved. (currently treat as x = 0)
The error indication generated when Type.x = 2 SHOULD be logged in some locally significant fashion. Consequential MARS message activity in response to such an error condition will be defined in future documents. ๐Ÿšจ

The TLV type space (Type.y) is split up to encourage use outside the IETF ๐ŸŒ:

      0                       Null TLV.
      0x0001 - 0x0FFF         Reserved for the IETF.
      0x1000 - 0x11FF         Allocated to the ATM Forum.
      0x1200 - 0x37FF         Reserved for the IETF.
      0x3800 - 0x3FFF         Experimental use.

10.3. Processing MARS messages with TLVs. ๐ŸŒท

Supplementary parameters act as modifiers to the basic behaviour set by the mar$op field of any MARS message ๐Ÿ’ซ.

If a MARS message arrives with a non-zero mar$extoff field, its TLV list MUST be parsed before the MARS message is handled according to the mar$op value ๐ŸŽ€. Unrecognised TLVs MUST be handled as their Type.x value requires ๐Ÿ’….

How TLVs change basic MARS operations depends on the mar$op and on the specific TLV ๐Ÿงš.

10.4. Initial set of TLV elements. ๐Ÿ“

Conformance with this document only REQUIRES recognising one TLV, the Null TLV ๐Ÿซถ. It ends a list of TLVs and MUST be present whenever mar$extoff is non-zero in a MARS message ๐Ÿ˜ญ. It MAY be the only TLV present โœจ.

The Null TLV is coded as:

      [0x00-00][0x00-00]

Future documents will describe the formats, contents, and meanings of more TLVs ๐Ÿ”ฎ. The minimal parsing requirements in this document are there so conformant MARS and MARS client implementations can handle future TLV developments gracefully and predictably ๐ŸŒˆ.

11. Key Decisions and open issues. ๐Ÿ’…

Here are the key decisions this document proposes ๐Ÿ’–:

  • A Multicast Address Resolution Server (MARS) is proposed to co-ordinate and distribute mappings of ATM endpoint addresses to arbitrary higher layer 'multicast group addresses'. IPv4 multicast is used as the example case ๐Ÿฆ‹.
  • The concept of 'clusters' is introduced to define the scope of a MARS's responsibility and the set of ATM endpoints willing to take part in link level multicasting ๐ŸŽ€.
  • A MARS is described with the functionality needed to support intra-cluster multicasting using either VC meshes or ATM level multicast servers (MCSs) โœจ.
  • LLC/SNAP encapsulation of MARS control messages lets MARS and ATMARP traffic share VCs, and lets partially co-resident MARS and ATMARP entities exist ๐Ÿงš.
  • New message types ๐Ÿ”ฅ:
    • MARS_JOIN, MARS_LEAVE, MARS_REQUEST. These let endpoints join, leave, and request the current membership list of multicast groups ๐Ÿ’œ.
    • MARS_MULTI. Lets multiple ATM addresses come back from the MARS in response to a MARS_REQUEST ๐Ÿ“.
    • MARS_MSERV, MARS_UNSERV. Let multicast servers register and deregister themselves with the MARS ๐ŸŒธ.
    • MARS_SJOIN, MARS_SLEAVE. Let the MARS pass group membership changes on to multicast servers ๐Ÿซถ.
    • MARS_GROUPLIST_REQUEST, MARS_GROUPLIST_REPLY. Let the MARS say which groups have actual layer 3 members. These may be used to support IGMP in IPv4 environments, and similar functions in other environments ๐Ÿ™ˆ.
    • MARS_REDIRECT_MAP. Lets the MARS specify a set of backup MARS addresses ๐ŸŒท.
    • MARS_MIGRATE. Lets the MARS force cluster members to shift from VC mesh to MCS based forwarding tree in a single operation ๐Ÿš€.
  • 'Wild card' MARS mapping table entries are possible, where a single ATM address is associated with blocks of multicast group addresses at the same time ๐ŸŒˆ.

For the MARS protocol, mar$op.version = 0. The complete set of MARS control messages and mar$op.type values is ๐Ÿ“‹:

      1   MARS_REQUEST
      2   MARS_MULTI
      3   MARS_MSERV
      4   MARS_JOIN
      5   MARS_LEAVE
      6   MARS_NAK
      7   MARS_UNSERV
      8   MARS_SJOIN
      9   MARS_SLEAVE
      10  MARS_GROUPLIST_REQUEST
      11  MARS_GROUPLIST_REPLY
      12  MARS_REDIRECT_MAP
      13  MARS_MIGRATE

A bunch of issues are still open at this stage, and they'll probably get more research and extra documents building on this one ๐Ÿง :

  • The specified endpoint behaviour allows redundant/backup MARSs within a cluster. However, no specifications exist yet on how these MARSs co-ordinate amongst themselves. (The default is to only have one MARS per cluster.) ๐Ÿซ 
  • The specified endpoint behaviour and MARS service allow multiple MCSs per group. However, no specifications exist yet on how this may be used, or how these MCSs co-ordinate amongst themselves. Until further work is done on MCS co-ordination protocols, the default is to only have one MCS per group. ๐Ÿ™ƒ
  • The MARS relies on the cluster member dropping off ClusterControlVC if the cluster member dies. It is not clear whether additional mechanisms are needed to detect and delete 'dead' cluster members ๐Ÿ’€.
  • Supporting layer 3 'broadcast' as a special case of multicasting (where the 'group' encompasses all cluster members) has not been explicitly discussed ๐Ÿ“ข.
  • Supporting layer 3 'unicast' as a special case of multicasting (where the 'group' is a single cluster member, identified by that member's unicast protocol address) has not been explicitly discussed ๐Ÿ“ฎ.
  • The future development of ATM Group Addresses and Leaf Initiated Join in the ATM Forum's UNI specification has not been addressed. (However, the problems this document identifies with respect to VC scarcity and impact on AAL contexts will not be fixed by such developments in the signalling protocol.) ๐Ÿ˜ค
  • Possible modifications to the interpretation of the mar$hrdrsv and mar$afn fields in the Fixed header, based on different values for mar$op.version, are for further study ๐Ÿ”ญ.

Security Considerations ๐Ÿšจ

Okay bestie, serious moment ๐Ÿซข: security issues are not addressed in this document. ๐Ÿ˜ญ

Acknowledgments ๐Ÿซถ

okay bestie, time for the thank-you hall of fame ๐Ÿ’œ The chats in the IP over ATM Working Group helped sharpen the ideas in this doc โœจ John Moy (Cascade Communications Corp.) first suggested the idea of wild-card entries in the ARP Server ๐Ÿ™Œ Drew Perkins (Fore Systems) gave rigorous and super useful critique of early mechanisms for distributing and validating group membership information ๐Ÿง  Susan Symington (and co-workers at MITRE Corp., Don Chirieleison, and Bill Barns) clearly laid out the need for multicast server support, proposed a solution, and challenged earlier block join/leave mechanisms ๐Ÿ”ฅ John Shirron (Fore Systems) made useful improvements on the original revalidation procedures ๐Ÿ› ๏ธ

Susan Symington and Bryan Gleeson (Adaptec) independently championed the need for the service provided by MARS_GROUPLIST_REQUEST/REPLY ๐Ÿ“ฃ The new encapsulation scheme came out of WG discussions, which Bryan Gleeson captured in an interim Work in Progress (with Keith McCloghrie (Cisco), Andy Malis (Ascom Nexion), and Andrew Smith (Bay Networks) as key contributors) ๐ŸŒˆ James Watt (Newbridge) and Joel Halpern (Newbridge) pushed for a more multiprotocol MARS control message format, moving it away from its original ATMARP roots ๐Ÿฆ‹ They also motivated the development of Type #1 and Type #2 data path encapsulations ๐Ÿ’– Rajesh Talpade (Georgia Tech) helped clarify the need for the MARS_MIGRATE function ๐ŸŽ€

Maryann Maher (ISI) gave valuable sanity and implementation checking during the latter stages of the document's development ๐ŸŒธ And finally, Jim Rubas (IBM) supplied the MARS pseudo-code in Appendix F and also did detailed proof-reading in the latter stages of the document's development. Iconic behaviour, honestly ๐Ÿ‘‘

Author's Address ๐Ÿ’Œ

Grenville Armitage Bellcore, 445 South Street Morristown, NJ, 07960 USA

EMail: gja@thumper.bellcore.com Phone: +1 201 829 2635

References ๐Ÿ“š

[1] Deering, S., "Host Extensions for IP Multicasting", STD 3, RFC 1112, Stanford University, August 1989.

[2] Heinanen, J., "Multiprotocol Encapsulation over ATM Adaption Layer 5", RFC 1483, Telecom Finland, July 1993.

[3] Laubach, M., "Classical IP and ARP over ATM", RFC 1577, Hewlett-Packard Laboratories, December 1993.

[4] ATM Forum, "ATM User Network Interface (UNI) Specification Version 3.1", ISBN 0-13-393828-X, Prentice Hall, Englewood Cliffs, NJ, June 1995.

[5] Waitzman, D., Partridge, C., and S. Deering, "Distance Vector Multicast Routing Protocol", RFC 1075, November 1988.

[6] Perez, M., Liaw, F., Grossman, D., Mankin, A., Hoffman, E., and A. Malis, "ATM Signaling Support for IP over ATM", RFC 1755, February 1995.

[7] Borden, M., Crawley, E., Davie, B., and S. Batsell, "Integration of Real-time Services in an IP-ATM Network Architecture.", RFC 1821, August 1995.

[8] ATM Forum, "ATM User-Network Interface Specification Version 3.0", Englewood Cliffs, NJ: Prentice Hall, September 1993.

Appendix A. Hole punching algorithms. ๐Ÿ•ณ๏ธ

Implementations are totally free to comply with the body of this memo in any way they see fit. This appendix is purely for clarification, so no pressure ๐Ÿ’…

A MARS implementation might pre-construct a set of <min,max> pairs (P) that reflects the entire Class D space, excluding any addresses currently supported by multicast servers. The <min> field of the first pair MUST be 224.0.0.0, and the <max> field of the last pair must be 239.255.255.255. The first and last pair may be the same. This set gets updated whenever a multicast server registers or deregisters ๐Ÿ”„

When the MARS has to perform 'hole punching', it might consider the following algorithm:

   Assume the MARS_JOIN/LEAVE received by the MARS from the cluster
   member specified the block <Emin, Emax>.

   Assume Pmin(N) and Pmax(N) are the <min> and <max> fields from the
   Nth pair in the MARS's current set P.

   Assume set P has K pairs. Pmin(1) MUST equal 224.0.0.0, and
   Pmax(M) MUST equal 239.255.255.255. (If K == 1 then no hole
   punching is required).

   Execute pseudo-code:

      create copy of set P, call it set C.

      index1 = 1;
      while (Pmax(index1) <= Emin)
         index1++;

      index2 = K;
      while (Pmin(index2) >= Emax)
         index2--;

      if (index1 > index2)
         Exit, as the hole-punched set is null.

      if (Pmin(index1) < Emin)
         Cmin(index1) = Emin;

      if (Pmax(index2) > Emax)
         Cmax(index2) = Emax;

      Set C is the required 'hole punched' set of address blocks.

The resulting set C keeps all the MARS's pre-constructed 'holes' covering the multicast servers, but gets pruned so it covers only the section of the Class D space specified by the originating host's <Emin,Emax> values โœ‚๏ธ

The host end should keep a table, H, of open VCs in ascending order of Class D address ๐Ÿ“‹

   Assume H(x).addr is the Class address associated with VC.x.
   Assume H(x).addr < H(x+1).addr.

The pseudo code for updating VCs based on an incoming JOIN/LEAVE might look like this ๐Ÿงš

   x = 1;
   N = 1;

   while (x < no.of VCs open)
   {
         while (H(x).addr > max(N))
         {
               N++;
               if (N > no. of pairs in JOIN/LEAVE)
                     return(0);
         }

         if ((H(x).addr <= max(N) &&
                     ((H(x).addr >= min(N))
                           perform_VC_update();
         x++;
   }

Appendix B. Minimising the impact of IGMP in IPv4 environments โœจ

Implementing any part of this appendix is not required for conformance with this document. ๐Ÿ’… It's here purely to document issues that have been spotted, so nobody has to rediscover them ๐Ÿ”

The whole point of section 5.1 is that cluster members should only have outgoing point to multipoint VCs open when they're actually sending data to a particular multicast group ๐Ÿฆ‹ But here's the tea: in most IPv4 environments, the multicast routers attached to a cluster will periodically issue IGMP Queries to check whether any particular groups have members ๐Ÿ‘€ IGMP tries to stop every group member from replying at once by making each member wait a random period, and only reply if nobody else has replied first ๐Ÿซถ The IGMP reply goes to the multicast address of the group being queried.

Unfortunately, IGMP as it stands is kind of a nuisance for cluster members that are basically passive receivers in a given multicast group ๐Ÿ˜ญ A passive member with no outgoing VC already established to the group is just as likely to decide to send an IGMP reply, which then causes a VC to be established even though there was no need for one ๐Ÿ’€ For small clusters that's not a dealbreaker, but it will seriously hurt a cluster's ability to scale ๐Ÿ“‰

The most obvious fix is for routers to use the MARS_GROUPLIST_REQUEST and MARS_GROUPLIST_REPLY messages, as described in section 8.5 โœจ That would get rid of the regular IGMP Queries, so cluster members would only send an IGMP Report when they first join a group ๐ŸŽ€

There are other options too ๐ŸŒˆ One would be to tweak the IGMP reply algorithm, like this:

  • If the group member already has a VC open to the group, proceed as per RFC 1112 (picking a random reply delay between 0 and 10 seconds). ๐Ÿ’œ
  • If the group member does not have a VC already open to the group, pick a random reply delay between 10 and 20 seconds instead, and then proceed as per RFC 1112. ๐Ÿงš

If even one group member is sending to the group when the IGMP Query goes out, then all the passive receivers will see the IGMP Reply has already been transmitted before their delay runs out, so no new VC is needed ๐Ÿ™Œ If every group member is passive when the IGMP Query goes out, a response will still show up eventually, just 10 seconds later than usual ๐Ÿข

The solution above means rewriting existing IGMP code, and it assumes the IGMP entity can figure out the status of VCs on the underlying ATM interface ๐Ÿฅฒ That's unlikely to be available any time soon.

A short-term option is to get something like that functionality through a 'hack' at the IP/ATM driver level inside cluster members ๐Ÿ› ๏ธ The IP/ATM driver snoops inside IP packets looking for IGMP traffic. If it accepts an IGMP packet for transmission and there's no VC already active to that group, it can buffer the packet locally and start a 10 second timer โฑ๏ธ If an IGMP Reply for that group arrives from elsewhere in the cluster, the timer gets reset. If the timer runs out, the IP/ATM driver sets up a VC to the group the way it would for a normal IP multicast packet โœจ

Some network implementors might find it helpful to configure a multicast server to support the group 224.0.0.1, rather than relying on a mesh ๐Ÿ“ Since IP multicast routers regularly send IGMP queries to this address, a mesh would mean each router permanently eats up an AAL context within every cluster member ๐Ÿ˜ฉ In clusters served by multiple routers, the VC load inside switches in the underlying ATM network becomes a scaling problem ๐Ÿšจ

Last but not least, if a multicast server is used to support 224.0.0.1, there's another ATM driver level hack that could handle IGMP Reply traffic ๐Ÿฆ‹ The ATM driver may choose to grab all outgoing IGMP packets and send them out on the VC set up for sending to 224.0.0.1, no matter which Class D address the IGMP message was actually meant for ๐Ÿ’… Since all hosts and routers must be members of 224.0.0.1, the intended recipients still get the IGMP Replies. The downside is that every cluster member will receive the IGMP Replies too ๐Ÿ˜ฌ


Appendix C. Further comments on 'Clusters' ๐ŸŽ€

The cluster concept was introduced in section 1 for two reasons ๐Ÿ’– Logical IP Subnet is the more well-known term, but it's super IP-specific and tied to unicast routing boundaries ๐Ÿ™„ The architecture in this document might get reused in non-IP environments, so a more neutral term was needed โœจ Multicasting doesn't always follow the same scopes as unicasting, so it wasn't obvious that locking ourselves into LISs from the start would be a good idea long-term ๐Ÿค”

Let's be super clear: clusters are purely an administrative construct ๐Ÿซถ You choose their size (that is, how many endpoints register with the same MARS) based on your multicasting needs and how much resource consumption you're willing to deal with ๐Ÿ’… The more ATM attached hosts you need multicast support for, the more individual clusters you might set up (along with multicast routers to provide inter-cluster traffic paths) ๐ŸŒธ

Since not every host in a given LIS necessarily needs multicast support, you might end up assigning a single MARS to support hosts across multiple LISs ๐Ÿ‘‘ Effectively, you've got a cluster covering multiple LISs, and you've achieved 'cut through' routing for multicast traffic โญ In that situation, making a cluster geographically bigger might be considered a good thing ๐Ÿ™Œ

Still, practical considerations limit how big clusters can get ๐Ÿงš Having a cluster span multiple LISs isn't always a total 'win' ๐Ÿ˜… As the number of multicast capable hosts in your LISs grows, it becomes more likely you'll want to cap a cluster's size and force multicast traffic to aggregate at multicast routers scattered across your ATM cloud ๐ŸŒˆ

Finally, multi-LIS clusters need a bit of care when you deploy IP multicast routers ๐Ÿฅบ Under the Classical IP model you need unicast routers on the edges of LISs. Under the MARS architecture you only need multicast routers on the edges of clusters ๐Ÿ’œ If your cluster spans multiple LISs, the multicast routers will think they have a single interface that's attached to multiple unicast subnets at the same time ๐Ÿคฏ Whether that works depends on the inter-domain multicast routing protocols you use, and on your multicast router's ability to understand the new relationship between unicast and multicast topologies ๐Ÿง 

Until there's more research in this area, networks deployed in conformance to this document MUST make their IP cluster and IP LIS coincide, so these complications get avoided ๐Ÿ™…โ€โ™€๏ธโœจ


Appendix D. TLV list parsing algorithm ๐Ÿ’ป

The pseudo-code below shows how a MARS or MARS client could handle the TLV list format described in section 10 ๐Ÿซถ

list = (mar$extoff & 0xFFFC);

if (list == 0) exit;

list = list + message_base;

while (list->Type.y != 0)
      {
            switch (list->Type.y)
            {
                  default:
                    {
                     if (list->Type.x == 0) break;

                     if (list->Type.x == 1) exit;

                     if (list->Type.x == 2) log-error-and-exit;
                    }

                  [...other handling goes here..]

            }

            list += (list->Length + 4 + ((4-(list->Length & 3)) %
            4));

      }

return;

Appendix E. Summary of timer values โฐ

This appendix sums up the various timers and limits mentioned in the main body of the document ๐Ÿ“ Values are written as [x, y, z], meaning a minimum of x, a recommended value of y, and a maximum of z ๐Ÿ’– A '-' means a category has no value specified. Minute values get the suffix 'min', and second values get 'sec' ๐ŸŽ€

   Idle time for MARS - MARS client pt to pt VC:
                                     [1 min, 20 min, -]

   Idle time for multipoint VCs from client.
                                     [1 min, 20 min, -]

   Allowed time between MARS_MULTI components.
                                     [-, -, 10 sec]

   Initial random L_MULTI_RQ/ADD retransmit timer range.
                                     [5 sec, -, 10 sec]

   Random time to set VC_revalidate flag.
                                     [1 sec, -, 10 sec]

   MARS_JOIN/LEAVE retransmit interval.
                                     [5 sec, 10 sec, -]

   MARS_JOIN/LEAVE retransmit limit.
                                     [-, -, 5]

   Random time to re-register with MARS.
                                     [1 sec, -, 10 sec]

   Force wait if MARS re-registration is looping.
                                     [1 min, -, -]

   Transmission interval for MARS_REDIRECT_MAP.
                                     [1 min, 1 min, 2 min]

   Limit for client to miss MARS_REDIRECT_MAPs.
                                     [-, -, 4 min]

Appendix F. Pseudo code for MARS operation ๐Ÿงš

Implementations are totally free to comply with the body of this memo however they like ๐Ÿฆ‹ This appendix is purely there for possible clarification ๐Ÿ’…

A MARS implementation might be built along the lines suggested in this pseudo-code โœจ

1. Main ๐Ÿ‘‘

1.1 Initilization ๐ŸŒธ

     Define a server list as the list of leaf nodes
                                        on ServerControlVC.
     Define a cluster list as the list of leaf nodes
                                        on ClusterControlVC.
     Define a host map as the list of hosts that are
                                        members of a group.
     Define a server map as the list of hosts (MCSs)
                                        that are serving a group.
     Read config file.
     Allocate message queues.
     Allocate internal tables.
     Set up passive open VC connection.
     Set up redirect_map timer.
     Establish logging.

1.2 Message Processing ๐Ÿ’œ

     Forever {
       If the message has a TLV then {
         If TLV is unsupported then {
           process as defined in TLV type field.
         } /* unknown TLV */
       } /* TLV present */
       Place incoming message in the queue.
       For (all messages in the queue) {
         If the message is not a JOIN/LEAVE/MSERV/UNSERV with
           mar$flags.register == 1 then {
           If the message source is (not a member of server list) &&
            (not a member of cluster list) then {
            Drop the message silently.
          }
         }
         If (mar$pro.type is not supported) or
            (the ATM source address is missing) then {
            Continue.

         }
         Determine type of message.
         If an ERR_L_RELEASE arrives on ClusterControlVC then {
           Remove the endpoints ATM address from all groups
           for which it has joined.
           Release the CMI.
           Continue.
         } /* error on CCVC */
         Call specific message handling routine.
         If redirect_map timer pops {
           Call MARS_REDIRECT_MAP message handling routine.
         } /* redirect timer pop */
       } /* all msgs in the queue */
     } /* forever loop */

2. Message Handler โœจ

2.1. Messages

okay so this is where the MARS server decides what to do with each incoming message ๐Ÿ’… it's basically a big sorting party, and every message type gets its own little routine ๐ŸŽ€

MARS_REQUEST

bestie, this one is the classic "who's asking and what do they want" check ๐Ÿ” the server looks at the TLV first, then at whether the source is on the server list or the cluster list ๐Ÿฆ‹

Indicate no MARS_MULTI support of TLV.
If the supported TLV is not NULL then {
  Indicate MARS_MULTI support of TLV.
  Process as required.
} else { /* TLV NULL */
  Indicate message to be sent on Private VC.
  If the message source is a member of server list then {
    If the group has a non-null host map then {
      Call MARS_MULTI with the host map for the group.
    } else { /* no group */
      Call MARS_NAK message routine.
    } /* no group */
  } else { /* source is cluster list */
    If the group has a non-null server map then {
      Call MARS_MULTI with the server map for the group.
    } else { /* cluster member but no server map */
      If the group has a non-null host map then {
        Call MARS_MULTI with the host map for the group.
      } else { /* no group */
        Call MARS_NAK message routine.
      } /* no group */
    } /* cluster member but no server map */
  } /* source is a cluster list */
} /* TLV NULL */
If a message exists then {
  Send message as indicated.
}
Return.

MARS_MULTI

this one builds the MARS_MULTI for whichever map was asked for, and if TLV support was indicated it also handles that TLV โœจ

Construct a MARS_MULTI for the specified map.
If the param indicates TLV support then {
  Process the TLV as required.
}
Return.

MARS_JOIN

ngl this is the big one ๐Ÿ˜ญ it checks for copies, checks for multiple <min,max> pairs, and then splits into register and not-register paths. there's also a duplicate check and a bunch of routing to the server-aware processing ๐ŸŒธ

If (mar$flags.copy != 0) silently ignore the message.
If more than a single <min,max> pair is specified then
silently ignore the message.
Indicate message to be sent on private VC.
If (mar$flags.register == 1) then {
  If the node is already a registered member of the cluster
  associated with protocol type then { /*previous register*/
    Copy the existing CMI into the MARS_JOIN.
  } else { /* new register */
    Add the node to ClusterControlVC.
    Add the node to cluster list.
    mar$cmi = obtain CMI.
  } /* new register */
} else { /* not a register */
  If the group is a duplicate of a previous MARS_JOIN then {
    mar$msn = current csn.
    Indicate message to be sent on Private VC.
  } else {
    Indicate no message to be sent.
    If the message source is in server map then {
      Drop the message silently.
    } else {
      If the first <min,max> encompasses any group with
      a server map then {
        Call the Modified JOIN/LEAVE Processing routine.
      } else {
        If the MARS_JOIN is for a multi group then {
          Call the MultiGroup JOIN/LEAVE Processing Routine.
        } else {
          Indicate message to be sent on ClusterControlVC.
        } /* not for a multi group */
      } /* group not handled by server */
    } /* msg src not in server map */
    Update internal tables.
  } /* not a duplicate */
} /* not a register */

If a message exists then {
  mar$flags.copy = 1.
  Send message as indicated.
}
Return.

MARS_LEAVE

basically the mirror of JOIN, but for leaving ๐Ÿฆ‹ the deregistration path is where the server cleans up after the member: tables, endpoints, and the CMI all get tidied ๐Ÿงน

If (mar$flags.copy != 0) silently ignore the message.
If more than a single <min,max> pair is specified then
silently ignore the message.
Indicate message to be sent on ClusterControlVC.
If (mar$flags.register == 1) then { /* deregistration */
  Update internal tables to remove the member's ATM addr
  from all groups it has joined.
  Drop the endpoint from ClusterControlVC.
  Drop the endpoint from cluster list.
  Release the CMI.
  Indicate message to be sent on Private VC.
} else { /* not a deregistration */
  If the group is a duplicate of a previous MARS_LEAVE then {
    mar$msn = current csn.
    Indicate message to be sent on Private VC.
  } else {
    Indicate no message to be sent.
    If the first <min,max> encompasses any group with
    a server map then {
      Call the Modified JOIN/LEAVE Processing routine.
    } else {
      If the MARS_LEAVE is for a multi group then {
        Call the MultiGroup JOIN/LEAVE Processing Routine.
      } else {
        Indicate message to be sent on ClusterControlVC.
      }
    }
    Update internal tables.
  } /* not a duplicate */
} /* not a deregistration */
If a message exists then {
  mar$flags.copy = 1.
  Send message as indicated.
}
Return.

MARS_MSERV

this is how a server (MCS) shows up ๐Ÿงš a register adds it as a leaf on ServerControlVC and to the server list, and a non-register checks that the source is registered before adding the server to a group's server map ๐Ÿ’œ

If (mar$flags.register == 1) then { /* server register */
  Add the endpoint as a leaf node to ServerControlVC.

  Add the endpoint to the server list.
  Indicate the message to be sent on Private VC.
  mar$cmi = 0.
} else { /* not a register */
If the source has not registered then {
  Drop and ignore the message.
  Indicate no message to be sent.
} else {  /* source is registered */
  If MCS is already member of indicated server map {
    Indicate message to be sent on Private VC.
    mar$flags.layer3grp = 0;
    mar$flags.copy = 1.
  } else { /* New MCS to add. */
    Add the server ATM addr to server map for group.
    Indicate message to be sent on ServerControlVC.
    Send message as indicated.
    Make a copy of the message.
    Indicate message to be sent on ClusterControlVC.
    If new server map was just created {
      Construct MARS_MIGRATE, with MCS as target.
    } else {
      Change the op code to MARS_JOIN.
      mar$flags.layer3grp = 0.
      mar$flags.copy = 1.
    } /* new server map */
  } /* New MCS to add. */
} /* source is registered */
} /* not a register */

If a message exists then {
  Send message as indicated.
}
Return.

MARS_UNSERV

the undo button for MARS_MSERV ๐Ÿซถ it pulls the server out of its maps, removes the leaf, and if the server was actually in the map it sends a MARS_LEAVE along to the cluster

If (mar$flags.register == 1) then { /* deregister */
  Remove the ATM addr of the MCS from all server maps.
  If a server map becomes null then delete it.
  Remove the endpoint as a leaf of ServerControlVC.
  Remove the endpoint from server list.
  Indicate the message to be sent on Private VC.
} else { /* not a deregister */
  If the source is not a member of server list then {
    Drop and ignore the message.
    Indicate no message to be sent.
  } else {  /* source is registered */

    If MCS is not member of indicated server map {
      Indicate message to be sent on Private VC.
      mar$flags.layer3grp = 0;
      mar$flags.copy = 1.
    } else { /* MCS existed, must be removed. */
      Remove ATM addr of the MCS from indicated server map.
      If a server map is null then delete it.
      Indicate the message to be sent on ServerControlVC.
      Send message as indicated.
      Make a copy of the message.
      Change the op code to MARS_LEAVE.
      Indicate message (copy) to be sent on ClusterControlVC.
      mar$flags.layer3grp = 0;
      mar$flags.copy = 1.
    } /* MCS existed, must be removed. */
  } /* source is registered */
} /* not a deregister */
If a message exists then {
  Send message as indicated.
}
Return.

MARS_NAK

short and sweet, this just builds the command ๐Ÿ’–

Build command.
Return.

MARS_GROUPLIST_REQUEST

only proceeds when mar$pnum is exactly 1, otherwise it's a hard stop ๐Ÿ›‘ if it goes ahead, it hands off to the group list reply with the range and the output VC ๐ŸŽ€

If (mar$pnum != 1) then Return.
Call MARS_GROUPLIST_REPLY with the range and output VC.
Return.

MARS_GROUPLIST_REPLY

builds the reply for the requested range, sends it on the specified VC, and that's the whole show ๐ŸŒˆ

Build command for specified range.
Indicate message to be sent on specified VC.
Send message as indicated.
Return.

MARS_REDIRECT_MAP

the server includes its own address, plus the addresses of any backup MARSs, then sends it back out on ClusterControlVC ๐Ÿ“

Include the MARSs own address in the message.
If there are backup MARSs then include their addresses.
Indicate MARS_REDIRECT_MAP is to be sent on ClusterControlVC.
Send message back as indicated.
Return.

3. Send Message Handler ๐Ÿฆ‹

okay so before anything heads out, this checks whether the message needs a fresh sequence number, and if it does, it grabs one ๐Ÿ’… cluster traffic gets a CSN and server traffic gets an SSN โœจ

If (the message is going out ClusterControlVC) &&
        (a new csn is required) then {
  mar$msn = obtain a CSN
}
If (the message is going out ServerControlVC) &&
        (a new ssn is required) then {
  mar$msn = obtain a SSN
}
Return.

4. Number Generator ๐Ÿ”ข

the generators themselves are super simple, they just make the next sequence number, but the CMI one is a little more involved ๐Ÿ’œ

4.1. Cluster Sequence Number

generate the next one, then return ๐ŸŽ€

Generate the next sequence number.
Return.

4.2. Server Sequence Number

same energy as the CSN, just for the server side ๐ŸŒธ

Generate the next sequence number.
Return.

4.3. CMI

ok this is giving "per member, per protocol" ๐Ÿ˜ญ CMIs are allocated uniquely for each registered cluster member, but only within the context of one particular layer 3 protocol type. a single node can register more than once if it supports multiple layer 3 protocols, and the CMIs for those registrations may or may not match each other ๐Ÿงš

Generate a CMI for this protocol.
Return.

5. Modified JOIN/LEAVE Processing ๐Ÿ’–

this routine handles JOIN and LEAVE whenever a server map exists ๐Ÿ‘‘ it makes a copy, converts it into MARS_SJOIN (or MARS_SLEAVE), hole punches the range for the ServerControlVC copy, then does the original version for the Private VC and the ClusterControlVC, punching holes again where needed ๐Ÿ•ณ๏ธ

Make a copy of the message.
Change the type of the copy to MARS_SJOIN.
If the message is a MARS_LEAVE then {
  Change the type of the copy to MARS_SLEAVE.
}
mar$flags.copy = 1 (copy).
Hole punch the <min,max> group by excluding
  from the range those groups which the joining
  (leaving) node is already (still) a member of
  due to it having previously issued a single group
  join.
Indicate the message to be sent on ServerControlVC.
If the message (copy) contains one or more <min,max> pair {
  Send message (copy) as indicated.
}
mar$flags.punched = 0 in the original message.
Indicate the message to be sent on Private VC.
Send message (original) as indicated.
Hole punch the <min,max> group by excluding
  from the range those groups that are served by MCSs
  or which the joining (leaving) node is already
  (still) a member of due to it having previously
  issued a single group join.
Indicate the (original) message to be sent on ClusterControlVC.
If (number of holes punched > 0) then { /* punched holes */
  In original message do {
    mar$flags.punched = 1.
    old punched list <- new punched list.
  }
} /* punched holes */
mar$flags.copy = 1.
Send message as indicated.
Return.

5.1. MultiGroup JOIN/LEAVE Processing

and this is the sibling routine, the one that takes over when a multi group is involved ๐ŸŒˆ it's the next piece of the puzzle โœจ

      If (mar$flags.layer3grp) {
       Ignore this setting, consider it reset.
      }
      mar$flags.copy = 1.
      Make a copy of the message.
      From the copy hole punch the <min,max> group by
       excluding from the range those groups that this
       node has already joined or left.
      If (number of holes punched > 0) then {
       mar$flags.punch = 0 in original message.
       Indicate original message to be sent on Private VC.
       Send original message as indicated.
       mar$flags.punch = 1 in copy message.
       old group range <- new punched list.
       Indicate message to be sent on ClusterControlVC.
       Send copy of message as indicated.
      } else {
         Indicate message to be sent on ClusterControlVC.
         Send original message as indicated.

      } /* no holes punched */
      Return.

๐Ÿ“ฆ where this page comes from