Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/7334/?format=api
https://patches.dpdk.org/api/patches/7334/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/patch/1443635148-31533-1-git-send-email-jasvinder.singh@intel.com/", "project": { "id": 1, "url": "https://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<1443635148-31533-1-git-send-email-jasvinder.singh@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/1443635148-31533-1-git-send-email-jasvinder.singh@intel.com", "date": "2015-09-30T17:45:48", "name": "[dpdk-dev] ip_pipeline: add flow id parameter to flow classification", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "41bab33f1abeca347842032b20239e5122eca3f4", "submitter": { "id": 285, "url": "https://patches.dpdk.org/api/people/285/?format=api", "name": "Jasvinder Singh", "email": "jasvinder.singh@intel.com" }, "delegate": null, "mbox": "https://patches.dpdk.org/project/dpdk/patch/1443635148-31533-1-git-send-email-jasvinder.singh@intel.com/mbox/", "series": [], "comments": "https://patches.dpdk.org/api/patches/7334/comments/", "check": "pending", "checks": "https://patches.dpdk.org/api/patches/7334/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@dpdk.org", "Delivered-To": "patchwork@dpdk.org", "Received": [ "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id E40068DAA;\n\tWed, 30 Sep 2015 19:46:17 +0200 (CEST)", "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id B2EDF8D90\n\tfor <dev@dpdk.org>; Wed, 30 Sep 2015 19:46:16 +0200 (CEST)", "from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby fmsmga102.fm.intel.com with ESMTP; 30 Sep 2015 10:45:50 -0700", "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby fmsmga002.fm.intel.com with ESMTP; 30 Sep 2015 10:45:49 -0700", "from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com\n\t[10.237.217.46])\n\tby irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id\n\tt8UHjmn8009995; Wed, 30 Sep 2015 18:45:48 +0100", "from sivswdev02.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev02.ir.intel.com with ESMTP id t8UHjmkI031570;\n\tWed, 30 Sep 2015 18:45:48 +0100", "(from jasvinde@localhost)\n\tby sivswdev02.ir.intel.com with id t8UHjmeO031566;\n\tWed, 30 Sep 2015 18:45:48 +0100" ], "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.17,613,1437462000\"; d=\"scan'208\";a=\"816416725\"", "From": "Jasvinder Singh <jasvinder.singh@intel.com>", "To": "dev@dpdk.org", "Date": "Wed, 30 Sep 2015 18:45:48 +0100", "Message-Id": "<1443635148-31533-1-git-send-email-jasvinder.singh@intel.com>", "X-Mailer": "git-send-email 1.7.4.1", "Subject": "[dpdk-dev] [PATCH] ip_pipeline: add flow id parameter to flow\n\tclassification", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "patches and discussions about DPDK <dev.dpdk.org>", "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://dpdk.org/ml/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "This patch adds flow id field to the flow\nclassification table entries and adds table action\nhandlers to read flow id from table entry and\nwrite it into the packet meta-data. The flow_id\n(32-bit) parameter is also added to CLI commands\nflow add, flow delete, etc.\n\nSigned-off-by: Jasvinder Singh <jasvinder.singh@intel.com>\n---\n .../pipeline/pipeline_flow_classification.c | 206 ++++++++++++++++++---\n .../pipeline/pipeline_flow_classification.h | 4 +-\n .../pipeline/pipeline_flow_classification_be.c | 114 +++++++++++-\n .../pipeline/pipeline_flow_classification_be.h | 2 +\n 4 files changed, 295 insertions(+), 31 deletions(-)", "diff": "diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c\nindex 4b82180..04b6915 100644\n--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c\n+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c\n@@ -152,6 +152,7 @@ app_pipeline_fc_key_convert(struct pipeline_fc_key *key_in,\n struct app_pipeline_fc_flow {\n \tstruct pipeline_fc_key key;\n \tuint32_t port_id;\n+\tuint32_t flow_id;\n \tuint32_t signature;\n \tvoid *entry_ptr;\n \n@@ -280,7 +281,8 @@ int\n app_pipeline_fc_add(struct app_params *app,\n \tuint32_t pipeline_id,\n \tstruct pipeline_fc_key *key,\n-\tuint32_t port_id)\n+\tuint32_t port_id,\n+\tuint32_t flow_id)\n {\n \tstruct app_pipeline_fc *p;\n \tstruct app_pipeline_fc_flow *flow;\n@@ -325,6 +327,7 @@ app_pipeline_fc_add(struct app_params *app,\n \treq->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD;\n \tapp_pipeline_fc_key_convert(key, req->key, &signature);\n \treq->port_id = port_id;\n+\treq->flow_id = flow_id;\n \n \t/* Send request and wait for response */\n \trsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);\n@@ -348,6 +351,7 @@ app_pipeline_fc_add(struct app_params *app,\n \tmemset(&flow->key, 0, sizeof(flow->key));\n \tmemcpy(&flow->key, key, sizeof(flow->key));\n \tflow->port_id = port_id;\n+\tflow->flow_id = flow_id;\n \tflow->signature = signature;\n \tflow->entry_ptr = rsp->entry_ptr;\n \n@@ -370,6 +374,7 @@ app_pipeline_fc_add_bulk(struct app_params *app,\n \tuint32_t pipeline_id,\n \tstruct pipeline_fc_key *key,\n \tuint32_t *port_id,\n+\tuint32_t *flow_id,\n \tuint32_t n_keys)\n {\n \tstruct app_pipeline_fc *p;\n@@ -389,6 +394,7 @@ app_pipeline_fc_add_bulk(struct app_params *app,\n \tif ((app == NULL) ||\n \t\t(key == NULL) ||\n \t\t(port_id == NULL) ||\n+\t\t(flow_id == NULL) ||\n \t\t(n_keys == 0))\n \t\treturn -1;\n \n@@ -496,6 +502,7 @@ app_pipeline_fc_add_bulk(struct app_params *app,\n \t\t\tflow_req[i].key,\n \t\t\t&signature[i]);\n \t\tflow_req[i].port_id = port_id[i];\n+\t\tflow_req[i].flow_id = flow_id[i];\n \t}\n \n \treq->type = PIPELINE_MSG_REQ_CUSTOM;\n@@ -535,6 +542,7 @@ app_pipeline_fc_add_bulk(struct app_params *app,\n \tfor (i = 0; i < rsp->n_keys; i++) {\n \t\tmemcpy(&flow[i]->key, &key[i], sizeof(flow[i]->key));\n \t\tflow[i]->port_id = port_id[i];\n+\t\tflow[i]->flow_id = flow_id[i];\n \t\tflow[i]->signature = signature[i];\n \t\tflow[i]->entry_ptr = flow_rsp[i].entry_ptr;\n \n@@ -731,13 +739,15 @@ print_fc_qinq_flow(struct app_pipeline_fc_flow *flow)\n {\n \tprintf(\"(SVLAN = %\" PRIu32 \", \"\n \t\t\"CVLAN = %\" PRIu32 \") => \"\n-\t\t\"Port = %\" PRIu32 \" \"\n+\t\t\"Port = %\" PRIu32 \", \"\n+\t\t\"Flow ID = %\" PRIu32 \", \"\n \t\t\"(signature = 0x%08\" PRIx32 \", \"\n \t\t\"entry_ptr = %p)\\n\",\n \n \t\tflow->key.key.qinq.svlan,\n \t\tflow->key.key.qinq.cvlan,\n \t\tflow->port_id,\n+\t\tflow->flow_id,\n \t\tflow->signature,\n \t\tflow->entry_ptr);\n }\n@@ -750,7 +760,8 @@ print_fc_ipv4_5tuple_flow(struct app_pipeline_fc_flow *flow)\n \t\t \"SP = %\" PRIu32 \", \"\n \t\t \"DP = %\" PRIu32 \", \"\n \t\t \"Proto = %\" PRIu32 \") => \"\n-\t\t \"Port = %\" PRIu32 \" \"\n+\t\t \"Port = %\" PRIu32 \", \"\n+\t\t \"Flow ID = %\" PRIu32 \" \"\n \t\t \"(signature = 0x%08\" PRIx32 \", \"\n \t\t \"entry_ptr = %p)\\n\",\n \n@@ -770,6 +781,7 @@ print_fc_ipv4_5tuple_flow(struct app_pipeline_fc_flow *flow)\n \t\t flow->key.key.ipv4_5tuple.proto,\n \n \t\t flow->port_id,\n+\t\t flow->flow_id,\n \t\t flow->signature,\n \t\t flow->entry_ptr);\n }\n@@ -787,7 +799,8 @@ print_fc_ipv6_5tuple_flow(struct app_pipeline_fc_flow *flow) {\n \t\t\"SP = %\" PRIu32 \", \"\n \t\t\"DP = %\" PRIu32 \" \"\n \t\t\"Proto = %\" PRIu32 \" \"\n-\t\t\"=> Port = %\" PRIu32 \" \"\n+\t\t\"=> Port = %\" PRIu32 \", \"\n+\t\t\"Flow ID = %\" PRIu32 \" \"\n \t\t\"(signature = 0x%08\" PRIx32 \", \"\n \t\t\"entry_ptr = %p)\\n\",\n \n@@ -831,6 +844,7 @@ print_fc_ipv6_5tuple_flow(struct app_pipeline_fc_flow *flow) {\n \t\tflow->key.key.ipv6_5tuple.proto,\n \n \t\tflow->port_id,\n+\t\tflow->flow_id,\n \t\tflow->signature,\n \t\tflow->entry_ptr);\n }\n@@ -895,7 +909,10 @@ struct cmd_fc_add_qinq_result {\n \tcmdline_fixed_string_t qinq_string;\n \tuint16_t svlan;\n \tuint16_t cvlan;\n+\tcmdline_fixed_string_t port_string;\n \tuint32_t port;\n+\tcmdline_fixed_string_t flowid_string;\n+\tuint32_t flow_id;\n };\n \n static void\n@@ -917,7 +934,8 @@ cmd_fc_add_qinq_parsed(\n \tstatus = app_pipeline_fc_add(app,\n \t\tparams->pipeline_id,\n \t\t&key,\n-\t\tparams->port);\n+\t\tparams->port,\n+\t\tparams->flow_id);\n \tif (status != 0)\n \t\tprintf(\"Command failed\\n\");\n }\n@@ -947,9 +965,20 @@ cmdline_parse_token_num_t cmd_fc_add_qinq_svlan =\n cmdline_parse_token_num_t cmd_fc_add_qinq_cvlan =\n \tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, cvlan, UINT16);\n \n+cmdline_parse_token_string_t cmd_fc_add_qinq_port_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, port_string,\n+\t\t\"port\");\n+\n cmdline_parse_token_num_t cmd_fc_add_qinq_port =\n \tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, port, UINT32);\n \n+cmdline_parse_token_string_t cmd_fc_add_qinq_flowid_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, flowid_string,\n+\t\t\"flowid\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_qinq_flow_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, flow_id, UINT32);\n+\n cmdline_parse_inst_t cmd_fc_add_qinq = {\n \t.f = cmd_fc_add_qinq_parsed,\n \t.data = NULL,\n@@ -962,7 +991,10 @@ cmdline_parse_inst_t cmd_fc_add_qinq = {\n \t\t(void *) &cmd_fc_add_qinq_qinq_string,\n \t\t(void *) &cmd_fc_add_qinq_svlan,\n \t\t(void *) &cmd_fc_add_qinq_cvlan,\n+\t\t(void *) &cmd_fc_add_qinq_port_string,\n \t\t(void *) &cmd_fc_add_qinq_port,\n+\t\t(void *) &cmd_fc_add_qinq_flowid_string,\n+\t\t(void *) &cmd_fc_add_qinq_flow_id,\n \t\tNULL,\n \t},\n };\n@@ -996,8 +1028,21 @@ cmd_fc_add_qinq_all_parsed(\n \tstruct app_params *app = data;\n \tstruct pipeline_fc_key *key;\n \tuint32_t *port_id;\n-\tuint32_t flow_id;\n+\tuint32_t *flow_id;\n+\tuint32_t id;\n \n+\t/* Check input arguments */\n+\tif (params->n_flows == 0) {\n+\t\tprintf(\"Invalid number of flows\\n\");\n+\t\treturn;\n+\t}\n+\n+\tif (params->n_ports == 0) {\n+\t\tprintf(\"Invalid number of output ports\\n\");\n+\t\treturn;\n+\t}\n+\n+\t/* Memory allocation */\n \tkey = rte_zmalloc(NULL,\n \t\tN_FLOWS_BULK * sizeof(*key),\n \t\tRTE_CACHE_LINE_SIZE);\n@@ -1015,23 +1060,36 @@ cmd_fc_add_qinq_all_parsed(\n \t\treturn;\n \t}\n \n-\tfor (flow_id = 0; flow_id < params->n_flows; flow_id++) {\n-\t\tuint32_t pos = flow_id & (N_FLOWS_BULK - 1);\n+\tflow_id = rte_malloc(NULL,\n+\t\tN_FLOWS_BULK * sizeof(*flow_id),\n+\t\tRTE_CACHE_LINE_SIZE);\n+\tif (flow_id == NULL) {\n+\t\trte_free(port_id);\n+\t\trte_free(key);\n+\t\tprintf(\"Memory allocation failed\\n\");\n+\t\treturn;\n+\t}\n+\n+\t/* Flow add */\n+\tfor (id = 0; id < params->n_flows; id++) {\n+\t\tuint32_t pos = id & (N_FLOWS_BULK - 1);\n \n \t\tkey[pos].type = FLOW_KEY_QINQ;\n-\t\tkey[pos].key.qinq.svlan = flow_id >> 12;\n-\t\tkey[pos].key.qinq.cvlan = flow_id & 0xFFF;\n+\t\tkey[pos].key.qinq.svlan = id >> 12;\n+\t\tkey[pos].key.qinq.cvlan = id & 0xFFF;\n \n-\t\tport_id[pos] = flow_id % params->n_ports;\n+\t\tport_id[pos] = id % params->n_ports;\n+\t\tflow_id[pos] = id;\n \n \t\tif ((pos == N_FLOWS_BULK - 1) ||\n-\t\t\t(flow_id == params->n_flows - 1)) {\n+\t\t\t(id == params->n_flows - 1)) {\n \t\t\tint status;\n \n \t\t\tstatus = app_pipeline_fc_add_bulk(app,\n \t\t\t\tparams->pipeline_id,\n \t\t\t\tkey,\n \t\t\t\tport_id,\n+\t\t\t\tflow_id,\n \t\t\t\tpos + 1);\n \n \t\t\tif (status != 0) {\n@@ -1042,6 +1100,8 @@ cmd_fc_add_qinq_all_parsed(\n \t\t}\n \t}\n \n+\t/* Memory free */\n+\trte_free(flow_id);\n \trte_free(port_id);\n \trte_free(key);\n }\n@@ -1110,7 +1170,10 @@ struct cmd_fc_add_ipv4_5tuple_result {\n \tuint16_t port_src;\n \tuint16_t port_dst;\n \tuint32_t proto;\n+\tcmdline_fixed_string_t port_string;\n \tuint32_t port;\n+\tcmdline_fixed_string_t flowid_string;\n+\tuint32_t flow_id;\n };\n \n static void\n@@ -1137,7 +1200,8 @@ cmd_fc_add_ipv4_5tuple_parsed(\n \tstatus = app_pipeline_fc_add(app,\n \t\tparams->pipeline_id,\n \t\t&key,\n-\t\tparams->port);\n+\t\tparams->port,\n+\t\tparams->flow_id);\n \tif (status != 0)\n \t\tprintf(\"Command failed\\n\");\n }\n@@ -1180,10 +1244,22 @@ cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_proto =\n \tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, proto,\n \t\tUINT32);\n \n+cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_port_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port_string,\n+\t\t\"port\");\n+\n cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_port =\n \tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port,\n \t\tUINT32);\n \n+cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_flowid_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result,\n+\t\tflowid_string, \"flowid\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_flow_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, flow_id,\n+\t\tUINT32);\n+\n cmdline_parse_inst_t cmd_fc_add_ipv4_5tuple = {\n \t.f = cmd_fc_add_ipv4_5tuple_parsed,\n \t.data = NULL,\n@@ -1199,7 +1275,10 @@ cmdline_parse_inst_t cmd_fc_add_ipv4_5tuple = {\n \t\t(void *) &cmd_fc_add_ipv4_5tuple_port_src,\n \t\t(void *) &cmd_fc_add_ipv4_5tuple_port_dst,\n \t\t(void *) &cmd_fc_add_ipv4_5tuple_proto,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_port_string,\n \t\t(void *) &cmd_fc_add_ipv4_5tuple_port,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_flowid_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_flow_id,\n \t\tNULL,\n \t},\n };\n@@ -1229,8 +1308,21 @@ cmd_fc_add_ipv4_5tuple_all_parsed(\n \tstruct app_params *app = data;\n \tstruct pipeline_fc_key *key;\n \tuint32_t *port_id;\n-\tuint32_t flow_id;\n+\tuint32_t *flow_id;\n+\tuint32_t id;\n+\n+\t/* Check input parameters */\n+\tif (params->n_flows == 0) {\n+\t\tprintf(\"Invalid number of flows\\n\");\n+\t\treturn;\n+\t}\n \n+\tif (params->n_ports == 0) {\n+\t\tprintf(\"Invalid number of ports\\n\");\n+\t\treturn;\n+\t}\n+\n+\t/* Memory allocation */\n \tkey = rte_zmalloc(NULL,\n \t\tN_FLOWS_BULK * sizeof(*key),\n \t\tRTE_CACHE_LINE_SIZE);\n@@ -1248,26 +1340,39 @@ cmd_fc_add_ipv4_5tuple_all_parsed(\n \t\treturn;\n \t}\n \n-\tfor (flow_id = 0; flow_id < params->n_flows; flow_id++) {\n-\t\tuint32_t pos = flow_id & (N_FLOWS_BULK - 1);\n+\tflow_id = rte_malloc(NULL,\n+\t\tN_FLOWS_BULK * sizeof(*flow_id),\n+\t\tRTE_CACHE_LINE_SIZE);\n+\tif (flow_id == NULL) {\n+\t\trte_free(port_id);\n+\t\trte_free(key);\n+\t\tprintf(\"Memory allocation failed\\n\");\n+\t\treturn;\n+\t}\n+\n+\t/* Flow add */\n+\tfor (id = 0; id < params->n_flows; id++) {\n+\t\tuint32_t pos = id & (N_FLOWS_BULK - 1);\n \n \t\tkey[pos].type = FLOW_KEY_IPV4_5TUPLE;\n \t\tkey[pos].key.ipv4_5tuple.ip_src = 0;\n-\t\tkey[pos].key.ipv4_5tuple.ip_dst = flow_id;\n+\t\tkey[pos].key.ipv4_5tuple.ip_dst = id;\n \t\tkey[pos].key.ipv4_5tuple.port_src = 0;\n \t\tkey[pos].key.ipv4_5tuple.port_dst = 0;\n \t\tkey[pos].key.ipv4_5tuple.proto = 6;\n \n-\t\tport_id[pos] = flow_id % params->n_ports;\n+\t\tport_id[pos] = id % params->n_ports;\n+\t\tflow_id[pos] = id;\n \n \t\tif ((pos == N_FLOWS_BULK - 1) ||\n-\t\t\t(flow_id == params->n_flows - 1)) {\n+\t\t\t(id == params->n_flows - 1)) {\n \t\t\tint status;\n \n \t\t\tstatus = app_pipeline_fc_add_bulk(app,\n \t\t\t\tparams->pipeline_id,\n \t\t\t\tkey,\n \t\t\t\tport_id,\n+\t\t\t\tflow_id,\n \t\t\t\tpos + 1);\n \n \t\t\tif (status != 0) {\n@@ -1278,6 +1383,8 @@ cmd_fc_add_ipv4_5tuple_all_parsed(\n \t\t}\n \t}\n \n+\t/* Memory free */\n+\trte_free(flow_id);\n \trte_free(port_id);\n \trte_free(key);\n }\n@@ -1346,7 +1453,10 @@ struct cmd_fc_add_ipv6_5tuple_result {\n \tuint16_t port_src;\n \tuint16_t port_dst;\n \tuint32_t proto;\n+\tcmdline_fixed_string_t port_string;\n \tuint32_t port;\n+\tcmdline_fixed_string_t flowid_string;\n+\tuint32_t flow_id;\n };\n \n static void\n@@ -1375,7 +1485,8 @@ cmd_fc_add_ipv6_5tuple_parsed(\n \tstatus = app_pipeline_fc_add(app,\n \t\tparams->pipeline_id,\n \t\t&key,\n-\t\tparams->port);\n+\t\tparams->port,\n+\t\tparams->flow_id);\n \tif (status != 0)\n \t\tprintf(\"Command failed\\n\");\n }\n@@ -1418,10 +1529,22 @@ cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_proto =\n \tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, proto,\n \t\tUINT32);\n \n+cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_port_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result,\n+\t\tport_string, \"port\");\n+\n cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_port =\n \tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, port,\n \t\tUINT32);\n \n+cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_flowid_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result,\n+\t\tflowid_string, \"flowid\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_flow_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, flow_id,\n+\t\tUINT32);\n+\n cmdline_parse_inst_t cmd_fc_add_ipv6_5tuple = {\n \t.f = cmd_fc_add_ipv6_5tuple_parsed,\n \t.data = NULL,\n@@ -1437,7 +1560,10 @@ cmdline_parse_inst_t cmd_fc_add_ipv6_5tuple = {\n \t\t(void *) &cmd_fc_add_ipv6_5tuple_port_src,\n \t\t(void *) &cmd_fc_add_ipv6_5tuple_port_dst,\n \t\t(void *) &cmd_fc_add_ipv6_5tuple_proto,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_port_string,\n \t\t(void *) &cmd_fc_add_ipv6_5tuple_port,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_flowid_string,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_flow_id,\n \t\tNULL,\n \t},\n };\n@@ -1467,8 +1593,21 @@ cmd_fc_add_ipv6_5tuple_all_parsed(\n \tstruct app_params *app = data;\n \tstruct pipeline_fc_key *key;\n \tuint32_t *port_id;\n-\tuint32_t flow_id;\n+\tuint32_t *flow_id;\n+\tuint32_t id;\n+\n+\t/* Check input parameters */\n+\tif (params->n_flows == 0) {\n+\t\tprintf(\"Invalid number of flows\\n\");\n+\t\treturn;\n+\t}\n+\n+\tif (params->n_ports == 0) {\n+\t\tprintf(\"Invalid number of ports\\n\");\n+\t\treturn;\n+\t}\n \n+\t/* Memory allocation */\n \tkey = rte_zmalloc(NULL,\n \t\tN_FLOWS_BULK * sizeof(*key),\n \t\tRTE_CACHE_LINE_SIZE);\n@@ -1486,25 +1625,38 @@ cmd_fc_add_ipv6_5tuple_all_parsed(\n \t\treturn;\n \t}\n \n-\tfor (flow_id = 0; flow_id < params->n_flows; flow_id++) {\n-\t\tuint32_t pos = flow_id & (N_FLOWS_BULK - 1);\n+\tflow_id = rte_malloc(NULL,\n+\t\tN_FLOWS_BULK * sizeof(*flow_id),\n+\t\tRTE_CACHE_LINE_SIZE);\n+\tif (flow_id == NULL) {\n+\t\trte_free(port_id);\n+\t\trte_free(key);\n+\t\tprintf(\"Memory allocation failed\\n\");\n+\t\treturn;\n+\t}\n+\n+\t/* Flow add */\n+\tfor (id = 0; id < params->n_flows; id++) {\n+\t\tuint32_t pos = id & (N_FLOWS_BULK - 1);\n \t\tuint32_t *x;\n \n \t\tkey[pos].type = FLOW_KEY_IPV6_5TUPLE;\n \t\tx = (uint32_t *) key[pos].key.ipv6_5tuple.ip_dst;\n-\t\t*x = rte_bswap32(flow_id);\n+\t\t*x = rte_bswap32(id);\n \t\tkey[pos].key.ipv6_5tuple.proto = 6;\n \n-\t\tport_id[pos] = flow_id % params->n_ports;\n+\t\tport_id[pos] = id % params->n_ports;\n+\t\tflow_id[pos] = id;\n \n \t\tif ((pos == N_FLOWS_BULK - 1) ||\n-\t\t\t(flow_id == params->n_flows - 1)) {\n+\t\t\t(id == params->n_flows - 1)) {\n \t\t\tint status;\n \n \t\t\tstatus = app_pipeline_fc_add_bulk(app,\n \t\t\t\tparams->pipeline_id,\n \t\t\t\tkey,\n \t\t\t\tport_id,\n+\t\t\t\tflow_id,\n \t\t\t\tpos + 1);\n \n \t\t\tif (status != 0) {\n@@ -1515,6 +1667,8 @@ cmd_fc_add_ipv6_5tuple_all_parsed(\n \t\t}\n \t}\n \n+\t/* Memory free */\n+\trte_free(flow_id);\n \trte_free(port_id);\n \trte_free(key);\n }\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.h b/examples/ip_pipeline/pipeline/pipeline_flow_classification.h\nindex 7529314..9c77500 100644\n--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification.h\n+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification.h\n@@ -77,13 +77,15 @@ int\n app_pipeline_fc_add(struct app_params *app,\n \tuint32_t pipeline_id,\n \tstruct pipeline_fc_key *key,\n-\tuint32_t port_id);\n+\tuint32_t port_id,\n+\tuint32_t flow_id);\n \n int\n app_pipeline_fc_add_bulk(struct app_params *app,\n \tuint32_t pipeline_id,\n \tstruct pipeline_fc_key *key,\n \tuint32_t *port_id,\n+\tuint32_t *flow_id,\n \tuint32_t n_keys);\n \n int\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c\nindex 06a648d..eb39a66 100644\n--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c\n+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c\n@@ -39,6 +39,7 @@\n #include <rte_byteorder.h>\n \n #include \"pipeline_flow_classification_be.h\"\n+#include \"pipeline_actions_common.h\"\n #include \"hash_func.h\"\n \n struct pipeline_flow_classification {\n@@ -46,9 +47,13 @@ struct pipeline_flow_classification {\n \tpipeline_msg_req_handler custom_handlers[PIPELINE_FC_MSG_REQS];\n \n \tuint32_t n_flows;\n-\tuint32_t key_offset;\n \tuint32_t key_size;\n+\tuint32_t flow_id;\n+\n+\tuint32_t key_offset;\n \tuint32_t hash_offset;\n+\tuint32_t flow_id_offset;\n+\n } __rte_cache_aligned;\n \n static void *\n@@ -104,6 +109,8 @@ static pipeline_msg_req_handler custom_handlers[] = {\n */\n struct flow_table_entry {\n \tstruct rte_pipeline_table_entry head;\n+\n+\tuint32_t flow_id;\n };\n \n rte_table_hash_op_hash hash_func[] = {\n@@ -117,6 +124,86 @@ rte_table_hash_op_hash hash_func[] = {\n \thash_default_key64\n };\n \n+/*\n+ * Flow table AH - Write flow_id to packet meta-data\n+ */\n+static inline void\n+pkt_work_flow_id(\n+\tstruct rte_mbuf *pkt,\n+\tstruct rte_pipeline_table_entry *table_entry,\n+\tvoid *arg)\n+{\n+\tstruct pipeline_flow_classification *p_fc = arg;\n+\tuint32_t *flow_id_ptr =\n+\t\tRTE_MBUF_METADATA_UINT32_PTR(pkt, p_fc->flow_id_offset);\n+\tstruct flow_table_entry *entry =\n+\t\t(struct flow_table_entry *) table_entry;\n+\n+\t/* Read */\n+\tuint32_t flow_id = entry->flow_id;\n+\n+\t/* Compute */\n+\n+\t/* Write */\n+\t*flow_id_ptr = flow_id;\n+}\n+\n+static inline void\n+pkt4_work_flow_id(\n+\tstruct rte_mbuf **pkts,\n+\tstruct rte_pipeline_table_entry **table_entries,\n+\tvoid *arg)\n+{\n+\tstruct pipeline_flow_classification *p_fc = arg;\n+\n+\tuint32_t *flow_id_ptr0 =\n+\t\tRTE_MBUF_METADATA_UINT32_PTR(pkts[0], p_fc->flow_id_offset);\n+\tuint32_t *flow_id_ptr1 =\n+\t\tRTE_MBUF_METADATA_UINT32_PTR(pkts[1], p_fc->flow_id_offset);\n+\tuint32_t *flow_id_ptr2 =\n+\t\tRTE_MBUF_METADATA_UINT32_PTR(pkts[2], p_fc->flow_id_offset);\n+\tuint32_t *flow_id_ptr3 =\n+\t\tRTE_MBUF_METADATA_UINT32_PTR(pkts[3], p_fc->flow_id_offset);\n+\n+\tstruct flow_table_entry *entry0 =\n+\t\t(struct flow_table_entry *) table_entries[0];\n+\tstruct flow_table_entry *entry1 =\n+\t\t(struct flow_table_entry *) table_entries[1];\n+\tstruct flow_table_entry *entry2 =\n+\t\t(struct flow_table_entry *) table_entries[2];\n+\tstruct flow_table_entry *entry3 =\n+\t\t(struct flow_table_entry *) table_entries[3];\n+\n+\t/* Read */\n+\tuint32_t flow_id0 = entry0->flow_id;\n+\tuint32_t flow_id1 = entry1->flow_id;\n+\tuint32_t flow_id2 = entry2->flow_id;\n+\tuint32_t flow_id3 = entry3->flow_id;\n+\n+\t/* Compute */\n+\n+\t/* Write */\n+\t*flow_id_ptr0 = flow_id0;\n+\t*flow_id_ptr1 = flow_id1;\n+\t*flow_id_ptr2 = flow_id2;\n+\t*flow_id_ptr3 = flow_id3;\n+}\n+\n+PIPELINE_TABLE_AH_HIT(fc_table_ah_hit,\n+\t\tpkt_work_flow_id, pkt4_work_flow_id);\n+\n+static rte_pipeline_table_action_handler_hit\n+get_fc_table_ah_hit(struct pipeline_flow_classification *p)\n+{\n+\tif (p->flow_id)\n+\t\treturn fc_table_ah_hit;\n+\n+\treturn NULL;\n+}\n+\n+/*\n+ * Argument parsing\n+ */\n static int\n pipeline_fc_parse_args(struct pipeline_flow_classification *p,\n \tstruct pipeline_params *params)\n@@ -125,9 +212,12 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,\n \tuint32_t key_offset_present = 0;\n \tuint32_t key_size_present = 0;\n \tuint32_t hash_offset_present = 0;\n-\n+\tuint32_t flow_id_offset_present = 0;\n \tuint32_t i;\n \n+\t/* default values */\n+\tp->flow_id = 0;\n+\n \tfor (i = 0; i < params->n_args; i++) {\n \t\tchar *arg_name = params->args_name[i];\n \t\tchar *arg_value = params->args_value[i];\n@@ -182,6 +272,18 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,\n \t\t\tcontinue;\n \t\t}\n \n+\t\t/* flow_id_offset */\n+\t\tif (strcmp(arg_name, \"flowid_offset\") == 0) {\n+\t\t\tif (flow_id_offset_present)\n+\t\t\t\treturn -1;\n+\t\t\tflow_id_offset_present = 1;\n+\n+\t\t\tp->flow_id = 1;\n+\t\t\tp->flow_id_offset = atoi(arg_value);\n+\n+\t\t\tcontinue;\n+\t\t}\n+\n \t\t/* Unknown argument */\n \t\treturn -1;\n \t}\n@@ -325,9 +427,9 @@ static void *pipeline_fc_init(struct pipeline_params *params,\n \t\tstruct rte_pipeline_table_params table_params = {\n \t\t\t.ops = NULL, /* set below */\n \t\t\t.arg_create = NULL, /* set below */\n-\t\t\t.f_action_hit = NULL,\n+\t\t\t.f_action_hit = get_fc_table_ah_hit(p_fc),\n \t\t\t.f_action_miss = NULL,\n-\t\t\t.arg_ah = NULL,\n+\t\t\t.arg_ah = p_fc,\n \t\t\t.action_data_size = sizeof(struct flow_table_entry) -\n \t\t\t\tsizeof(struct rte_pipeline_table_entry),\n \t\t};\n@@ -485,6 +587,7 @@ pipeline_fc_msg_req_add_handler(struct pipeline *p, void *msg)\n \t\t\t.action = RTE_PIPELINE_ACTION_PORT,\n \t\t\t{.port_id = p->port_out_id[req->port_id]},\n \t\t},\n+\t\t.flow_id = req->flow_id,\n \t};\n \n \trsp->status = rte_pipeline_table_entry_add(p->p,\n@@ -513,6 +616,7 @@ pipeline_fc_msg_req_add_bulk_handler(struct pipeline *p, void *msg)\n \t\t\t\t.action = RTE_PIPELINE_ACTION_PORT,\n \t\t\t\t{.port_id = p->port_out_id[flow_req->port_id]},\n \t\t\t},\n+\t\t\t.flow_id = flow_req->flow_id,\n \t\t};\n \n \t\tint status = rte_pipeline_table_entry_add(p->p,\n@@ -558,6 +662,8 @@ pipeline_fc_msg_req_add_default_handler(struct pipeline *p, void *msg)\n \t\t\t.action = RTE_PIPELINE_ACTION_PORT,\n \t\t\t{.port_id = p->port_out_id[req->port_id]},\n \t\t},\n+\n+\t\t.flow_id = 0,\n \t};\n \n \trsp->status = rte_pipeline_table_default_entry_add(p->p,\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.h b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.h\nindex 46403d5..d8129b2 100644\n--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.h\n+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.h\n@@ -59,6 +59,7 @@ struct pipeline_fc_add_msg_req {\n \tuint8_t key[PIPELINE_FC_FLOW_KEY_MAX_SIZE];\n \n \tuint32_t port_id;\n+\tuint32_t flow_id;\n };\n \n struct pipeline_fc_add_msg_rsp {\n@@ -73,6 +74,7 @@ struct pipeline_fc_add_msg_rsp {\n struct pipeline_fc_add_bulk_flow_req {\n \tuint8_t key[PIPELINE_FC_FLOW_KEY_MAX_SIZE];\n \tuint32_t port_id;\n+\tuint32_t flow_id;\n };\n \n struct pipeline_fc_add_bulk_flow_rsp {\n", "prefixes": [ "dpdk-dev" ] }{ "id": 7334, "url": "