RFC 2022
Support for Multicast over UNI 3.0/3.1 based ATM Networks
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 resetsVC_revalidate. - When an event occurs that demands revalidation, every group has its
VC_revalidateflag setTRUEat 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 itsmar$msnindicated that some previous MARS traffic had been missed on ClusterControlVC), then every open VC, EXCEPT the one just established, MUST have itsVC_revalidateflag 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$tpafield (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.layer3grpMUST be set when the cluster member is issuing theMARS_JOINbecause a layer 3 multicast group was explicitly joined. (for example, from a JoinHostGroup operation in an RFC1112 compliant host ๐ฅ๏ธ)mar$flags.layer3grpMUST be reset in eachMARS_JOINif theMARS_JOINis just the local ip/atm interface registering to receive traffic on that group for its own reasons ๐โโ๏ธ.mar$flags.layer3grpis ignored and MUST be treated as reset by the MARS for anyMARS_JOINthat 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$opmar$flags.registermar$flags.sequencemar$pnum- Source ATM address
- First
<min,max>pair
on top of that, a valid copy MUST have these field values ๐ :
mar$flags.punched = 0mar$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$cmifield 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/LEAVEis made with typeMARS_SJOINorMARS_SLEAVEas appropriate, and transmitted onServerControlVC. 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. Themar$flags.punchedfield 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/LEAVEis made with typeMARS_SJOINorMARS_SLEAVEas 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 originalMARS_JOIN/LEAVEhas 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/LEAVEis retransmitted out onClusterControlVCunchanged. Otherwise, the following happens:- The original
MARS_JOIN/LEAVEis transmitted back to the source cluster member unchanged, using the VC it arrived on. Themar$flags.punchedfield MUST be reset to 0 in this message. ๐ - If the hole-punched set contains 1 or more
<min,max>pair, a copy of the originalMARS_JOIN/LEAVEis transmitted onClusterControlVC, carrying the new<min,max>list. Themar$flags.punchedfield MUST be set to 1 in this message. ๐ณ๏ธ
- The original
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_MAPmessages 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_MAPmessages 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 trackMARS_JOINs andMARS_LEAVEs that arrive withmar$flags.layer3grpset. 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 aMARS_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$hrdrsvandmar$afnfields in the Fixed header, based on different values formar$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
- ietf: rfc2022 1996-11
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms