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