RFC 1795
Data Link Switching: Switch-to-Switch Protocol AIW DLSw RIG: DLSw Closed Pages, DLSw Standard Version 1
RFC 1795: Data Link Switching: Switch-to-Switch Protocol โจ
okay so meet RFC 1795 ๐ฆ It's a Network Working Group doc from April 1995, and the two people behind it are L. Wells (Chair) from the Internetwork Technology Institute and A. Bartky (Editor) from Sync Research, Inc. It's filed as Informational ๐ and it obsoletes RFC 1434. The subtitle is AIW DLSw RIG: DLSw Closed Pages, DLSw Standard Version 1.0 ๐
Status of This Memo ๐ธ
this memo is here to inform the Internet community, so it's not a standard or anything ๐ it does not specify an Internet standard of any kind. distribution is unlimited, so share it with your whole crew ๐ซถ
Abstract ๐ฅ
this RFC is all about using Data Link Switching over TCP/IP ๐ง the whole point is to get reactions from the Internet community about the proposals inside. ngl the issues might not be directly relevant to the Internet's research problems, but a bunch of researchers and Implementers could still find them super interesting ๐
this RFC was made as a joint project of the Advanced Peer-to-Peer Networking (APPN) Implementers Workshop (AIW) Data Link Switching (DLSw) Related Interest Group (RIG) ๐ the APPN Implementers Workshop is sponsored by IBM and is made up of reps from member companies building current and future IBM Networking interoperable products. the DLSw RIG was formed in that forum for a few big reasons: to produce one version of the Switch to Switch Protocol (SSP) that every vendor could implement, to fix the documentation problems in the existing RFC 1434, and to enhance and evolve the protocol with new functions and features โจ
this document is based on RFC 1434 but has significant changes, so it obsoletes that document ๐
any questions or comments about this RFC should go to this Internet address: aiw-dlsw@networking.raleigh.ibm.com ๐
NOTE 1: this is a widely subscribed mailing list, so messages sent there go to all members of the DLSw mailing list ๐ญ for specific questions about subscribing to the AIW and any of its working groups, email appn@vnet.ibm.com
info about all the AIW working groups and what they're producing can be grabbed with anonymous ftp. you want the file aiwinfo.psbin or aiwinfo.txt from the Internet host networking.raleigh.ibm.com, in the directory aiw ๐
NOTE 2: these mailing lists and addresses are subject to change ๐
1. Introduction ๐ฆ
okay so Data Link Switching (DLSw) is a forwarding mechanism for the IBM SNA (Systems Network Architecture) and IBM NetBIOS (Network Basic Input Output Services) protocols ๐ this doc is the spec for the Switch-to-Switch Protocol (SSP) that Data Link Switches use between each other. it's not full routing, bestie. it does switching at the SNA Data Link layer (that's layer 2 in the SNA architecture) and then encapsulates in TCP/IP so it can travel over the Internet ๐ธ this RFC covers the frame formats and the protocols for multiplexing data between Data Link Switches. the first version of SSP uses TCP as the reliable transport between Data Link Switches. other transports like OSI TP4 could show up later ๐ฎ
a Data Link Switch (also abbreviated DLSw in this document) can support SNA systems (Physical Unit (PU) 2, PU 2.1 and PU 4) and, optionally, NetBIOS systems. those are attached to IEEE 802.2 compliant Local Area Networks ๐ซง it can also support SNA systems (PU 2, primary or secondary, and PU 2.1) attached to IBM Synchronous Data Link Control (SDLC) links ๐ for the SDLC ones, the Data Link Switch gives them a LAN appearance, since each SDLC PU is presented to the SSP protocol as a unique MAC/SAP address pair ๐ for the Token-Ring LAN attached systems, the Data Link Switch shows up as a source-routing bridge ๐ Token-Ring Remote systems that are reached through the Data Link Switch look like they're attached to an adjacent ring. that ring is a virtual ring that exists inside each Data Link Switch โจ
1.1. Backwards Compatibility with RFC 1434 ๐
this document has significant changes from RFC 1434 ๐ it does not say how to interoperate with RFC 1434 or with "enhanced" implementations (like the ones that added enter and exit busy flow control) ๐ญ if you need interop with pre-AIW DLSw RIG standards, the implementer has to look at RFC 1434 and/or the vendor documentation of whichever vendor's implementation they're talking to ๐ซถ
2. Overview ๐
okay so Data Link Switching was built to support SNA and NetBIOS in multi-protocol routers ๐ง SNA and NetBIOS are basically connection oriented protocols, so the Data Link Control procedure they use on the LAN is IEEE 802.2 Logical Link Control (LLC) Type 2 ๐ Data Link Switching also handles SNA protocols over WAN (Wide Area Network) links through the SDLC protocol ๐
IEEE 802.2 LLC Type 2 was designed assuming the network transit delay would be predictable, because it's a local LAN ๐ so its elements of procedure use a fixed timer to detect lost frames. when remote bridging runs over wide area lines (especially slower ones), the network delay gets bigger and can swing a lot depending on congestion ๐ once the delay goes past the time-out value, LLC Type 2 tries to retransmit. if the frame wasn't actually lost and just got delayed, the LLC Type 2 procedures can get confused ๐ต and then the link might eventually get taken down if the delay goes past the T1 timer times the N2 retry count ๐
because LLC Type 2 services are in play, Data Link Switching tackles these bridging problems:
DLC Time-outs
DLC Acknowledgments over the WAN
Flow and Congestion Control
Broadcast Control of Search Packets
Source-Route Bridging Hop Count Limits
NetBIOS also uses a lot of datagram services that run on connectionless LLC Type 1 service ๐ for NetBIOS, Data Link Switching handles the last two problems in that list โจ
the main difference between Data Link Switching and bridging is that for connection-oriented data, DLSw terminates the Data Link Control, while bridging does not ๐ฆ this diagram shows that difference with two end systems running LLC Type 2 services:
Bridging
--------
Bridge Bridge
+------+ +----+ +----+ +------+
| End | +-----+ | +-----/ | | +-----+ | End |
|System+-+ LAN +-+ | /------+ +-+ LAN +-+System|
| | +-----+ | | TCP/IP | | +-----+ | |
+------+ +----+ +----+ +------+
Info----------------------------------------------->
<-----------------------------------------------RR
Data Link Switching
-------------------
+------+ +----+ +----+ +------+
| End | +-----+ | +-----/ | | +-----+ | End |
|System+-+ LAN +-+DLSw| /------+DLSw+-+ LAN +-+System|
| | +-----+ | | TCP/IP | | +-----+ | |
+------+ +----+ +----+ +------+
Info---------------> -------------> Info
<---------------RR ------------>
<------------RR
in traditional bridging, the Data Link Control is end-to-end ๐ธ Data Link Switching terminates the LLC Type 2 connection at the switch. so the LLC Type 2 connections don't cross the wide area network ๐ DLSw multiplexes LLC connections onto a TCP connection to another DLSw. so the LLC connections at each end are totally independent of each other ๐ it's the Data Link Switch's job to deliver frames it got from an LLC connection to the other end. TCP is used between the Data Link Switches to guarantee delivery of frames ๐ซถ
because of this design, LLC time-outs are limited to the local LAN (they don't traverse the wide area) ๐ the LLC Type 2 acknowledgments (RR's) also don't cross the WAN, which cuts down traffic on the wide area links ๐ for SDLC links, polling and poll response happen locally, not over the WAN ๐ broadcast of search frames is controlled by the Data Link Switches once they've found where a target system is ๐ and finally, switches can now apply back pressure to the end systems for flow and congestion control ๐
only one copy of a Link Protocol Data Unit (LPDU) gets sent between Data Link Switches in SSP messages (XIDFRAME and INFOFRAME) ๐ค retries of the LPDU get absorbed by the Data Link Switch that receives it ๐ง the Data Link Switch that sends the LPDU from an SSP message to a local DLC does the retries, in a way that fits the local DLC. this can involve running a reply timer and keeping a poll retry count ๐ฐ๏ธ the length of the timer and the number of retries is an implementation choice based on user configuration parameters and the DLC type โญ
Data Link Switching uses LAN addressing to set up connections between SNA systems ๐ SDLC attached devices are defined with MAC and SAP addresses so they can talk to LAN attached devices ๐ซง for NetBIOS systems, Data Link Switching uses the NetBIOS name to forward datagrams and set up connections for NetBIOS sessions ๐ for LLC type 2 connection establishment, SNA systems send TEST (or in some cases, XID) frames to the null (0x00) SAP ๐ NetBIOS systems have an address resolution procedure, based on the Name Query and Name Recognized frames, that's used to set up an end-to-end circuit ๐
since Data Link Switching may be implemented in multi-protocol routers, both bridging and switching can be enabled at the same time ๐ฆ SNA frames can be identified by their link SAP. typical SAP values for SNA are 0x04, 0x08, and 0x0C ๐ NetBIOS always uses a link SAP value of 0xF0 โจ
3. Transport Connection โจ
okay so Data Link Switches can be used in pairs or all by themselves ๐ซถ
A single DLSw internally switches one data link to another without using TCP (DLC(1) to DLC(2) in the figure below) ๐ This RFC doesn't go into details on how to implement this feature, and it's not a requirement to support this RFC ๐
A paired DLSw multiplexes data links over a reliable transport using a Switch-to-Switch Protocol (SSP) ๐ฆ
+-------------------------------------------+Switch-to-Switch
| DLC Interfaces | Protocol (SSP)
|+-----------+ DLC Request +-----------+ |
|| Data |<---------------| | |Send SSP Frame
|| Link | DLC Indication | | |-------------->
|| Control 1 |--------------->| | |
|+-----------+ | Data Link | |
|+-----------+ DLC Request | Switch | |
|| Data |<-------------- | | |Rec. SSP Frame
|| Link | DLC Indication | | |<-------------
|| Control 2 | -------------->| | |
|+-----------+ +-----------+ |
| Multi-Protocol Router |
+-------------------------------------------+
Before Data Link Switching can happen between two routers, they have to set up two TCP connections between them ๐ Each Data Link Switch keeps a list of DLSw capable routers and their status (active/inactive) ๐ Once the TCP connection is up, SSP messages get swapped so the two Data Link Switches can figure out what each other can do โจ After that exchange wraps up, the DLSw uses SSP control messages to set up end-to-end circuits over the transport connection ๐ฅ Inside that transport connection, DLSw SSP messages keep getting exchanged. The message formats and types for these SSP messages are documented in the following sections ๐
The default parameters for the TCP connections between Data Link Switches are:
Socket Family AF_INET (Internet protocols)
Socket Type SOCK_STREAM (stream socket)
Read Port Number 2065
Write Port Number 2067
Two or more Data Link Switches can be attached to the same LAN, which is made of a bunch of token-ring segments linked together by source-routing bridges ๐ In this case, no TCP connection is defined between bridges attached to the same LAN. This lets the systems pick one of the possible Data Link Switches, kind of like how they pick a bridge path through a source-routed bridged network ๐ง The virtual ring segment in each Data Link Switch attached to a common LAN must be configured with the same ring number. This keeps LAN frames sent by one Data Link Switch from getting propagated through the other Data Link Switches ๐
3.1. SSP Frame Formats ๐ฆโจ
okay so bestie, these diagrams show the two header formats that Data Link Switches swap with each other: Control and Information. ๐ Control headers are used for every message except Information Frames (INFOFRAME) and Independent Flow Control Messages (IFCM), which go out in Information header format. INFOFRAME, KEEPALIVE and IFCM headers are 16 bytes long, and Control headers are 72 bytes long. ๐ The first sixteen bytes look exactly the same in every header, so it's giving consistency. ๐ซถ
Control Message (72 bytes):
CONTROL MESSAGES (72 Bytes)
(zero based offsets below shown in decimal (xx) )
+-----------------------------+-----------------------------+
| (00) Version Number | (01) Header Length (= 72) |
+-----------------------------+-----------------------------+
| (02) Message Length |
+-----------------------------+-----------------------------+
| (04) Remote Data Link Correlator |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (08) Remote DLC Port ID |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (12) Reserved Field |
+-----------------------------+-----------------------------+
| (14) Message Type | (15) Flow Control Byte |
+-----------------------------+-----------------------------+
| (16) Protocol ID | (17) Header Number |
+-----------------------------+-----------------------------+
| (18) Reserved |
+-----------------------------+-----------------------------+
| (20) Largest Frame Size | (21) SSP Flags |
+-----------------------------+-----------------------------+
| (22) Circuit Priority | (23) Message Type (see note)|
+-----------------------------+-----------------------------+
| (24) Target MAC Address (non-canonical format) |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -|
| |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (30) Origin MAC Address (non-canonical format) |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -|
| |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| . . |
+-----------------------------+-----------------------------+
| (36) Origin Link SAP | (37) Target Link SAP |
+-----------------------------+-----------------------------+
| (38) Frame Direction | (39) Reserved |
+-----------------------------+-----------------------------+
| (40) Reserved |
+-----------------------------+-----------------------------+
| (42) DLC Header Length |
+-----------------------------+-----------------------------+
| (44) Origin DLC Port ID |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (48) Origin Data Link Correlator |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (52) Origin Transport ID |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (56) Target DLC Port ID |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (60) Target Data Link Correlator |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (64) Target Transport ID |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (68) Reserved Field |
+-----------------------------+-----------------------------+
| (70) Reserved Field |
+-----------------------------+-----------------------------+
(Even Byte) (Odd Byte)
Information Message (16 bytes):
INFORMATION MESSAGE (16 Bytes)
+-----------------------------+-----------------------------+
| (00) Version Number | (01) Header Length (= 16) |
+-----------------------------+-----------------------------+
| (02) Message Length |
+-----------------------------+-----------------------------+
| (04) Remote Data Link Correlator |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (08) Remote DLC Port ID |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| (12) Reserved Field |
+-----------------------------+-----------------------------+
| (14) Message Type | (15) Flow Control Byte |
+-----------------------------+-----------------------------+
(Even Byte) (Odd Byte)
Both headers share the same first sixteen bytes, so let's break down the fields that matter most. ๐ง
The Version Number field (offset 0) is set to 0x31 (ASCII '1'), which is decimal 49. That's how you know it's DLSw version 1. ๐
The Header Length field (offset 1) is 0x48 for control messages, which is 72 bytes. For information and Independent Flow Control messages it's 0x10, which is 16 bytes. ๐
The Message Length field (offset 2) tells you how many bytes are in the data field after the header. ๐ธ
The Flow Control Byte field (offset 15) is explained in section 8. ๐ฆ
The Header Number field (offset 17) is 0x01, which means one. ๐
The Circuit Priority field (offset 22) is explained in section 4. โจ
The Frame Direction field (offset 38) is 0x01 for frames going from the origin DLSw to the target DLSw, and 0x02 for frames going from the target DLSw back to the origin DLSw. ๐ฅ
Note: the Remote Data Link Correlator and Remote DLC Port ID get set to the Target Data Link Correlator and Target DLC Port ID when Frame Direction is 0x01. When Frame Direction is 0x02, they get set to the Origin Data Link Correlator and Origin DLC Port ID instead. ๐
The Protocol ID field is set to 0x42, which is decimal 66. ๐
The DLC Header Length is zero for SNA. For NetBIOS datagrams it's 0x23, which is 35 bytes. That 35 bytes covers the Access Control (AC) field, the Frame Control (FC) field, the Destination MAC Address (DA), the Source MAC Address (SA), the Routing Information (RI) field (padded to 18 bytes), the Destination link SAP (DSAP), the Source link SAP (SSAP), and the LLC control field (UI). ๐
NOTE: the Message Type field values are defined in section 3.5. This value shows up in two different spots in the control header (offset 14 and offset 23 decimal). Only the first one gets used when you parse a received SSP message. New implementations should ignore the second one on reception. It's only still there for backwards compatibility with RFC 1434 implementations, and it might get used in future versions if needed. ๐
The SSP Flags field holds extra info about the SSP message. Bit 7 is the most significant bit and bit 0 is the least significant bit of the octet. ๐ซถ
Bit(s)
76543210 Name Meaning
--------- ----- -------
x....... SSPex 1 = explorer message (CANUREACH and ICANREACH)
Reserved fields are set to zero when they're sent and should be ignored when they're received. That's the whole vibe on reserved fields, periodt. ๐ โจ
3.2. Address Parameters โจ
Okay so a data link is basically the logical pairing between the two end stations using Data Link Switching ๐. It gets identified by a Data Link ID (14 bytes) made of the attachment addresses for each end system. Each attachment address is the MAC address (6 bytes) plus the LLC address (1 byte) ๐ซถ. Depending on the situation, an attachment address is either "Target" (the Destination MAC/SAP addresses of an explorer frame sent in the first frame used to set up a circuit) or "Origin" (the Source MAC/SAP addresses). And all MAC addresses are written in non-canonical (Token-Ring) format, periodt ๐ .
DATA LINK ID (14 Bytes @ Control message offset 24 decimal)
+-----------------------------+-----------------------------+
| Target MAC Address |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| Origin MAC Address |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| Origin Link SAP | Target Link SAP |
+-----------------------------+-----------------------------+
Next up, end-to-end circuits ๐ฆ. Each one is identified by a pair of Circuit IDs. A Circuit ID is a 64 bit number that identifies the DLC circuit within a single DLSw. It's made of a DLC Port ID (4 bytes) and a Data Link Correlator (4 bytes). The Circuit ID MUST be unique in a single DLSw, and it's assigned locally (no cap, that's the whole vibe). The pair of Circuit IDs along with the Data Link IDs uniquely identifies a single end-to-end circuit ๐. Each DLSw MUST keep a table of these Circuit ID pairs, one for the local end of the circuit and the other for the remote end. To keep track of which Data Link Switch started the circuit, this document uses the terms "Origin" DLSw and "Target" DLSw ๐.
CIRCUIT ID (8 Bytes)
+-----------------------------+-----------------------------+
| DLC Port ID |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
| Data Link Correlator |
+- - - - - - - - - - - - - - -+- - - - - - - - - - - - - - -+
| |
+-----------------------------+-----------------------------+
The Origin Transport ID and the Target Transport ID fields in the message header are how you find the individual TCP/IP port on a Data Link Switch ๐ธ. Those values only have local significance, BUT each Data Link Switch is REQUIRED to reflect the values in these two fields, along with the matching DLC Port ID and Data Link Correlator values, whenever it returns a message to the other Data Link Switch. Not optional, bestie ๐.
Here's how the addressing parameters show up when an end-to-end connection gets set up ๐ง. CANUREACH, ICANREACH and REACH_ACK all carry the Data Link ID, which is the MAC and Link SAP addresses of the two end stations. CANUREACH and ICANREACH get qualified by the SSPex flag into CANUREACH_ex and ICANREACH_ex (explorer messages) or CANUREACH_cs and ICANREACH_cs (circuit start). CANUREACH_ex is used to find a remote MAC and Link SAP address without setting up an SSP circuit. When the target DLSw gets a CANUREACH_cs, it starts a data link for each port, which gets it a Data Link Correlator. If the target station can be reached, an ICANREACH_cs goes back to the origin DLSw with the Target Circuit ID parameter in it. Once the origin DLSw gets that, it starts a data link and sends the Origin Circuit ID back to the target DLSw inside REACH_ACK. (Note: for a full list of message types, see section 3.5.)
+------------+ +------------+
|Disconnected| |Disconnected|
+------------+ CANUREACH_cs (Data Link ID) +------------+
------------------------------------------------->
ICANREACH_cs (Data Link ID, Target Circuit ID)
<------------------------------------------------
REACH_ACK (Data Link ID, Origin Cir ID, Target Cir ID)
------------------------------------------------->
+------------+ +------------+
|Circuit Est.| |Circuit Est.|
+------------+ +------------+
XIDFRAME (Data Link ID, Origin Cir ID, Target Cir ID)
<------------------------------------------------>
CONTACT (Data Link ID, Origin Cir ID, Target Cir ID)
------------------------------------------------->
CONTACTED (Data Link ID, Origin Cir ID, Target Cir ID)
<-------------------------------------------------
+------------+ +------------+
| Connected | | Connected |
+------------+ +------------+
INFOFRAME (Remote Circuit ID = Target Circuit ID)
------------------------------------------------->
INFOFRAME (Remote Circuit ID = Origin Circuit ID)
<-------------------------------------------------
While XIDFRAME, CONTACT and CONTACTED are being exchanged, the pair of Circuit ID parameters goes along in the message format together with the DATA LINK ID parameter ๐. Once the connection is up, INFOFRAME messages get exchanged with a shorter header. That header only carries the Circuit ID for the remote DLSw. The Remote Data Link Correlator and the Remote DLC Port ID are set equal to the Data Link Correlator and DLC Port ID belonging to the origin or target Data Link Switch, depending on which direction the packet is going โจ.
3.3. Correlators ๐ซง
The local use and contents of the Data Link Correlator, Port ID and Transport ID fields in SSP messages are an implementation choice, totally up to you ๐. These fields only have local significance. Values received from a partner DLSw MUST NOT be interpreted by the DLSw that receives them, and they SHOULD be echoed "as is" to a partner DLSw in later messages. Every implementation MUST follow the rules in this section (3.3) for assigning and fixing these correlator fields for each transport connection or circuit ๐ฅ.
The Transport ID fields get learned from the first SSP message exchanged with a DLSw partner (the Capabilities exchange). This field SHOULD NOT be varied by a DLSw after the capabilities exchange, and it MUST be reflected to the partner DLSw in every SSP control message ๐ฆ.
The Target Data Link Correlator, Target Port ID and Target Transport ID MUST remain the same once the Target DLSw has sent the ICANREACH_cs for a given circuit. The Origin DLSw MUST store the values specified in the ICANREACH_cs and use them on all subsequent SSP messages for this circuit ๐.
The Origin DLSw MUST allow these fields to vary until the ICANREACH_cs is received. Each SSP message issued for a circuit MUST reflect the values specified by the Target DLSw in the last SSP message for this circuit that the Origin DLSw received. Binary zero SHOULD be used if no such message has been received yet for a given circuit (apart from the Target Transport ID, which will have been learnt as described above) ๐.
The Origin Data Link Correlator, Origin Port ID and Origin Transport ID MUST remain the same once the Origin DLSw has issued the REACH_ACK for a given circuit. The Target DLSw MUST store the values specified in the REACH_ACK and use them on all subsequent SSP messages for this circuit ๐ง.
The Target DLSw MUST allow these fields to vary until the REACH_ACK is received. Each SSP message issued for a circuit MUST reflect the values specified by the Origin DLSw in the last SSP message for this circuit that the Target DLSw received. Binary zero SHOULD be used if no such message has been received yet for a given circuit (apart from the Origin Transport ID, which will have been learnt as described above) ๐.
For correlator exchange, explorer messages form a separate circuit ๐. Both DLSw partners MUST reflect the last received correlator values as described above. However, correlators learned on explorer messages need not be carried over to a later circuit setup attempt. Specifically, the Origin DLSw MAY elect to use the same values for the Origin Data Link Correlator and Origin Port ID when it issues a CANUREACH_cs after receiving an ICANREACH_ex or NETBIOS_NR_ex. But the Target DLSw MUST NOT assume that the CANUREACH_cs will specify any of the Target Data Link Correlator or Target Port ID values that were exchanged on the explorer messages ๐.
Received SSP messages that require a valid Remote Circuit ID but can't be associated with an existing circuit SHOULD be rejected with a HALT_DL_NOACK message. This is done to prevent a situation where one DLSw partner has a circuit defined while the other partner does not. The exception would be a HALT_DL_NOACK message with an invalid Remote Circuit ID. The HALT_DL_NOACK message is typically used in error situations where a response is not appropriate ๐.
The SSP messages that require a valid Remote Circuit ID are all messages except these: CANUREACH_ex, CANUREACH_cs, ICANREACH_ex, ICANREACH_cs, NETBIOS_NQ_cs, NETBIOS_NR_cs, DATAFRAME, NETBIOS_ANQ, NETBIOS_ANR, KEEPALIVE and CAP_EXCHANGE ๐.
3.4. Largest Frame Size Field โจ
okay so the Largest Frame Size (LF Size) field lives in the SSP Control Header ๐ and its whole job is carrying the LF Size bits across the DLSw connection. the goal is that both end-stations agree on a frame size for the circuit that doesn't make the Origin and Target DLSw partners re-segment frames. no re-segmenting drama ๐
this field only shows up on CANUREACH_ex, CANUREACH_cs, ICANREACH_ex, ICANREACH_cs, NETBIOS_NQ_ex and NETBIOS_NR_ex messages. on every other frame, the contents SHOULD be ignored ๐
every DLSw forwarding an SSP frame to its DLSw partner MUST make sure the contents reflect the minimum capability of the route to its local end-station, or any limit the DLSw itself imposes. main character energy for the smallest link wins ๐
here's the bit layout (bit 7 is the most significant, bit 0 is the least significant) ๐ฆ
7 6 5 4 3 2 1 0
+-------------------------------+
| c | r | b | b | b | e | e | e |
+-------------------------------+
c . . . . . . . LF Size Control flag
(significant on messages
from Origin to Target
DLSw only)
0=fail circuit if route
obtained requires a
smaller LF size
1=don't fail the circuit
but return the LF size
obtained even if it is
smaller
. r . . . . . . Reserved
. . b . . . . . Largest Frame Bit Base
. . . b . . . . Largest Frame Bit Base
. . . . b . . . Largest Frame Bit Base
. . . . . e . . Largest Frame Bit Extended
. . . . . . e . Largest Frame Bit Extended
. . . . . . . e Largest Frame Bit Extended
<----- LF Bits ----->
for the encoding of the Largest Frame base and extended bit values, check the IEEE 802.1D Standard, Annex C ๐
now the Origin DLSw "Size Control" flag is the spicy one ๐ถ๏ธ it tells a Target DLSw that answers *_cs messages from cached info that it MAY safely return a smaller LF Size on the ICANREACH_cs frame, if it had to pick a different route to start the circuit. if this bit is 1, the Origin DLSw takes responsibility for making sure the end-stations negotiate a suitable frame size for the circuit. if this bit is 0, the Target DLSw MUST NOT reply to the CANUREACH_cs if it can't get a route to the Target end station that supports an LF Size at least as large as the one specified in the CANUREACH_cs frame. no compromises, bestie ๐
3.5. Message Types ๐
this table lists the protocol data units that get exchanged between Data Link Switches. anything not listed is reserved for potential use in follow-on releases ๐ง
Command Description Type flags/notes
------- -------- ------ -----------
CANUREACH_ex Can U Reach Station-explorer 0x03 SSPex
CANUREACH_cs Can U Reach Station-circuit start 0x03
ICANREACH_ex I Can Reach Station-explorer 0x04 SSPex
ICANREACH_cs I Can Reach Station-circuit start 0x04
REACH_ACK Reach Acknowledgment 0x05
DGRMFRAME Datagram Frame 0x06 (note 1)
XIDFRAME XID Frame 0x07
CONTACT Contact Remote Station 0x08
CONTACTED Remote Station Contacted 0x09
RESTART_DL Restart Data Link 0x10
DL_RESTARTED Data Link Restarted 0x11
ENTER_BUSY Enter Busy 0x0C (note 2)
EXIT_BUSY Exit Busy 0x0D (note 2)
INFOFRAME Information (I) Frame 0x0A
HALT_DL Halt Data Link 0x0E
DL_HALTED Data Link Halted 0x0F
NETBIOS_NQ_ex NETBIOS Name Query-explorer 0x12 SSPex
NETBIOS_NQ_cs NETBIOS Name Query-circuit setup 0x12 (note 3)
NETBIOS_NR_ex NETBIOS Name Recognized-explorer 0x13 SSPex
NETBIOS_NR_cs NETBIOS Name Recog-circuit setup 0x13 (note 3)
DATAFRAME Data Frame 0x14 (note 1)
HALT_DL_NOACK Halt Data Link with no Ack 0x19
NETBIOS_ANQ NETBIOS Add Name Query 0x1A
NETBIOS_ANR NETBIOS Add Name Response 0x1B
KEEPALIVE Transport Keepalive Message 0x1D (note 4)
CAP_EXCHANGE Capabilities Exchange 0x20
IFCM Independent Flow Control Message 0x21
TEST_CIRCUIT_REQ Test Circuit Request 0x7A
TEST_CIRCUIT_RSP Test Circuit Response 0x7B
Note 1: both DGRMFRAME and DATAFRAME carry information that the DLC entity received inside UI frames ๐ฆ DGRMFRAME is addressed by a pair of Circuit IDs, while DATAFRAME is addressed by a Data Link ID, which is made of a pair of MAC addresses and a pair of link SAP addresses. the Data Link ID is used before the end-to-end circuit exists (when Circuit IDs aren't set up yet) or during a circuit restart, when Data Links get reset.
Note 2: these messages aren't used for the DLSw Standard, but older DLSw implementations MAY use them ๐ฐ๏ธ they're listed just for information. they were added after RFC 1434 was published and got deleted in this standard, since adaptive pacing does the job now.
Note 3: a Standard DLSw doesn't normally send these ๐ it uses the NB_*_ex messages instead, as shown in section 5.4. but if a Standard DLSw wants to interoperate with older DLSw implementations, these messages line up with the NETBIOS_NQ and NETBIOS_NR messages from RFC1434, used both to find the resource and to set up a circuit. this document doesn't try to fully spec how these get used.
Note 4: a KEEPALIVE message MAY be sent by a DLSw to a partner DLSw to check that the TCP connection (or some future SSP carrying protocol) is still alive ๐ if a DLSw receives one, it gets discarded and ignored. using this message is OPTIONAL.
for NetBIOS control messages, the whole DLC header rides along as part of the message unit ๐ that includes the MAC header, with the routing information field padded to 18 bytes, plus the LLC header. the affected message types are NETBIOS_NQ, NETBIOS_NR, NETBIOS_ANQ, NETBIOS_ANR, and DATAFRAME when NetBIOS systems are using it. the remote Data Link Switch doesn't use the routing information in the DLC header when it gets any of those five messages ๐
any SSP message types that aren't defined above are supposed to be ignored if a DLSw receives them, meaning no error action happens ๐ซถ a Data Link Switch SHOULD quietly drop any SSP message whose Message Type it doesn't recognize or support. getting one of those MUST NOT... sorry, SHOULD NOT cause the transport connection to the sender to get terminated ๐ญ
4. Circuit Priority ๐
at circuit start time, each circuit end point gives its circuit partner some priority info ๐ the initiator of the circuit picks which priority sticks for the whole life of the circuit. if the Data Link Switch doesn't implement Priority, then "Unsupported" priority gets used.
4.1. Frame format ๐ฆ
circuit priority is only valid in the CANUREACH_cs, ICANREACH_cs, and REACH_ACK frames. the relevant header field is below. the Circuit Priority value is a byte at offset 22 in an SSP Control Message.
here's the Circuit Priority byte format:
7 6 5 4 3 2 1 0
+-------------------+-----------+
| reserved | CP |
+-------------------+-----------+
and here's what the CP bits mean ๐
CP: Circuit Priority bits
000 - Unsupported (note 1)
001 - Low Priority
010 - Medium Priority
011 - High Priority
100 - Highest Priority
101 to 111 are reserved for future use
Note 1: "Unsupported" means the Data Link Switch that started the circuit doesn't implement priority. what happens with Unsupported priority is vendor specific ๐คทโโ๏ธ
4.2. Circuit Startup ๐
whoever sends a CANUREACH_cs is in charge of setting the CP bits to match the priority they want for the circuit they're requesting ๐ how they pick that value is implementation dependent. the sender of an ICANREACH_cs does the same thing, also with an implementation dependent way of choosing ๐ง the receiver of the ICANREACH_cs picks from the priorities in the CANUREACH_cs and ICANREACH_cs frames, then sets the CP field in the REACH_ACK that comes next to whatever value the circuit will use. that priority sticks for the life of the circuit โจ a CANUREACH_cs or ICANREACH_cs with CP set to Unsupported (CP=000) means the sender doesn't support the circuit priority function ๐
here's how the flow plays out:
DLSw A DLSw B
CANUREACH_cs (CP=011) -----> Circuit initiator requests
high Priority.
<--------- ICANREACH_cs (CP=010) Circuit target requests
medium priority.
REACH_ACK (CP=010) --------> Circuit initiator sets
the priority for this
circuit to medium. The
circuit initiator could
choose either high or
medium in this example.
5. DLSw State Machine โจ
okay so this is the part where we talk about the state machine ๐ซถ Every circuit going through the Data Link Switch gets its own state tracking, and every connection keeps its own state info too. A connection always starts out in DISCONNECTED (the blank slate ๐ง). The steady states are either CIRCUIT_ESTABLISHED or CONNECTED. In CIRCUIT_ESTABLISHED, an end-to-end circuit is up, so the end systems can talk Type 1 LLC ๐. CONNECTED means there's an end-to-end connection for Type 2 LLC services between the end systems, and that's the one that gets the full glam ๐
For SNA, LLC type 2 connection setup happens through IEEE 802.2 Test or XID frames. SNA devices send these to the null SAP so they can figure out source route info for bridging ๐ธ Normally SNA devices use SAP 0x04, 0x08, or 0x0C (most SNA LLC2 devices with a single PU per MAC address default to 0x04). Usually the SAP is what decides whether those Test frames get sent to the DLSw code in the router. If bridging and DLSw are both turned on, this lets the product make sure SNA frames don't get bridged and switched, which would be chaos ๐ญ Also, although SNA typically uses a DSAP and SSAP of 0x04, it's allowed to use other SAPs if they're configured, and it supports unequal SAPs too. That means multiple PUs can share connections between two MAC addresses, with each PU to PU session using one LLC2 connection. Very efficient, very iconic ๐ฆ
For NetBIOS, LLC type 2 connection setup happens through the Name Query and Name Recognized frames. Those frames do double duty for address resolution and source route determination ๐ง NetBIOS devices use SAP 0xF0.
5.1. Data Link Switch States
The Switch-to-Switch Protocol is formally defined through the state machines in this chapter ๐ The table below lists the thirteen possible states for the main circuit FSM. Each end-to-end circuit that the Data Link Switch maintains gets its own separate state machine instance, so they're all doing their own thing ๐
State Name Description
---------- -----------
CIRCUIT_ESTABLISHED The end-to-end circuit has been
established. At this time LLC Type 1
services are available from end-to-end.
CIRCUIT_PENDING The target DLSw is awaiting a REACH_ACK
response to an ICANREACH_cs message.
CIRCUIT_RESTART The DLSw that originated the reset is
awaiting the restart of the data link
and the DL_RESTARTED response to a
RESTART_DL message.
CIRCUIT_START The origin DLSw is awaiting a
ICANREACH_cs in response to a
CANUREACH_cs message.
CONNECTED The end-to-end connection has
been established thereby allowing
LLC Type 2 services from end-to-end
in addition to LLC Type 1 services.
CONNECT_PENDING The origin DLSw is awaiting the
CONTACTED response to a CONTACT
message.
CONTACT_PENDING The target DLSw is awaiting the
DLC_CONTACTED confirmation to a
DLC_CONTACT signal (i.e., DLC
is waiting for a UA response to
an SABME command).
DISCONNECTED The initial state with no circuit
or connection established, the
DLSw is awaiting either a
CANUREACH_cs, or an ICANREACH_cs.
DISCONNECT_PENDING The DLSw that originated the
disconnect is awaiting the DL_HALTED
response to a HALT_DL message.
HALT_PENDING The remote DLSw is awaiting the
DLC_DL_HALTED indication following
the DLC_HALT_DL request (i.e., DLC
is waiting for a UA response to a
DISC command), due to receiving a
HALT_DL message.
HALT_PENDING_NOACK The remote DLSw is awaiting the
DLC_DL_HALTED indication following
the DLC_HALT_DL request (i.e., DLC
is waiting for a UA response to a
DISC command), due to receiving a
HALT_DL_NOACK message.
RESTART_PENDING The remote DLSw is awaiting the
DLC_DL_HALTED indication following
the DLC_HALT_DL request (i.e., DLC
is waiting for a UA response to a
DISC command), and the restart of
the data link.
RESOLVE_PENDING The target DLSw is awaiting
the DLC_DL_STARTED indication
following the DLC_START_DL request
(i.e., DLC is waiting for a Test
response as a result of sending a
Test command).
DISCONNECTED is the starting state for a new circuit ๐ One end station kicks things off with an XID or SABME command (i.e., DLC_XID or DLC_CONTACTED). When that comes in, the Data Link Switches swap a set of CANUREACH_cs, ICANREACH_cs and REACH_ACK messages. It's a three-legged exchange, and once it wraps up, both Data Link Switches land in CIRCUIT_ESTABLISHED โจ Three pending states show up during this dance. CIRCUIT_START gets entered by the origin Data Link Switch after it sends the CANUREACH_cs message. RESOLVE_PENDING gets entered by the target Data Link Switch while it waits for a Test response to a Test Command. And last but not least, CIRCUIT_PENDING is entered by the target DLSw while it waits for the REACH_ACK reply to an ICANREACH_cs message.
In CIRCUIT_ESTABLISHED, LLC Type 1 frames can be exchanged, like the XID exchanges between SNA stations that happen before a connection gets set up ๐ Datagram traffic (i.e., UI frames) can also flow between the end stations. These exchanges use the XIDFRAME and DGRMFRAME messages sent between the Data Link Switches.
Now, in CIRCUIT_ESTABLISHED, if a SABME command shows up (i.e., DLC_CONTACTED), the origin DLSw issues a CONTACT message, sends an RNR supervisory frame (i.e., DLC_ENTER_BUSY) to the origin station, and enters CONNECT_PENDING to wait for a CONTACTED message. The target DLSw, once it gets the CONTACT message, issues a SABME command (i.e., DLC_CONTACT) and enters the Contact Pending state. When the UA response arrives (i.e., DLC_CONTACTED), the target DLSw sends a CONTACTED message and enters CONNECTED. Then, when the origin DLSw receives that, it enters CONNECTED too and sends an RR supervisory frame (i.e., DLC_EXIT_BUSY). Plot twist, everyone's connected ๐
CONNECTED is the steady state for normal data flow once a connection has been set up ๐ Information frames (i.e., INFOFRAME messages) just go back and forth between the endpoints of the connection. This is the path that should be optimized for performance โญ
The connection ends when a DISC frame is received or when DLC detects some other error condition (i.e., DLC_ERROR) ๐ When that indication arrives, the DLSw halts the local data link, sends a HALT_DL message to the remote DLSw, and enters the DISCONNECT_PENDING State. When the other DLSw receives the HALT_DL frame, it halts the local DLC for that data link, returns a DL_HALTED message, and enters DISCONNECTED. Getting that DL_HALTED message makes the other DLSw enter DISCONNECTED as well, so both sides are out ๐ซถ
CIRCUIT_RESTART gets entered if one of the Data Link Switches receives a SABME command (i.e., DLC_RESET) after data transfer while it's in CONNECTED ๐ฅ That causes a DM command to be sent back to the origin station, and a RESTART_DL message goes to the remote Data Link Switch. That halts the remote data link and then restarts it. The remote DLSw then sends a DL_RESTARTED message back to the first DLSw. When the first DLSw gets DL_RESTARTED, it issues a new CONTACT message, as long as the local DLC has been contacted (i.e., the origin station has resent the SABME command). That gets answered eventually with a CONTACTED message, and after that exchange, both Data Link Switches go back to CONNECTED ๐ฆ If the local DLC hasn't been contacted, getting a DL_RESTARTED command makes the Data Link Switch enter CIRCUIT_ESTABLISHED and wait for a SABME command (i.e., DLC_CONTACTED signal) instead.
HALT_PENDING, HALT_PENDING_NOACK and RESTART_PENDING are for when the Data Link Switch is waiting on responses from the local station on the adjacent LAN (e.g., a UA response to a DISC command) ๐ In RESTART_PENDING, the Data Link Switch also tries to restart the data link before it sends a DL_RESTARTED message. In some implementations, starting a data link involves a Test command/response exchange on the adjacent LAN (i.e., DLC_START_DL). For other implementations, that extra exchange might not be needed at all ๐ง
5.2. State Transition Tables โจ
Okay bestie, this is where the state machine gets fully detailed ๐ง The tables spell out every event, action, and next state. A lot of the transitions depend on local signals passing between the DLSw and one of the DLC entities, so first we need the signal list ๐
DLC Events:
Event Name Description
---------- -----------
DLC_CONTACTED Contact Indication: DLC has received an SABME
command or DLC has received a UA response as a
result of sending an SABME command.
DLC_DGRM Datagram Indication: DLC has received a UI frame.
DLC_ERROR Error condition indicated by DLC: Such a
condition occurs when a DISC command is received
or when DLC experiences an unrecoverable error.
DLC_INFO Information Indication: DLC has received an
Information (I) frame.
DLC_DL_HALTED Data Link Halted Indication: DLC has
received a UA response to a DISC command.
DLC_DL_STARTED Data Link Started Indication: DLC has
received a Test response from the null SAP.
DLC_RESET Reset Indication: DLC has received an SABME
command during the time a connection is
currently active and has responded with DM.
DLC_RESOLVE_C Resolve Command Indication: DLC has received
a Test command addressed to the null SAP, or an
XID command addressed to the null SAP.
DLC_RESOLVED Resolve request: DLC has received a TEST response
frame (or equivalent for non-LAN DLCs) but has not
reserved the resources required for a circuit yet.
DLC_XID XID Indication: DLC has received an XID command
or response to a non-null SAP.
Other Events:
Event Name Description
---------- -----------
XPORT_FAILURE Failure of the transport connection used by the
circuit.
CS_TIMER_EXP The CIRCUIT_START timer (started when the circuit
went into CIRCUIT_START state) has expired.
DLC Actions:
Action Name Description
----------- -----------
DLC_CONTACT Contact Station Request: DLC will send a SABME
command or a UA response to an outstanding SABME
command.
DLC_DGRM Datagram Request: DLC will send a UI frame.
DLC_ENTER_BUSY Enter Link Station Busy: DLC will send an
RNR supervisory frame.
DLC_EXIT_BUSY Exit Link Station Busy: DLC will send an RR
supervisory frame.
DLC_HALT_DL Halt Data Link Request: DLC will send a DISC
command.
DLC_INFO Information Request: DLC will send an I frame.
DLC_RESOLVE Resolve request: DLC should issue a TEST (or
appropriate equivalent for non-LAN DLCs) but need
not reserve the resources required for a circuit yet.
DLC_RESOLVE_R Resolve Response Request: DLC will send a
Test response or XID response from the null SAP.
DLC_START_DL Start Data Link Request: DLC will send a Test
command to the null SAP.
DLC_XID XID Request: DLC will send an XID command or an
XID response.
Other Actions:
Action Name Description
---------- -----------
START_CS_TIMER Start the CIRCUIT_START timer.
DLC_RESOLVE_RandDLC_START_DLactions require the DLC to reserve the resources necessary for a link station, since they are only used when a circuit is about to be started. TheDLC_RESOLVEaction is used for topology explorer traffic and does not require such resources to be reserved, though a DLC implementation may choose not to distinguish this from theDLC_START_DLaction. See section 5.4 for details of the actions and events for explorer frames.
The Data Link Switch is described by a state transition table, as laid out in the following sections. Each state is described below in terms of the events, actions, and next state for each transition. If a particular event is not listed for a given state, no action and no state transition should occur for that event. Any significant comments about the transitions within a given state come right after the table for that state ๐ธ
A separate state machine instance is maintained by the Data Link Switch for each end-to-end circuit. How many circuits each Data Link Switch can support is a local implementation option ๐ฆ
The CANUREACH_ex, ICANREACH_ex, NETBIOS_NQ_ex, and NETBIOS_NR_ex are SSP messages that aren't tied to a particular circuit, so they're handled separately. Their processing is covered in section 5.4 ๐ซถ
5.2.1. DISCONNECTED State
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive CANUREACH_cs | DLC_START_DL | RESOLVE_PENDING |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| DLC_XID | If source route | If CANUREACH_cs was |
| | bridged frame with | sent: |
| | broadcast indicated:| CIRCUIT_START |
| | Send CANUREACH_ex | |
| | else: | |
| | Send CANUREACH_cs | |
| | START_CS_TIMER | |
+----------------------+---------------------+----------------------+
| DLC_DGRM | If NETBIOS | |
| | NAME_QUERY: | |
| | Send NETBIOS_NQ_ex | |
| | else: | |
| | Send DATAFRAME | |
+----------------------+---------------------+----------------------+
| DLC_CONTACTED | Send CANUREACH_cs | CIRCUIT_START |
+----------------------+---------------------+----------------------+
It's assumed that each Data Link Switch will build a set of topology tables that give the identity of each Data Link Switch that can reach a specific MAC address or a specific NetBIOS name. These tables can be built using the explorer frames, as per the Explorer FSM in section 5.4, so the amount of search traffic can be kept to a minimum ๐
When a TEST command, broadcast XID, or NetBIOS NAME_QUERY comes in, the Data Link Switch checks the topology table for the target MAC/SAP or NetBIOS name. If there's no matching entry in the table, the Data Link Switch uses the explorer FSMs in section 5.4 to locate the target MAC/SAP or NetBIOS name ๐งญ
When the first non-broadcast XID or SABME flows, the Data Link Switch issues a CANUREACH_cs to attempt to start a circuit. The CANUREACH_cs message is sent only to those Data Link Switches that are known to be able to reach the given MAC address. The mechanism by which a topology table entry is judged out-of-date and deleted from the table is implementation specific ๐
The DISCONNECTED state is exited upon the sending of a CANUREACH_cs by the origin DLSw, or the receipt of a CANUREACH_cs message by a prospective target Data Link Switch. In the latter case, the Data Link Switch will issue a Test command to the target station (i.e., the DLC_START_DL signal is presented to the DLC) ๐
5.2.2. RESOLVE_PENDING State
+-------------------+-----------------------+-----------------------+
| Event | Action(s) | Next State |
+-------------------+-----------------------+-----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+-------------------+-----------------------+-----------------------+
| DLC_DL_STARTED | If LF value of | If LF value of |
| | DLC_DL_STARTED | DLC_DL_STARTED |
| | is greater than or | is greater than or |
| | equal to LF Size of | equal to LF Size of |
| | CANUREACH_cs or LF | CANUREACH_cs or LF |
| | Size Control bit set: | Size Control bit set: |
| | Send ICANREACH_cs | CIRCUIT_PENDING |
| | else: | else: |
| | Send DLC_HALT_DL | HALT_PENDING_NOACK |
+-------------------+-----------------------+-----------------------+
| DLC_ERROR | | DISCONNECTED |
+-------------------+-----------------------+-----------------------+
| DLC_DGRM | Send DATAFRAME | |
+-------------------+-----------------------+-----------------------+
The RESOLVE_PENDING state is entered upon receipt of a CANUREACH_cs message by the target DLSw. A data link is started, which causes a Test command to be sent by the DLC ๐
Several CANUREACH_cs messages can be received while in the RESOLVE_PENDING state. The Data Link Switch may update its topology information based on the origin MAC address information in each CANUREACH_cs message ๐
When a DLC_DL_STARTED signal is received in the RESOLVE_PENDING state, the Data Link Switch may update its topology table based on the remote MAC address information. The ICANREACH_cs message must be returned to the first partner DLSw from which a CANUREACH_cs was received for this circuit, or an implementation may optionally reply to all partners from which the CANUREACH_cs was received ๐
The RESOLVE_PENDING state is exited once the data link has been started (i.e., a DLC_DL_STARTED signal is received as a result of a Test response received by the DLC). The target Data Link Switch then enters the CIRCUIT_PENDING state ๐ฆ
5.2.3. CIRCUIT_START State โจ
okay bestie, this is the state where the origin Data Link Switch is basically waiting for its partner to show up ๐ฅบ๐ Here's the whole table, exactly as it's written:
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive CANUREACH_cs | If origin MAC addr | If DLC_START_DL |
| for circuit in | in CANUREACH_cs is | issued: |
| opposite direction | greater than origin | RESOLVE_PENDING |
| | MAC addr of circuit:| |
| | DLC_START_DL | |
| | else: | |
| | no action taken | |
+----------------------+---------------------+----------------------+
| Receive ICANREACH_cs | If LF Size Control | If LF Size Control |
| | bit set and LF Size | bit set and LF Size |
| | is not negotiable: | is not negotiable: |
| | Send HALT_DL_NOACK| DISCONNECTED |
| | else: | else if Connected: |
| | Send REACH_ACK, | CONNECT_PENDING |
| | Send appropriate | else: |
| | SSP message based | CIRCUIT_ESTABLISHED|
| | on the event | |
| | that generated | |
| | CANUREACH_cs | |
| | (see Note) | |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DATAFRAME | |
+----------------------+---------------------+----------------------+
| DLC_ERROR | | DISCONNECTED |
+----------------------+---------------------+----------------------+
| CS_TIMER_EXP | | DISCONNECTED |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | | DISCONNECTED |
+----------------------+---------------------+----------------------+
The origin Data Link Switch jumps into CIRCUIT_START when it gets a DLC_XID or DLC_CONTACTED signal from the DLC ๐
It leaves this state as soon as an ICANREACH_cs message shows up. Then it sends a REACH_ACK back to the target Data Link Switch. If we got here because of DLC_XID, it also sends an XIDFRAME carrying the XID to the target Data Link Switch. If we got here because of DLC_CONTACTED, it sends a CONTACT message to the target Data Link Switch instead โจ
5.2.4. CIRCUIT_PENDING State ๐ฆ
this one is the target's waiting room ๐ง Here's the table, untouched:
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive CONTACT | DLC_CONTACT | CONTACT_PENDING |
+----------------------+---------------------+----------------------+
| Receive HALT_DL | DLC_HALT_DL | HALT_PENDING |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
| Receive REACH_ACK | If Connected: | If Connected: |
| | Send CONTACT | CONNECT_PENDING, |
| | | else: |
| | | CIRCUIT_ESTABLISHED |
+----------------------+---------------------+----------------------+
| Receive XIDFRAME | DLC_XID | |
+----------------------+---------------------+----------------------+
| Receive DGRMFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| DLC_CONTACTED | If UA is sent in | |
| | response to SABME: | |
| | DLC_ENTER_BUSY | |
| | else: | |
| | no action taken | |
+----------------------+---------------------+----------------------+
| DLC_ERROR | | DISCONNECTED |
+----------------------+---------------------+----------------------+
| DLC_XID | Drop or hold until | |
| | REACH_ACK received | |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DATAFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
The target Data Link Switch lands here right after it sends an ICANREACH_cs message. It's just waiting for a REACH_ACK from the origin Data Link Switch ๐ฅน
Now, if the target station sends a SABME command while we're in CIRCUIT_PENDING (aka the DLC gave us a DLC_CONTACTED signal), then when the REACH_ACK finally arrives, the target Data Link Switch moves into CONNECT_PENDING and sends a CONTACT message to the origin Data Link Switch. Plot twist, but make it iconic ๐
If no SABME shows up, the REACH_ACK just gets the Data Link Switch into CIRCUIT_ESTABLISHED. Clean and simple ๐ธ
5.2.5. CONNECT_PENDING State ๐
this is the state with the most drama, so buckle up ๐ญ Here's the table:
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive CONTACTED | If UA was sent in | CONNECTED |
| | response to SABME: | |
| | DLC_EXIT_BUSY | |
| | else: | |
| | DLC_CONTACT | |
+----------------------+---------------------+----------------------+
| Receive HALT_DL | DLC_HALT_DL | HALT_PENDING |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
| Receive DGRMFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| Receive ICANREACH_cs | Send HALT_DL_NOACK | |
+----------------------+---------------------+----------------------+
| DLC_RESET | Send RESTART_DL | CIRCUIT_RESTART |
+----------------------+---------------------+----------------------+
| DLC_ERROR | Send HALT_DL | DISCONNECT_PENDING |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DGRMFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
CONNECT_PENDING gets entered when the DLC hands us a DLC_CONTACTED signal, which means a SABME command came in. From there, a CONTACT message gets issued. We only leave this state once a CONTACTED message shows up ๐ If a DLC_RESET signal comes in, the local data link gets restarted and a RESTART_DL message is sent to the remote DLSw. Ugh, so dramatic, I love it ๐
Here's the spicy bit โก If an ICANREACH_cs arrives after we've already moved into CONNECT_PENDING, that means more than one CANUREACH_cs got sent when the circuit was being set up, and the target station was found by more than one Data Link Switch partner. So we send a HALT_DL_NOACK to halt the circuit that each of those extra partners started when it sent its ICANREACH_cs. Not the vibe for those duplicates ๐ โโ๏ธ
Note: Some implementations will also send a Test command in order to restart the data link to the station that sent the SABME command (i.e., a DLC_START_DL will be issued).
5.2.6. CIRCUIT_ESTABLISHED State โจ
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive CONTACT | DLC_CONTACT | CONTACT_PENDING |
+----------------------+---------------------+----------------------+
| Receive HALT_DL | DLC_HALT_DL | HALT_PENDING |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
| Receive XIDFRAME | DLC_XID | |
+----------------------+---------------------+----------------------+
| Receive DGRMFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| Receive ICANREACH_cs | Send HALT_DL_NOACK | |
+----------------------+---------------------+----------------------+
| DLC_CONTACTED | Send CONTACT | CONNECT_PENDING |
| | If UA is sent in | |
| | response to SABME: | |
| | DLC_ENTER_BUSY | |
| | else: | |
| | no action taken | |
+----------------------+---------------------+----------------------+
| DLC_ERROR | Send HALT_DL | DISCONNECT_PENDING |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DGRMFRAME | |
+----------------------+---------------------+----------------------+
| DLC_XID | Send XIDFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
Okay so the CIRCUIT_ESTABLISHED state is where the origin Data Link Switch lands coming from CIRCUIT_START, and the target Data Link Switch lands here coming from CIRCUIT_PENDING ๐
. You leave when a connection gets started (aka DLC receives a SABME command) or when a CONTACT shows up. From there you go to CONTACT_PENDING or CONNECT_PENDING ๐ฆ.
An ICANREACH_cs that arrives after you've already hit CIRCUIT_ESTABLISHED means more than one CANUREACH_cs went out at circuit establishment time, and the target station got found by more than one Data Link Switch partner ๐ญ. So a HALT_DL_NOACK gets sent to halt the circuit started by the Data Link Switch partner that originated each one of those ICANREACH_cs messages. Main character energy, but make it a cleanup crew ๐งน.
5.2.7. CONTACT_PENDING State ๐
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive HALT_DL | DLC_HALT_DL | HALT_PENDING |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
| Receive RESTART_DL | DLC_HALT_DL | RESTART_PENDING |
+----------------------+---------------------+----------------------+
| Receive DGRMFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| DLC_CONTACTED | Send CONTACTED | CONNECTED |
+----------------------+---------------------+----------------------+
| DLC_ERROR | Send HALT_DL | DISCONNECT_PENDING |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DGRMFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
The CONTACT_PENDING state gets entered when a CONTACT message arrives, which makes the Data Link Switch fire a DLC_CONTACT signal at the DLC (i.e., the DLC sends a SABME command) ๐ก. You hang out here until a DLC_CONTACTED signal comes back from the DLC (i.e., a UA response is received) and then you're out ๐ฆ.
If a RESTART_DL message comes in, that means the remote Data Link Switch got a DLC_RESET signal. So the local Data Link Switch sends a DISC command frame on the adjacent LAN (i.e., DLC_HALT_DL signal) and enters the RESTART_PENDING state ๐.
An ICANREACH_cs received after the transition to CONTACT_PENDING is the same plot twist as before: more than one CANUREACH_cs was sent at circuit establishment time, and the target station was found by more than one Data Link Switch partner. A HALT_DL_NOACK is sent to halt the data link started by the Data Link Switch partner that originated this ICANREACH_cs ๐
โโ๏ธ.
5.2.8. CONNECTED State ๐
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive HALT_DL | DLC_HALT_DL | HALT_PENDING |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
| Receive RESTART_DL | DLC_HALT_DL | RESTART_PENDING |
+----------------------+---------------------+----------------------+
| Receive DGRMFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| Receive INFOFRAME | DLC_INFO | |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| Receive XIDFRAME | If non-activation | |
| | XID3: | |
| | DLC_XID | |
+----------------------+---------------------+----------------------+
| Receive ICANREACH_cs | Send HALT_DL_NOACK | |
+----------------------+---------------------+----------------------+
| Receive ENTER_BUSY | DLC_ENTER_BUSY | |
+----------------------+---------------------+----------------------+
| Receive EXIT_BUSY | DLC_EXIT_BUSY | |
+----------------------+---------------------+----------------------+
| Rec TEST_CIRCUIT_REQ | Snd TEST_CIRCUIT_RSP| |
+----------------------+---------------------+----------------------+
| DLC_RESET | Send RESTART_DL | CIRCUIT_RESTART |
+----------------------+---------------------+----------------------+
| DLC_ERROR | Send HALT_DL | DISCONNECT_PENDING |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DGRMFRAME | |
+----------------------+---------------------+----------------------+
| DLC_INFO | Send INFOFRAME | |
+----------------------+---------------------+----------------------+
| DLC_XID | If non-activation | |
| | XID3: | |
| | Send XIDFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
The CONNECTED state is entered from CONNECT_PENDING when a CONTACTED message arrives, or from CONTACT_PENDING when a DLC_CONTACTED signal shows up ๐.
You usually leave CONNECTED in one of two ways. Either a DLC_ERROR signal comes in from the DLC (e.g., a DISC command received by the local DLC), or a HALT_DL message comes in from the other Data Link Switch (e.g., a DISC command received by the remote DLC) ๐.
A SABME command (i.e., a DLC_RESET signal) received by either Data Link Switch also makes both of them leave CONNECTED and try to restart the circuit ๐. After getting a SABME, the local Data Link Switch sends a RESTART_DL message to the other one and enters the CIRCUIT_RESTART state. When that RESTART_DL message lands, the remote Data Link Switch sends a DISC command (i.e., DLC_HALT_DL signal) and enters the RESTART_PENDING state ๐ซถ.
An ICANREACH_cs received after the transition to CONNECTED is the same story as before. More than one CANUREACH_cs was sent at circuit establishment time, and the target station was found by more than one Data Link Switch partner. A HALT_DL_NOACK is sent to halt the circuit started by the Data Link Switch partner that originated each such ICANREACH_cs ๐ซ.
Note: Some implementations will also send a Test command in order to restart the data link to the station that sent the SABME command (i.e., a DLC_START_DL will be issued). ๐ง
5.2.9. CIRCUIT_RESTART State โจ
okay bestie, this one is the "we're starting over" state ๐๐
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive DL_RESTARTED | If Connected: | If Connected: |
| | Send CONTACT | CONNECT_PENDING, |
| | | else: |
| | | CIRCUIT_ESTABLISHED |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
| Receive DGRMFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| DLC_ERROR | Send HALT_DL | DISCONNECT_PENDING |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DGRMFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
So the CIRCUIT_RESTART state kicks in when the local DLC sends a DLC_RESET signal ๐ซถ. That happens because a SABME command showed up while a connection was already active ๐. The Data Link Switch answers that SABME with a DM response, then tries to restart the whole end-to-end circuit ๐ฆ.
There are two ways out of this state ๐ช, and which one you get depends on timing โฐ. What matters is whether the local DLC hits the contacted state (aka a DLC_CONTACTED signal shows up) before or after the DL_RESTARTED message arrives. That DLC_CONTACTED signal happens because the origin station resends the SABME command that originally kicked the Data Link Switch into CIRCUIT_RESTART ๐. So the two cases are:
- DL_RESTARTED message received before the DLC_CONTACTED signal. In this case, the CIRCUIT_ESTABLISHED state is entered. โจ
- DL_RESTARTED message received after the DLC_CONTACTED signal. In this case, the CONNECT_PENDING state is entered. ๐
5.2.10. DISCONNECT_PENDING State ๐ง๏ธ
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive DL_HALTED | | DISCONNECTED |
+----------------------+---------------------+----------------------+
| Receive HALT_DL | Send DL_HALTED | |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| | DISCONNECTED |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DATAFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | | DISCONNECTED |
+----------------------+---------------------+----------------------+
DISCONNECT_PENDING is the state you land in when the local DLC sends a DLC_ERROR signal ๐จ. The moment that signal arrives, the Data Link Switch sends a HALT_DL message ๐ค. Once a DL_HALTED message comes back ๐ฉ, the state is exited and the Data Link Switch moves over to DISCONNECTED ๐ .
5.2.11. RESTART_PENDING State ๐ง
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
| Receive DGRMFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| DLC_DL_HALTED | Send DL_RESTARTED | CIRCUIT_ESTABLISHED |
+----------------------+---------------------+----------------------+
| DLC_ERROR | Send HALT_DL | DISCONNECT_PENDING |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DGRMFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | DLC_HALT_DL | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
RESTART_PENDING gets entered when a RESTART_DL message shows up from the remote DLSw ๐จ. That only happens if the local Data Link Switch is sitting in either CONTACT_PENDING or CONNECTED. Once it's in here, the local DLSw issues a DISC command to the DLC ๐. When the UA response comes back (that's the DLC_DL_HALTED), the data link gets restarted โป๏ธ, a DL_RESTARTED message gets sent back to the remote DLSw ๐, and the CIRCUIT_ESTABLISHED state is entered ๐.
Note: Some implementations will send a Test command in order to restart the data link to the target station (i.e., a DLC_START_DL will be issued) prior to sending the DL_RESTARTED message. ๐งช
5.2.12. HALT_PENDING State ๐
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive HALT_DL_NOACK| | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| DLC_DL_HALTED | Send DL_HALTED | DISCONNECTED |
+----------------------+---------------------+----------------------+
| DLC_ERROR | Send DL_HALTED | DISCONNECTED |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DATAFRAME | |
+----------------------+---------------------+----------------------+
| XPORT_FAILURE | | HALT_PENDING_NOACK |
+----------------------+---------------------+----------------------+
HALT_PENDING is entered when a HALT_DL message is received ๐ง. That makes the local DLC issue a DISC command ๐ด. When the UA response (DLC_DL_HALTED) comes back, a DL_HALTED message goes back to the remote DLSw ๐, and then the DISCONNECTED state is entered ๐ธ.
5.2.13. HALT_PENDING_NOACK State ๐ฅ
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive DATAFRAME | DLC_DGRM | |
+----------------------+---------------------+----------------------+
| DLC_DL_HALTED | | DISCONNECTED |
+----------------------+---------------------+----------------------+
| DLC_ERROR | | DISCONNECTED |
+----------------------+---------------------+----------------------+
| DLC_DGRM | Send DATAFRAME | |
+----------------------+---------------------+----------------------+
HALT_PENDING_NOACK gets entered when a HALT_DL_NOACK message is received ๐ โโ๏ธ. That causes the local DLC to issue a DISC command. When the UA response (DLC_DL_HALTED) finally comes in, the DISCONNECTED state is entered ๐โจ.
5.3 NetBIOS Datagrams โจ
okay so NetBIOS uses a bunch of UI frames for directory services and sending datagrams ๐ฎ Most of these go to a group MAC address (GA) with the routing information field set to spanning tree explorer (STE), which is also called Single Route Broadcast ๐ธ The NB_Add_Name_Response and NB_Name_Recognized frames go to one specific MAC address with the routing information field set to an all routes explorer frame (ARE), aka All Routes Broadcast ๐ฆ And the NB_Status_Response frame goes to a specific MAC address too, but its routing information field says specifically routed frame (SRF) ๐ Here's how it all gets handled:
+---------------------------+------------------+--------------------+
| Event | Action(s) | Comment |
+---------------------------+------------------+--------------------+
| DLC_DGRM for NETBIOS | Send NETBIOS_ANQ | Transmitted to all |
| group address: | | remote DLSw |
| NB_Add_Name_Query | | |
+---------------------------+------------------+--------------------+
| DLC_DGRM for a specific | Send NETBIOS_ANR | Transmitted to |
| address: | | specific DLSw |
| NB_Add_Name_Response | | |
+---------------------------+------------------+--------------------+
| DLC_DGRM for a specific | Send DATAFRAME | Transmitted to all |
| address: | | remote DLSw |
| NB_Status_Response | | |
+---------------------------+------------------+--------------------+
| DLC_DGRM for NETBIOS | Send DATAFRAME | Transmitted to all |
| group address: | | remote DLSw |
| NB_Name_in_Conflict | | |
| NB_Add_Group_Name_Query | | |
| NB_Datagram, | | |
| NB_Datagram_Broadcast | | |
| NB_Status_Query | | |
| NB_Terminate_Trace | | |
+---------------------------+------------------+--------------------+
โ ๏ธ Heads up bestie: the actions above do not apply in these states: CIRCUIT_ESTABLISHED, CONTACT_PENDING, CONNECT_PENDING, CONNECTED, and CIRCUIT_PENDING. ๐
The other two NetBIOS UI frames, NB_Name_Query and NB_Name_Recognized, are handled as part of the DLSw state machine in the previous section, specifically the DISCONNECTED and RESOLVE_PENDING states ๐ง And NetBIOS datagrams (NB_Datagram) sent to a specific MAC address are also run through the DLSw state machine ๐
Note: some implementations also send Test frames during the NB_Name_Query and NB_Name_Recognized exchange ๐ This exchange happens when a data link is starting up and it's how the routing information gets figured out. Most other NetBIOS implementations use the NB_Name_Query/NB_Name_Recognized exchange to work out routes at the same time they resolve NetBIOS names, and these differences are not reflected in the SSP protocols ๐ซถ
Here's how the NetBIOS-specific SSP messages get handled:
+---------------+-------------------------+-------------------------+
| Event | Action(s) | Comment |
+---------------+-------------------------+-------------------------+
| NETBIOS_ANQ | DLC_DGRM: | Routed STE |
| | NB_Add_Name_Query | (NETBIOS Group Address) |
+---------------+-------------------------+-------------------------+
| NETBIOS_ANR | DLC_DGRM: | Routed ARE |
| | NB_Add_Name_Response | (Specific MAC Address) |
+---------------+-------------------------+-------------------------+
| NETBIOS_NQ_ex | DLC_DGRM: | Routed STE |
| | NB_Name_Query | (NETBIOS Group Address) |
+---------------+-------------------------+-------------------------+
| NETBIOS_NQ_cs | DLC_DGRM: | Routed STE |
| | NB_Name_Query | (NETBIOS Group Address) |
+---------------+-------------------------+-------------------------+
| NETBIOS_NR_ex | DLC_DGRM: | Routed ARE |
| | NB_Name_Recognized | (Specific MAC Address) |
+---------------+-------------------------+-------------------------+
| NETBIOS_NR_cs | DLC_DGRM: | Routed ARE |
| | NB_Name_Recognized | (Specific MAC Address) |
+---------------+-------------------------+-------------------------+
| DATAFRAME | DLC_DGRM | If NB_Status_Response: |
| | | Routed ARE |
| | | (Specific MAC Address) |
| | | Else: |
| | | Routed STE |
| | | (NETBIOS Group Address)|
+---------------+-------------------------+-------------------------+
These actions apply in all DLSw states ๐ NetBIOS datagrams that ride inside DGRMFRAME messages are governed by the DLSw state machine. DGRMFRAME is used instead of DATAFRAME once the end-to-end circuit is up, and at that point the message gets addressed using the pair of Circuit IDs in the message header, not the MAC address info in the token ring header ๐
5.4 Explorer Traffic ๐ฅ
The CANUREACH_ex, ICANREACH_ex, NETBIOS_NQ_ex, and NETBIOS_NR_ex SSP messages are the explorers ๐งญ They map out the topology of the DLSw cloud and the networks attached to it. Explorer frames are how a DLSw finds out which DLSw partners can reach a given MAC or NetBIOS name. This info can optionally be cached so there's less explorer traffic floating around the DLSw cloud โจ
If a DLSw knows from cached info that a certain MAC address or NetBIOS name is reachable through a certain partner DLSw, it should send all its circuit setup attempts to that partner ๐ If the setup fails, or there's no data for it in the MAC or name cache, the DLSw may fall back to trying every DLSw partner, since the cached data might be outdated by now ๐ฆ How it decides when to fall back is implementation defined.
DLSw implementations can also keep a local MAC cache, so they can reply to CANUREACH_ex requests without doing a TEST frame exchange (or something equivalent) until CANUREACH_cs shows up ๐ธ Again, when that local cache is out of date is implementation defined ๐
Using either cache is totally optional in DLSw. An implementation can always send explorer frames, or use either or both caches. Its choice ๐
The next sections describe the FSMs for explorer frames. The DLC events and actions are a subset of what's in section 5.2 for the main circuit FSM ๐ง
5.4.1 CANUREACH/ICANREACH Explorer FSM ๐ฆ
This FSM handles explorer frames that get routed by MAC address. There's one instance of it for each Data Link ID (that's the Target and Origin MAC/SAP pair) with explorer traffic flowing ๐ The states are:
State Name Description
---------- -----------
RESET The initial state.
SENT_EX Local DLSw has issued an explorer message
RECEIVED_EX Local DLSw has received an explorer message
5.4.1.1 RESET State ๐ซง
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive CANUREACH_ex | If replying from | If DLC_RESOLVE sent, |
| | cache, send | RECEIVED_EX |
| | ICANREACH_ex | |
| | else if allowed to | |
| | test availability, | |
| | issue DLC_RESOLVE. | |
| | Optionally update | |
| | cache. | |
+----------------------+---------------------+----------------------+
| Receive ICANREACH_ex | Optionally update | RESET |
| | cache | |
+----------------------+---------------------+----------------------+
| DLC_RESOLVE_C | Send CANUREACH_ex | SENT_EX |
+----------------------+---------------------+----------------------+
RESET is the starting state for the CANUREACH/ICANREACH explorer FSM ๐ธ You leave it when a DLC_RESOLVE_C request comes in from the DLC, or when a CANUREACH_ex arrives from a remote DLSw.
A DLSw implementation can optionally reply to CANUREACH_ex messages using cached topology info ๐ If it does, the DLC_RESOLVE exchange (the TEST) isn't needed. If there's no cache, or nothing matches, and the DLC allows TEST, the DLSw issues DLC_RESOLVE to find the target MAC and moves to RECEIVED_EX. If there's no cache entry and the DLC doesn't allow TEST, a received CANUREACH_ex is simply ignored ๐
5.4.1.2 SENT_EX State ๐ฎ
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive ICANREACH_ex | DLC_RESOLVE_R | RESET |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
| DLC_RESOLVE_C | | SENT_EX |
+----------------------+---------------------+----------------------+
SENT_EX is entered once the DLSw has sent a CANUREACH_ex message to locate a MAC address ๐ฆ You leave this state when a remote DLSw sends back a matching ICANREACH_ex, or after an implementation defined timeout. DLC_RESOLVE events that show up in this state line up with TEST retries from the origin DLC station, so they get absorbed โจ
An implementation can pick how it handles explorer frame crossover. It can use totally separate FSM instances and just let both ends send TEST frames, or it can detect a reverse CANUREACH_ex frame right here and send an ICANREACH_ex message plus the DLC_RESOLVE_R action instead ๐
5.4.1.3 RECEIVED_EX State ๐ฆ
okay so this is the RECEIVED_EX state, and it's giving "I got a question and I'm figuring out the answer" ๐โจ
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive CANUREACH_ex | Optionally update | RECEIVED_EX |
| | cache | |
+----------------------+---------------------+----------------------+
| Receive ICANREACH_ex | | RECEIVED_EX |
+----------------------+---------------------+----------------------+
| DLC_RESOLVED | Send ICANREACH_ex | RESET |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
RECEIVED_EX gets entered when the DLSw has gotten a CANUREACH_ex from a remote DLSw and has sent out a DLC_RESOLVE to find the MAC address ๐ต๏ธโโ๏ธ๐ . It gets exited once the DLC_RESOLVED response shows up, or after an implementation defined timeout, whichever comes first โฐ.
So if the target MAC is found, the DLSw has to reply to the first CANUREACH_ex that got it into this state, no skipping that one ๐ซถ. If more CANUREACH_ex messages roll in from other remote DLSw partners while it's in this state, the DLSw can reply to those too if it wants to, but it's not required to do that, so no pressure ๐.
An implementation gets to pick how it handles explorer frame crossover ๐ฆ. It can either use totally separate FSM instances and just let both ends send TEST frames, or it can catch that reverse DLC_RESOLVE_C event right here and send an ICANREACH_ex message plus do a DLC_RESOLVE_R action instead โจ. Both are valid, bestie, it's a choice ๐.
5.4.2 NETBIOS_NQ/NR Explorer FSM ๐
This FSM is for handling explorer frames that get routed by NetBIOS names ๐ง. There's one instance of it for every unique combo of Source Name, Destination Name, Data 2 field and Response Correlator, so it's super specific, iykyk ๐.
State Name Description
---------- -----------
RESET The initial state.
SENT_EX Local DLSw has issued an explorer
message
RECEIVED_EX Local DLSw has received an explorer
message
SENT_REC_EX An explorer frame has been both sent
and received for the same (potential)
NetBIOS circuit.
5.4.2.1 RESET State ๐ธ
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive NETBIOS_NQ_ex| DLC_DGRM(NAME_QUERY)| RECEIVED_EX |
| | Optionally update | |
| | cache. | |
+----------------------+---------------------+----------------------+
| Receive NETBIOS_NR_ex| Optionally update | RESET |
| | cache | |
+----------------------+---------------------+----------------------+
| DLC_DGRM (NAME_QUERY)| Send NETBIOS_NQ_ex | SENT_EX |
+----------------------+---------------------+----------------------+
RESET is the starting state for the NETBIOS_NQ/NR explorer FSM ๐. It gets exited when the DLC gets either a NETBIOS_NQ_ex or a DLC_DGRM carrying a NetBIOS NAME_QUERY frame ๐. If a NETBIOS_NQ_ex comes in, the NAME_QUERY gets passed along to the DLC and the FSM moves over to RECEIVED_EX. If a NetBIOS NAME_QUERY frame comes in, the NETBIOS_NQ_ex gets sent out to the appropriate DLSw partners (see below), and the FSM moves to SENT_EX ๐.
Here's the tea โ: SNA traffic can skip the CANUREACH_ex/ICANREACH_ex exchange if the MAC location is already cached, but NETBIOS_NQ_ex/NETBIOS_NR_ex frames have to be issued every single time during NetBIOS session setup ๐ญ. That's because the NetBIOS session numbers need to get swapped correctly between the DLC end stations ๐ . If the location of a NetBIOS name is already known from cached data, the NETBIOS_NQ_ex only needs to go to the cached DLSw partners โจ. Otherwise the NETBIOS_NQ_ex should go out to every partner that supports NetBIOS ๐.
5.4.2.2 SENT_EX State ๐ง
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive NETBIOS_NQ_ex| DLC_DGRM(NAME_QUERY)| SENT_REC_EX |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
| Receive NETBIOS_NR_ex| DLC_DGRM(NAME_RECOG)| RESET |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
| DLC_DGRM (NAME_QUERY)| Send NETBIOS_NQ_ex | SENT_EX |
| (different local | Optionally update | |
| session number than | cache | |
| existing searches) | | |
+----------------------+---------------------+----------------------+
SENT_EX kicks in when the local DLSw sends a NETBIOS_NQ_ex out to its remote DLSw partners ๐ค. It gets exited when a NETBIOS_NR_ex comes back from a remote DLSw, or if a matching NETBIOS_NQ_ex comes in from a remote DLSw (that's the NETBIOS_NQ_ex crossover case, bestie ๐). If the local NetBIOS end station sends a NAME_QUERY with a different session number from any earlier NAME_QUERY for this search, that NAME_QUERY gets passed to the DLSw partners so the session numbers keep getting handled correctly ๐.
5.4.2.3 RECEIVED_EX State ๐
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive NETBIOS_NQ_ex| DLC_DGRM(NAME_QUERY)| RECEIVED_EX |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
| Receive NETBIOS_NR_ex| | RECEIVED_EX |
+----------------------+---------------------+----------------------+
| DLC_DGRM (NAME_QUERY)| Send NETBIOS_NQ_ex | SENT_REC_EX |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
| DLC_DGRM (NAME_RECOG)| Send NETBIOS_NR_ex | RESET |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
RECEIVED_EX is entered when the local DLSw gets a NETBIOS_NQ_ex message from a remote DLSw ๐ฅ. It gets exited when a NAME_RECOGNIZED NetBIOS frame arrives from the DLC, which wraps up the query โ , or when a matching NAME_QUERY comes in from the DLC (aka NAME_QUERY crossover, lowkey a plot twist ๐ญ).
5.4.2.4 SENT_REC_EX State ๐ท
+----------------------+---------------------+----------------------+
| Event | Action(s) | Next State |
+----------------------+---------------------+----------------------+
| Receive NETBIOS_NQ_ex| DLC_DGRM(NAME_QUERY)| SENT_REC_EX |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
| Receive NETBIOS_NR_ex| DLC_DGRM(NAME_RECOG)| RECEIVED_EX |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
| DLC_DGRM (NAME_QUERY)| Send NETBIOS_NQ_ex | SENT_REC_EX |
| (different local | Optionally update | |
| session number than | cache | |
| existing searches) | | |
+----------------------+---------------------+----------------------+
| DLC_DGRM (NAME_RECOG)| Send NETBIOS_NR_ex | SENT_EX |
| | Optionally update | |
| | cache | |
+----------------------+---------------------+----------------------+
This state is required if an implementation wants to handle NQ/NR crossover cases from one FSM instance by spotting 'opposite' NAME_QUERY attempts between the same two NetBIOS names ๐. If separate FSM instances are used instead, this state isn't required and the transitions into it from other states can be removed ๐งฉ.
SENT_RCV_EX gets exited once the NAME_QUERY search is resolved in either direction ๐. If the local NetBIOS end station sends a NAME_QUERY with a different session number from any NAME_QUERY it already sent for this search, that NAME_QUERY gets passed to the DLSw partners so the session number exchange stays correct ๐ .
5.4.2.5 NetBIOS Session Numbers ๐ฆ
NetBIOS NAME_QUERY and NAME_RECOGNIZED frames are how the end stations swap NetBIOS session numbers ๐ข. For NetBIOS to work right over DLSw, every SSP NETBIOS_NQ_ex frame a DLSw receives has to make NetBIOS NAME_QUERY frames flow on the LAN with the new session number from that NETBIOS_NQ_ex โจ. These frames can't get answered from a cache of local NetBIOS names the way MAC addresses and CANUREACH_ex messages can ๐ โโ๏ธ.
Also, NAME_QUERY messages usually get retried a bunch of times on the LAN ๐. Making and absorbing those frames is outside the scope of the FSM above, so that's a different story ๐.
6. Protocol Flow Diagrams ๐
The Switch-to-Switch Protocol is what sets up and takes down circuits between a pair of Data Link Switches ๐. Once a circuit is up, the end stations on the local networks can use LLC Type 1 (connectionless UI frames) protocols end-to-end ๐. The end systems can also set up an end-to-end connection to support LLC Type 2 (connection oriented I frames) protocols, where Type 2 I frames go end-to-end and supervisory frames get handled locally ๐ซถ.
The term Data Link is used in this document to mean both a "logical data link" when Type 1 LLC services are in play, and a "data link connection" when Type 2 LLC services are in play โจ. Either way, the Data Link is identified by the Data Link ID defined in section 3.2 ๐ชช.
NOTE: THIS SECTION CONTAINS EXAMPLES ONLY. IT CANNOT AND DOES NOT SHOW ALL POSSIBLE VARIATIONS AND OPTIONS ON PROTOCOL FLOWS FOR SNA/SDLC, SSP, AND LLC PROTOCOLS. ๐
6.1 Connect Protocols ๐
The two basic startup flows, from a pure FSM point of view, are shown below ๐ง. The first one is a startup that involves XIDs, and the second one doesn't use XIDs at all ๐.
Flow #1 - DLSw Startup With XIDs โจ
Okay bestie, this is Flow #1, where DLSw starts up with XIDs ๐ฆ Both stations start out disconnected, then a bunch of resolve and XID messages get passed around until they're both connected. It's giving full choreography ๐
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
disconnected disconnected
DLC_RESOLVE_C CANUREACH_ex
-----------> ----------->
DLC_RESOLVE_R ICANREACH_ex
<----------- <-----------
DLC_XID CANUREACH_cs DLC_START_DL
-----------> -----------> ----------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED
<----------- <-----------
circuit_established circuit_pending
REACH_ACK
-----------> circuit_established
XIDFRAME DLC_XID
-----------> ----------->
DLC_XID XIDFRAME DLC_XID
<----------- <----------- <-----------
DLC_XID XIDFRAME DLC_XID
-----------> -----------> ----------->
DLC_XIDs XIDFRAMEs DLC_XIDs
<------------> <------------> <------------>
DLC_CONTACTED CONTACT DLC_CONTACT
-----------> -----------> ----------->
connect_pending contact_pending
DLC_CONTACT CONTACTED DLC_CONTACTED
<----------- <----------- <-----------
connected connected
DLC_INFOs IFRAMEs DLC_INFOs
<------------> <------------> <------------>
Now let's map the LAN events onto the DLC events and actions for Flow #1. Here's what that looks like ๐
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
disconnected disconnected
TEST_cmd DLC_RESOLVE_C CANUREACH_ex TEST_cmd
-----------> -----------> -----------> ---------->
TEST_rsp DLC_RESOLVE_R ICANREACH_ex TEST_rsp
<--------- <----------- <----------- <-----------
null XID DLC_XID CANUREACH_cs DLC_START_DL
-----------> -----------> -----------> ----------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED
<----------- <-------------
circuit_established circuit_pending
REACH_ACK
-----------> circuit_established
XIDFRAME DLC_XID null XID
-----------> ---------> -------->
XID DLC_XID XIDFRAME DLC_XID XID
<-------- <----------- <----------- <----------- <--------
XIDs DLC_XIDs XIDFRAMEs DLC_XIDs XIDs
<----------> <----------> <------------> <------------> <--------->
SABME DLC_CONTACTED CONTACT DLC_CONTACT SABME
-----------> -----------> -----------> -----------> -------->
connect_pending contact_pending
UA DLC_CONTACT CONTACTED DLC_CONTACTED UA
<--------- <----------- <----------- <----------- <--------
connected connected
IFRAMEs DLC_INFOs IFRAMEs DLC_INFOs IFRAMEs
<----------> <-----------> <------------> <------------> <-------->
Some implementations like to answer the SABME right away, and they can use the same events to do it ๐ธ
SABME DLC_CONTACTED CONTACT DLC_CONTACT SABME
-----------> -----------> -----------> -----------> -------->
UA connect_pending contact_pending
<---------
RR
----------->
RNR
<---------
RR DLC_CONTACT CONTACTED DLC_CONTACTED UA
<--------- <----------- <----------- <----------- <--------
connected connected
IFRAMEs DLC_INFOs IFRAMEs DLC_INFOs IFRAMEs
<----------> <------------> <------------> <------------> <-------->
Flow #2 - DLSw Startup Without XIDs (circuit setup) ๐ง
Flow #2 skips the XIDs and goes straight to setting up the circuit ๐
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
disconnected disconnected
DLC_CONTACTED CANUREACH_cs DLC_START_DL
-----------> -----------> ----------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED
<----------- <-----------
circuit_established circuit_pending
REACH_ACK
-----------> circuit_established
CONTACT DLC_CONTACT
-----------> ----------->
connect_pending contact_pending
DLC_CONTACT CONTACTED DLC_CONTACTED
<----------- <----------- <-----------
connected connected
DLC_INFOs IFRAMEs DLC_INFOs
<------------> <------------> <------------>
Next up is the LAN-event mapping for Flow #2, where we also add a NETBIOS_NQ and a NETBIOS_NR_ex ๐
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
disconnected disconnected
NAME_QUERY DLC_DGRM NETBIOS_NQ_ex DLC_DGRM NAME_QUERY
-----------> -----------> -----------> -----------> --------->
NAME_RECOG DLC_DGRM NETBIOS_NR_ex DLC_DGRM NAME_RECOG
<----------- <------------ <----------- <----------- <---------
SABME DLC_CONTACTED CANUREACH_cs DLC_START_DL
-----------> -----------> -----------> ----------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED
<----------- <-----------
circuit_established circuit_pending
REACH_ACK
-----------> circuit_established
CONTACT DLC_CONTACT SABME
-----------> -----------> --------->
connect_pending contact_pending
UA DLC_CONTACT CONTACTED DLC_CONTACTED UA
<--------- <----------- <----------- <----------- <---------
connected connected
IFRAMEs DLC_INFOs IFRAMEs DLC_INFOs IFRAMEs
<------------> <------------> <------------> <------------> <-------->
Okay, the big idea here is "DLSw is a big 802.2 LAN" ๐ Under that paradigm, every other DLC type (SDLC for now, QLLC, channel, or whatever shows up later) gets handled by a "DLC transformation layer." That layer translates the specific protocol's events into the matching DLSw DLC events, and it translates DLSw DLC actions back into the matching protocol actions ๐ฅ The XIDs that go out in the SSP XIDFRAME should stay 802.2-ish (so the ABM bit is set), and the DLC transformation layer is the one that adjusts the XID to fit its particular DLC type ๐
Here's an example of a leased SDLC PU 2.0 device acting as the origin station ๐ It should use Flow #2, because we can't tell whether the other side is a LAN, a switched line, or a leased line ๐คทโโ๏ธ
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
disconnected disconnected
implementer's DLC_RESOLVE_C CANUREACH_ex
choice (power -----------> ----------->
up, configuration
change, DLC_RESOLVE_R ICANREACH_ex
never, <----------- <-----------
connect timer,etc.)
PU 2.0 is
configured
in DLSw to DLC_XID(null) CANUREACH_cs DLC_START_DL
call in -----------> -----------> ----------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED
<----------- <-----------
circuit_established circuit_pending
REACH_ACK
-----------> circuit_established
XIDFRAME DLC_XID
-----------> ----------->
DLC_XID XIDFRAME DLC_XID
respond with <----------- <----------- <-----------
XID configured
for station or
forward XID to
station and
send response DLC_XID XIDFRAME DLC_XID
-----------> -----------> ----------->
SNRM DLC_CONTACT CONTACT DLC_CONTACTED
<--------- <----------- <----------- <------------
contact_pending connect_pending
UA DLC_CONTACTED CONTACTED DLC_CONTACT
----------> -----------> -----------> ----------->
connected connected
IFRAMEs DLC_INFOs IFRAMEs DLC_INFOs
okay bestie, picking up right where we left off ๐
<-----------> <------------> <------------> <------------>
Here's a switched SDLC PU 2.0 device playing the origin station ๐ฆ The little boxes are the same cast as always: the origin station, the origin DLSw partner, the IP network in the middle, then the target DLSw partner and the target station. The message flow is what matters, so scroll down and vibe with it ๐ง
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
disconnected disconnected
implementer's DLC_RESOLVE_C CANUREACH_ex
choice (power -----------> ----------->
up, configuration
change, DLC_RESOLVE_R ICANREACH_ex
never, <----------- <-----------
connect timer,etc.)
XID(null) DLC_XID(null) CANUREACH_cs DLC_START_DL
-----------> -----------> -----------> ----------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED
<----------- <-----------
circuit_established circuit_pending
REACH_ACK
-----------> circuit_established
XIDFRAME DLC_XID
-----------> ----------->
XID DLC_XID XIDFRAME DLC_XID
<--------- <----------- <----------- <-----------
XID DLC_XID XIDFRAME DLC_XID
---------> -----------> -----------> ----------->
SNRM DLC_CONTACT CONTACT DLC_CONTACTED
<--------- <----------- <----------- <-----------
contact_pending connect_pending
UA DLC_CONTACTED CONTACTED DLC_CONTACT
---------> -----------> -----------> ----------->
connected connected
IFRAMEs DLC_INFOs IFRAMEs DLC_INFOs
<----------> <------------> <------------> <------------>
Next up: a leased SDLC PU 2.0 device as the target station ๐ธ This time the target is the SDLC box, so the DLSw partner has to answer for it. Notice the notes in the diagram about when it replies, like what happens with TEST/SNRM/DISC, and how the XID gets handled ๐
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
(SDLC)
disconnected disconnected
DLC_RESOLVE_C CANUREACH_ex
-----------> -----------> reply if virtual MAC/SAP
for SDLC station is
configured, if SDLC
station responds to
DLC_RESOLVE_R ICANREACH_ex TEST/SNRM/DISC, etc.
<----------- <-----------
DLC_XID CANUREACH_cs DLC_START_DL SNRM
-----------> -----------> -----------> --------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED UA
<----------- <----------- <-------
circuit_established circuit_pending
RNR
REACH_ACK --------->
-----------> circuit_established
XIDFRAME DLC_XID
-----------> -----------> respond with
XID configured
for station
or forward
XID to
station and
send
DLC_XID XIDFRAME DLC_XID response
<----------- <----------- <-----------
DLC_CONTACTED CONTACT DLC_CONTACT RR
-----------> -----------> -----------> --------->
connect_pending contact_pending
DLC_CONTACT CONTACTED DLC_CONTACTED
<----------- <----------- <-----------
connected connected
DLC_INFOs IFRAMEs DLC_INFOs IFRAMEs
<------------> <------------> <------------> <------->
Now the mirror image: a switched SDLC PU 2.0 device as the target station ๐ Same setup, but this time the DLSw side answers TEST/XID/SNRM/DISC, and the XID that was received gets echoed back, so the flow looks a little different ๐
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
(SDLC)
disconnected disconnected
DLC_RESOLVE_C CANUREACH_ex
-----------> -----------> reply if virtual MAC/SAP
for SDLC station is
configured, if SDLC
station responds to
DLC_RESOLVE_R ICANREACH_ex TEST/XID/SNRM/DISC, etc.
<----------- <-----------
DLC_XID CANUREACH_cs DLC_START_DL XID
-----------> -----------> -----------> --------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED XID
<----------- <----------- <--------
circuit_established circuit_pending
REACH_ACK
-----------> circuit_established
XIDFRAME DLC_XID
-----------> -----------> respond
with XID
received
DLC_XID XIDFRAME DLC_XID above
<----------- <----------- <---------
DLC_CONTACTED CONTACT DLC_CONTACT SNRM
-----------> -----------> -----------> --------->
connect_pending contact_pending
DLC_CONTACT CONTACTED DLC_CONTACTED UA
<----------- <----------- <----------- <--------
connected connected
DLC_INFOs IFRAMEs DLC_INFOs IFRAMEs
<------------> <------------> <------------> <-------->
Last one, and it's a fun one ๐ This is an SDLC T2.1 device as the target station. The T2.1 origin station looks exactly like the LAN T2.1 origin station, so you don't need a separate picture for it ๐ซถ Here the DLSw side can check whether the station is powered up using TEST/XID/DISC, and you'll see null XIDs and a bunch of XIDs flying around before the SNRM finally lands ๐ญ
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
disconnected disconnected
DLC_RESOLVE_C CANUREACH_ex
-----------> -----------> implementer's choice
(virtual MAC/SAP
configured,
check to see if station
is powered up using
DLC_RESOLVE_R ICANREACH_ex TEST/XID/DISC, etc.)
<----------- <-----------
DLC_XID CANUREACH_cs DLC_START_DL null XID
-----------> -----------> -----------> --------->
circuit_start resolve_pending
ICANREACH_cs DLC_DL_STARTED XID
<----------- <----------- <-------
circuit_established circuit_pending
REACH_ACK
-----------> circuit_established
XIDFRAME DLC_XID
-----------> -----------> respond with
XID received
DLC_XID XIDFRAME DLC_XID above
<----------- <----------- <----------
DLC_XIDs XIDFRAMEs DLC_XIDs XIDs
<------------> <------------> <------------> <-------->
DLC_CONTACTED CONTACT DLC_CONTACT SNRM
-----------> -----------> -----------> --------->
connect_pending contact_pending
DLC_CONTACT CONTACTED DLC_CONTACTED UA
<----------- <----------- <----------- <-------
connected connected
DLC_INFOs IFRAMEs DLC_INFOs IFRAMEs
<------------> <------------> <------------> <-------->
6.2. Link Restart Protocols ๐
okay so this one's about restarting the whole end-to-end connection ๐ the figure below shows the message flows that happen when that restart goes down. the Data Link Switches terminate the existing connection and land in the Circuit Established state, just waiting for a brand new connection to kick off ๐ฆ
Data Link Data Link Data Link Data Link
Control Switch Switch Control
--------------------- ---------------------
+-----------+ +-----------+
| Connected | | Connected |
SABME +-----------+ +-----------+
-----------> RESTART_DL
DM -------------------------------------> DISC
<----------- -------->
UA
DL_RESTARTED (Case 1) <--------
<-------------------------------------
+-----------+ +-----------+
|Circuit Est| |Circuit Est|
+-----------+ +-----------+
........... or ...........
SABME
-----------> DL_RESTARTED (Case 2)
UA <-------------------------------------
<----------- +-----------+
|Circuit Est|
CONTACT +-----------+
RNR ------------------------------------>
<----------
Figure 5. DLSw Link Restart Message Protocols
bestie, when the origin station sends a SABME command, the origin DLSw sends a RESTART_DL message to the target DLSw. a DM response also goes back to the origin station and the data link gets restarted ๐ฅ
when the target DLSw gets RESTART_DL, it issues a DISC command to the target station. that station is expected to send back a UA response. then the target DLSw restarts its own data link and sends a DL_RESTARTED message back to the origin DLSw. during all of this, both Data Link Switches move from the Connected state to the Circuit Established state โจ
if the origin station resends the SABME command, the origin DLSw sends a CONTACT message to the target DLSw. if SABME shows up before DL_RESTARTED arrives (that's case 2 in the figure, iykyk ๐), the CONNECT message gets held until DL_RESTARTED comes in. from there, everything lines up with the connect sequence we already covered ๐
6.3. Disconnect Protocols ๐ช
this figure shows what happens when the end system ends an existing connection. it's not just the connection that gets terminated, the circuit between the Data Link Switches gets taken down too ๐
Data Link Data Link Data Link Data Link
Control Switch Switch Control
-------------------- --------------------
+-----------+ +-----------+
| Connected | | Connected |
+-----------+ +-----------+
DISC
----------> HALT_DL
UA -------------------------------------> DISC
<---------- --------->
UA
DL_HALTED <--------
<-------------------------------------
+-----------+ +-----------+
|Disconnectd| |Disconnectd|
+-----------+ +-----------+
......... or ..........
+-----------+ +-----------+
| Connected | | Connected |
+-----------+ +-----------+
DISC TCP Connection Failure DISC
<-------- <------------------------------------> --------->
UA UA
--------> <--------
+-----------+ +-----------+
|Disconnectd| |Disconnectd|
+-----------+ +-----------+
Figure 6. DLSw Disconnect Message Protocols
so when the origin station sends a DISC command, the origin DLSw replies with a UA response and issues a HALT_DL message to the target DLSw. once the target DLSw gets HALT_DL, it sends a DISC command to the target station. the target station responds with a UA response, and that makes the target DLSw send a DL_HALTED message back to the origin DLSw. during this whole exchange, both Data Link Switches go from the Connected state to the Disconnected state ๐ซถ
now the other plot twist ๐ญ if the TCP connection between two Data Link Switches fails, every connection multiplexed on that failed TCP connection gets taken down. that means both Data Link Switches send DISC commands to all the local systems tied to those failed connections. the second a Data Link Switch sends its DISC command, it enters the DISCONNECTED state for each circuit ๐
7.0. Capabilities Exchange Formats/Protocol ๐
the Data Link Switching Capabilities Exchange is a special DLSw Switch-to-Switch control message. it describes what the sending data link switch is capable of ๐ it gets sent right after the switch-to-switch connection is established, and it can also be sent during run time, optionally, if some operational parameters have changed and the partner switch needs to know ๐
the actual contents live in the data field right after the SSP message header. the Capabilities Exchange itself is formatted as a single General Data Stream (GDS) Variable made up of multiple type "LT" structured subfields ๐ง
the SSP Message Header has these fields set for the Capabilities Exchange:
Offset Field Value
------ ----- -----
0x00 Version Number 0x31
0x01 Header Length 0x48 (decimal 72)
0x02 Message Length same as LL in GDS Variable
0x14 Message Type 0x20 (CAP_EXCHANGE)
0x16 Protocol Id 0x42
0x17 Header Number 0x01
0x23 Message Type 0x20 (CAP_EXCHANGE)
0x38 Direction 0x01 for CapEx request
0x02 for CapEx response
any other SSP header fields aren't referenced here, and they should be set to zero ๐
the DLSw Capabilities Exchange Request has this overall format:
+----+----+-----------------+
| LL | ID | Control Vectors |
+----+----+-----------------+
0-1: the length, in binary, of the DLSw Capabilities Exchange Request GDS Variable. the value of LL is the sum of the length of all fields in the GDS Variable (that's the length of LL plus the length of ID plus the length of Control Vectors) ๐งฎ2-3: GDS Id, which is0x1520๐ฅ4-n: Control Vectors, made up of type LT structured subfields (aka the DLSw Capabilities Exchange Structured Subfields) ๐
type LT structured subfields have a 1-byte length field (the "L"), a 1-byte type field (the "T"), and n bytes of data. the length field counts itself plus the structured subfield. the structured subfield is the type field plus the data, so the length works out to n + 2. this means all data inside a structured subfield is limited to 253 bytes โญ
7.1. Control Vector Id Range ๐ธ
Control Vector identifiers (aka Type) from 0x80 through 0xCF are reserved for use by the Data Link Switching standard ๐
Control Vector identifiers (aka Type) from 0xD0 through 0xFD are used for vendor-specific stuff ๐ ๏ธ
here are the currently defined vectors:
Vector Description Hex Value
Vendor Id Control Vector 0x81
DLSw Version Control Vector 0x82
Initial Pacing Window Control Vector 0x83
Version String Control Vector 0x84
Mac Address Exclusivity Control Vector 0x85
Supported SAP List Control Vector 0x86
TCP Connections Control Vector 0x87
NetBIOS Name Exclusivity Control Vector 0x88
MAC Address List Control Vector 0x89
NetBIOS Name List Control Vector 0x8A
Vendor Context Control Vector 0x8B
Reserved for future use 0x8C - 0xCF
Vendor Specific 0xD0 - 0xFD
7.2. Control Vector Order and Continuity ๐ฆ
the order matters a LOT here, because the required control vectors can seriously change how the Capabilities Exchange GDS Variable gets parsed ๐ญ so the required ones have to come first, in this exact order: Vendor Id, DLSw Version Number, Initial Pacing Window, Supported SAP List. everything else can show up in any order โจ
control vectors that can repeat within the same message (like the MAC Address List Control Vector and the NetBIOS Name List Control Vector) aren't necessarily next to each other. it's advisable, but not required, to put the Exclusivity Control Vector before either of those two, so the individual MAC addresses or NetBIOS names are already known before they get parsed ๐
both the Vendor Context and Vendor Specific control vectors can be repeated. if there are multiple Vendor Context control vectors, the specified context stays in effect for all Vendor Specific control vectors until the next Vendor Context control vector shows up in the Capabilities Exchange ๐ซง
7.3. Initial Capabilities Exchange ๐
the Capabilities Exchange is always the first SSP message sent on a new SSP connection between two DLSw switches, no exceptions ๐ this initial exchange tells each switch which DLSw version the other is running, plus any other required info and details about optional extensions the switches can support ๐
if a DLSw gets an initial capabilities message that's formatted wrong, or has invalid or unsupported data that stops it from interoperating correctly with the partner DLSw, it should send a Capabilities Exchange negative response ๐
if a DLSw gets a negative response to its own initial capabilities message, it should take down its TCP connections with the offended partner ๐
Note: Pre v1.0 DLSw implementations don't send or respond to capabilities messages. you can spot them by the lack of a capabilities exchange as the first message on a new SSP connection. this document doesn't try to specify how to interoperate with back-level DLSw implementations. ๐ผ
7.4. Run-Time Capabilities Exchange ๐
okay so the capabilities exchange always happens when the SSP connection starts between two DLSw switches ๐ฆ but it can also happen at run-time, usually when someone changes a config โจ
running this is OPTIONAL ๐ if a node doesn't support receiving or using a run-time exchange and gets one anyway, it SHOULD discard it quietly (no negative response, bestie ๐). if a node does support it, it SHOULD send back a positive or negative response, whichever fits. the one who gets a negative response is not REQUIRED to tear down its TCP connections with the partner who sent it. no drama needed ๐
a run-time exchange can have one or more of these control vectors. fun fact: the ones REQUIRED at start-up are NOT in a run-time exchange ๐
- MAC Address Exclusivity CV,
- NetBIOS Name Exclusivity CV,
- MAC Address List CV,
- NetBIOS Name List CV,
- Supported SAP List CV,
- Vendor Context CV,
- Vendor Specific CVs
the big rule here: a run-time exchange is a REPLACEMENT operation ๐ง so every relevant MAC address and NetBIOS name MUST be included in it. and changes to capabilities at run-time will not affect existing link station circuits, so your current connections are safe ๐ซถ
7.5. Capabilities Exchange Filtering Responsibilities ๐
ok, quick one ๐ธ the people who receive the SAP, MAC, and NetBIOS lists are not REQUIRED to actually use them for filtering traffic, whether that's at start-up or at run-time. no pressure, lol โจ
7.6. DLSw Capabilities Exchange Structured Subfields ๐
here's the lineup of the Capabilities Exchange subfields. the details for each one are in the sections right after this table ๐
Required Allowed @
ID @ Startup Length Repeatable* Runtime Order Content
==== ========= ====== ========== ======= ===== ===============
0x81 Y 0x05 N N 1 Vendor ID
0x82 Y 0x04 N N 2 DLSw Version
0x83 Y 0x04 N N 3 Initial pacing
window
0x84 N >=0x02 N N 5+ Version String
0x85 N 0x03 N Y 5+ MAC Address
Exclusivity
0x86 Y 0x12 N Y 4 Supported SAP
List
0x87 N 0x03 N N 5+ TCP Connections
0x88 N 0x03 N Y 5+ NetBIOS Name
Exclusivity
0x89 N 0x0E Y Y 5+ MAC Address
List
0x8A N <=0x13 Y Y 5+ NetBIOS Name
List
0x8B N 0x05 Y Y 5+ Vendor Context
0xD0 N varies Y Y 5+ Vendor Specific
*Note: "Repeatable" means a Control Vector is repeatable within a single
message.
7.6.1. Vendor Id (0x81) Control Vector ๐ฆ
the Vendor Id CV tells everyone the manufacturer's IEEE-assigned Organizationally Unique Identifier (OUI) for the Data Link Switch that's sending the DLSw Capabilities Exchange ๐ the OUI goes out in non-canonical (Token-Ring) format. this one is REQUIRED and MUST be the first control vector, so it's always the main character ๐
Offset Length Value Contents
------ ------ ----- --------
0 1 0x05 Length of the Vendor Id structured
subfield
1 1 0x81 key = 0x81 that identifies this as the
Vendor Id structured subfield
2-4 3 the 3-byte Organizationally Unique
Identifier (OUI) for the vendor
(non-canonical format)
7.6.2. DLSw Version (0x82) Control Vector โจ
this one tells you which version of the DLSw standard the sending Data Link Switch supports ๐ธ it's REQUIRED and MUST follow the Vendor Id Control Vector, no skipping ahead ๐
Offset Length Value Contents
------ ------ ----- --------
0 1 0x04 Length of the Version String structured
subfield
1 1 0x82 key = 0x82 that identifies this as the
DLSw Version structured subfield
2 1 the hexadecimal value representing the
DLSw standard Version number of the
sending Data Link Switch.
0x01 (indicates version 1 - closed pages)
3 1 the hexadecimal value representing the
DLSw standard Release number of the
sending Data Link Switch.
0x00 (indicates release 0)
7.6.3. Initial Pacing Window (0x83) Control Vector ๐
this CV sets the starting value of the receive pacing window size for the sending Data Link Switch ๐ง it's REQUIRED and MUST follow the DLSw Version Control Vector, so the order really matters here bestie ๐
Offset Length Value Contents
------ ------ ----- --------
0 1 0x04 Length of the Initial Pacing Window
structured subfield
1 1 0x83 key = 0x83 that identifies this
as the Initial Pacing Window
structured subfield
2-3 2 the pacing window size, specified
in byte normal form..
Note: the pacing window size MUST be non-zero. zero is a no-go, periodt ๐ โโ๏ธ
7.6.4. Version String (0x84) Control Vector ๐
this one shares the particular version number of the sending Data Link Switch ๐ the format of the version string is up to the vendor. this control vector is OPTIONAL, so it's totally your call โจ
Offset Length Value Contents
------ ------ ----- --------
0 1 0xn Length of the Version String
structured subfield
1 1 0x84 key = 0x84 that identifies
this as the Version String
structured subfield
2-n n-2 the ASCII string that identifies
the software version for the
sending DLSw.
7.6.5. MAC Address Exclusivity (0x85) Control Vector ๐ฅ
okay this one is lowkey important ๐ it tells you how to read the MAC Address List CV data. specifically, it says whether the MAC addresses in the MAC Address List CVs are the ONLY ones you can reach through the sending Data Link Switch ๐ฆ
if there's a MAC Address List CV but the MAC Address Exclusivity CV is missing, then those MAC addresses are NOT assumed to be the only ones reachable through that switch. no assumptions, bestie ๐
a node can say it has no local MAC addresses at all ๐ซถ by including the MAC Address List Exclusivity CV (with byte 2 == 0x01) and NOT including any instances of the MAC Address List CV. (that's a MAY, so it's the node's choice ๐ง)
Offset Length Value Contents
------ ------ ----- --------
0 1 0x03 Length of the Exclusivity structured
subfield
1 1 0x85 key = 0x85 that identifies this as the
MAC address Exclusivity structured
subfield
2 1 an indicator of the relationship of the
MAC addresses to the sending Data Link
Switch.
0x00 the MAC addresses specified in
this Capabilities Exchange
can be accessed via this
switch but are not the
exclusive set (i.e., other
entities are accessible in
addition to the ones specified)
0x01 the MAC addresses specified in
this Capabilities Exchange
are the only ones accessible
via this switch.
7.6.6 SAP List Support (0x86) Control Vector โจ๐
Okay so the SAP List Support control vector is how a sending Data Link Switch shows off which Logical Link Control SAPs (DSAPs and SSAPs) it's actually supporting ๐ The DLSw that sends it is basically saying "these are my faves, use them for SNA, and NetBIOS too if you want" ๐ฆ The receiving DLSw can even use the list to filter explorer traffic (TEST, XID, or NetBIOS UI frames) so it doesn't reach the DLSw state machine. Iconic filtering, honestly ๐ญ
For SNA, a DLSw should set bits for all SAP values (SSAP or DSAP) that may be used for SNA traffic. For NetBIOS support, the bit for SAP 0xF0 should be set (if not supported then the same bit should be cleared). ๐ธ
Each bit in the SAP control vector data field represents a SAP, as defined below. This vector is required and must follow the Initial Pacing Window Control Vector. Bestie, don't skip this ordering rule ๐
Offset Length Value Contents
------ ------ ----- --------
0 1 0x12 Length of the Supported SAP List structured
subfield
1 1 0x86 key = 0x86 that identifies this as the
Supported SAP List structured subfield
2-17 16 the 16-byte bit vector describing all
even numbered SAPs enabled.
Each Bit within the 16 byte bit vector will
indicate whether an even numbered SAP is
enabled (b'1') or disabled (b'0').
Each Byte within the 16 byte bit vector
will be numbered from 0 - F. (Most
significant byte first).
Byte 0 1 2 3 ... F
XX XX XX XX ... XX
The bits in each byte indicate whether an
even numbered SAP is enabled (b'1') or
disabled (b'0'). (Most significant bit first)
Bits 7 6 5 4 ... 0
SAP 0 2 4 6 ... E
By combining the byte label with the enabled
bits, all supported SAPs can be determined.
In the following diagram, 'n' would equal 0
through F depending on which byte was being
interpreted.
Bit ordering is shown below with bit
7 being the most significant bit and bit
0 the least significant bit.
7654 3210
bbbb bbbb....
|||| ||||
|||| |||SAP 0xnE enabled or not
|||| |||
|||| ||SAP 0xnC enabled or not
|||| ||
|||| |SAP 0xnA enabled or not
|||| |
|||| SAP 0xn8 enabled or not
||||
|||SAP 0xn6 enabled or not
|||
||SAP 0xn4 enabled or not
||
|SAP 0xn2 enabled or not
|
SAP 0xn0 enabled or not
Let's do an example, because this is where it clicks ๐ง Say you want every User Definable SAP from 0x04 to 0xEC for SNA Data Link Switching, plus SAP 0xF0 for NetBIOS Data Link Switching. Here's how that looks, bit by bit:
Offset SAPs Binary Hex
0 4,8,C 0010 1010 0x2A
1 10,14,18,1C 1010 1010 0xAA
2 20,24,28,2C 1010 1010 0xAA
3 30,34,38,3C 1010 1010 0xAA
4 40,44,48,4C 1010 1010 0xAA
5 50,54,58,5C 1010 1010 0xAA
6 60,64,68,6C 1010 1010 0xAA
7 70,74,78,7C 1010 1010 0xAA
8 80,84,88,8C 1010 1010 0xAA
9 90,94,98,9C 1010 1010 0xAA
A A0,A4,A8,AC 1010 1010 0xAA
B B0,B4,B8,BC 1010 1010 0xAA
C C0,C4,C8,CC 1010 1010 0xAA
D D0,D4,D8,DC 1010 1010 0xAA
E E0,E4,E8,EC 1010 1010 0xAA
F F0 1000 0000 0x80
7.6.7 TCP Connections (0x87) Control Vector ๐ฅ
The TCP Connections control vector is how a DLSw says it can handle a different number of TCP Connections for Data Link Switching traffic. The base implementation uses two TCP Connections, one for each direction of data traffic, so that's the default vibe ๐
This control vector is optional. If it gets left out of a DLSw Capabilities Exchange, then two TCP Connections are assumed. It's also assumed that if a Data Link Switch can support one TCP Connection, it can support two TCP Connections ๐
If TCP Connections CV values agree and the number of connections is one, then the DLSw with the higher IP address must tear down the TCP connections on its local port 2065. Hot tip: that's the one with the higher IP address, so double-check your numbers ๐ซถ
The format of the TCP Connections Control Vector is shown below:
Offset Length Value Contents
------ ------ ----- --------
0 1 0x03 Length of the TCP Connections structured
subfield
1 1 0x87 key = 0x87 that identifies this as the
TCP Connections structured subfield
2 1 an indicator of the support for an
alternate number of TCP Connections by
the sending Data Link Switch.
0x01 the number of TCP Connections
may be brought down to one
after Capabilities Exchange
is completed.
0x02 the number of TCP Connections
will remain at two for
the duration of the DLSw
connection.
7.6.8 NetBIOS Name Exclusivity (0x88) Control Vector ๐
The NetBIOS Name Exclusivity control vector tells you how to read the NetBIOS Name List control vector data. Specifically, it says whether the NetBIOS Names in the NetBIOS Name List control vectors are the only ones you can reach through the sending Data Link Switch ๐
If a NetBIOS Name List control vector is specified and the NetBIOS Name Exclusivity control vector is missing, then the NetBIOS Names are not assumed to be the only ones accessible via this switch. So no, you can't just assume it's exclusive ๐ โโ๏ธ
A node can say it supports no local NetBIOS names by including the NetBIOS Name List Exclusivity CV (with byte 2 == 0x01) and not including any instances of the NetBIOS Name List CV. That's a very intentional, very main character move โญ
Offset Length Value Contents
------ ------ ----- --------
0 1 0x03 Length of the Exclusivity structured
subfield
1 1 0x88 key = 0x88 that identifies this as the
NetBIOS Name Exclusivity structured
subfield
2 1 an indicator of the relationship of the
NetBIOS Names to the sending Data Link
Switch.
0x00 the NetBIOS Names specified in
this Capabilities Exchange
can be accessed via this
switch but are not the
exclusive set (i.e., other
entities are accessible in
addition to the ones specified)
0x01 the NetBIOS Names specified in
this Capabilities Exchange
are the only ones accessible
via this switch.
7.6.9 MAC Address List (0x89) Control Vector ๐
The MAC Address List control vector lists one or more MAC addresses that the sending Data Link Switch can reach. It gives a single MAC address value plus a MAC address mask, and together those pick out one address or a whole range of them ๐ง Heads up: MAC addresses and masks are in non-canonical (Token-Ring) format in this control vector, so don't mix up your bit order ๐
This control vector is optional and can be repeated if necessary. Stack 'em up ๐
Note 1: If a particular MAC address, <mac-addr>, satisfies the following algorithm, then <mac-addr> is assumed to be accessible via the sending Data Link Switch:
<mac-addr> & <mac-addr-mask> == <mac-addr-value>
where:
<mac-addr-value> is the MAC Address
Value specified in
this control vector
<mac-addr-mask> is the MAC Address
Mask specified in
this control vector
Note 2: If an individual MAC Address is desired, then <mac-addr-value> should be the individual MAC address and <mac-addr-mask> should be 0xFFFFFFFFFFFF. Individual addresses get the full mask, no cap ๐
Offset Length Value Contents
------ ------ ----- --------
0 1 0x0E Length of the MAC Address List
structured subfield
1 1 0x89 key = 0x89 that identifies this as the
MAC Address List structured subfield
2-7 6 the 6-byte MAC Address Value,
<mac-addr-value> in the above formula
8-13 6 the 6-byte MAC Address Mask,
<mac-addr-mask> in the above formula
7.6.10 NetBIOS Name List (0x8A) Control Vector ๐ฆ
The NetBIOS Name List control vector identifies one or more NetBIOS names that the sending Data Link Switch can reach. Each control vector carries a single NetBIOS name in ASCII, but that name can have "don't care" and "wildcard" characters so it can match a whole bunch of names ๐ธ A ? in a character position means that position is a "don't care". A * at the end of a name means everything after it is a "don't care". Only a * at the very end counts as a wildcard, so anywhere else it's just a regular character ๐
Blanks or nulls at the end of NetBIOS names in this control vector are ignored. NetBIOS names with fewer than 16 bytes that don't end with * are not assumed to have a trailing *. The "wildcard" character has to be explicit, no guessing allowed ๐ซ
NetBIOS group names can exist across several LANs/networks, so group names from a NetBIOS Name List Control Vector can't be treated the same as individual names. The Individual/Group Flag is how Data Link Switches tell the two apart ๐
This control vector is optional and can be repeated if necessary. โจ
Offset Length Value Contents
------ ------ ----- --------
0 1 0xn Length of the NetBIOS Name List
structured subfield (maximum = 0x13)
1 1 0x8A key = 0x8A that identifies this as the
NetBIOS Name List structured subfield
2 1 Individual/Group Flag
0x00 - Individual NetBIOS Name
0x01 - Group NetBIOS Name
3-n n-3 the NetBIOS name with possible embedded
'?' and terminating '*'.
7.6.11 Vendor Context (0x8B) Control Vector โจ
okay bestie, this one is the Vendor Context control vector ๐ It tells everyone the manufacturer's IEEE assigned Organizationally Unique Identifier (OUI) of the Data Link Switch that's sending the DLSw Capabilities Exchange. The OUI goes in non-canonical (Token-Ring) format ๐
This control vector is optional ๐ซถ Its whole job is to set the context for any Vendor Specific control vectors that come after it in the Capabilities Exchange. If you send more than one Vendor Context control vector, the most recent context stays in effect for all the Vendor Specific control vectors until the next Vendor Context control vector shows up ๐ฆ
Offset Length Value Contents
------ ------ ----- --------
0 1 0x05 Length of the Vendor Context structured
subfield
1 1 0x8B key = 0x8B that identifies this as the
Vendor Context structured subfield
2-4 3 the 3-byte Organizationally Unique
Identifier (OUI) for the vendor
(non-canonical format)
7.7 Capabilities Exchange Responses ๐
there are two kinds of DLSw Capabilities Exchange Responses: positive and negative ๐ธ A positive response goes back to the sending Data Link Switch when there were no errors in the DLSw Capabilities Exchange Request. A negative response goes back when there's at least one error ๐ญ
A positive DLSw Capabilities Exchange Response has this overall format:
+----+----+
| LL | ID |
+----+----+
- Bytes 0-1: the length, in binary, of the DLSw Capabilities Exchange Response GDS Variable. For this one, LL is 0x0004.
- Bytes 2-3: the GDS Id, which is 0x1521 ๐
A negative DLSw Capabilities Exchange Response has this overall format:
+----+----+--------+--------+
| LL | ID | Offset | Reason |
+----+----+--------+--------+
- Bytes 0-1: the length, in binary, of the DLSw Capabilities Exchange Response GDS Variable. LL is the sum of the length of all the fields in the GDS Variable (so LL + ID + the Offsets/Reasons).
- Bytes 2-3: the GDS Id, which is 0x1522 ๐ฆ
- Bytes 4-5: the Offset into the DLSw Capabilities Exchange Request where the error is. The Offset should always point to the start of the GDS Variable or to a specific control vector ๐ง
- Bytes 6-7: the Reason code that uniquely identifies the error. These are the specific values:
0x0001 invalid GDS length for a DLSw Capabilities
Exchange Request. (The value of Offset
is ignored.)
0x0002 invalid GDS id for a DLSw Capabilities
Exchange Request. (The value of Offset
is ignored.)
0x0003 Vendor Id control vector is missing. (The
value of Offset is ignored.)
0x0004 DLSw Version control vector is missing. (The
value of Offset is ignored.)
0x0005 Initial Pacing Window control vector is
missing. (The value of Offset is ignored.)
0x0006 length of control vectors doesn't correlate
to the length of the GDS variable
0x0007 invalid control vector id
0x0008 length of control vector invalid
0x0009 invalid control vector data value
0x000A duplicate control vector (for non-repeating
control vectors)
0x000B out-of-sequence control vector (for
repeating control vector)
0x000C DLSw Supported SAP List control vector is
missing.
(The value of Offset is ignored.)
NOTE: you can get multiple Offset, Reason pairs back in one response, with one pair for each error that was found ๐ฅ
8. Pacing/Flow Control ๐
this section covers the required Pacing and Flow Control mechanisms that a Data Link Switch uses ๐
it's out of scope for this document to set a policy for how an implementation maps SSP flow control to the native data link flow control at the edges ๐ But the paragraphs below give a general big-picture overview of how the mechanism is meant to be used โจ
there are two types of flows covered by the flow control mechanism: connection-oriented and connectionless ๐ฆ For connection-oriented flows, the implementer maps the native flow control of the two data links at the boundaries onto the SSP flow control. That gives you end-to-end flow control that "pushes back" all the way to the originating station in either direction ๐
connectionless traffic is a whole different story, because there's no native flow control mechanism for connectionless data links ๐ญ At first it's tempting to just let connectionless traffic flow through the DLSw cloud unthrottled. But the reason these flows get flow control inside the DLSw cloud is so that, if frames ever need to be discarded, that discarding gets "pushed" back to the ingress of the cloud. This "early discarding" of excessive DATAGRAMs keeps the cloud deterministic without wasting network bandwidth ๐ง
8.1 Basic Overview ๐
each circuit has two data flows, one in each direction ๐ Every data flow has its own independent flow control mechanism. For each data flow there's an entity that originates the traffic, called the sender, and a target entity that receives it, called the receiver ๐ซถ
a sender can only send data when its receiver has explicitly granted permission to send a set number of data units. Data units are either a DGRMFRAME or an INFOFRAME ๐ธ
the receiver grants permission by sending a Flow Control Indicator (FCIND, defined later). The sender must acknowledge every FCIND by sending a Flow Control Acknowledgment (FCACK, defined later) ๐ฅ
a sending implementation has to keep track of these values:
- GrantedUnits - the number of units (frames) the sender currently has permission to send.
- CurrentWindow - a discrete number of units, controlled by the receiver, that is the basis for granting additional units.
- InitialWindowSize - global for all circuits on a transport connection. It's learned during the capabilities exchange when the transport connection is established, and it sets the initial value for CurrentWindow whenever a circuit is established ๐
a receiving implementation has to keep track of these values:
- CurrentWindow - a discrete number of units, controlled by the receiver, that is the basis for granting additional units.
- InitialWindowSize - global for all circuits on a transport connection. It's sent during the capabilities exchange when the transport connection is established, and it sets the initial value for CurrentWindow whenever a circuit is established.
- FCACKOwed - the sender owes an FCACK. If this is true, no FCIND may be sent ๐
8.2 Frame Format ๐ฆ
the Flow control Byte sits at offset 15 in both the Information and Control SSP messages. From a flow control point of view, the flow control information in those two frames is handled exactly the same way โจ
here's the layout of the Flow Control Byte (Bit 7 is the most significant and Bit 0 is the least significant bit of the octet):
bit 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|FCI|FCA| reserved | FCO |
+---+---+---+---+---+---+---+---+
- FCI: Flow Control Indicator
- FCA: Flow Control Ack
- FCO: Flow Control Operator Bits
000 - Repeat Window Operator
001 - Increment Window Operator
010 - Decrement Window Operator
011 - Reset Window Operator
100 - Halve Window Operator
101 - Reserved
110 - Reserved
111 - Reserved
a frame with the FCI bit set is called a Flow Control Indication (FCIND) ๐ An FCIND manages the flow in the opposite direction from the frame that carries it.
a frame with the FCA bit set is called a Flow Control Acknowledgment (FCACK) ๐ An FCACK manages the flow in the same direction as the frame that carries it.
NOTE: a frame can be both an FCIND and an FCACK ๐
a frame carrying an FCIND or FCACK can also contain data for the flow in the direction it's traveling ๐ซถ In that case the FCIND or FCACK is called piggy-backed. An FCIND that isn't piggy-backed is called an Independent Flow Control Indication (IFCIND), and an FCACK that isn't piggy-backed is called an Independent Flow Control Acknowledgment (IFCACK). IFCIND and IFCACK messages are sent in an Independent Flow Control SSP message (type 0x21) ๐ง
NOTE: a frame can be both an IFCIND and an IFCACK ๐
it's really useful to carry flow control information inside control messages so you don't have to send a flow-control-only message ๐ The diagram below shows which messages can carry valid flow control information:
====== ___ ======
| | --------- __/ \__ --------- | |
| | __| _|_ |__ / IP \ __| _|_ |__ | |
====== | | | < Network > | | | ======
/______\ --------- \__ __/ --------- /______\
Origin Origin DLSw \___/ Target DLSw Target
Station partner partner Station
May have valid
FCI/FCA/FCO Data carrying
N N CANUREACH_cs
----------->
Y* N ICANREACH_cs
<-----------
Y N REACH_ACK
----------->
Y Y XIDFRAMEs
<------------>
Y Y DGRMFRAMEs
<------------>
Y N CONTACT
----------->
Y N CONTACTED
<-----------
Y Y INFOFRAMEs
<------------>
Y N RESTART_DL
----------->
Y N DL_RESTARTED
<-----------
Y N CONTACT
----------->
Y N CONTACTED
<-----------
N N HALT_DL
----------->
N N DL_HALTED
<-----------
*Note: ICANREACH_cs cannot carry FCA, because there could never be an outstanding FCI for it to acknowledge ๐
8.3 Granting Permission to Send Data ๐
a receiver gives a sender permission to send units of data by sending an FCIND ๐ธ Each FCIND also has a flow control operator, which is encoded in the FCO bits of the FCIND header. With one exception (the Reset Window operator), every operator can be either piggy-backed or carried in an IFCIND โจ
the five flow control operators are outlined below:
8.3.1 Repeat Window Operator ๐
okay so the Repeat Window operator is the chill one ๐ CurrentWindow doesn't move at all, and we just add it onto GrantedUnits ๐ฆ
(CurrentWindow unchanged)
GrantedUnits += CurrentWindow
8.3.2 Increment Window Operator ๐
bestie this one bumps CurrentWindow up by one first, then adds the new number to GrantedUnits ๐
CurrentWindow++
GrantedUnits += CurrentWindow
8.3.3 Decrement Window Operator ๐
same energy but going down โจ it bumps CurrentWindow down by one, then adds the new number to GrantedUnits
CurrentWindow--
GrantedUnits += CurrentWindow
NOTE: This operator may only be sent if CurrentWindow is greater than one. ๐
8.3.4 Reset Window Operator ๐งน
this one is a full reset moment ๐ it wipes both CurrentWindow and GrantedUnits back to zero
CurrentWindow = 0;
GrantedUnits = 0;
NOTE: This operator may only flow on an independent pacing indication (may NOT be piggy-backed). ๐ซ
NOTE: After sending this operator, the only legal subsequent operator is Increment Window. ๐ธ
8.3.5 Halve Window Operator ๐ฐ
the Halve Window operator shall be processed like this ๐ซถ if CurrentWindow is bigger than 1, cut it in half, then add whatever's left to GrantedUnits
IF CurrentWindow > 1 THEN
CurrentWindow = CurrentWindow / 2
ENDIF
GrantedUnits += CurrentWindow
Note: The divide by two operation is an unsigned integer divide (round down) or bit shift right operation. ๐งฎ
8.4. Acknowledging a Flow Control Operator ๐
every sender must acknowledge each FCIND with an FCACK, and that FCACK gets piggy-backed on the next frame going the other way in all cases except the Reset Window Operator ๐ซถ no exceptions, periodt
the receiver may have no more than one unacknowledged FCIND outstanding at any time, with one exception ๐ a Reset Window Operator may be sent while another FCIND is still waiting on its acknowledgment
NOTE: The FCI and FCO bits of the FCACK are used independently by the flow in the opposite direction ๐ฆ
8.4.1 Acknowledging a Reset Window Operator ๐งผ
since this operator wipes out all the units that were granted before, the sender must acknowledge this FCIND using an IFCACK (Independent Flow Control Acknowledgment) ๐ this is the only case where IFCACK is used, so it's kind of a big deal
should a sender get a non-reset FCIND and then a Reset Window FCIND before it acks the first one, it only acknowledges the Reset Window ๐ the reset is the one that matters
NOTE: The FCI and FCO bits on these frames are used independently by the flow in the opposite direction. ๐
8.5 Capabilities Exchange Initial Window Size ๐ค
when two nodes set up a transport connection, they do a capabilities exchange (and yes, this part is a requirement ๐) you can check out the Capabilities Exchange section 7 for the deets ๐ง the two nodes are required to swap the following parameter:
InitialWindowSize - This indicates to the partner what
the sending flow entity initializes
its CurrentWindow value to for each
multiplexed circuit subsequently
established on that transport
connection. This value must be
non-zero.
8.6 Circuit Startup ๐
the startup process is super simple โจ
CurrentWindow = InitialWindowSize
GrantedUnits = 0
NOTE: The InitialWindow Size variable has a scope of one per DLSw transport connection, while CurrentWindow and Granted units are maintained on a per circuit basis. At circuit startup, a sender may not send data units until the receiver grants explicit permission with an FCIND message. This grant may be an independent FCIND message or the FCIND may be piggy-backed on any of the message types listed in section 8.2. ๐ so basically the sender waits for a green light before it sends anything ๐ฆ
8.7 Example Receiving Implementations ๐
the next two examples show receiving implementations that get more complicated as they go ๐ they're not meant to be complete implementations, they're just here to illustrate the protocol, so don't panic if things feel a bit incomplete โจ
NOTE: The examples are independent of the buffering model ( buffers may be deterministicly or statistically committed) ๐ง
NOTE: The examples assume a process model where each event processes to completion without being preempted by another event. โณ
8.7.1 Fixed Pacing Example ๐ง
first, here are the variables we're adding on top of InitialWindowSize, CurrentWindow and FCACKOwed ๐
GrantDelayed - Boolean
GrantedUnits - Outstanding Units
the following section describes how each event gets processed in this example implementation ๐ฆ
8.7.1.1 Circuit Startup ๐
CurrentWindow = InitialWindowSize
FCACKOwed = FALSE
GrantDelayed = FALSE
GrantedUnits = 0
Repeat Window Operator
8.7.1.2 Check Buffers Available ๐งบ
can my implementation afford to grant CurrentWindow just now? ๐ค
8.7.1.3 Buffers Become Available ๐ซง
IF Check Buffers Available THEN
Send FCIND( Repeat Window)
GrantDelayed = FALSE
ELSE
Wait on buffers to become available (LIFO)
ENDIF
8.7.1.4 Repeat Window Operator ๐
IF Check Buffers Available THEN
Send FCIND( Repeat Window)
ELSE
GrantDelayed = TRUE
Wait on buffers to become available (FIFO)
ENDIF
8.7.1.5 Send FCIND( operator) ๐ค
GrantedUnits += CurrentWindow
FCACKOwed = TRUE
Encode and Transmit FCIND piggybacked or as IFCIND
8.7.1.6 A Frame Arrives from Sender ๐ฌ
GrantedUnits--;
IF frame is FCACK THEN
IF FCACKOwed THEN
FCACKOwed = FALSE
ELSE
Protocol Violation
ENDIF
ENDIF
IF NOT GrantDelayed THEN
IF GrantedUnits <= CurrentWindow THEN
IF FCACKOwed THEN
Protocol Violation
ELSE
Repeat Window Operator
ENDIF
ENDIF
ENDIF
8.7.2 Adaptive Pacing Example ๐ท
this one is the glow-up version ๐ซ it adjusts the window size and granted units based on buffer availability and transport utilization ๐
NOTE: This example ignores other factors which might compel the receiving implementation to adjust the window size (i.e., Outbound queue length, traffic priority, ...) ๐
here are the variables, on top of InitialWindowSize, CurrentWindow and FCACKOwed ๐
GrantDelayed - Boolean
GrantedUnits - Outstanding Units
8.7.2.1 Circuit Startup ๐
CurrentWindow = InitialWindowSize
FCACK = FALSE
GrantDelayed = FALSE
GrantedUnits = 0
Repeat Window Operator
8.7.2.2 Check Buffers Available ( X) ๐งบ
Can my implementation afford to grant X units just now?
8.7.2.3 Buffers Become Available ๐ซง
IF Check Buffers Available THEN
CurrentWindow--;
Send FCIND( Decrement Window)
GrantDelayed = FALSE
ELSE
Wait on buffers to become available (LIFO)
ENDIF
8.7.2.4 Repeat Window Operator ๐
IF Check Buffers Available (CurrentWindow) THEN
Send FCIND( Repeat Window)
ELSE
GrantDelayed = TRUE
Wait on buffers to become available (FIFO)
ENDIF
8.7.2.5 Increment Window Operator ๐
IF Check Buffers Available ( CurrentWindow + 1) THEN
CurrentWindow++
Send FCIND( Increment Window)
ELSE
Repeat Window Operator
ENDIF
8.7.2.6 Send FCIND( operator) ๐ค
FCACKOwed = TRUE
GrantedUnits += CurrentWindow
Encode and Transmit FCIND piggybacked or as IFCIND
8.7.2.7 An FCACK Arrives from Sender ๐ฌ
GrantedUnits--;
IF NOT FCACKOwed THEN
Protocol Violation
ENDIF
FCACKOwed = FALSE;
IF NOT GrantDelayed THEN
IF GrantedUnits < CurrentWindow THEN
Increment Window Operator
ELSE IF GrantedUnits == CurrentWindow THEN
Repeat Window Operator
END
ENDIF
8.7.2.8 A Non-FCACK Frame Arrives from Sender ๐ญ
GrantedUnits--;
IF NOT GrantDelayed THEN
IF FCACKOwed THEN
IF GrantedUnits < CurrentWindow THEN
Protocol Violation
END
ELSE
IF GrantedUnits <= CurrentWindow THEN
Repeat Window Operator
ENDIF
ENDIF
ENDIF
8.8 Adaptive Pacing Example Flow Diagrams ๐จ
8.8.1 Example Flows from the Above Implementation ๐
time for the pictures ๐ฅน this diagram shows adaptive pacing in action (the Halve Window and Reset operations get their own diagrams later on โจ)
-----SENDER----- ----RECEIVER----
Granted Window Window Granted
0 2 circuit established 2 0
2 2 <-------- FCIND(Rpt) 2 2
1 2 FCACK--------------> 2 1
4 3 <-------- FCIND(Inc) 3 4
3 3 FCACK--------------> 3 3
+- FCIND(Rpt) 3 6
2 3 DATA---|-----------> 3 5
1 3 DATA---|-----------> 3 4
4 3 <------+
3 3 FCACK--------------> 3 3
6 3 <-------- FCIND(Rpt) 3 6
5 3 FCACK--------------> 3 5
4 3 DATA---------------> 3 4
3 3 DATA---------------> 3 3
+- FCIND(Rpt) 3 6
2 3 DATA---|-----------> 3 5
1 3 DATA---|-----------> 3 4
0 3 DATA---|-----------> 3 3
3 3 <------+
2 3 FCACK--------------> 3 2
6 4 <-------- FCIND(Inc) 4 6
5 4 FCACK--------------> 4 5
4 4 DATA---------------> 4 4
Waiting on Buffer
+- FCIND(Dec) 3 7
3 4 DATA---|-----------> 3 6
2 4 DATA---|-----------> 3 5
1 4 DATA---|-----------> 3 4
0 4 DATA---|-----------> 3 3
3 3 <------+
2 3 FCACK--------------> 3 2
Waiting on Buffer
+- FCIND(Dec) 2 4
1 3 DATA---|-----------> 2 3
0 3 DATA---|-----------> 2 2
2 2 <------+
1 2 FCACK--------------> 2 1
4 3 <-------- FCIND(Inc) 3 4
3 3 FCACK--------------> 3 3
6 3 <-------- FCIND(Rpt) 3 6
5 3 FCACK--------------> 3 5
4 3 DATA---------------> 3 4
3 3 DATA---------------> 3 3
6 3 <-------- FCIND(Rpt) 3 6
8.8.2. Example Halve Window Flow โจ
okay bestie, this flow shows the Halve Window Operator in action ๐ฆ watch the sender's granted units and window size drop as the receiver hits a resource shortage ๐
-----SENDER----- ----RECEIVER----
Granted Window Window Granted
0 2 circuit established 2 0
2 2 <-------- FCIND(Rpt) 2 2
1 2 FCACK--------------> 2 1
4 3 <-------- FCIND(Inc) 3 4
3 3 FCACK--------------> 3 3
Resource Shortage
2 3 DATA---------------> 1 2
1 3 DATA---------------> 1 1
0 3 DATA---------------> 1 0
1 1 <-------- FCIND(Hlv) 1 1
0 1 FCACK--------------> 1 0
NOTE: The Halve Window Operator could have been sent before the granted units fell to zero. The implementer may make a choice based on the severity of the condition. ๐ธ
8.8.3. Example Reset Window Flows ๐
this one is the ResetWindow operation when the receiver has no FCIND outstanding, so it's a clean little reset โจ
-----SENDER----- ----RECEIVER----
Granted Window Window Granted
0 2 circuit established 2 0
2 2 <-------- FCIND(Rpt) 2 2
1 2 FCACK--------------> 2 1
4 3 <-------- FCIND(Inc) 3 4
3 3 FCACK--------------> 3 3
+- FCIND(Rpt) 3 6
2 3 DATA---|-----------> 3 5
1 3 DATA---|-----------> 3 4
4 3 <------+
3 3 FCACK--------------> 3 3
6 3 <-------- FCIND(Rpt) 3 6
5 3 FCACK--------------> 3 5
Resource shortage!
0 0 <-------- FCIND(Rst) 0 5 (note still
committed)
0 0 IFCACK-------------> 0 0
Condition eases
1 1 <-------- FCIND(Inc) 1 1
0 1 FCACK--------------> 1 0
2 2 <-------- FCIND(Inc) 2 2
1 2 FCACK--------------> 3 4
the next two flows are the Reset Window operation when the receiver does have an outstanding FCIND ๐ slay
-----SENDER----- ----RECEIVER----
Granted Window Window Granted
0 2 circuit established 2 0
2 2 <-------- FCIND(Rpt) 2 2
1 2 FCACK--------------> 2 1
4 3 <-------- FCIND(Inc) 3 4
3 3 FCACK--------------> 3 3
+- FCIND(Rpt) 3 6
2 3 DATA---|-----------> 3 5
| Resource shortage!
|+-FCIND(Rst) 0 5
1 3 DATA---||----------> 0 4
4 3 <------+|
3 3 FCACK---+----------> 0 3 (Not IFCACK!)
2 3 DATA----|----------> 0 2
0 0 <-------+
0 0 IFCACK-------------> 0 0
Condition eases
1 1 <-------- FCIND(Inc) 1 1
0 1 FCACK--------------> 1 0
2 2 <-------- FCIND(Inc) 2 2
1 2 FCACK--------------> 3 4
-----SENDER----- ----RECEIVER----
Granted Window Window Granted
0 2 circuit established 2 0
2 2 <-------- FCIND(Rpt) 2 2
1 2 FCACK--------------> 2 1
4 3 <-------- FCIND(Inc) 3 4
3 3 FCACK--------------> 3 3
+- FCIND(Rpt) 3 6
2 3 DATA---|-----------> 3 5
| Resource shortage!
|+-FCIND(Rst) 0 5
1 3 DATA---||----------> 0 4
4 3 <------+|
0 0 <-------+
0 0 IFCACK-------------> 0 0
Condition eases
1 1 <-------- FCIND(Inc) 1 1
0 1 FCACK--------------> 1 0
2 2 <-------- FCIND(Inc) 2 2
1 2 FCACK--------------> 3 4
8.9. Other Considerations ๐ง
8.9.1. Protocol Violations ๐
okay so these are the events that count as protocol violations, and yes I'm taking them seriously ๐ญ
- Sender exceeds granted units or does not acknowledge FCIND on first frame after its receipt (the receiver can not discern the difference between the two).
- Receiver does not follow a Reset Window Operator with an Increment Window Operator.
- Receiver has two unacknowledged FCINDs ( other than Reset Window) outstanding.
- Receiver sends Decrement Window Operator with a window size of one.
- Receiver attempts to increment the window size beyond 0xFFFF.
what the node does about a violation is up to its implementation ๐
if it decides to take down the circuit where the violation happened, HALT_DL is the appropriate action.
Acknowledgments ๐ซถ
Original RFC 1434 Authors:
- Roy C. Dixon, IBM
- David M. Kushi, IBM
Chair of APPN Implementers Workshop Data Link Switching Related Interest Group:
- Louise Herndon Wells, Internetworking Technology Institute
Working Group Chairs (and significant contributors to this document):
- Connect/Disconnect (State Machines): Steve Klein, IBM
- Capabilities Exchange: Wayne Clark, Cisco Systems
- Flow Control (Adaptive Pacing): Shannon Nix, Metaplex
- Priority/Class of Service: Gene Cox, IBM
Other significant contributors:
- Peter Gayek, IBM
- Paul Brittain, Data Connection Limited
References ๐
- ISO 8802-2/IEEE Std 802.2 International Standard, Information Processing Systems, Local Area Networks, Part 2: Logical Link Control, December 31, 1989.
- IBM LAN Technical Reference IEEE 802.2 and NETBIOS Application Program Interfaces SC30-3587-00, December 1993.
- ISO/IEC DIS 10038 DAM 2, MAC Bridging, Source Routing Supplement, December 1991.
- ISO 8802-2/IEEE Std 802.1D International Standard, Information Processing Systems, Local Area Networks, Part 2: MAC layer Bridging.
Security Considerations ๐
Security issues are not discussed in this memo. no vibes to report, bestie ๐
Chair's Address ๐ท
Louise Wells Internetwork Technology Institute 2021 Stratford Dr. Milpitas, CA 95035
EMail: lhwells@cup.portal.com
Editor's Address ๐ฆ
Alan K. Bartky Manager of Technology Sync Research Inc. 7 Studebaker Irvine, CA 91728-2013
Phone: 1-714-588-2070 EMail: alan@sync.com
Note: Any questions or comments relative to the contents of this RFC should be sent to the following Internet address: aiw-dlsw@networking.raleigh.ibm.com.
This address will be used to coordinate the handling of responses.
NOTE 1: This is a widely subscribed mailing list and messages sent to this address will be sent to all members of the DLSw mailing list. For specific questions relating to subscribing to the AIW and any of it's working groups send email to: appn@vnet.ibm.com
Information regarding all of the AIW working groups and the work they are producing can be obtained by copying, via anonymous ftp, the file aiwinfo.psbin or aiwinfo.txt from the Internet host networking.raleigh.ibm.com, located in directory aiw.
NOTE 2: These mailing lists and addresses are subject to change. ๐ bye bestie, you did amazing ๐
๐ฆ where this page comes from
- ietf: rfc1795 1995-04
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms