Olivier Dugeon | 4f59357 | 2016-04-19 19:03:05 +0200 | [diff] [blame] | 1 | /* |
| 2 | * IS-IS Rout(e)ing protocol - isis_te.c |
| 3 | * |
| 4 | * This is an implementation of RFC5305, RFC 5307 and draft-ietf-isis-te-metric-extensions-11 |
| 5 | * |
| 6 | * Copyright (C) 2014 Orange Labs |
| 7 | * http://www.orange.com |
| 8 | * |
| 9 | * This file is part of GNU Zebra. |
| 10 | * |
| 11 | * GNU Zebra is free software; you can redistribute it and/or modify it |
| 12 | * under the terms of the GNU General Public License as published by the |
| 13 | * Free Software Foundation; either version 2, or (at your option) any |
| 14 | * later version. |
| 15 | * |
| 16 | * GNU Zebra is distributed in the hope that it will be useful, but |
| 17 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 19 | * General Public License for more details. |
| 20 | * |
| 21 | * You should have received a copy of the GNU General Public License |
| 22 | * along with GNU Zebra; see the file COPYING. If not, write to the Free |
| 23 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
| 24 | * 02111-1307, USA. |
| 25 | */ |
| 26 | |
| 27 | #ifndef _ZEBRA_ISIS_MPLS_TE_H |
| 28 | #define _ZEBRA_ISIS_MPLS_TE_H |
| 29 | |
| 30 | /* |
| 31 | * Traffic Engineering information are transport through LSP: |
| 32 | * - Extended IS Reachability TLV = 22 |
| 33 | * - Traffic Engineering Router ID TLV = 134 |
| 34 | * - Extended IP Reachability TLV = 135 |
| 35 | * - Inter-AS Reachability Information TLV = 141 |
| 36 | * |
| 37 | * and support following sub-TLV: |
| 38 | * |
| 39 | * Name Value Status |
| 40 | * _________________________________________________ |
| 41 | * Administartive group (color) 3 RFC5305 |
| 42 | * Link Local/Remote Identifiers 4 RFC5307 |
| 43 | * IPv4 interface address 6 RFC5305 |
| 44 | * IPv4 neighbor address 8 RFC5305 |
| 45 | * Maximum link bandwidth 9 RFC5305 |
| 46 | * Reservable link bandwidth 10 RFC5305 |
| 47 | * Unreserved bandwidth 11 RFC5305 |
| 48 | * TE Default metric 18 RFC5305 |
| 49 | * Link Protection Type 20 RFC5307 |
| 50 | * Interface Switching Capability 21 RFC5307 |
| 51 | * Remote AS number 24 RFC5316 |
| 52 | * IPv4 Remote ASBR identifier 25 RFC5316 |
| 53 | * |
| 54 | */ |
| 55 | |
| 56 | /* NOTE: RFC5316 is not yet supported in this version */ |
| 57 | |
| 58 | /* Following define the type of TE link regarding the various RFC */ |
| 59 | #define STD_TE 0x01 |
| 60 | #define GMPLS 0x02 |
| 61 | #define INTER_AS 0x04 |
| 62 | #define FLOOD_L1 0x10 |
| 63 | #define FLOOD_L2 0x20 |
| 64 | #define FLOOD_AS 0x40 |
| 65 | #define EMULATED 0x80 |
| 66 | |
| 67 | #define IS_STD_TE(x) (x & STD_TE) |
| 68 | #define IS_INTER_AS(x) (x & INTER_AS) |
| 69 | #define IS_EMULATED(x) (x & EMULATED) |
| 70 | #define IS_FLOOD_L1(x) (x & FLOOD_L1) |
| 71 | #define IS_FLOOD_L2(x) (x & FLOOD_L2) |
| 72 | #define IS_FLOOD_AS(x) (x & FLOOD_AS) |
| 73 | #define IS_INTER_AS_EMU(x) (x & INTER_AS & EMULATED) |
| 74 | #define IS_INTER_AS_AS(x) (x & INTER_AS & FLOOD_AS) |
| 75 | |
| 76 | /* |
| 77 | * Following section defines subTLV (tag, length, value) structures, |
| 78 | * used for Traffic Engineering. |
| 79 | */ |
| 80 | struct subtlv_header |
| 81 | { |
| 82 | u_char type; /* sub_TLV_XXX type (see above) */ |
| 83 | u_char length; /* Value portion only, in byte */ |
| 84 | }; |
| 85 | |
| 86 | #define SUBTLV_HDR_SIZE 2 /* (sizeof (struct sub_tlv_header)) */ |
| 87 | |
| 88 | #define SUBTLV_SIZE(stlvh) (SUBTLV_HDR_SIZE + (stlvh)->length) |
| 89 | |
| 90 | #define SUBTLV_HDR_TOP(lsph) (struct subtlv_header *)((char *)(lsph) + ISIS_LSP_HEADER_SIZE) |
| 91 | |
| 92 | #define SUBTLV_HDR_NEXT(stlvh) (struct subtlv_header *)((char *)(stlvh) + SUBTLV_SIZE(stlvh)) |
| 93 | |
| 94 | #define SUBTLV_TYPE(stlvh) stlvh.header.type |
| 95 | #define SUBTLV_LEN(stlvh) stlvh.header.length |
| 96 | #define SUBTLV_VAL(stlvh) stlvh.value |
| 97 | #define SUBTLV_DATA(stlvh) stlvh + SUBTLV_HDR_SIZE |
| 98 | |
| 99 | #define SUBTLV_DEF_SIZE 4 |
| 100 | |
| 101 | /* Link Sub-TLV: Resource Class/Color - RFC 5305 */ |
| 102 | #define TE_SUBTLV_ADMIN_GRP 3 |
| 103 | struct te_subtlv_admin_grp |
| 104 | { |
| 105 | struct subtlv_header header; /* Value length is 4 octets. */ |
| 106 | u_int32_t value; /* Admin. group membership. */ |
| 107 | } __attribute__((__packed__)); |
| 108 | |
| 109 | /* Link Local/Remote Identifiers - RFC 5307 */ |
| 110 | #define TE_SUBTLV_LLRI 4 |
| 111 | #define TE_SUBTLV_LLRI_SIZE 8 |
| 112 | struct te_subtlv_llri |
| 113 | { |
| 114 | struct subtlv_header header; /* Value length is 8 octets. */ |
| 115 | u_int32_t local; /* Link Local Identifier */ |
| 116 | u_int32_t remote; /* Link Remote Identifier */ |
| 117 | } __attribute__((__packed__)); |
| 118 | |
| 119 | /* Link Sub-TLV: Local Interface IP Address - RFC 5305 */ |
| 120 | #define TE_SUBTLV_LOCAL_IPADDR 6 |
| 121 | struct te_subtlv_local_ipaddr |
| 122 | { |
| 123 | struct subtlv_header header; /* Value length is 4 x N octets. */ |
| 124 | struct in_addr value; /* Local IP address(es). */ |
| 125 | } __attribute__((__packed__)); |
| 126 | |
| 127 | /* Link Sub-TLV: Neighbor Interface IP Address - RFC 5305 */ |
| 128 | #define TE_SUBTLV_RMT_IPADDR 8 |
| 129 | struct te_subtlv_rmt_ipaddr |
| 130 | { |
| 131 | struct subtlv_header header; /* Value length is 4 x N octets. */ |
| 132 | struct in_addr value; /* Neighbor's IP address(es). */ |
| 133 | } __attribute__((__packed__)); |
| 134 | |
| 135 | /* Link Sub-TLV: Maximum Bandwidth - RFC 5305 */ |
| 136 | #define TE_SUBTLV_MAX_BW 9 |
| 137 | struct te_subtlv_max_bw |
| 138 | { |
| 139 | struct subtlv_header header; /* Value length is 4 octets. */ |
| 140 | float value; /* bytes/sec */ |
| 141 | } __attribute__((__packed__)); |
| 142 | |
| 143 | /* Link Sub-TLV: Maximum Reservable Bandwidth - RFC 5305 */ |
| 144 | #define TE_SUBTLV_MAX_RSV_BW 10 |
| 145 | struct te_subtlv_max_rsv_bw |
| 146 | { |
| 147 | struct subtlv_header header; /* Value length is 4 octets. */ |
| 148 | float value; /* bytes/sec */ |
| 149 | } __attribute__((__packed__)); |
| 150 | |
| 151 | /* Link Sub-TLV: Unreserved Bandwidth - RFC 5305 */ |
| 152 | #define TE_SUBTLV_UNRSV_BW 11 |
| 153 | #define TE_SUBTLV_UNRSV_SIZE 32 |
| 154 | struct te_subtlv_unrsv_bw |
| 155 | { |
| 156 | struct subtlv_header header; /* Value length is 32 octets. */ |
| 157 | float value[8]; /* One for each priority level. */ |
| 158 | } __attribute__((__packed__)); |
| 159 | |
| 160 | /* Link Sub-TLV: Traffic Engineering Metric - RFC 5305 */ |
| 161 | #define TE_SUBTLV_TE_METRIC 18 |
| 162 | #define TE_SUBTLV_TE_METRIC_SIZE 3 |
| 163 | struct te_subtlv_te_metric |
| 164 | { |
| 165 | struct subtlv_header header; /* Value length is 4 octets. */ |
| 166 | u_char value[3]; /* Link metric for TE purpose. */ |
| 167 | } __attribute__((__packed__)); |
| 168 | |
| 169 | /* Remote AS Number sub-TLV - RFC5316 */ |
| 170 | #define TE_SUBTLV_RAS 24 |
| 171 | struct te_subtlv_ras |
| 172 | { |
| 173 | struct subtlv_header header; /* Value length is 4 octets. */ |
| 174 | u_int32_t value; /* Remote AS number */ |
| 175 | } __attribute__((__packed__)); |
| 176 | |
| 177 | /* IPv4 Remote ASBR ID Sub-TLV - RFC5316 */ |
| 178 | #define TE_SUBTLV_RIP 25 |
| 179 | struct te_subtlv_rip |
| 180 | { |
| 181 | struct subtlv_header header; /* Value length is 4 octets. */ |
| 182 | struct in_addr value; /* Remote ASBR IP address */ |
| 183 | } __attribute__((__packed__)); |
| 184 | |
| 185 | |
| 186 | /* draft-ietf-isis-te-metric-extensions-11.txt */ |
| 187 | /* Link Sub-TLV: Average Link Delay */ |
| 188 | #define TE_SUBTLV_AV_DELAY 33 |
| 189 | struct te_subtlv_av_delay |
| 190 | { |
| 191 | struct subtlv_header header; /* Value length is 4 bytes. */ |
| 192 | u_int32_t value; /* Average delay in micro-seconds only 24 bits => 0 ... 16777215 |
| 193 | with Anomalous Bit (A) as Upper most bit */ |
| 194 | } __attribute__((__packed__)); |
| 195 | |
| 196 | /* Link Sub-TLV: Low/High Link Delay */ |
| 197 | #define TE_SUBTLV_MM_DELAY 34 |
| 198 | #define TE_SUBTLV_MM_DELAY_SIZE 8 |
| 199 | struct te_subtlv_mm_delay |
| 200 | { |
| 201 | struct subtlv_header header; /* Value length is 8 bytes. */ |
| 202 | u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ... 16777215 |
| 203 | with Anomalous Bit (A) as Upper most bit */ |
| 204 | u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ... 16777215 */ |
| 205 | } __attribute__((__packed__)); |
| 206 | |
| 207 | /* Link Sub-TLV: Link Delay Variation i.e. Jitter */ |
| 208 | #define TE_SUBTLV_DELAY_VAR 35 |
| 209 | struct te_subtlv_delay_var |
| 210 | { |
| 211 | struct subtlv_header header; /* Value length is 4 bytes. */ |
| 212 | u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ... 16777215 */ |
| 213 | } __attribute__((__packed__)); |
| 214 | |
| 215 | /* Link Sub-TLV: Routine Unidirectional Link Packet Loss */ |
| 216 | #define TE_SUBTLV_PKT_LOSS 36 |
| 217 | struct te_subtlv_pkt_loss |
| 218 | { |
| 219 | struct subtlv_header header; /* Value length is 4 bytes. */ |
| 220 | u_int32_t value; /* in percentage of total traffic only 24 bits (2^24 - 2) |
| 221 | with Anomalous Bit (A) as Upper most bit */ |
| 222 | } __attribute__((__packed__)); |
| 223 | |
| 224 | /* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */ |
| 225 | #define TE_SUBTLV_RES_BW 37 |
| 226 | struct te_subtlv_res_bw |
| 227 | { |
| 228 | struct subtlv_header header; /* Value length is 4 bytes. */ |
| 229 | float value; /* bandwidth in IEEE floating point format with units in bytes per second */ |
| 230 | } __attribute__((__packed__)); |
| 231 | |
| 232 | /* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */ |
| 233 | #define TE_SUBTLV_AVA_BW 38 |
| 234 | struct te_subtlv_ava_bw |
| 235 | { |
| 236 | struct subtlv_header header; /* Value length is 4 octets. */ |
| 237 | float value; /* bandwidth in IEEE floating point format with units in bytes per second */ |
| 238 | } __attribute__((__packed__)); |
| 239 | |
| 240 | /* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */ |
| 241 | #define TE_SUBTLV_USE_BW 39 |
| 242 | struct te_subtlv_use_bw |
| 243 | { |
| 244 | struct subtlv_header header; /* Value length is 4 octets. */ |
| 245 | float value; /* bandwidth in IEEE floating point format with units in bytes per second */ |
| 246 | } __attribute__((__packed__)); |
| 247 | |
| 248 | #define TE_SUBTLV_MAX 40 /* Last SUBTLV + 1 */ |
| 249 | |
| 250 | /* Following declaration concerns the MPLS-TE and LINk-TE management */ |
| 251 | typedef enum _status_t { disable, enable, learn } status_t; |
| 252 | |
| 253 | /* Mode for Inter-AS LSP */ /* TODO: Check how if LSP is flooded in RFC5316 */ |
| 254 | typedef enum _interas_mode_t { off, region, as, emulate } interas_mode_t; |
| 255 | |
| 256 | #define IS_MPLS_TE(m) (m.status == enable) |
| 257 | #define IS_CIRCUIT_TE(c) (c->status == enable) |
| 258 | |
| 259 | /* Following structure are internal use only. */ |
| 260 | struct isis_mpls_te |
| 261 | { |
| 262 | /* Status of MPLS-TE: enable or disable */ |
| 263 | status_t status; |
| 264 | |
| 265 | /* L1, L1-L2, L2-Only */ |
| 266 | u_int8_t level; |
| 267 | |
| 268 | /* RFC5316 */ |
| 269 | interas_mode_t inter_as; |
| 270 | struct in_addr interas_areaid; |
| 271 | |
| 272 | /* Circuit list on which TE are enable */ |
| 273 | struct list *cir_list; |
| 274 | |
| 275 | /* MPLS_TE router ID */ |
| 276 | struct in_addr router_id; |
| 277 | }; |
| 278 | |
| 279 | extern struct isis_mpls_te isisMplsTE; |
| 280 | |
| 281 | struct mpls_te_circuit |
| 282 | { |
| 283 | |
| 284 | /* Status of MPLS-TE on this interface */ |
| 285 | status_t status; |
| 286 | |
| 287 | /* Type of MPLS-TE circuit: STD_TE(RFC5305), INTER_AS(RFC5316), INTER_AS_EMU(RFC5316 emulated) */ |
| 288 | u_int8_t type; |
| 289 | |
| 290 | /* Total size of sub_tlvs */ |
| 291 | u_char length; |
| 292 | |
| 293 | /* Store subTLV in network byte order. */ |
| 294 | /* RFC5305 */ |
| 295 | struct te_subtlv_admin_grp admin_grp; |
| 296 | /* RFC5307 */ |
| 297 | struct te_subtlv_llri llri; |
| 298 | /* RFC5305 */ |
| 299 | struct te_subtlv_local_ipaddr local_ipaddr; |
| 300 | struct te_subtlv_rmt_ipaddr rmt_ipaddr; |
| 301 | struct te_subtlv_max_bw max_bw; |
| 302 | struct te_subtlv_max_rsv_bw max_rsv_bw; |
| 303 | struct te_subtlv_unrsv_bw unrsv_bw; |
| 304 | struct te_subtlv_te_metric te_metric; |
| 305 | /* RFC5316 */ |
| 306 | struct te_subtlv_ras ras; |
| 307 | struct te_subtlv_rip rip; |
| 308 | /* draft-ietf-isis-te-metric-extension */ |
| 309 | struct te_subtlv_av_delay av_delay; |
| 310 | struct te_subtlv_mm_delay mm_delay; |
| 311 | struct te_subtlv_delay_var delay_var; |
| 312 | struct te_subtlv_pkt_loss pkt_loss; |
| 313 | struct te_subtlv_res_bw res_bw; |
| 314 | struct te_subtlv_ava_bw ava_bw; |
| 315 | struct te_subtlv_use_bw use_bw; |
| 316 | }; |
| 317 | |
| 318 | /* Prototypes. */ |
| 319 | void isis_mpls_te_init (void); |
| 320 | struct mpls_te_circuit *mpls_te_circuit_new(void); |
| 321 | void mpls_te_print_detail(struct vty *, struct te_is_neigh *); |
| 322 | void set_circuitparams_local_ipaddr (struct mpls_te_circuit *, struct in_addr); |
| 323 | void set_circuitparams_rmt_ipaddr (struct mpls_te_circuit *, struct in_addr); |
| 324 | u_char subtlvs_len (struct mpls_te_circuit *); |
| 325 | u_char add_te_subtlvs(u_char *, struct mpls_te_circuit *); |
| 326 | u_char build_te_subtlvs(u_char *, struct isis_circuit *); |
| 327 | void isis_link_params_update(struct isis_circuit *, struct interface *); |
| 328 | void isis_mpls_te_update(struct interface *); |
| 329 | void isis_mpls_te_config_write_router (struct vty *); |
| 330 | |
| 331 | #endif /* _ZEBRA_ISIS_MPLS_TE_H */ |