7. Packet Types (Normative)
ROHC-TCP uses three different packet types: the Initialization and Refresh (IR) packet type, the Context Replication (IR-CR) packet type, and the Compressed (CO) packet type. Each packet type defines a number of packet formats: two packet formats are defined for the IR type, one packet format is defined for the IR-CR type, and two sets of eight base header formats are defined for the CO type with one additional format that is common to both sets. The profile identifier for ROHC-TCP is 0x0006.7.1. Initialization and Refresh (IR) Packets
ROHC-TCP uses the basic structure of the ROHC IR and IR-DYN packets as defined in [RFC5795] (Sections 5.2.2.1 and 5.2.2.2, respectively). Packet type: IR This packet type communicates the static part and the dynamic part of the context. For the ROHC-TCP IR packet, the value of the x bit MUST be set to one. It has the following format, which corresponds to the "Header" and "Payload" fields described in Section 5.2.1 of [RFC5795]:
0 1 2 3 4 5 6 7 --- --- --- --- --- --- --- --- : Add-CID octet : if for small CIDs and (CID != 0) +---+---+---+---+---+---+---+---+ | 1 1 1 1 1 1 0 1 | IR type octet +---+---+---+---+---+---+---+---+ : : / 0-2 octets of CID / 1-2 octets if for large CIDs : : +---+---+---+---+---+---+---+---+ | Profile = 0x06 | 1 octet +---+---+---+---+---+---+---+---+ | CRC | 1 octet +---+---+---+---+---+---+---+---+ | | / Static chain / variable length | | - - - - - - - - - - - - - - - - | | / Dynamic chain / variable length | | - - - - - - - - - - - - - - - - | | / Payload / variable length | | - - - - - - - - - - - - - - - - CRC: 8-bit CRC, computed according to Section 5.3.1.1 of [RFC5795]. The CRC covers the entire IR header, thus excluding payload, padding, and feedback, if any. Static chain: See Section 6.2. Dynamic chain: See Section 6.2. Payload: The payload of the corresponding original packet, if any. The payload consists of all data after the last octet of the TCP header to the end of the uncompressed packet. The presence of a payload is inferred from the packet length. Packet type: IR-DYN This packet type communicates the dynamic part of the context. The ROHC-TCP IR-DYN packet has the following format, which corresponds to the "Header" and "Payload" fields described in Section 5.2.1 of [RFC5795]:
0 1 2 3 4 5 6 7 --- --- --- --- --- --- --- --- : Add-CID octet : if for small CIDs and (CID != 0) +---+---+---+---+---+---+---+---+ | 1 1 1 1 1 0 0 0 | IR-DYN type octet +---+---+---+---+---+---+---+---+ : : / 0-2 octets of CID / 1-2 octets if for large CIDs : : +---+---+---+---+---+---+---+---+ | Profile = 0x06 | 1 octet +---+---+---+---+---+---+---+---+ | CRC | 1 octet +---+---+---+---+---+---+---+---+ | | / Dynamic chain / variable length | | - - - - - - - - - - - - - - - - | | / Payload / variable length | | - - - - - - - - - - - - - - - - CRC: 8-bit CRC, computed according to Section 5.3.1.1 of [RFC5795]. The CRC covers the entire IR-DYN header, thus excluding payload, padding, and feedback, if any. Dynamic chain: See Section 6.2. Payload: The payload of the corresponding original packet, if any. The payload consists of all data after the last octet of the TCP header to end of the uncompressed packet. The presence of a payload is inferred from the packet length.7.2. Context Replication (IR-CR) Packets
Context replication requires a dedicated IR packet format that uniquely identifies the IR-CR packet for the ROHC-TCP profile. This section defines the profile-specific part of the IR-CR packet [RFC4164]. Packet type: IR-CR This packet type communicates a reference to a base context along with the static and dynamic parts of the replicated context that differs from the base context.
The ROHC-TCP IR-CR packet follows the general format of the ROHC IR-CR packet, as defined in [RFC4164], Section 3.5.2. With consideration to the extensibility of the IR packet type defined in [RFC5795], the ROHC-TCP profile supports context replication through the profile-specific part of the IR packet. This is achieved using the bit (x) left in the IR header for "Profile specific information". For ROHC-TCP, this bit is defined as a flag indicating whether this packet is an IR packet or an IR-CR packet. For the ROHC-TCP IR-CR packet, the value of the x bit MUST be set to zero. The ROHC-TCP IR-CR has the following format, which corresponds to the "Header" and "Payload" fields described in Section 5.2.1 of [RFC5795]: 0 1 2 3 4 5 6 7 --- --- --- --- --- --- --- --- : Add-CID octet : if for small CIDs and (CID != 0) +---+---+---+---+---+---+---+---+ | 1 1 1 1 1 1 0 0 | IR-CR type octet +---+---+---+---+---+---+---+---+ : : / 0-2 octets of CID / 1-2 octets if for large CIDs : : +---+---+---+---+---+---+---+---+ | Profile = 0x06 | 1 octet +---+---+---+---+---+---+---+---+ | CRC | 1 octet +---+---+---+---+---+---+---+---+ | B | CRC7 | 1 octet +---+---+---+---+---+---+---+---+ : Reserved | Base CID : 1 octet, for small CID, if B=1 +---+---+---+---+---+---+---+---+ : : / Base CID / 1-2 octets, for large CIDs, : : if B=1 +---+---+---+---+---+---+---+---+ | | / Replicate chain / variable length | | - - - - - - - - - - - - - - - - | | / Payload / variable length | | - - - - - - - - - - - - - - - -
B: B = 1 indicates that the Base CID field is present. CRC: This CRC covers the entire IR-CR header, thus excluding payload, padding, and feedback, if any. This 8-bit CRC is calculated according to Section 5.3.1.1 of [RFC5795]. CRC7: The CRC over the original, uncompressed, header. Calculated according to Section 3.5.1.1 of [RFC4164]. Reserved: MUST be set to zero; otherwise, the decompressor MUST discard the packet. Base CID: CID of base context. Encoded according to [RFC4164], Section 3.5.3. Replicate chain: See Section 6.2. Payload: The payload of the corresponding original packet, if any. The presence of a payload is inferred from the packet length.7.3. Compressed (CO) Packets
The ROHC-TCP CO packets communicate irregularities in the packet header. All CO packets carry a CRC and can update the context. The general format for a compressed TCP header is as follows, which corresponds to the "Header" and "Payload" fields described in Section 5.2.1 of [RFC5795]:
0 1 2 3 4 5 6 7 --- --- --- --- --- --- --- --- : Add-CID octet : if for small CIDs and CID 1-15 +---+---+---+---+---+---+---+---+ | First octet of base header | (with type indication) +---+---+---+---+---+---+---+---+ : : / 0, 1, or 2 octets of CID / 1-2 octets if large CIDs : : +---+---+---+---+---+---+---+---+ / Remainder of base header / variable number of octets +---+---+---+---+---+---+---+---+ : Irregular chain : / (including irregular chain / variable : items for TCP options) : --- --- --- --- --- --- --- --- | | / Payload / variable length | | - - - - - - - - - - - - - - - - Base header: The complete set of base headers is defined in Section 8. Irregular chain: See Sections 6.2 and 6.3.6. Payload: The payload of the corresponding original packet, if any. The presence of a payload is inferred from the packet length.8. Header Formats (Normative)
This section describes the set of compressed TCP/IP packet formats. The normative description of the packet formats is given using the formal notation for ROHC profiles defined in [RFC4997]. The formal description of the packet formats specifies all of the information needed to compress and decompress a header relative to the context. In particular, the notation provides a list of all the fields present in the uncompressed and compressed TCP/IP headers, and defines how to map from each uncompressed packet to its compressed equivalent and vice versa.
8.1. Design Rationale for Compressed Base Headers
The compressed header formats are defined as two separate sets: one set for the packets where the innermost IP header contains a sequential IP-ID (either network byte order or byte swapped), and one set for the packets without sequential IP-ID (either random, zero, or no IP-ID). These two sets of header formats are referred to as the "sequential" and the "random" set of header formats, respectively. In addition, there is one compressed format that is common to both sets of header formats and that can thus be used regardless of the type of IP-ID behavior. This format can transmit rarely changing fields and also send the frequently changing fields coded in variable lengths. It can also change the value of control fields such as IP-ID behavior and ECN behavior. All compressed base headers contain a 3-bit CRC, unless they update control fields such as "ip_id_behavior" or "ecn_used" that affect the interpretation of subsequent headers. Headers that can modify these control fields carry a 7-bit CRC instead. When discussing LSB-encoded fields below, "p" equals the "offset_param" and "k" equals the "num_lsbs_param" in [RFC4997]. The encoding methods used in the compressed base headers are based on the following design criteria: o MSN Since the MSN is a number generated by the compressor, it only needs to be large enough to ensure robust operation and to accommodate a small amount of reordering [RFC4163]. Therefore, each compressed base header has an MSN field that is LSB- encoded with k=4 and p=4 to handle a reordering depth of up to 4 packets. Additional guidance to improve robustness when reordering is possible can be found in [RFC4224]. o TCP Sequence Number ROHC-TCP has the capability to handle bulk data transfers efficiently, for which the sequence number is expected to increase by about 1460 octets (which can be represented by 11 bits). For the compressed base headers to handle retransmissions (i.e., negative delta to the sequence number),
the LSB interpretation interval has to handle negative offsets about as large as positive offsets, which means that one more bit is needed. Also, for ROHC-TCP to be robust to losses, two additional bits are added to the LSB encoding of the sequence number. This means that the base headers should contain at least 14 bits of LSB-encoded sequence number when present. According to the logic above, the LSB offset value is set to be as large as the positive offset, i.e., p = 2^(k-1)-1. o TCP Acknowledgment Number The design criterion for the acknowledgment number is similar to that of the TCP Sequence Number. However, often only every other data packet is acknowledged, which means that the expected delta value is twice as large as for sequence numbers. Therefore, at least 15 bits of acknowledgment number should be used in compressed base headers. Since the acknowledgment number is expected to constantly increase, and the only exception to this is packet reordering (either on the ROHC channel [RFC3759] or prior to the compression point), the negative offset for LSB encoding is set to be 1/4 of the total interval, i.e., p = 2^(k-2)-1. o TCP Window The TCP Window field is expected to increase in increments of similar size as the TCP Sequence Number; therefore, the design criterion for the TCP window is to send at least 14 bits when used. o IP-ID For the "sequential" set of packet formats, all the compressed base headers contain LSB-encoded IP-ID offset bits, where the offset is the difference between the value of the MSN field and the value of the IP-ID field. The requirement is that at least 3 bits of IP-ID should always be present, but it is preferable to use 4 to 7 bits. When k=3 then p=1, and if k>3 then p=3 since the offset is expected to increase most of the time. Each set of header formats contains eight different compressed base headers. The reason for having this large number of header formats is that the TCP Sequence Number, TCP Acknowledgment Number, and TCP Window are frequently changing in a non-linear pattern.
The design of the header formats is derived from the field behavior analysis found in [RFC4413]. All of the compressed base headers transmit LSB-encoded MSN bits, the TCP Push flag, and a CRC, and in addition to this, all the base headers in the sequential packet format set contain LSB-encoded IP-ID bits. The following header formats exist in both the sequential and random packet format sets: o Format 1: This header format carries changes to the TCP Sequence Number and is expected to be used on the downstream of a data transfer. o Format 2: This header format carries the TCP Sequence Number in scaled form and is expected to be useful for the downstream of a data transfer where the payload size is constant for multiple packets. o Format 3: This header format carries changes in the TCP Acknowledgment Number and is expected to be useful for the acknowledgment direction of a data transfer. o Format 4: This header format is similar to format 3, but carries a scaled TCP Acknowledgment Number. o Format 5: This header format carries both the TCP Sequence Number and the TCP Acknowledgment Number and is expected to be useful for flows that send data in both directions. o Format 6: This header format is similar to format 5, but carries the TCP Sequence Number in scaled form, when the payload size is static for certain intervals in a data flow. o Format 7: This header format carries changes to both the TCP Acknowledgment Number and the TCP Window and is expected to be useful for the acknowledgment flows of data connections. o Format 8: This header format is used to convey changes to some of the more seldom changing fields in the TCP flow, such as ECN behavior, RST/SYN/FIN flags, the TTL/Hop Limit, and the TCP options list. This format carries a 7-bit CRC, since it can change the structure of the contents of the irregular chain for subsequent packets. Note that this can be seen as a reduced form of the common packet format.
o Common header format: The common header format can be used for all kinds of IP-ID behavior and should be useful when some of the more rarely changing fields in the IP or TCP header change. Since this header format can update control fields that decide how the decompressor interprets packets, it carries a 7-bit CRC to reduce the probability of context corruption. This header can basically convey changes to any of the dynamic fields in the IP and TCP headers, and it uses a large set of flags to provide information about which fields are present in the header format.8.2. Formal Definition of Header Formats
// NOTE: The irregular, static, and dynamic chains (see Section 6.2) // are defined across multiple encoding methods and are embodied // in the correspondingly named formats within those encoding // methods. In particular, note that the static and dynamic // chains ordinarily go together. The uncompressed fields are // defined across these two formats combined, rather than in one // or the other of them. The irregular chain items are likewise // combined with a baseheader format. //////////////////////////////////////////// // Constants //////////////////////////////////////////// IP_ID_BEHAVIOR_SEQUENTIAL = 0; IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED = 1; IP_ID_BEHAVIOR_RANDOM = 2; IP_ID_BEHAVIOR_ZERO = 3; //////////////////////////////////////////// // Global control fields //////////////////////////////////////////// CONTROL { ecn_used [ 1 ]; msn [ 16 ]; // ip_id fields are for innermost IP header only ip_id_offset [ 16 ]; ip_id_behavior_innermost [ 2 ]; // ACK-related ack_stride [ 32 ]; ack_number_scaled [ 32 ]; ack_number_residue [ 32 ]; seq_number_scaled [ 32 ]; seq_number_residue [ 32 ]; }
/////////////////////////////////////////////// // Encoding methods not specified in FN syntax /////////////////////////////////////////////// list_tcp_options "defined in Section 6.3.3"; inferred_ip_v4_header_checksum "defined in Section 6.4.1"; inferred_mine_header_checksum "defined in Section 6.4.2"; inferred_ip_v4_length "defined in Section 6.4.3"; inferred_ip_v6_length "defined in Section 6.4.4"; inferred_offset "defined in Section 6.4.5"; baseheader_extension_headers "defined in Section 6.4.6"; baseheader_outer_headers "defined in Section 6.4.7"; //////////////////////////////////////////// // General encoding methods //////////////////////////////////////////// static_or_irreg(flag, width) { UNCOMPRESSED { field [ width ]; } COMPRESSED irreg_enc { field =:= irregular(width) [ width ]; ENFORCE(flag == 1); } COMPRESSED static_enc { field =:= static [ 0 ]; ENFORCE(flag == 0); } } zero_or_irreg(flag, width) { UNCOMPRESSED { field [ width ]; } COMPRESSED non_zero { field =:= irregular(width) [ width ]; ENFORCE(flag == 0); } COMPRESSED zero { field =:= uncompressed_value(width, 0) [ 0 ]; ENFORCE(flag == 1);
} } variable_length_32_enc(flag) { UNCOMPRESSED { field [ 32 ]; } COMPRESSED not_present { field =:= static [ 0 ]; ENFORCE(flag == 0); } COMPRESSED lsb_8_bit { field =:= lsb(8, 63) [ 8 ]; ENFORCE(flag == 1); } COMPRESSED lsb_16_bit { field =:= lsb(16, 16383) [ 16 ]; ENFORCE(flag == 2); } COMPRESSED irreg_32_bit { field =:= irregular(32) [ 32 ]; ENFORCE(flag == 3); } } optional32(flag) { UNCOMPRESSED { item [ 0, 32 ]; } COMPRESSED present { item =:= irregular(32) [ 32 ]; ENFORCE(flag == 1); } COMPRESSED not_present { item =:= compressed_value(0, 0) [ 0 ]; ENFORCE(flag == 0); } } lsb_7_or_31
{ UNCOMPRESSED { item [ 32 ]; } COMPRESSED lsb_7 { discriminator =:= '0' [ 1 ]; item =:= lsb(7, 8) [ 7 ]; } COMPRESSED lsb_31 { discriminator =:= '1' [ 1 ]; item =:= lsb(31, 256) [ 31 ]; } } opt_lsb_7_or_31(flag) { UNCOMPRESSED { item [ 0, 32 ]; } COMPRESSED present { item =:= lsb_7_or_31 [ 8, 32 ]; ENFORCE(flag == 1); } COMPRESSED not_present { item =:= compressed_value(0, 0) [ 0 ]; ENFORCE(flag == 0); } } crc3(data_value, data_length) { UNCOMPRESSED { } COMPRESSED { crc_value =:= crc(3, 0x06, 0x07, data_value, data_length) [ 3 ]; } } crc7(data_value, data_length) { UNCOMPRESSED { }
COMPRESSED { crc_value =:= crc(7, 0x79, 0x7f, data_value, data_length) [ 7 ]; } } one_bit_choice { UNCOMPRESSED { field [ 1 ]; } COMPRESSED zero { field [ 1 ]; ENFORCE(field.UVALUE == 0); } COMPRESSED nonzero { field [ 1 ]; ENFORCE(field.UVALUE == 1); } } // Encoding method for updating a scaled field and its associated // control fields. Should be used both when the value is scaled // or unscaled in a compressed format. // Does not have an uncompressed side. field_scaling(stride_value, scaled_value, unscaled_value, residue_value) { UNCOMPRESSED { // Nothing } COMPRESSED no_scaling { ENFORCE(stride_value == 0); ENFORCE(residue_value == unscaled_value); ENFORCE(scaled_value == 0); } COMPRESSED scaling_used { ENFORCE(stride_value != 0); ENFORCE(residue_value == (unscaled_value % stride_value)); ENFORCE(unscaled_value == scaled_value * stride_value + residue_value); } }
//////////////////////////////////////////// // IPv6 Destination options header //////////////////////////////////////////// ip_dest_opt { UNCOMPRESSED { next_header [ 8 ]; length [ 8 ]; value [ length.UVALUE * 64 + 48 ]; } DEFAULT { length =:= static; next_header =:= static; value =:= static; } COMPRESSED dest_opt_static { next_header =:= irregular(8) [ 8 ]; length =:= irregular(8) [ 8 ]; } COMPRESSED dest_opt_dynamic { value =:= irregular(length.UVALUE * 64 + 48) [ length.UVALUE * 64 + 48 ]; } COMPRESSED dest_opt_0_replicate { discriminator =:= '00000000' [ 8 ]; } COMPRESSED dest_opt_1_replicate { discriminator =:= '10000000' [ 8 ]; length =:= irregular(8) [ 8 ]; value =:= irregular(length.UVALUE*64+48) [ length.UVALUE * 64 + 48 ]; } COMPRESSED dest_opt_irregular { } } //////////////////////////////////////////// // IPv6 Hop-by-Hop options header //////////////////////////////////////////// ip_hop_opt {
UNCOMPRESSED { next_header [ 8 ]; length [ 8 ]; value [ length.UVALUE * 64 + 48 ]; } DEFAULT { length =:= static; next_header =:= static; value =:= static; } COMPRESSED hop_opt_static { next_header =:= irregular(8) [ 8 ]; length =:= irregular(8) [ 8 ]; } COMPRESSED hop_opt_dynamic { value =:= irregular(length.UVALUE*64+48) [ length.UVALUE * 64 + 48 ]; } COMPRESSED hop_opt_0_replicate { discriminator =:= '00000000' [ 8 ]; } COMPRESSED hop_opt_1_replicate { discriminator =:= '10000000' [ 8 ]; length =:= irregular(8) [ 8 ]; value =:= irregular(length.UVALUE*64+48) [ length.UVALUE * 64 + 48 ]; } COMPRESSED hop_opt_irregular { } } //////////////////////////////////////////// // IPv6 Routing header //////////////////////////////////////////// ip_rout_opt { UNCOMPRESSED { next_header [ 8 ]; length [ 8 ]; value [ length.UVALUE * 64 + 48 ]; }
DEFAULT { length =:= static; next_header =:= static; value =:= static; } COMPRESSED rout_opt_static { next_header =:= irregular(8) [ 8 ]; length =:= irregular(8) [ 8 ]; value =:= irregular(length.UVALUE*64+48) [ length.UVALUE * 64 + 48 ]; } COMPRESSED rout_opt_dynamic { } COMPRESSED rout_opt_0_replicate { discriminator =:= '00000000' [ 8 ]; } COMPRESSED rout_opt_0_replicate { discriminator =:= '10000000' [ 8 ]; length =:= irregular(8) [ 8 ]; value =:= irregular(length.UVALUE*64+48) [ length.UVALUE * 64 + 48 ]; } COMPRESSED rout_opt_irregular { } } //////////////////////////////////////////// // GRE Header //////////////////////////////////////////// optional_checksum(flag_value) { UNCOMPRESSED { value [ 0, 16 ]; reserved1 [ 0, 16 ]; } COMPRESSED cs_present { value =:= irregular(16) [ 16 ]; reserved1 =:= uncompressed_value(16, 0) [ 0 ]; ENFORCE(flag_value == 1); } COMPRESSED not_present {
value =:= compressed_value(0, 0) [ 0 ]; reserved1 =:= compressed_value(0, 0) [ 0 ]; ENFORCE(flag_value == 0); } } gre_proto { UNCOMPRESSED { protocol [ 16 ]; } COMPRESSED ether_v4 { discriminator =:= compressed_value(1, 0) [ 1 ]; protocol =:= uncompressed_value(16, 0x0800) [ 0 ]; } COMPRESSED ether_v6 { discriminator =:= compressed_value(1, 1) [ 1 ]; protocol =:= uncompressed_value(16, 0x86DD) [ 0 ]; } } gre { UNCOMPRESSED { c_flag [ 1 ]; r_flag =:= uncompressed_value(1, 0) [ 1 ]; k_flag [ 1 ]; s_flag [ 1 ]; reserved0 =:= uncompressed_value(9, 0) [ 9 ]; version =:= uncompressed_value(3, 0) [ 3 ]; protocol [ 16 ]; checksum_and_res [ 0, 32 ]; key [ 0, 32 ]; sequence_number [ 0, 32 ]; } DEFAULT { c_flag =:= static; k_flag =:= static; s_flag =:= static; protocol =:= static; key =:= static; sequence_number =:= static; } COMPRESSED gre_static {
ENFORCE((c_flag.UVALUE == 1 && checksum_and_res.ULENGTH == 32) || checksum_and_res.ULENGTH == 0); ENFORCE((s_flag.UVALUE == 1 && sequence_number.ULENGTH == 32) || sequence_number.ULENGTH == 0); protocol =:= gre_proto [ 1 ]; c_flag =:= irregular(1) [ 1 ]; k_flag =:= irregular(1) [ 1 ]; s_flag =:= irregular(1) [ 1 ]; padding =:= compressed_value(4, 0) [ 4 ]; key =:= optional32(k_flag.UVALUE) [ 0, 32 ]; } COMPRESSED gre_dynamic { checksum_and_res =:= optional_checksum(c_flag.UVALUE) [ 0, 16 ]; sequence_number =:= optional32(s_flag.UVALUE) [ 0, 32 ]; } COMPRESSED gre_0_replicate { discriminator =:= '00000000' [ 8 ]; checksum_and_res =:= optional_checksum(c_flag.UVALUE) [ 0, 16 ]; sequence_number =:= optional32(s_flag.UVALUE) [ 0, 8, 32 ]; } COMPRESSED gre_1_replicate { discriminator =:= '10000' [ 5 ]; c_flag =:= irregular(1) [ 1 ]; k_flag =:= irregular(1) [ 1 ]; s_flag =:= irregular(1) [ 1 ]; checksum_and_res =:= optional_checksum(c_flag.UVALUE) [ 0, 16 ]; key =:= optional32(k_flag.UVALUE) [ 0, 32 ]; sequence_number =:= optional32(s_flag.UVALUE) [ 0, 32 ]; } COMPRESSED gre_irregular { checksum_and_res =:= optional_checksum(c_flag.UVALUE) [ 0, 16 ]; sequence_number =:= opt_lsb_7_or_31(s_flag.UVALUE) [ 0, 8, 32 ]; } } ///////////////////////////////////////////// // MINE header /////////////////////////////////////////////
mine { UNCOMPRESSED { next_header [ 8 ]; s_bit [ 1 ]; res_bits [ 7 ]; checksum [ 16 ]; orig_dest [ 32 ]; orig_src [ 0, 32 ]; } DEFAULT { next_header =:= static; s_bit =:= static; res_bits =:= static; checksum =:= inferred_mine_header_checksum; orig_dest =:= static; orig_src =:= static; } COMPRESSED mine_static { next_header =:= irregular(8) [ 8 ]; s_bit =:= irregular(1) [ 1 ]; // Reserved bits are included to achieve byte-alignment res_bits =:= irregular(7) [ 7 ]; orig_dest =:= irregular(32) [ 32 ]; orig_src =:= optional32(s_bit.UVALUE) [ 0, 32 ]; } COMPRESSED mine_dynamic { } COMPRESSED mine_0_replicate { discriminator =:= '00000000' [ 8 ]; } COMPRESSED mine_1_replicate { discriminator =:= '10000000' [ 8 ]; s_bit =:= irregular(1) [ 1 ]; res_bits =:= irregular(7) [ 7 ]; orig_dest =:= irregular(32) [ 32 ]; orig_src =:= optional32(s_bit.UVALUE) [ 0, 32 ]; } COMPRESSED mine_irregular { } }