From patchwork Mon Mar 13 13:36:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roi Dayan X-Patchwork-Id: 738133 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vhf8W168cz9s0Z for ; Tue, 14 Mar 2017 00:38:35 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 2F20BBDA; Mon, 13 Mar 2017 13:37:29 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 81C4FB75 for ; Mon, 13 Mar 2017 13:37:25 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 8C567258 for ; Mon, 13 Mar 2017 13:37:23 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from roid@mellanox.com) with ESMTPS (AES256-SHA encrypted); 13 Mar 2017 15:37:21 +0200 Received: from r-vnc05.mtr.labs.mlnx (r-vnc05.mtr.labs.mlnx [10.208.0.115]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id v2DDbJZE028197; Mon, 13 Mar 2017 15:37:21 +0200 From: Roi Dayan To: dev@openvswitch.org Date: Mon, 13 Mar 2017 15:36:59 +0200 Message-Id: <1489412234-30916-10-git-send-email-roid@mellanox.com> X-Mailer: git-send-email 1.8.4.3 In-Reply-To: <1489412234-30916-1-git-send-email-roid@mellanox.com> References: <1489412234-30916-1-git-send-email-roid@mellanox.com> X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Shahar Klein , Hadar Hen Zion , Rony Efraim , Jiri Pirko , Marcelo Ricardo Leitner , Simon Horman , Or Gerlitz , Andy Gospodarek Subject: [ovs-dev] [PATCH ovs V4 09/24] netdev-tc-offloads: Add ufid to tc/netdev map X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Paul Blakey Flows offloaded to tc are identified by priority and handle pair while OVS flows are identified by ufid. Added a hash map to convert between the two for later retrieval and deleting of offloaded flows. Signed-off-by: Paul Blakey Reviewed-by: Roi Dayan --- lib/netdev-tc-offloads.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 144 insertions(+), 0 deletions(-) diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c index 2ea7fe3..bdde965 100644 --- a/lib/netdev-tc-offloads.c +++ b/lib/netdev-tc-offloads.c @@ -77,6 +77,150 @@ VLOG_DEFINE_THIS_MODULE(netdev_tc_offloads); static struct vlog_rate_limit rl_err = VLOG_RATE_LIMIT_INIT(9999, 5); +static struct hmap ufid_to_tc = HMAP_INITIALIZER(&ufid_to_tc); +static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid); +static struct ovs_mutex ufid_lock = OVS_MUTEX_INITIALIZER; + +struct ufid_to_tc_data { + struct hmap_node node; + ovs_u128 ufid; + uint16_t prio; + uint32_t handle; + int ifindex; + struct netdev *netdev; +}; + +/* Remove ufid from ufid_to_tc and matching entry from tc_to_ufid hashmap. */ +static void +del_ufid_tc_mapping(const ovs_u128 *ufid) +{ + size_t hash = hash_bytes(ufid, sizeof *ufid, 0); + struct ufid_to_tc_data *data; + uint16_t prio; + uint32_t handle; + int ifindex; + size_t hash2; + + ovs_mutex_lock(&ufid_lock); + HMAP_FOR_EACH_WITH_HASH(data, node, hash, &ufid_to_tc) { + if (ovs_u128_equals(*ufid, data->ufid)) { + break; + } + } + + if (!data) { + ovs_mutex_unlock(&ufid_lock); + return; + } + + /* remove from ufid_to_tc map and get info to remove tc_to_ufid map */ + hmap_remove(&ufid_to_tc, &data->node); + netdev_close(data->netdev); + prio = data->prio; + handle = data->handle; + ifindex = data->ifindex; + hash2 = hash_int(hash_int(prio, handle), ifindex); + free(data); + + HMAP_FOR_EACH_WITH_HASH(data, node, hash2, &tc_to_ufid) { + if (data->prio == prio && data->handle == handle && data->ifindex == ifindex) { + break; + } + } + if (data) { + hmap_remove(&tc_to_ufid, &data->node); + netdev_close(data->netdev); + free(data); + } + ovs_mutex_unlock(&ufid_lock); +} + +/* Add ufid to ufid_tc hashmap and prio/handle/ifindex to tc_ufid hashmap. + * If those exists already they will be replaced. */ +static void +add_ufid_tc_mapping(const ovs_u128 *ufid, int prio, int handle, + struct netdev *netdev, int ifindex) +{ + size_t hash = hash_bytes(ufid, sizeof *ufid, 0); + size_t hash2 = hash_int(hash_int(prio, handle), ifindex); + struct ufid_to_tc_data *new_data = xzalloc(sizeof *new_data); + struct ufid_to_tc_data *new_data2 = xzalloc(sizeof *new_data2); + + del_ufid_tc_mapping(ufid); + + new_data->ufid = *ufid; + new_data->prio = prio; + new_data->handle = handle; + new_data->netdev = netdev_ref(netdev); + new_data->ifindex = ifindex; + + new_data2->ufid = *ufid; + new_data2->prio = prio; + new_data2->handle = handle; + new_data2->netdev = netdev_ref(netdev); + new_data2->ifindex = ifindex; + + ovs_mutex_lock(&ufid_lock); + hmap_insert(&ufid_to_tc, &new_data->node, hash); + hmap_insert(&tc_to_ufid, &new_data2->node, hash2); + ovs_mutex_unlock(&ufid_lock); +} + +/* Get ufid from ufid_tc hashmap. + * + * Returns handle if successful and fill prio and netdev for that ufid. + * Otherwise returns 0. + */ +static int +get_ufid_tc_mapping(const ovs_u128 *ufid, int *prio, struct netdev **netdev) +{ + size_t hash = hash_bytes(ufid, sizeof *ufid, 0); + struct ufid_to_tc_data *data; + int handle = 0; + + ovs_mutex_lock(&ufid_lock); + HMAP_FOR_EACH_WITH_HASH(data, node, hash, &ufid_to_tc) { + if (ovs_u128_equals(*ufid, data->ufid)) { + if (prio) { + *prio = data->prio; + } + if (netdev) { + *netdev = netdev_ref(data->netdev); + } + handle = data->handle; + break; + } + } + ovs_mutex_unlock(&ufid_lock); + + return handle; +} + +/* Find ufid in tc_to_ufid hashmap using prio, handle and netdev. + * The result is saved in ufid. + * + * Returns true on success. + */ +static bool +find_ufid(int prio, int handle, struct netdev *netdev, ovs_u128 *ufid) +{ + int ifindex = netdev_get_ifindex(netdev); + struct ufid_to_tc_data *data; + size_t hash2 = hash_int(hash_int(prio, handle), ifindex); + + ovs_mutex_lock(&ufid_lock); + HMAP_FOR_EACH_WITH_HASH(data, node, hash2, &tc_to_ufid) { + if (data->prio == prio && data->handle == handle + && data->ifindex == ifindex) { + *ufid = data->ufid; + break; + } + } + ovs_mutex_unlock(&ufid_lock); + + return (data != NULL); +} + int netdev_tc_flow_flush(struct netdev *netdev) {