RFC 1326
Mutual Encapsulation Considered Dangerous
Mutual Encapsulation Considered Dangerous ๐ฆ
RFC: 1326 Title: Mutual Encapsulation Considered Dangerous Author: P. Tsuchiya, Paul Tsuchiya of Bellcore ๐ Date: May 1992 Status: provides information for the Internet community, and does not specify an Internet standard Obsoletes / Updates: its title block doesn't list any Obsoletes or Updates lines โจ
Status of this Memo ๐
This memo provides information for the Internet community. It does not specify an Internet standard. Distribution of this memo is unlimited. ๐ธ
Abstract ๐
okay so this memo is all about a packet explosion problem that can happen when two protocols encapsulate each other (A wraps B, and B wraps A) ๐ญ it's giving chaos, fr fr.
The Current Environment ๐
ngl, even with all the international standardization efforts ๐, we're seeing a plethora of protocols, both standard and proprietary, each one built for some technical or marketing niche ๐ . Eventually they bump into each other and are expected to work together.
One way to make that happen is to encapsulate one protocol inside another. This has led to mutual encapsulation, where protocol A runs over protocol B in some cases, and protocol B runs over protocol A in others. For example, there are real cases of both IP over AppleTalk and AppleTalk over IP ๐. (The term "mutual encapsulation" comes from the paper by Shoch, Cohen, and Taft, called Mutual Encapsulation of Internetwork Protocols, Computer Networks 5, North-Holland, 1981, 287-300. The problem identified in this RFC is not mentioned in the Shoch et. al. paper.)
If there aren't already other instances of mutual encapsulation, there will likely be more later ๐ฎ. This is especially true for the various internet protocols, like IP, CLNP, AppleTalk, IPX, DECNET, and so on.
The Problem ๐ฅ
so here's the tea. Picture the topology in Figure 1 ๐ง. We've got two backbones and four stubs. Backbone B(X) uses a native protocol of X (so it expects to receive packets with an X header). B(Y) uses a native protocol of Y. The left and right S(Y) stubs use protocol Y, and the left and right S(X) stubs use protocol X.
::: ::::: ::::: ::: :::
+------+ :Y :X:Y +------+ :X:Y :Y +------+ :Y +------+
| | ::: ::::: | | ::::: ::: | | ::: | |
| S(Y) |-----Ra-----| |-------Rb----| |------| S(Y) |
| | | | | | | |
+------+ | | | | +------+
| B(X) | | B(Y) |
| | | |
::: | | ::: ::::: | | ::::: :::
+------+ X: | | X: X:Y: | | X:Y: X: +------+
| | ::: | | ::: ::::: | | ::::: ::: | |
| S(X) |------| |-----Rc------| |------Rd----| S(X) |
| | | | | | | |
+------+ | |-----Re------| | +------+
+------+ +------+
:::::
X:Y: A packet with protocol X encapsulated in protocol
::::: Y, moving left to right
Rx Router x
S(Y) A stub network whose native protocol is protocol Y
B(X) A backbone network whose native protocol is protocol X
FIGURE 1: MUTUAL ENCAPSULATION
Figure 1 shows how packets travel from left S(X) to right S(X), and from right S(Y) to left S(Y) โ๏ธ. Let's follow a packet from left S(X) to right S(X). It has just an X header until it reaches router Rc. Since B(Y) can't forward an X header, Rc wraps the packet in a Y header addressed to Rd. When Rd gets the packet from B(Y), it strips off the Y header and forwards the X packet on to right S(X). Packets going from right S(Y) to left S(Y) do the same thing in reverse.
In this example, Rc and Rd treat B(Y) as a lower-level subnetwork, exactly the way an IP router currently treats an Ethernet as a lower-level subnetwork. Also notice that Rc treats Rd as the right "exit router" for packets headed to right S(X), and Rb treats Ra as the right "exit router" for packets headed to left S(Y) ๐ช.
Now, imagine a routing loop somehow forms. The routers in B(Y) think Rd is reachable via Rb, Rb thinks Rd is reachable via Re, and the routers in B(X) think Re is reachable via Rc. (This could be a temporary glitch in the routing algorithm if Rd and Re crashed at the same time ๐ฌ.) When the first packet from left S(X) reaches Rc, it gets wrapped in Y and sent into B(Y), which forwards it to Rb. (The notation for this packet is Y<X>, meaning that X is encapsulated in Y.)
When Rb gets Y<X> from B(Y), it wraps the packet in an X header to get it to Re through B(X). Now the packet has headers X<Y<X>>, so it has two X encapsulations. When Rc gets X<Y<X>>, it wraps the packet again, resulting in Y<X<Y<X>>>. The packet keeps growing with every encapsulation ๐ซ .
Now here's the scary part. If each new encapsulation doesn't preserve the hop count from the previous header, the packet will never expire ๐. Worse, it will eventually hit the Maximum Transmission Unit (MTU) size and fragment. Each fragment keeps circling the loop, getting bigger until those fragments fragment too. The result is an exponential explosion of looping packets! ๐งจ
The explosion lasts until the links are saturated, and they stay saturated until the loop is broken. If the looping packets crowd out other packets, like routing updates or management packets, and those get thrown away, the loop may not break on its own. That means someone has to step in manually ๐. Once the loop is broken, the packets get flushed out of the network pretty quickly.
Potential Fixes ๐ง
Fix #1: preserve the hop count. The first fix that comes to mind is to always preserve the hop count information in the new header. Since hop count info is kept in fragments, the explosion won't happen even if some fragmentation occurs before the hop count runs out. The catch is that not all headers have hop count info (X.25 and SMDS, for instance) ๐.
Also, hop count ranges differ between protocols, so a direct translation isn't always possible. For example, AppleTalk has a maximum hop count of 16, while IP goes up to 256. You could define a mapping that lowers the hop count to fit into the smaller range when needed. But that can cause unnecessary black holes because the hop counts end up overly small. There are plenty of IP paths that are longer than 16 hops ๐บ๏ธ.
It's worth noting that the current IP over AppleTalk Internet Draft does not preserve hop counts ("A Standard for the Transmission of Internet Packets Over AppleTalk Networks") ๐.
Fix #2: peek into the network layer headers. Another potential fix is to have routers peek into network layer headers to see if the planned encapsulation already exists ๐ต๏ธโโ๏ธ. For example, in Figure 1, when Rb receives Y<X>, it would look at what Y is encapsulating (say, by checking the protocol id field of X's header). It would notice that X has already been encapsulated and throw the packet away. If the encapsulation loop involves more than two protocols, the router might have to peek into successive network layer headers. It would stop when it finally reached a transport layer header.
There are several pitfalls with this approach:
- Pitfall one: A network layer protocol could be encapsulated within a transport layer protocol, so, I suppose, the router would need to keep peeking even above the transport layer ๐ตโ๐ซ.
- Pitfall two: The router might not recognize one of the network layer headers, which stops it from peeking any further. For example, consider a loop with three routers, Rxy, Ryz, and Rzx, and three protocols X, Y, and Z (the subscripts on the routers show which protocols each router recognizes). After the first loop, Rxy receives
X<Z<Y<X>>>. Since Rxy doesn't recognize Z, it can't peek past Z to find the embedded Y header ๐. - Pitfall three: A router might be encrypting the packet it sends to its peer, like Blacker routers do. For example, Rc might be encrypting packets it encapsulates for Rd, expecting Rd to decrypt them. When Rb receives this packet (because of the loop), it can't peek past the Y header ๐.
- Pitfall four: Sometimes it's actually appropriate to have multiple instances of the same header. In the nested mutual encapsulation of Figure 2, Ra encapsulates Y in X to reach Rd, but Rb encapsulates
X<Y>in Y to reach Rc. In this case, it's appropriate for Rb to transmit a packet with two Y headers ๐ฏ.
Fix #3: the hybrid. A third (somewhat hybrid) solution is to outlaw nested mutual encapsulation, use both hop count preservation and header peeking where appropriate, and generally discourage mutual encapsulation. (Or you can just adopt the attitude that people who engage in mutual encapsulation deserve what they get ๐ ๐ค.)
+--------------------+
| |
| B(X) |
+------+ | +------+ | +------+
| | | | | | | |
| S(Y) |--Ra--+ Rb-| B(Y) |-Rc +--Rd--| S(Y) |
| | | | | | | |
+------+ | +------+ | +------+
| |
| |
+--------------------+
FIGURE 2: NESTED MUTUAL ENCAPSULATION
Security Considerations ๐จ
Security issues are not discussed in this memo. (Yes, this is the part where we all go "hmm." ๐ซฃ Consider it a flag for anyone implementing this stuff. Take the security side seriously and dig into it yourself.)
Author's Address ๐๏ธ
Paul Tsuchiya
Bellcore
435 South St.
MRE 2L-281
Morristown, NJ 07960
Phone: (908) 829-4484
EMail: tsuchiya@thumper.bellcore.com
thanks for reading, bestie!! ๐๐โจ
๐ฆ where this page comes from
- ietf: rfc1326 1992-05
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms