From patchwork Mon Jan 28 12:29:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pieter Jansen van Vuuren X-Patchwork-Id: 1031889 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="YM6CB5dP"; dkim-atps=neutral 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 43p8F11Lnnz9s7h for ; Mon, 28 Jan 2019 23:33:41 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 296FD2216; Mon, 28 Jan 2019 12:33:09 +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 D7E761EC0 for ; Mon, 28 Jan 2019 12:29:48 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-wm1-f65.google.com (mail-wm1-f65.google.com [209.85.128.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 2057F7A6 for ; Mon, 28 Jan 2019 12:29:48 +0000 (UTC) Received: by mail-wm1-f65.google.com with SMTP id n190so13820143wmd.0 for ; Mon, 28 Jan 2019 04:29:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OacCfwyG8bhLjzHVFw9ga6rAOq+Sp8rpfNoUjzNwONw=; b=YM6CB5dPjOUaNL13M9haDAWhAInvNPZqKQ5fRKdsZtUme6ErKC0uaTysU8bs0vXcmI Is2imFhWuNZz/wqrL8HDHXrgafLqWn8Vfc8CmRO5dO7JmJQo2O4kW7LtAtF7+N21MoK4 93YyAUTeb7olgZdqt0GiEvr2JLvlJFAmDshHDweBfmv64bo8zl6Pvu/4dIKjjkikSJgb P8MYOQfqtmmBS9ERmOWvW3X0iHVTguwHE2iDAtwavJN3lExQAfYpUpmsPFLFjhM/YQsu vpYe977UhBUvXLitK8cRZJx3Oyj5pxLaXKX5GCy41Skf2aY8qzBh/K5atNA74WnrW4yO 4M0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OacCfwyG8bhLjzHVFw9ga6rAOq+Sp8rpfNoUjzNwONw=; b=h09Z3GqxS6nPCulFY71p9WKiheS+iOyXSBUitTWQOaOrWO0GEoKx0rchd5kxNzbIBI b88MCNZJJ6uRW27u1PlKWAd9x79KZ6+AuokDUcEVLpu2xctE0YPkL4jBMOAMa1+fCegM tsS5lmLS3kNeumne8jpsQE08kyfmK+3w+dBE/VWEaiizTlDk+EjWm6473d9Um7cMmGxW MTp09+8+Ba2oHxODd98xlVSRFfvFttXYhGOAh5YSAEQnQiczl2n6XM/JJCZ3rJFtLRuA 230JYU0pjsD6CDt6oEedEg5yBufaI+BSzr8De8AoNA39WynV4/sMRMy7/qjKZyCkdQR7 zNvQ== X-Gm-Message-State: AJcUukcZzkwGbj0mYeEszdFliyodH1FFVR2EwJhaQD6VWRehifRp1Nd2 Kt1QTjNL19j/2e2w/tT/yFXSdk2qoyk= X-Google-Smtp-Source: ALg8bN7uRdD/yZ+th/gMYHER1SVyawnCbwiCIXmrcJslq17HQTJbBlEN5VBRicy3clnhZpsLenScHQ== X-Received: by 2002:a1c:bbd6:: with SMTP id l205mr15946987wmf.97.1548678586347; Mon, 28 Jan 2019 04:29:46 -0800 (PST) Received: from pieter-Netronome.netronome.com ([217.38.71.146]) by smtp.gmail.com with ESMTPSA id x186sm94367285wmg.41.2019.01.28.04.29.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 28 Jan 2019 04:29:45 -0800 (PST) From: Pieter Jansen van Vuuren To: dev@openvswitch.org Date: Mon, 28 Jan 2019 12:29:07 +0000 Message-Id: <1548678550-6661-2-git-send-email-pieter.jansenvanvuuren@netronome.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1548678550-6661-1-git-send-email-pieter.jansenvanvuuren@netronome.com> References: <1548678550-6661-1-git-send-email-pieter.jansenvanvuuren@netronome.com> X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: simon.horman@netronome.com, Pieter Jansen van Vuuren Subject: [ovs-dev] [RFC v3 1/4] lib/tc: make pedit mask calculations byte order agnostic 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 pedit allows setting entire words with an optional mask and OVS makes use of such masks to allow setting fields that do not span entire words. The struct tc_pedit_key structure, which is part of the kernel ABI, uses host byte order fields to store the mask and value for a pedit action, however, these fields contain values in network byte order. In order to allow static analysis tools to check for endianness problems this patch adds a local version of struct tc_pedit_key which uses big endian types and refactors the relevant code as appropriate. In the course of making this change it became apparent that the calculation of masks was occurring using host byte order although the values are in network byte order. This patch also fixes that problem by shifting values in host byte order and then converting them to network byte order. It is believe this fixes a bug on big endian systems although we are not in a position to test that. Signed-off-by: Pieter Jansen van Vuuren Reviewed-by: Simon Horman --- include/sparse/automake.mk | 3 ++- include/sparse/linux/tc_act/tc_pedit.h | 29 ++++++++++++++++++++++++++ lib/tc.c | 22 +++++++++---------- 3 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 include/sparse/linux/tc_act/tc_pedit.h diff --git a/include/sparse/automake.mk b/include/sparse/automake.mk index 985ee6a2f..4c7b17783 100644 --- a/include/sparse/automake.mk +++ b/include/sparse/automake.mk @@ -26,4 +26,5 @@ noinst_HEADERS += \ include/sparse/sys/sysmacros.h \ include/sparse/sys/types.h \ include/sparse/sys/wait.h \ - include/sparse/threads.h + include/sparse/threads.h \ + include/sparse/linux/tc_act/tc_pedit.h diff --git a/include/sparse/linux/tc_act/tc_pedit.h b/include/sparse/linux/tc_act/tc_pedit.h new file mode 100644 index 000000000..ca5c1f1fe --- /dev/null +++ b/include/sparse/linux/tc_act/tc_pedit.h @@ -0,0 +1,29 @@ +#ifndef FIX_LINUX_TC_PEDIT_H +#define FIX_LINUX_TC_PEDIT_H + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +#include_next + +/* Fixes endianness of 'mask' and 'val' members. */ +#define tc_pedit_key rpl_tc_pedit_key +struct rpl_tc_pedit_key { + ovs_be32 mask; /* AND */ + ovs_be32 val; /* XOR */ + __u32 off; /* offset */ + __u32 at; + __u32 offmask; + __u32 shift; +}; + +#define tc_pedit_sel rpl_tc_pedit_sel +struct rpl_tc_pedit_sel { + tc_gen; + unsigned char nkeys; + unsigned char flags; + struct tc_pedit_key keys[0]; +}; + +#endif diff --git a/lib/tc.c b/lib/tc.c index b19f075f2..ae5017c17 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -825,17 +825,17 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) if ((keys->off >= mf && keys->off < mf + sz) || (keys->off + 3 >= mf && keys->off + 3 < mf + sz)) { int diff = flower_off + (keys->off - mf); - uint32_t *dst = (void *) (rewrite_key + diff); - uint32_t *dst_m = (void *) (rewrite_mask + diff); - uint32_t mask = ~(keys->mask); + ovs_be32 *dst = (void *) (rewrite_key + diff); + ovs_be32 *dst_m = (void *) (rewrite_mask + diff); + ovs_be32 mask = ~(keys->mask); uint32_t zero_bits; if (keys->off < mf) { zero_bits = 8 * (mf - keys->off); - mask &= UINT32_MAX << zero_bits; + mask &= htonl(UINT32_MAX >> zero_bits); } else if (keys->off + 4 > mf + m->size) { zero_bits = 8 * (keys->off + 4 - mf - m->size); - mask &= UINT32_MAX >> zero_bits; + mask &= htonl(UINT32_MAX << zero_bits); } *dst_m |= mask; @@ -1725,8 +1725,8 @@ nl_msg_put_act_cookie(struct ofpbuf *request, struct tc_cookie *ck) { * (as we read entire words). */ static void calc_offsets(struct tc_flower *flower, struct flower_key_to_pedit *m, - int *cur_offset, int *cnt, uint32_t *last_word_mask, - uint32_t *first_word_mask, uint32_t **mask, uint32_t **data) + int *cur_offset, int *cnt, ovs_be32 *last_word_mask, + ovs_be32 *first_word_mask, ovs_be32 **mask, ovs_be32 **data) { int start_offset, max_offset, total_size; int diff, right_zero_bits, left_zero_bits; @@ -1742,8 +1742,8 @@ calc_offsets(struct tc_flower *flower, struct flower_key_to_pedit *m, *cur_offset = start_offset; *cnt = (total_size / 4) + (total_size % 4 ? 1 : 0); - *last_word_mask = UINT32_MAX >> right_zero_bits; - *first_word_mask = UINT32_MAX << left_zero_bits; + *last_word_mask = htonl(UINT32_MAX << right_zero_bits); + *first_word_mask = htonl(UINT32_MAX >> left_zero_bits); *data = (void *) (rewrite_key + m->flower_offset - diff); *mask = (void *) (rewrite_mask + m->flower_offset - diff); } @@ -1815,7 +1815,7 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, struct flower_key_to_pedit *m = &flower_pedit_map[i]; struct tc_pedit_key *pedit_key = NULL; struct tc_pedit_key_ex *pedit_key_ex = NULL; - uint32_t *mask, *data, first_word_mask, last_word_mask; + ovs_be32 *mask, *data, first_word_mask, last_word_mask; int cnt = 0, cur_offset = 0; if (!m->size) { @@ -1826,7 +1826,7 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, &first_word_mask, &mask, &data); for (j = 0; j < cnt; j++, mask++, data++, cur_offset += 4) { - uint32_t mask_word = *mask; + ovs_be32 mask_word = *mask; if (j == 0) { mask_word &= first_word_mask;