diff options
author | Ilya Maximets <i.maximets@samsung.com> | 2016-05-27 16:32:50 +0300 |
---|---|---|
committer | Daniele Di Proietto <diproiettod@vmware.com> | 2016-06-06 18:10:22 -0700 |
commit | c673049c79aa9b79c4318f5092f373740a81c5be (patch) | |
tree | cf61a413a94db964d1ba83c1b454ebb3a931fa82 /lib | |
parent | f9176a3a7f805b04f721ea9a88a48a5d2b881730 (diff) | |
download | openvswitch-c673049c79aa9b79c4318f5092f373740a81c5be.tar.gz |
dpctl: Implement dpctl/flow-get for dpif-netdev.
Currently 'dpctl/flow-get' doesn't work for flows installed by
PMD threads.
Fix that by implementing search across all PMD threads. Will be returned
flow from first PMD thread with match.
Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
Signed-off-by: Daniele Di Proietto <diproiettod@vmware.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/dpctl.c | 3 | ||||
-rw-r--r-- | lib/dpif-netdev.c | 50 |
2 files changed, 37 insertions, 16 deletions
diff --git a/lib/dpctl.c b/lib/dpctl.c index ffe702e73..b870e30fd 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1089,8 +1089,7 @@ dpctl_get_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p) goto out; } - /* Does not work for DPDK, since do not know which 'pmd' to apply the - * operation. So, just uses PMD_ID_NULL. */ + /* In case of PMD will be returned flow from first PMD thread with match. */ error = dpif_flow_get(dpif, NULL, 0, &ufid, PMD_ID_NULL, &buf, &flow); if (error) { dpctl_error(dpctl_p, error, "getting flow"); diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 119e16916..61a939aca 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2045,26 +2045,48 @@ dpif_netdev_flow_get(const struct dpif *dpif, const struct dpif_flow_get *get) struct dp_netdev *dp = get_dp_netdev(dpif); struct dp_netdev_flow *netdev_flow; struct dp_netdev_pmd_thread *pmd; - unsigned pmd_id = get->pmd_id == PMD_ID_NULL - ? NON_PMD_CORE_ID : get->pmd_id; - int error = 0; + struct hmapx to_find = HMAPX_INITIALIZER(&to_find); + struct hmapx_node *node; + int error = EINVAL; - pmd = dp_netdev_get_pmd(dp, pmd_id); - if (!pmd) { - return EINVAL; + if (get->pmd_id == PMD_ID_NULL) { + CMAP_FOR_EACH (pmd, node, &dp->poll_threads) { + if (dp_netdev_pmd_try_ref(pmd) && !hmapx_add(&to_find, pmd)) { + dp_netdev_pmd_unref(pmd); + } + } + } else { + pmd = dp_netdev_get_pmd(dp, get->pmd_id); + if (!pmd) { + goto out; + } + hmapx_add(&to_find, pmd); } - netdev_flow = dp_netdev_pmd_find_flow(pmd, get->ufid, get->key, - get->key_len); - if (netdev_flow) { - dp_netdev_flow_to_dpif_flow(netdev_flow, get->buffer, get->buffer, - get->flow, false); - } else { - error = ENOENT; + if (!hmapx_count(&to_find)) { + goto out; } - dp_netdev_pmd_unref(pmd); + HMAPX_FOR_EACH (node, &to_find) { + pmd = (struct dp_netdev_pmd_thread *) node->data; + netdev_flow = dp_netdev_pmd_find_flow(pmd, get->ufid, get->key, + get->key_len); + if (netdev_flow) { + dp_netdev_flow_to_dpif_flow(netdev_flow, get->buffer, get->buffer, + get->flow, false); + error = 0; + break; + } else { + error = ENOENT; + } + } + HMAPX_FOR_EACH (node, &to_find) { + pmd = (struct dp_netdev_pmd_thread *) node->data; + dp_netdev_pmd_unref(pmd); + } +out: + hmapx_destroy(&to_find); return error; } |