Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1 | /* |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 2 | * Copyright (c) 2016 Cisco and/or its affiliates. |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at: |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
Ole Troan | 944f548 | 2016-05-24 11:56:58 +0200 | [diff] [blame] | 15 | #ifndef __included_ip6_hop_by_hop_ioam_h__ |
| 16 | #define __included_ip6_hop_by_hop_ioam_h__ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 17 | |
| 18 | #include <vnet/ip/ip6_hop_by_hop_packet.h> |
Shwetha Bhandari | 05866a1 | 2016-05-04 08:12:57 +0200 | [diff] [blame] | 19 | #include <vnet/ip/ip.h> |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 20 | |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 21 | |
| 22 | #define MAX_IP6_HBH_OPTION 256 |
| 23 | |
| 24 | /* To determine whether a node is decap MS bit is set */ |
| 25 | #define IOAM_DECAP_BIT 0x80000000 |
| 26 | |
| 27 | #define IOAM_DEAP_ENABLED(opaque_data) (opaque_data & IOAM_DECAP_BIT) |
| 28 | |
| 29 | #define IOAM_SET_DECAP(opaque_data) \ |
| 30 | (opaque_data |= IOAM_DECAP_BIT) |
| 31 | |
| 32 | #define IOAM_MASK_DECAP_BIT(x) (x & ~IOAM_DECAP_BIT) |
| 33 | |
| 34 | /* |
| 35 | * Stores the run time flow data of hbh options |
| 36 | */ |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 37 | typedef struct |
| 38 | { |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 39 | u32 ctx[MAX_IP6_HBH_OPTION]; |
| 40 | u8 flow_name[64]; |
| 41 | } flow_data_t; |
| 42 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 43 | typedef struct |
| 44 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 45 | /* The current rewrite we're using */ |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 46 | u8 *rewrite; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 47 | |
| 48 | /* Trace data processing callback */ |
| 49 | void *ioam_end_of_path_cb; |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 50 | /* Configuration data */ |
| 51 | /* Adjacency */ |
| 52 | ip6_address_t adj; |
| 53 | #define IOAM_HBYH_ADD 0 |
| 54 | #define IOAM_HBYH_MOD 1 |
| 55 | #define IOAM_HBYH_POP 2 |
| 56 | u8 ioam_flag; |
| 57 | /* time scale transform. Joy. */ |
| 58 | u32 unix_time_0; |
| 59 | f64 vlib_time_0; |
| 60 | |
| 61 | |
| 62 | /* Trace option */ |
Vengada Govindan | 07d2f84 | 2016-08-25 10:34:34 -0700 | [diff] [blame] | 63 | u8 has_trace_option; |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 64 | |
Shwetha | 85b528e | 2016-06-15 16:34:16 +0100 | [diff] [blame] | 65 | /* Pot option */ |
| 66 | u8 has_pot_option; |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 67 | |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 68 | /* Per Packet Counter option */ |
| 69 | u8 has_seqno_option; |
| 70 | |
| 71 | /* Enabling analyis of iOAM data on decap node */ |
| 72 | u8 has_analyse_option; |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 73 | |
Shwetha | 85b528e | 2016-06-15 16:34:16 +0100 | [diff] [blame] | 74 | /* Array of function pointers to ADD and POP HBH option handling routines */ |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 75 | u8 options_size[MAX_IP6_HBH_OPTION]; |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 76 | int (*add_options[MAX_IP6_HBH_OPTION]) (u8 * rewrite_string, |
| 77 | u8 * rewrite_size); |
| 78 | int (*pop_options[MAX_IP6_HBH_OPTION]) (vlib_buffer_t * b, |
| 79 | ip6_header_t * ip, |
| 80 | ip6_hop_by_hop_option_t * opt); |
| 81 | int (*get_sizeof_options[MAX_IP6_HBH_OPTION]) (u32 * rewrite_size); |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 82 | int (*config_handler[MAX_IP6_HBH_OPTION]) (void *data, u8 disable); |
| 83 | |
| 84 | /* Array of function pointers to handle hbh options being used with classifier */ |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 85 | u32 (*flow_handler[MAX_IP6_HBH_OPTION]) (u32 flow_ctx, u8 add); |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 86 | flow_data_t *flows; |
| 87 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 88 | /* convenience */ |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 89 | vlib_main_t *vlib_main; |
| 90 | vnet_main_t *vnet_main; |
Ole Troan | 944f548 | 2016-05-24 11:56:58 +0200 | [diff] [blame] | 91 | } ip6_hop_by_hop_ioam_main_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 92 | |
Ole Troan | 944f548 | 2016-05-24 11:56:58 +0200 | [diff] [blame] | 93 | extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main; |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 94 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 95 | extern clib_error_t *ip6_ioam_enable (int has_trace_option, |
| 96 | int has_pot_option, |
| 97 | int has_seqno_option, |
| 98 | int has_analyse_option); |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 99 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 100 | extern int ip6_ioam_set_destination (ip6_address_t * addr, u32 mask_width, |
| 101 | u32 vrf_id, int is_add, int is_pop, |
| 102 | int is_none); |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 103 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 104 | extern clib_error_t *clear_ioam_rewrite_fn (void); |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 105 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 106 | static inline u8 |
| 107 | is_zero_ip4_address (ip4_address_t * a) |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 108 | { |
| 109 | return (a->as_u32 == 0); |
| 110 | } |
| 111 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 112 | static inline void |
| 113 | copy_ip6_address (ip6_address_t * dst, ip6_address_t * src) |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 114 | { |
| 115 | dst->as_u64[0] = src->as_u64[0]; |
| 116 | dst->as_u64[1] = src->as_u64[1]; |
| 117 | } |
| 118 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 119 | static inline void |
| 120 | set_zero_ip6_address (ip6_address_t * a) |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 121 | { |
| 122 | a->as_u64[0] = 0; |
| 123 | a->as_u64[1] = 0; |
| 124 | } |
| 125 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 126 | static inline u8 |
| 127 | cmp_ip6_address (ip6_address_t * a1, ip6_address_t * a2) |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 128 | { |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 129 | return ((a1->as_u64[0] == a2->as_u64[0]) |
| 130 | && (a1->as_u64[1] == a2->as_u64[1])); |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 131 | } |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 132 | |
| 133 | static inline u8 |
| 134 | is_zero_ip6_address (ip6_address_t * a) |
rangan | 4f81085 | 2016-03-18 03:31:17 +0530 | [diff] [blame] | 135 | { |
| 136 | return ((a->as_u64[0] == 0) && (a->as_u64[1] == 0)); |
| 137 | } |
| 138 | |
Shwetha | 85b528e | 2016-06-15 16:34:16 +0100 | [diff] [blame] | 139 | int ip6_hbh_add_register_option (u8 option, |
| 140 | u8 size, |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 141 | int rewrite_options (u8 * rewrite_string, |
| 142 | u8 * size)); |
Shwetha | 85b528e | 2016-06-15 16:34:16 +0100 | [diff] [blame] | 143 | int ip6_hbh_add_unregister_option (u8 option); |
| 144 | |
| 145 | int ip6_hbh_pop_register_option (u8 option, |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 146 | int options (vlib_buffer_t * b, |
| 147 | ip6_header_t * ip, |
| 148 | ip6_hop_by_hop_option_t * opt)); |
Shwetha | 85b528e | 2016-06-15 16:34:16 +0100 | [diff] [blame] | 149 | int ip6_hbh_pop_unregister_option (u8 option); |
| 150 | |
Vengada Govindan | 07d2f84 | 2016-08-25 10:34:34 -0700 | [diff] [blame] | 151 | int |
| 152 | ip6_hbh_get_sizeof_register_option (u8 option, |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 153 | int get_sizeof_hdr_options (u32 * |
| 154 | rewrite_size)); |
Shwetha | 85b528e | 2016-06-15 16:34:16 +0100 | [diff] [blame] | 155 | |
Vengada Govindan | 07d2f84 | 2016-08-25 10:34:34 -0700 | [diff] [blame] | 156 | int |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 157 | ip6_ioam_set_rewrite (u8 ** rwp, int has_trace_option, |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 158 | int has_pot_option, int has_seq_no); |
| 159 | |
| 160 | int |
| 161 | ip6_hbh_config_handler_register (u8 option, |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 162 | int config_handler (void *data, u8 disable)); |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 163 | |
| 164 | int ip6_hbh_config_handler_unregister (u8 option); |
| 165 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 166 | int ip6_hbh_flow_handler_register (u8 option, |
| 167 | u32 ioam_flow_handler (u32 flow_ctx, |
| 168 | u8 add)); |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 169 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 170 | int ip6_hbh_flow_handler_unregister (u8 option); |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 171 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 172 | u8 *get_flow_name_from_flow_ctx (u32 flow_ctx); |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 173 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 174 | static inline flow_data_t * |
| 175 | get_flow (u32 index) |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 176 | { |
| 177 | flow_data_t *flow = NULL; |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 178 | ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main; |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 179 | |
| 180 | if (pool_is_free_index (hm->flows, index)) |
| 181 | return NULL; |
| 182 | |
| 183 | flow = pool_elt_at_index (hm->flows, index); |
| 184 | return flow; |
| 185 | } |
| 186 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 187 | static inline u32 |
| 188 | get_flow_data_from_flow_ctx (u32 flow_ctx, u8 option) |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 189 | { |
| 190 | flow_data_t *flow = NULL; |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 191 | ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main; |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 192 | u32 index; |
| 193 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 194 | index = IOAM_MASK_DECAP_BIT (flow_ctx); |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 195 | //flow = pool_elt_at_index (hm->flows, index); |
| 196 | flow = &hm->flows[index]; |
| 197 | return (flow->ctx[option]); |
| 198 | } |
| 199 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 200 | static inline u8 |
| 201 | is_seqno_enabled (void) |
AkshayaNadahalli | ed4a2fd | 2016-08-09 13:38:04 +0530 | [diff] [blame] | 202 | { |
| 203 | return (ip6_hop_by_hop_ioam_main.has_seqno_option); |
| 204 | } |
| 205 | |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 206 | int ip6_trace_profile_setup (); |
AkshayaNadahalli | fdd81af | 2016-12-01 16:33:51 +0530 | [diff] [blame] | 207 | |
| 208 | static inline u32 |
| 209 | ioam_flow_add (u8 encap, u8 * flow_name) |
| 210 | { |
| 211 | ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main; |
| 212 | flow_data_t *flow = 0; |
| 213 | u32 index = 0; |
| 214 | u8 i; |
| 215 | |
| 216 | pool_get (hm->flows, flow); |
Dave Barach | b7b9299 | 2018-10-17 10:38:51 -0400 | [diff] [blame^] | 217 | clib_memset (flow, 0, sizeof (flow_data_t)); |
AkshayaNadahalli | fdd81af | 2016-12-01 16:33:51 +0530 | [diff] [blame] | 218 | |
| 219 | index = flow - hm->flows; |
| 220 | strncpy ((char *) flow->flow_name, (char *) flow_name, 31); |
| 221 | |
| 222 | if (!encap) |
| 223 | IOAM_SET_DECAP (index); |
| 224 | |
| 225 | for (i = 0; i < 255; i++) |
| 226 | { |
| 227 | if (hm->flow_handler[i]) |
| 228 | flow->ctx[i] = hm->flow_handler[i] (index, 1); |
| 229 | } |
| 230 | return (index); |
| 231 | } |
| 232 | |
AkshayaNadahalli | 1b56352 | 2017-01-23 22:05:35 +0530 | [diff] [blame] | 233 | always_inline ip6_hop_by_hop_option_t * |
| 234 | ip6_hbh_get_option (ip6_hop_by_hop_header_t * hbh0, u8 option_to_search) |
| 235 | { |
| 236 | ip6_hop_by_hop_option_t *opt0, *limit0; |
| 237 | u8 type0; |
| 238 | |
| 239 | if (!hbh0) |
| 240 | return NULL; |
| 241 | |
| 242 | opt0 = (ip6_hop_by_hop_option_t *) (hbh0 + 1); |
| 243 | limit0 = (ip6_hop_by_hop_option_t *) |
| 244 | ((u8 *) hbh0 + ((hbh0->length + 1) << 3)); |
| 245 | |
| 246 | /* Scan the set of h-b-h options, process ones that we understand */ |
| 247 | while (opt0 < limit0) |
| 248 | { |
| 249 | type0 = opt0->type; |
| 250 | switch (type0) |
| 251 | { |
| 252 | case 0: /* Pad1 */ |
| 253 | opt0 = (ip6_hop_by_hop_option_t *) ((u8 *) opt0) + 1; |
| 254 | continue; |
| 255 | case 1: /* PadN */ |
| 256 | break; |
| 257 | default: |
| 258 | if (type0 == option_to_search) |
| 259 | return opt0; |
| 260 | break; |
| 261 | } |
| 262 | opt0 = |
| 263 | (ip6_hop_by_hop_option_t *) (((u8 *) opt0) + opt0->length + |
| 264 | sizeof (ip6_hop_by_hop_option_t)); |
| 265 | } |
| 266 | return NULL; |
| 267 | } |
| 268 | |
Ole Troan | 944f548 | 2016-05-24 11:56:58 +0200 | [diff] [blame] | 269 | #endif /* __included_ip6_hop_by_hop_ioam_h__ */ |
Dave Barach | d7cb1b5 | 2016-12-09 09:52:16 -0500 | [diff] [blame] | 270 | |
| 271 | /* |
| 272 | * fd.io coding-style-patch-verification: ON |
| 273 | * |
| 274 | * Local Variables: |
| 275 | * eval: (c-set-style "gnu") |
| 276 | * End: |
| 277 | */ |