1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2018 Intel Corporation 3 */ 4 5 #include <stdint.h> 6 #include <stdlib.h> 7 #include <string.h> 8 9 #include <rte_string_fns.h> 10 #include <rte_table_hash_func.h> 11 12 #include "action.h" 13 14 /** 15 * Input port 16 */ 17 static struct port_in_action_profile_list port_in_action_profile_list; 18 19 int 20 port_in_action_profile_init(void) 21 { 22 TAILQ_INIT(&port_in_action_profile_list); 23 24 return 0; 25 } 26 27 struct port_in_action_profile * 28 port_in_action_profile_find(const char *name) 29 { 30 struct port_in_action_profile *profile; 31 32 if (name == NULL) 33 return NULL; 34 35 TAILQ_FOREACH(profile, &port_in_action_profile_list, node) 36 if (strcmp(profile->name, name) == 0) 37 return profile; 38 39 return NULL; 40 } 41 42 struct port_in_action_profile * 43 port_in_action_profile_create(const char *name, 44 struct port_in_action_profile_params *params) 45 { 46 struct port_in_action_profile *profile; 47 struct rte_port_in_action_profile *ap; 48 int status; 49 50 /* Check input params */ 51 if ((name == NULL) || 52 port_in_action_profile_find(name) || 53 (params == NULL)) 54 return NULL; 55 56 if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) && 57 (params->lb.f_hash == NULL)) { 58 switch (params->lb.key_size) { 59 case 8: 60 params->lb.f_hash = rte_table_hash_crc_key8; 61 break; 62 63 case 16: 64 params->lb.f_hash = rte_table_hash_crc_key16; 65 break; 66 67 case 24: 68 params->lb.f_hash = rte_table_hash_crc_key24; 69 break; 70 71 case 32: 72 params->lb.f_hash = rte_table_hash_crc_key32; 73 break; 74 75 case 40: 76 params->lb.f_hash = rte_table_hash_crc_key40; 77 break; 78 79 case 48: 80 params->lb.f_hash = rte_table_hash_crc_key48; 81 break; 82 83 case 56: 84 params->lb.f_hash = rte_table_hash_crc_key56; 85 break; 86 87 case 64: 88 params->lb.f_hash = rte_table_hash_crc_key64; 89 break; 90 91 default: 92 return NULL; 93 } 94 95 params->lb.seed = 0; 96 } 97 /* Resource */ 98 ap = rte_port_in_action_profile_create(0); 99 if (ap == NULL) 100 return NULL; 101 102 if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) { 103 status = rte_port_in_action_profile_action_register(ap, 104 RTE_PORT_IN_ACTION_FLTR, 105 ¶ms->fltr); 106 107 if (status) { 108 rte_port_in_action_profile_free(ap); 109 return NULL; 110 } 111 } 112 113 if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) { 114 status = rte_port_in_action_profile_action_register(ap, 115 RTE_PORT_IN_ACTION_LB, 116 ¶ms->lb); 117 118 if (status) { 119 rte_port_in_action_profile_free(ap); 120 return NULL; 121 } 122 } 123 124 status = rte_port_in_action_profile_freeze(ap); 125 if (status) { 126 rte_port_in_action_profile_free(ap); 127 return NULL; 128 } 129 130 /* Node allocation */ 131 profile = calloc(1, sizeof(struct port_in_action_profile)); 132 if (profile == NULL) { 133 rte_port_in_action_profile_free(ap); 134 return NULL; 135 } 136 137 /* Node fill in */ 138 strlcpy(profile->name, name, sizeof(profile->name)); 139 memcpy(&profile->params, params, sizeof(*params)); 140 profile->ap = ap; 141 142 /* Node add to list */ 143 TAILQ_INSERT_TAIL(&port_in_action_profile_list, profile, node); 144 145 return profile; 146 } 147 148 /** 149 * Table 150 */ 151 static struct table_action_profile_list table_action_profile_list; 152 153 int 154 table_action_profile_init(void) 155 { 156 TAILQ_INIT(&table_action_profile_list); 157 158 return 0; 159 } 160 161 struct table_action_profile * 162 table_action_profile_find(const char *name) 163 { 164 struct table_action_profile *profile; 165 166 if (name == NULL) 167 return NULL; 168 169 TAILQ_FOREACH(profile, &table_action_profile_list, node) 170 if (strcmp(profile->name, name) == 0) 171 return profile; 172 173 return NULL; 174 } 175 176 struct table_action_profile * 177 table_action_profile_create(const char *name, 178 struct table_action_profile_params *params) 179 { 180 struct table_action_profile *profile; 181 struct rte_table_action_profile *ap; 182 int status; 183 184 /* Check input params */ 185 if ((name == NULL) || 186 table_action_profile_find(name) || 187 (params == NULL) || 188 ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0)) 189 return NULL; 190 191 if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) && 192 (params->lb.f_hash == NULL)) { 193 switch (params->lb.key_size) { 194 case 8: 195 params->lb.f_hash = rte_table_hash_crc_key8; 196 break; 197 198 case 16: 199 params->lb.f_hash = rte_table_hash_crc_key16; 200 break; 201 202 case 24: 203 params->lb.f_hash = rte_table_hash_crc_key24; 204 break; 205 206 case 32: 207 params->lb.f_hash = rte_table_hash_crc_key32; 208 break; 209 210 case 40: 211 params->lb.f_hash = rte_table_hash_crc_key40; 212 break; 213 214 case 48: 215 params->lb.f_hash = rte_table_hash_crc_key48; 216 break; 217 218 case 56: 219 params->lb.f_hash = rte_table_hash_crc_key56; 220 break; 221 222 case 64: 223 params->lb.f_hash = rte_table_hash_crc_key64; 224 break; 225 226 default: 227 return NULL; 228 } 229 230 params->lb.seed = 0; 231 } 232 233 /* Resource */ 234 ap = rte_table_action_profile_create(¶ms->common); 235 if (ap == NULL) 236 return NULL; 237 238 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) { 239 status = rte_table_action_profile_action_register(ap, 240 RTE_TABLE_ACTION_FWD, 241 NULL); 242 243 if (status) { 244 rte_table_action_profile_free(ap); 245 return NULL; 246 } 247 } 248 249 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) { 250 status = rte_table_action_profile_action_register(ap, 251 RTE_TABLE_ACTION_LB, 252 ¶ms->lb); 253 254 if (status) { 255 rte_table_action_profile_free(ap); 256 return NULL; 257 } 258 } 259 260 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) { 261 status = rte_table_action_profile_action_register(ap, 262 RTE_TABLE_ACTION_MTR, 263 ¶ms->mtr); 264 265 if (status) { 266 rte_table_action_profile_free(ap); 267 return NULL; 268 } 269 } 270 271 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) { 272 status = rte_table_action_profile_action_register(ap, 273 RTE_TABLE_ACTION_TM, 274 ¶ms->tm); 275 276 if (status) { 277 rte_table_action_profile_free(ap); 278 return NULL; 279 } 280 } 281 282 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) { 283 status = rte_table_action_profile_action_register(ap, 284 RTE_TABLE_ACTION_ENCAP, 285 ¶ms->encap); 286 287 if (status) { 288 rte_table_action_profile_free(ap); 289 return NULL; 290 } 291 } 292 293 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) { 294 status = rte_table_action_profile_action_register(ap, 295 RTE_TABLE_ACTION_NAT, 296 ¶ms->nat); 297 298 if (status) { 299 rte_table_action_profile_free(ap); 300 return NULL; 301 } 302 } 303 304 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) { 305 status = rte_table_action_profile_action_register(ap, 306 RTE_TABLE_ACTION_TTL, 307 ¶ms->ttl); 308 309 if (status) { 310 rte_table_action_profile_free(ap); 311 return NULL; 312 } 313 } 314 315 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) { 316 status = rte_table_action_profile_action_register(ap, 317 RTE_TABLE_ACTION_STATS, 318 ¶ms->stats); 319 320 if (status) { 321 rte_table_action_profile_free(ap); 322 return NULL; 323 } 324 } 325 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) { 326 status = rte_table_action_profile_action_register(ap, 327 RTE_TABLE_ACTION_TIME, 328 NULL); 329 330 if (status) { 331 rte_table_action_profile_free(ap); 332 return NULL; 333 } 334 } 335 336 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) { 337 status = rte_table_action_profile_action_register(ap, 338 RTE_TABLE_ACTION_SYM_CRYPTO, 339 ¶ms->sym_crypto); 340 341 if (status) { 342 rte_table_action_profile_free(ap); 343 return NULL; 344 } 345 } 346 347 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) { 348 status = rte_table_action_profile_action_register(ap, 349 RTE_TABLE_ACTION_TAG, 350 NULL); 351 352 if (status) { 353 rte_table_action_profile_free(ap); 354 return NULL; 355 } 356 } 357 358 if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) { 359 status = rte_table_action_profile_action_register(ap, 360 RTE_TABLE_ACTION_DECAP, 361 NULL); 362 363 if (status) { 364 rte_table_action_profile_free(ap); 365 return NULL; 366 } 367 } 368 369 status = rte_table_action_profile_freeze(ap); 370 if (status) { 371 rte_table_action_profile_free(ap); 372 return NULL; 373 } 374 375 /* Node allocation */ 376 profile = calloc(1, sizeof(struct table_action_profile)); 377 if (profile == NULL) { 378 rte_table_action_profile_free(ap); 379 return NULL; 380 } 381 382 /* Node fill in */ 383 strlcpy(profile->name, name, sizeof(profile->name)); 384 memcpy(&profile->params, params, sizeof(*params)); 385 profile->ap = ap; 386 387 /* Node add to list */ 388 TAILQ_INSERT_TAIL(&table_action_profile_list, profile, node); 389 390 return profile; 391 } 392