From: Peng Zhang <[email protected]> Manage "transfer" flows via the corresponding mechanism. Doing so requires that the traffic source be specified explicitly, via the corresponding pattern item.
Signed-off-by: Peng Zhang <[email protected]> Signed-off-by: Jin Liu <[email protected]> Signed-off-by: Simon Horman <[email protected]> --- lib/netdev-dpdk.c | 60 +++++++++++++++++++++++++++++++++++++++++++++-- lib/netdev-dpdk.h | 2 ++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index fff57f78279a..d6f2f0517da6 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -437,6 +437,7 @@ enum dpdk_hw_ol_features { struct netdev_dpdk { PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0, dpdk_port_t port_id; + dpdk_port_t flow_transfer_proxy_port_id; /* If true, device was attached by rte_eth_dev_attach(). */ bool attached; @@ -1155,6 +1156,24 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) uint32_t rx_chksm_offload_capa = RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM | RTE_ETH_RX_OFFLOAD_IPV4_CKSUM; + int ret; + + /* Managing "transfer" flows requires that the user communicate them + * via a port which has the privilege to control the embedded switch. + * For some vendors, all ports in a given switching domain have + * this privilege. For other vendors, it's only one port. + * + * Get the proxy port ID and remember it for later use. + */ + ret = rte_flow_pick_transfer_proxy(dev->port_id, + &dev->flow_transfer_proxy_port_id, + NULL); + if (ret != 0) { + /* The PMD does not indicate the proxy port. + * Assume the proxy is unneeded. + */ + dev->flow_transfer_proxy_port_id = dev->port_id; + } rte_eth_dev_info_get(dev->port_id, &info); @@ -3769,6 +3788,7 @@ netdev_dpdk_detach(struct unixctl_conn *conn, int argc OVS_UNUSED, struct ds used_interfaces = DS_EMPTY_INITIALIZER; struct rte_eth_dev_info dev_info; dpdk_port_t sibling_port_id; + struct netdev_dpdk *dev; dpdk_port_t port_id; bool used = false; char *response; @@ -3786,8 +3806,6 @@ netdev_dpdk_detach(struct unixctl_conn *conn, int argc OVS_UNUSED, argv[1]); RTE_ETH_FOREACH_DEV_SIBLING (sibling_port_id, port_id) { - struct netdev_dpdk *dev; - LIST_FOR_EACH (dev, list_node, &dpdk_list) { if (dev->port_id != sibling_port_id) { continue; @@ -3807,6 +3825,17 @@ netdev_dpdk_detach(struct unixctl_conn *conn, int argc OVS_UNUSED, } ds_destroy(&used_interfaces); + /* The device being detached may happen to be a flow proxy port + * for another device (still attached). Update the flow proxy port id, + * indicate that the device being detached no longer needs a flow proxy. + */ + LIST_FOR_EACH (dev, list_node, &dpdk_list) { + if (dev->port_id == port_id) { + dev->flow_transfer_proxy_port_id = port_id; + break; + } + } + rte_eth_dev_info_get(port_id, &dev_info); rte_eth_dev_close(port_id); if (rte_dev_remove(dev_info.device) < 0) { @@ -3817,6 +3846,16 @@ netdev_dpdk_detach(struct unixctl_conn *conn, int argc OVS_UNUSED, response = xasprintf("All devices shared with device '%s' " "have been detached", argv[1]); + /* The device being detached may happen to be a flow proxy port. + * After the flow proxy port was detached, the related ports + * will reconfigure the device and update the proxy_port_id. + */ + LIST_FOR_EACH (dev, list_node, &dpdk_list) { + if (dev->flow_transfer_proxy_port_id == port_id) { + netdev_request_reconfigure(&dev->up); + } + } + ovs_mutex_unlock(&dpdk_mutex); unixctl_command_reply(conn, response); free(response); @@ -5192,6 +5231,23 @@ out: return ret; } +int +netdev_dpdk_get_prox_port_id(struct netdev *netdev) +{ + struct netdev_dpdk *dev; + int ret = -1; + + if (!is_dpdk_class(netdev->netdev_class)) { + return ret; + } + + dev = netdev_dpdk_cast(netdev); + ovs_mutex_lock(&dev->mutex); + ret = dev->flow_transfer_proxy_port_id; + ovs_mutex_unlock(&dev->mutex); + return ret; +} + bool netdev_dpdk_flow_api_supported(struct netdev *netdev) { diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h index 5cd95d00f5a5..277db156fe06 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -51,6 +51,8 @@ netdev_dpdk_rte_flow_query_count(struct netdev *netdev, struct rte_flow_error *error); int netdev_dpdk_get_port_id(struct netdev *netdev); +int +netdev_dpdk_get_prox_port_id(struct netdev *netdev); #ifdef ALLOW_EXPERIMENTAL_API -- 2.30.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
