1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2020 Mellanox Technologies, Ltd 3 * 4 * This file contain the implementations of the items 5 * related methods. Each Item have a method to prepare 6 * the item and add it into items array in given index. 7 */ 8 9 #include <stdint.h> 10 #include <rte_flow.h> 11 12 #include "items_gen.h" 13 #include "config.h" 14 15 /* Storage for additional parameters for items */ 16 struct additional_para { 17 rte_be32_t src_ip; 18 }; 19 20 static void 21 add_ether(struct rte_flow_item *items, 22 uint8_t items_counter, 23 __rte_unused struct additional_para para) 24 { 25 static struct rte_flow_item_eth eth_spec; 26 static struct rte_flow_item_eth eth_mask; 27 28 memset(ð_spec, 0, sizeof(struct rte_flow_item_eth)); 29 memset(ð_mask, 0, sizeof(struct rte_flow_item_eth)); 30 31 items[items_counter].type = RTE_FLOW_ITEM_TYPE_ETH; 32 items[items_counter].spec = ð_spec; 33 items[items_counter].mask = ð_mask; 34 } 35 36 static void 37 add_vlan(struct rte_flow_item *items, 38 uint8_t items_counter, 39 __rte_unused struct additional_para para) 40 { 41 static struct rte_flow_item_vlan vlan_spec; 42 static struct rte_flow_item_vlan vlan_mask; 43 44 uint16_t vlan_value = VLAN_VALUE; 45 46 memset(&vlan_spec, 0, sizeof(struct rte_flow_item_vlan)); 47 memset(&vlan_mask, 0, sizeof(struct rte_flow_item_vlan)); 48 49 vlan_spec.tci = RTE_BE16(vlan_value); 50 vlan_mask.tci = RTE_BE16(0xffff); 51 52 items[items_counter].type = RTE_FLOW_ITEM_TYPE_VLAN; 53 items[items_counter].spec = &vlan_spec; 54 items[items_counter].mask = &vlan_mask; 55 } 56 57 static void 58 add_ipv4(struct rte_flow_item *items, 59 uint8_t items_counter, struct additional_para para) 60 { 61 static struct rte_flow_item_ipv4 ipv4_spec; 62 static struct rte_flow_item_ipv4 ipv4_mask; 63 64 memset(&ipv4_spec, 0, sizeof(struct rte_flow_item_ipv4)); 65 memset(&ipv4_mask, 0, sizeof(struct rte_flow_item_ipv4)); 66 67 ipv4_spec.hdr.src_addr = RTE_BE32(para.src_ip); 68 ipv4_mask.hdr.src_addr = RTE_BE32(0xffffffff); 69 70 items[items_counter].type = RTE_FLOW_ITEM_TYPE_IPV4; 71 items[items_counter].spec = &ipv4_spec; 72 items[items_counter].mask = &ipv4_mask; 73 } 74 75 76 static void 77 add_ipv6(struct rte_flow_item *items, 78 uint8_t items_counter, struct additional_para para) 79 { 80 static struct rte_flow_item_ipv6 ipv6_spec; 81 static struct rte_flow_item_ipv6 ipv6_mask; 82 83 memset(&ipv6_spec, 0, sizeof(struct rte_flow_item_ipv6)); 84 memset(&ipv6_mask, 0, sizeof(struct rte_flow_item_ipv6)); 85 86 /** Set ipv6 src **/ 87 memset(&ipv6_spec.hdr.src_addr, para.src_ip, 88 sizeof(ipv6_spec.hdr.src_addr) / 2); 89 90 /** Full mask **/ 91 memset(&ipv6_mask.hdr.src_addr, 0xff, 92 sizeof(ipv6_spec.hdr.src_addr)); 93 94 items[items_counter].type = RTE_FLOW_ITEM_TYPE_IPV6; 95 items[items_counter].spec = &ipv6_spec; 96 items[items_counter].mask = &ipv6_mask; 97 } 98 99 static void 100 add_tcp(struct rte_flow_item *items, 101 uint8_t items_counter, 102 __rte_unused struct additional_para para) 103 { 104 static struct rte_flow_item_tcp tcp_spec; 105 static struct rte_flow_item_tcp tcp_mask; 106 107 memset(&tcp_spec, 0, sizeof(struct rte_flow_item_tcp)); 108 memset(&tcp_mask, 0, sizeof(struct rte_flow_item_tcp)); 109 110 items[items_counter].type = RTE_FLOW_ITEM_TYPE_TCP; 111 items[items_counter].spec = &tcp_spec; 112 items[items_counter].mask = &tcp_mask; 113 } 114 115 static void 116 add_udp(struct rte_flow_item *items, 117 uint8_t items_counter, 118 __rte_unused struct additional_para para) 119 { 120 static struct rte_flow_item_udp udp_spec; 121 static struct rte_flow_item_udp udp_mask; 122 123 memset(&udp_spec, 0, sizeof(struct rte_flow_item_udp)); 124 memset(&udp_mask, 0, sizeof(struct rte_flow_item_udp)); 125 126 items[items_counter].type = RTE_FLOW_ITEM_TYPE_UDP; 127 items[items_counter].spec = &udp_spec; 128 items[items_counter].mask = &udp_mask; 129 } 130 131 static void 132 add_vxlan(struct rte_flow_item *items, 133 uint8_t items_counter, 134 __rte_unused struct additional_para para) 135 { 136 static struct rte_flow_item_vxlan vxlan_spec; 137 static struct rte_flow_item_vxlan vxlan_mask; 138 139 uint32_t vni_value; 140 uint8_t i; 141 142 vni_value = VNI_VALUE; 143 144 memset(&vxlan_spec, 0, sizeof(struct rte_flow_item_vxlan)); 145 memset(&vxlan_mask, 0, sizeof(struct rte_flow_item_vxlan)); 146 147 /* Set standard vxlan vni */ 148 for (i = 0; i < 3; i++) { 149 vxlan_spec.vni[2 - i] = vni_value >> (i * 8); 150 vxlan_mask.vni[2 - i] = 0xff; 151 } 152 153 /* Standard vxlan flags */ 154 vxlan_spec.flags = 0x8; 155 156 items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN; 157 items[items_counter].spec = &vxlan_spec; 158 items[items_counter].mask = &vxlan_mask; 159 } 160 161 static void 162 add_vxlan_gpe(struct rte_flow_item *items, 163 uint8_t items_counter, 164 __rte_unused struct additional_para para) 165 { 166 static struct rte_flow_item_vxlan_gpe vxlan_gpe_spec; 167 static struct rte_flow_item_vxlan_gpe vxlan_gpe_mask; 168 169 uint32_t vni_value; 170 uint8_t i; 171 172 vni_value = VNI_VALUE; 173 174 memset(&vxlan_gpe_spec, 0, sizeof(struct rte_flow_item_vxlan_gpe)); 175 memset(&vxlan_gpe_mask, 0, sizeof(struct rte_flow_item_vxlan_gpe)); 176 177 /* Set vxlan-gpe vni */ 178 for (i = 0; i < 3; i++) { 179 vxlan_gpe_spec.vni[2 - i] = vni_value >> (i * 8); 180 vxlan_gpe_mask.vni[2 - i] = 0xff; 181 } 182 183 /* vxlan-gpe flags */ 184 vxlan_gpe_spec.flags = 0x0c; 185 186 items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE; 187 items[items_counter].spec = &vxlan_gpe_spec; 188 items[items_counter].mask = &vxlan_gpe_mask; 189 } 190 191 static void 192 add_gre(struct rte_flow_item *items, 193 uint8_t items_counter, 194 __rte_unused struct additional_para para) 195 { 196 static struct rte_flow_item_gre gre_spec; 197 static struct rte_flow_item_gre gre_mask; 198 199 uint16_t proto; 200 201 proto = RTE_ETHER_TYPE_TEB; 202 203 memset(&gre_spec, 0, sizeof(struct rte_flow_item_gre)); 204 memset(&gre_mask, 0, sizeof(struct rte_flow_item_gre)); 205 206 gre_spec.protocol = RTE_BE16(proto); 207 gre_mask.protocol = RTE_BE16(0xffff); 208 209 items[items_counter].type = RTE_FLOW_ITEM_TYPE_GRE; 210 items[items_counter].spec = &gre_spec; 211 items[items_counter].mask = &gre_mask; 212 } 213 214 static void 215 add_geneve(struct rte_flow_item *items, 216 uint8_t items_counter, 217 __rte_unused struct additional_para para) 218 { 219 static struct rte_flow_item_geneve geneve_spec; 220 static struct rte_flow_item_geneve geneve_mask; 221 222 uint32_t vni_value; 223 uint8_t i; 224 225 vni_value = VNI_VALUE; 226 227 memset(&geneve_spec, 0, sizeof(struct rte_flow_item_geneve)); 228 memset(&geneve_mask, 0, sizeof(struct rte_flow_item_geneve)); 229 230 for (i = 0; i < 3; i++) { 231 geneve_spec.vni[2 - i] = vni_value >> (i * 8); 232 geneve_mask.vni[2 - i] = 0xff; 233 } 234 235 items[items_counter].type = RTE_FLOW_ITEM_TYPE_GENEVE; 236 items[items_counter].spec = &geneve_spec; 237 items[items_counter].mask = &geneve_mask; 238 } 239 240 static void 241 add_gtp(struct rte_flow_item *items, 242 uint8_t items_counter, 243 __rte_unused struct additional_para para) 244 { 245 static struct rte_flow_item_gtp gtp_spec; 246 static struct rte_flow_item_gtp gtp_mask; 247 248 uint32_t teid_value; 249 250 teid_value = TEID_VALUE; 251 252 memset(>p_spec, 0, sizeof(struct rte_flow_item_gtp)); 253 memset(>p_mask, 0, sizeof(struct rte_flow_item_gtp)); 254 255 gtp_spec.teid = RTE_BE32(teid_value); 256 gtp_mask.teid = RTE_BE32(0xffffffff); 257 258 items[items_counter].type = RTE_FLOW_ITEM_TYPE_GTP; 259 items[items_counter].spec = >p_spec; 260 items[items_counter].mask = >p_mask; 261 } 262 263 static void 264 add_meta_data(struct rte_flow_item *items, 265 uint8_t items_counter, 266 __rte_unused struct additional_para para) 267 { 268 static struct rte_flow_item_meta meta_spec; 269 static struct rte_flow_item_meta meta_mask; 270 271 uint32_t data; 272 273 data = META_DATA; 274 275 memset(&meta_spec, 0, sizeof(struct rte_flow_item_meta)); 276 memset(&meta_mask, 0, sizeof(struct rte_flow_item_meta)); 277 278 meta_spec.data = RTE_BE32(data); 279 meta_mask.data = RTE_BE32(0xffffffff); 280 281 items[items_counter].type = RTE_FLOW_ITEM_TYPE_META; 282 items[items_counter].spec = &meta_spec; 283 items[items_counter].mask = &meta_mask; 284 } 285 286 287 static void 288 add_meta_tag(struct rte_flow_item *items, 289 uint8_t items_counter, 290 __rte_unused struct additional_para para) 291 { 292 static struct rte_flow_item_tag tag_spec; 293 static struct rte_flow_item_tag tag_mask; 294 uint32_t data; 295 uint8_t index; 296 297 data = META_DATA; 298 index = TAG_INDEX; 299 300 memset(&tag_spec, 0, sizeof(struct rte_flow_item_tag)); 301 memset(&tag_mask, 0, sizeof(struct rte_flow_item_tag)); 302 303 tag_spec.data = RTE_BE32(data); 304 tag_mask.data = RTE_BE32(0xffffffff); 305 tag_spec.index = index; 306 tag_mask.index = 0xff; 307 308 items[items_counter].type = RTE_FLOW_ITEM_TYPE_TAG; 309 items[items_counter].spec = &tag_spec; 310 items[items_counter].mask = &tag_mask; 311 } 312 313 static void 314 add_icmpv4(struct rte_flow_item *items, 315 uint8_t items_counter, 316 __rte_unused struct additional_para para) 317 { 318 static struct rte_flow_item_icmp icmpv4_spec; 319 static struct rte_flow_item_icmp icmpv4_mask; 320 321 memset(&icmpv4_spec, 0, sizeof(struct rte_flow_item_icmp)); 322 memset(&icmpv4_mask, 0, sizeof(struct rte_flow_item_icmp)); 323 324 items[items_counter].type = RTE_FLOW_ITEM_TYPE_ICMP; 325 items[items_counter].spec = &icmpv4_spec; 326 items[items_counter].mask = &icmpv4_mask; 327 } 328 329 static void 330 add_icmpv6(struct rte_flow_item *items, 331 uint8_t items_counter, 332 __rte_unused struct additional_para para) 333 { 334 static struct rte_flow_item_icmp6 icmpv6_spec; 335 static struct rte_flow_item_icmp6 icmpv6_mask; 336 337 memset(&icmpv6_spec, 0, sizeof(struct rte_flow_item_icmp6)); 338 memset(&icmpv6_mask, 0, sizeof(struct rte_flow_item_icmp6)); 339 340 items[items_counter].type = RTE_FLOW_ITEM_TYPE_ICMP6; 341 items[items_counter].spec = &icmpv6_spec; 342 items[items_counter].mask = &icmpv6_mask; 343 } 344 345 void 346 fill_items(struct rte_flow_item *items, 347 uint64_t *flow_items, uint32_t outer_ip_src) 348 { 349 uint8_t items_counter = 0; 350 uint8_t i, j; 351 struct additional_para additional_para_data = { 352 .src_ip = outer_ip_src, 353 }; 354 355 /* Support outer items up to tunnel layer only. */ 356 static const struct items_dict { 357 uint64_t mask; 358 void (*funct)( 359 struct rte_flow_item *items, 360 uint8_t items_counter, 361 struct additional_para para 362 ); 363 } items_list[] = { 364 { 365 .mask = RTE_FLOW_ITEM_TYPE_META, 366 .funct = add_meta_data, 367 }, 368 { 369 .mask = RTE_FLOW_ITEM_TYPE_TAG, 370 .funct = add_meta_tag, 371 }, 372 { 373 .mask = RTE_FLOW_ITEM_TYPE_ETH, 374 .funct = add_ether, 375 }, 376 { 377 .mask = RTE_FLOW_ITEM_TYPE_VLAN, 378 .funct = add_vlan, 379 }, 380 { 381 .mask = RTE_FLOW_ITEM_TYPE_IPV4, 382 .funct = add_ipv4, 383 }, 384 { 385 .mask = RTE_FLOW_ITEM_TYPE_IPV6, 386 .funct = add_ipv6, 387 }, 388 { 389 .mask = RTE_FLOW_ITEM_TYPE_TCP, 390 .funct = add_tcp, 391 }, 392 { 393 .mask = RTE_FLOW_ITEM_TYPE_UDP, 394 .funct = add_udp, 395 }, 396 { 397 .mask = RTE_FLOW_ITEM_TYPE_VXLAN, 398 .funct = add_vxlan, 399 }, 400 { 401 .mask = RTE_FLOW_ITEM_TYPE_VXLAN_GPE, 402 .funct = add_vxlan_gpe, 403 }, 404 { 405 .mask = RTE_FLOW_ITEM_TYPE_GRE, 406 .funct = add_gre, 407 }, 408 { 409 .mask = RTE_FLOW_ITEM_TYPE_GENEVE, 410 .funct = add_geneve, 411 }, 412 { 413 .mask = RTE_FLOW_ITEM_TYPE_GTP, 414 .funct = add_gtp, 415 }, 416 { 417 .mask = RTE_FLOW_ITEM_TYPE_ICMP, 418 .funct = add_icmpv4, 419 }, 420 { 421 .mask = RTE_FLOW_ITEM_TYPE_ICMP6, 422 .funct = add_icmpv6, 423 }, 424 }; 425 426 for (j = 0; j < MAX_ITEMS_NUM; j++) { 427 if (flow_items[j] == 0) 428 break; 429 for (i = 0; i < RTE_DIM(items_list); i++) { 430 if ((flow_items[j] & 431 FLOW_ITEM_MASK(items_list[i].mask)) == 0) 432 continue; 433 items_list[i].funct( 434 items, items_counter++, 435 additional_para_data 436 ); 437 break; 438 } 439 } 440 441 items[items_counter].type = RTE_FLOW_ITEM_TYPE_END; 442 } 443