X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fip_pipeline%2Fpipeline%2Fpipeline_flow_classification_be.c;h=60e9c39575121d8644f798502133446892324357;hb=88ac2fd99fa06419c5b95ad662dc1e618bd8ac49;hp=e22f96f10a927f2c600cb5920d7d2f5c34e86ef1;hpb=a620df642c914d69d0c65184cc4aa5d26321581c;p=dpdk.git diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c index e22f96f10a..60e9c39575 100644 --- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c +++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +40,8 @@ #include #include "pipeline_flow_classification_be.h" +#include "pipeline_actions_common.h" +#include "parser.h" #include "hash_func.h" struct pipeline_flow_classification { @@ -47,10 +49,14 @@ struct pipeline_flow_classification { pipeline_msg_req_handler custom_handlers[PIPELINE_FC_MSG_REQS]; uint32_t n_flows; - uint32_t key_offset; uint32_t key_size; + uint32_t flow_id; + + uint32_t key_offset; uint32_t hash_offset; - uint8_t *key_mask; + uint8_t key_mask[PIPELINE_FC_FLOW_KEY_MAX_SIZE]; + uint32_t flow_id_offset; + } __rte_cache_aligned; static void * @@ -106,6 +112,9 @@ static pipeline_msg_req_handler custom_handlers[] = { */ struct flow_table_entry { struct rte_pipeline_table_entry head; + + uint32_t flow_id; + uint32_t pad; }; rte_table_hash_op_hash hash_func[] = { @@ -119,6 +128,86 @@ rte_table_hash_op_hash hash_func[] = { hash_default_key64 }; +/* + * Flow table AH - Write flow_id to packet meta-data + */ +static inline void +pkt_work_flow_id( + struct rte_mbuf *pkt, + struct rte_pipeline_table_entry *table_entry, + void *arg) +{ + struct pipeline_flow_classification *p_fc = arg; + uint32_t *flow_id_ptr = + RTE_MBUF_METADATA_UINT32_PTR(pkt, p_fc->flow_id_offset); + struct flow_table_entry *entry = + (struct flow_table_entry *) table_entry; + + /* Read */ + uint32_t flow_id = entry->flow_id; + + /* Compute */ + + /* Write */ + *flow_id_ptr = flow_id; +} + +static inline void +pkt4_work_flow_id( + struct rte_mbuf **pkts, + struct rte_pipeline_table_entry **table_entries, + void *arg) +{ + struct pipeline_flow_classification *p_fc = arg; + + uint32_t *flow_id_ptr0 = + RTE_MBUF_METADATA_UINT32_PTR(pkts[0], p_fc->flow_id_offset); + uint32_t *flow_id_ptr1 = + RTE_MBUF_METADATA_UINT32_PTR(pkts[1], p_fc->flow_id_offset); + uint32_t *flow_id_ptr2 = + RTE_MBUF_METADATA_UINT32_PTR(pkts[2], p_fc->flow_id_offset); + uint32_t *flow_id_ptr3 = + RTE_MBUF_METADATA_UINT32_PTR(pkts[3], p_fc->flow_id_offset); + + struct flow_table_entry *entry0 = + (struct flow_table_entry *) table_entries[0]; + struct flow_table_entry *entry1 = + (struct flow_table_entry *) table_entries[1]; + struct flow_table_entry *entry2 = + (struct flow_table_entry *) table_entries[2]; + struct flow_table_entry *entry3 = + (struct flow_table_entry *) table_entries[3]; + + /* Read */ + uint32_t flow_id0 = entry0->flow_id; + uint32_t flow_id1 = entry1->flow_id; + uint32_t flow_id2 = entry2->flow_id; + uint32_t flow_id3 = entry3->flow_id; + + /* Compute */ + + /* Write */ + *flow_id_ptr0 = flow_id0; + *flow_id_ptr1 = flow_id1; + *flow_id_ptr2 = flow_id2; + *flow_id_ptr3 = flow_id3; +} + +PIPELINE_TABLE_AH_HIT(fc_table_ah_hit, + pkt_work_flow_id, pkt4_work_flow_id); + +static rte_pipeline_table_action_handler_hit +get_fc_table_ah_hit(struct pipeline_flow_classification *p) +{ + if (p->flow_id) + return fc_table_ah_hit; + + return NULL; +} + +/* + * Argument parsing + */ static int pipeline_fc_parse_args(struct pipeline_flow_classification *p, struct pipeline_params *params) @@ -128,102 +217,170 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p, uint32_t key_size_present = 0; uint32_t hash_offset_present = 0; uint32_t key_mask_present = 0; + uint32_t flow_id_offset_present = 0; uint32_t i; - char *key_mask_str = NULL; + char key_mask_str[PIPELINE_FC_FLOW_KEY_MAX_SIZE * 2]; p->hash_offset = 0; + /* default values */ + p->flow_id = 0; + for (i = 0; i < params->n_args; i++) { char *arg_name = params->args_name[i]; char *arg_value = params->args_value[i]; /* n_flows */ if (strcmp(arg_name, "n_flows") == 0) { - if (n_flows_present) - return -1; + int status; + + PIPELINE_PARSE_ERR_DUPLICATE( + n_flows_present == 0, params->name, + arg_name); n_flows_present = 1; - p->n_flows = atoi(arg_value); - if (p->n_flows == 0) - return -1; + status = parser_read_uint32(&p->n_flows, + arg_value); + PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) && + (p->n_flows != 0)), params->name, + arg_name, arg_value); + PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE), + params->name, arg_name, arg_value); continue; } /* key_offset */ if (strcmp(arg_name, "key_offset") == 0) { - if (key_offset_present) - return -1; + int status; + + PIPELINE_PARSE_ERR_DUPLICATE( + key_offset_present == 0, params->name, + arg_name); key_offset_present = 1; - p->key_offset = atoi(arg_value); + status = parser_read_uint32(&p->key_offset, + arg_value); + PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL), + params->name, arg_name, arg_value); + PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE), + params->name, arg_name, arg_value); continue; } /* key_size */ if (strcmp(arg_name, "key_size") == 0) { - if (key_size_present) - return -1; + int status; + + PIPELINE_PARSE_ERR_DUPLICATE( + key_size_present == 0, params->name, + arg_name); key_size_present = 1; - p->key_size = atoi(arg_value); - if ((p->key_size == 0) || - (p->key_size > PIPELINE_FC_FLOW_KEY_MAX_SIZE) || - (p->key_size % 8)) - return -1; + status = parser_read_uint32(&p->key_size, + arg_value); + PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) && + (p->key_size != 0) && + (p->key_size % 8 == 0)), + params->name, arg_name, arg_value); + PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) && + (p->key_size <= + PIPELINE_FC_FLOW_KEY_MAX_SIZE)), + params->name, arg_name, arg_value); continue; } /* key_mask */ if (strcmp(arg_name, "key_mask") == 0) { - if (key_mask_present) - return -1; - - key_mask_str = strdup(arg_value); - if (key_mask_str == NULL) - return -1; + int mask_str_len = strlen(arg_value); + PIPELINE_PARSE_ERR_DUPLICATE( + key_mask_present == 0, + params->name, arg_name); key_mask_present = 1; + PIPELINE_ARG_CHECK((mask_str_len < + (PIPELINE_FC_FLOW_KEY_MAX_SIZE * 2)), + "Parse error in section \"%s\": entry " + "\"%s\" is too long", params->name, + arg_name); + + snprintf(key_mask_str, mask_str_len, "%s", + arg_value); + continue; } /* hash_offset */ if (strcmp(arg_name, "hash_offset") == 0) { - if (hash_offset_present) - return -1; + int status; + + PIPELINE_PARSE_ERR_DUPLICATE( + hash_offset_present == 0, params->name, + arg_name); hash_offset_present = 1; - p->hash_offset = atoi(arg_value); + status = parser_read_uint32(&p->hash_offset, + arg_value); + PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL), + params->name, arg_name, arg_value); + PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE), + params->name, arg_name, arg_value); + + continue; + } + + /* flow_id_offset */ + if (strcmp(arg_name, "flowid_offset") == 0) { + int status; + + PIPELINE_PARSE_ERR_DUPLICATE( + flow_id_offset_present == 0, params->name, + arg_name); + flow_id_offset_present = 1; + + status = parser_read_uint32(&p->flow_id_offset, + arg_value); + PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL), + params->name, arg_name, arg_value); + PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE), + params->name, arg_name, arg_value); + + p->flow_id = 1; continue; } /* Unknown argument */ - return -1; + PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name); } /* Check that mandatory arguments are present */ - if ((n_flows_present == 0) || - (key_offset_present == 0) || - (key_size_present == 0)) - return -1; + PIPELINE_PARSE_ERR_MANDATORY((n_flows_present), params->name, + "n_flows"); + PIPELINE_PARSE_ERR_MANDATORY((key_offset_present), params->name, + "key_offset"); + PIPELINE_PARSE_ERR_MANDATORY((key_size_present), params->name, + "key_size"); if (key_mask_present) { - p->key_mask = rte_malloc(NULL, p->key_size, 0); - if (p->key_mask == NULL) - return -1; - - if (parse_hex_string(key_mask_str, p->key_mask, &p->key_size) - != 0) { - free(p->key_mask); - return -1; - } + uint32_t key_size = p->key_size; + int status; - free(key_mask_str); + PIPELINE_ARG_CHECK((strlen(key_mask_str) == + (key_size * 2)), "Parse error in section " + "\"%s\": key_mask should have exactly %u hex " + "digits", params->name, (key_size * 2)); + + status = parse_hex_string(key_mask_str, p->key_mask, + &p->key_size); + + PIPELINE_PARSE_ERR_INV_VAL(((status == 0) && + (key_size == p->key_size)), params->name, + "key_mask", key_mask_str); } return 0; @@ -305,7 +462,6 @@ static void *pipeline_fc_init(struct pipeline_params *params, .arg_create = pipeline_port_out_params_convert( ¶ms->port_out[i]), .f_action = NULL, - .f_action_bulk = NULL, .arg_ah = NULL, }; @@ -360,9 +516,9 @@ static void *pipeline_fc_init(struct pipeline_params *params, struct rte_pipeline_table_params table_params = { .ops = NULL, /* set below */ .arg_create = NULL, /* set below */ - .f_action_hit = NULL, + .f_action_hit = get_fc_table_ah_hit(p_fc), .f_action_miss = NULL, - .arg_ah = NULL, + .arg_ah = p_fc, .action_data_size = sizeof(struct flow_table_entry) - sizeof(struct rte_pipeline_table_entry), }; @@ -380,7 +536,6 @@ static void *pipeline_fc_init(struct pipeline_params *params, } table_params.arg_create = &table_hash_key8_params; break; - break; case 16: if (p_fc->hash_offset != 0) { @@ -533,6 +688,7 @@ pipeline_fc_msg_req_add_handler(struct pipeline *p, void *msg) .action = RTE_PIPELINE_ACTION_PORT, {.port_id = p->port_out_id[req->port_id]}, }, + .flow_id = req->flow_id, }; rsp->status = rte_pipeline_table_entry_add(p->p, @@ -561,6 +717,7 @@ pipeline_fc_msg_req_add_bulk_handler(struct pipeline *p, void *msg) .action = RTE_PIPELINE_ACTION_PORT, {.port_id = p->port_out_id[flow_req->port_id]}, }, + .flow_id = flow_req->flow_id, }; int status = rte_pipeline_table_entry_add(p->p, @@ -606,6 +763,8 @@ pipeline_fc_msg_req_add_default_handler(struct pipeline *p, void *msg) .action = RTE_PIPELINE_ACTION_PORT, {.port_id = p->port_out_id[req->port_id]}, }, + + .flow_id = 0, }; rsp->status = rte_pipeline_table_default_entry_add(p->p,