Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1 | #ifndef included_vnet_sr_packet_h |
| 2 | #define included_vnet_sr_packet_h |
| 3 | |
| 4 | #include <vnet/ip/ip.h> |
| 5 | |
| 6 | /* |
| 7 | * ipv6 segment-routing header format |
| 8 | * |
| 9 | * Copyright (c) 2013 Cisco and/or its affiliates. |
| 10 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 11 | * you may not use this file except in compliance with the License. |
| 12 | * You may obtain a copy of the License at: |
| 13 | * |
| 14 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 15 | * |
| 16 | * Unless required by applicable law or agreed to in writing, software |
| 17 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 19 | * See the License for the specific language governing permissions and |
| 20 | * limitations under the License. |
| 21 | */ |
| 22 | |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 23 | /** |
| 24 | * @file |
| 25 | * @brief The Segment Routing Header (SRH). |
| 26 | * |
| 27 | * The Segment Routing Header (SRH) is defined in the diagram below. |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 28 | * |
| 29 | * |
| 30 | * 0 1 2 3 |
| 31 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
| 32 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 33 | * | Next Header | Hdr Ext Len | Routing Type | Segments Left | |
| 34 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 35 | * | First Segment | Flags | HMAC Key ID | |
| 36 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 37 | * | | |
| 38 | * | Segment List[0] (128 bits ipv6 address) | |
| 39 | * | | |
| 40 | * | | |
| 41 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 42 | * | | |
| 43 | * | | |
| 44 | * ... |
| 45 | * | | |
| 46 | * | | |
| 47 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 48 | * | | |
| 49 | * | Segment List[n] (128 bits ipv6 address) | |
| 50 | * | | |
| 51 | * | | |
| 52 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 53 | * | | |
| 54 | * | Policy List[0] (optional) | |
| 55 | * | | |
| 56 | * | | |
| 57 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 58 | * | | |
| 59 | * | Policy List[1] (optional) | |
| 60 | * | | |
| 61 | * | | |
| 62 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 63 | * | | |
| 64 | * | Policy List[2] (optional) | |
| 65 | * | | |
| 66 | * | | |
| 67 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 68 | * | | |
| 69 | * | | |
| 70 | * | | |
| 71 | * | HMAC (256 bits) | |
| 72 | * | (optional) | |
| 73 | * | | |
| 74 | * | | |
| 75 | * | | |
| 76 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 77 | * |
| 78 | * where: |
| 79 | * |
| 80 | * o Next Header: 8-bit selector. Identifies the type of header |
| 81 | * immediately following the SRH. |
| 82 | * |
| 83 | * o Hdr Ext Len: 8-bit unsigned integer, is the length of the SRH |
| 84 | * header in 8-octet units, not including the first 8 octets. |
| 85 | * |
| 86 | * o Routing Type: TBD, to be assigned by IANA (suggested value: 4). |
| 87 | * |
| 88 | * o Segments Left. Defined in [RFC2460], it contains the index, in |
| 89 | * the Segment List, of the next segment to inspect. Segments Left |
| 90 | * is decremented at each segment and it is used as an index in the |
| 91 | * segment list. |
| 92 | * |
| 93 | * o First Segment: offset in the SRH, not including the first 8 octets |
| 94 | * and expressed in 16-octet units, pointing to the last element of |
| 95 | * the segment list, which is in fact the first segment of the |
| 96 | * segment routing path. |
| 97 | * |
| 98 | * o Flags: 16 bits of flags. Following flags are defined: |
| 99 | * |
| 100 | * 1 |
| 101 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 |
| 102 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 103 | * |C|P|R|R| Policy Flags | |
| 104 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 105 | * |
| 106 | * C-flag: Clean-up flag. Set when the SRH has to be removed from |
| 107 | * the packet when packet reaches the last segment. |
| 108 | * |
| 109 | * P-flag: Protected flag. Set when the packet has been rerouted |
| 110 | * through FRR mechanism by a SR endpoint node. See Section 6.3 |
| 111 | * for more details. |
| 112 | * |
| 113 | * R-flags. Reserved and for future use. |
| 114 | * |
| 115 | * Policy Flags. Define the type of the IPv6 addresses encoded |
| 116 | * into the Policy List (see below). The following have been |
| 117 | * defined: |
| 118 | * |
| 119 | * Bits 4-6: determine the type of the first element after the |
| 120 | * segment list. |
| 121 | * |
| 122 | * Bits 7-9: determine the type of the second element. |
| 123 | * |
| 124 | * Bits 10-12: determine the type of the third element. |
| 125 | * |
| 126 | * Bits 13-15: determine the type of the fourth element. |
| 127 | * |
| 128 | * The following values are used for the type: |
| 129 | * |
| 130 | * 0x0: Not present. If value is set to 0x0, it means the |
| 131 | * element represented by these bits is not present. |
| 132 | * |
| 133 | * 0x1: SR Ingress. |
| 134 | * |
| 135 | * 0x2: SR Egress. |
| 136 | * |
| 137 | * 0x3: Original Source Address. |
| 138 | * |
| 139 | * o HMAC Key ID and HMAC field, and their use are defined in |
| 140 | * [I-D.vyncke-6man-segment-routing-security]. |
| 141 | * |
| 142 | * o Segment List[n]: 128 bit IPv6 addresses representing the nth |
| 143 | * segment in the Segment List. The Segment List is encoded starting |
| 144 | * from the last segment of the path. I.e., the first element of the |
| 145 | * segment list (Segment List [0]) contains the last segment of the |
| 146 | * path while the last segment of the Segment List (Segment List[n]) |
| 147 | * contains the first segment of the path. The index contained in |
| 148 | * "Segments Left" identifies the current active segment. |
| 149 | * |
| 150 | * o Policy List. Optional addresses representing specific nodes in |
| 151 | * the SR path such as: |
| 152 | * |
| 153 | * SR Ingress: a 128 bit generic identifier representing the |
| 154 | * ingress in the SR domain (i.e.: it needs not to be a valid IPv6 |
| 155 | * address). |
| 156 | * |
| 157 | * SR Egress: a 128 bit generic identifier representing the egress |
| 158 | * in the SR domain (i.e.: it needs not to be a valid IPv6 |
| 159 | * address). |
| 160 | * |
| 161 | * Original Source Address: IPv6 address originally present in the |
| 162 | * SA field of the packet. |
| 163 | * |
| 164 | * The segments in the Policy List are encoded after the segment list |
| 165 | * and they are optional. If none are in the SRH, all bits of the |
| 166 | * Policy List Flags MUST be set to 0x0. |
| 167 | */ |
| 168 | |
Chris Luke | 4b8b718 | 2016-05-25 14:39:47 -0400 | [diff] [blame] | 169 | #ifndef IPPROTO_IPV6_ROUTE |
| 170 | #define IPPROTO_IPV6_ROUTE 43 |
| 171 | #endif |
| 172 | |
| 173 | #define ROUTING_HEADER_TYPE_SR 4 |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 174 | /** |
| 175 | @brief SR header struct. |
| 176 | */ |
Keith Burns (alagalah) | 06c5ffd | 2016-08-06 08:32:45 -0700 | [diff] [blame] | 177 | typedef struct |
| 178 | { |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 179 | /** Protocol for next header. */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 180 | u8 protocol; |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 181 | |
| 182 | /** |
Damjan Marion | 607de1a | 2016-08-16 22:53:54 +0200 | [diff] [blame] | 183 | * Length of routing header in 8 octet units, |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 184 | * not including the first 8 octets |
| 185 | */ |
| 186 | u8 length; |
| 187 | |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 188 | /** Type of routing header; type 4 = segement routing */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 189 | u8 type; |
| 190 | |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 191 | /** Next segment in the segment list */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 192 | u8 segments_left; |
| 193 | |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 194 | /** |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 195 | * Policy list pointer: offset in the SRH of the policy |
| 196 | * list - in 16-octet units - not including the first 8 octets. |
| 197 | */ |
| 198 | u8 first_segment; |
| 199 | |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 200 | /** Flag bits */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 201 | #define IP6_SR_HEADER_FLAG_CLEANUP (0x8000) |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 202 | /** Flag bits */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 203 | #define IP6_SR_HEADER_FLAG_PROTECTED (0x4000) |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 204 | /** Flag bits */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 205 | #define IP6_SR_HEADER_FLAG_RESERVED (0x3000) |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 206 | /** Flag bits */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 207 | #define IP6_SR_HEADER_FLAG_PL_ELT_NOT_PRESENT (0x0) |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 208 | /** Flag bits */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 209 | #define IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE (0x1) |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 210 | /** Flag bits */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 211 | #define IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE (0x2) |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 212 | /** Flag bits */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 213 | #define IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR (0x3) |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 214 | /** values 0x4 - 0x7 are reserved */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 215 | u16 flags; |
| 216 | u8 hmac_key; |
Keith Burns (alagalah) | 06c5ffd | 2016-08-06 08:32:45 -0700 | [diff] [blame] | 217 | |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 218 | /** The segment + policy list elts */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 219 | ip6_address_t segments[0]; |
Keith Burns (alagalah) | 06c5ffd | 2016-08-06 08:32:45 -0700 | [diff] [blame] | 220 | } __attribute__ ((packed)) ip6_sr_header_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 221 | |
| 222 | static inline int |
| 223 | ip6_sr_policy_list_shift_from_index (int pl_index) |
| 224 | { |
| 225 | return (-3 * pl_index) + 12; |
| 226 | } |
| 227 | |
Keith Burns (alagalah) | 7214cf1 | 2016-08-08 15:56:50 -0700 | [diff] [blame] | 228 | /** pl_index is one-origined */ |
Keith Burns (alagalah) | 06c5ffd | 2016-08-06 08:32:45 -0700 | [diff] [blame] | 229 | static inline int |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 230 | ip6_sr_policy_list_flags (u16 flags_host_byte_order, int pl_index) |
| 231 | { |
| 232 | int shift; |
| 233 | |
| 234 | if (pl_index <= 0 || pl_index > 4) |
| 235 | return 0; |
| 236 | |
| 237 | shift = (-3 * pl_index) + 12; |
| 238 | flags_host_byte_order >>= shift; |
| 239 | |
| 240 | return (flags_host_byte_order & 7); |
| 241 | } |
| 242 | |
| 243 | #endif /* included_vnet_sr_packet_h */ |
Keith Burns (alagalah) | 06c5ffd | 2016-08-06 08:32:45 -0700 | [diff] [blame] | 244 | |
| 245 | /* |
| 246 | * fd.io coding-style-patch-verification: ON |
| 247 | * |
| 248 | * Local Variables: |
| 249 | * eval: (c-set-style "gnu") |
| 250 | * End: |
| 251 | */ |