From patchwork Tue Feb 7 07:56:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Vadai X-Patchwork-Id: 724989 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vHc9c115qz9s4s for ; Tue, 7 Feb 2017 18:56:36 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753178AbdBGH4b (ORCPT ); Tue, 7 Feb 2017 02:56:31 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:33091 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753147AbdBGH4a (ORCPT ); Tue, 7 Feb 2017 02:56:30 -0500 Received: by mail-wm0-f66.google.com with SMTP id v77so26601195wmv.0 for ; Mon, 06 Feb 2017 23:56:29 -0800 (PST) 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=NZCxSAFnHATbg7uZsFbz5mWauaD8n1HkAp6l2C4tJ8A=; b=mT2k790C0wuac7tMNCDheaJY5Xjsx5MyvnUEUhlLsZ7Mqnr7sV/g5t1RIkvMRJuYN3 2wiNA5SNKbnfNhpfE8iGrPtqeaOe+H2FEcXFx4RdWemKCZS2nV1sZF9qWf/7G4VL6wrX zw8c6nVtAoDkQZ4UA0AG4s+tXhyFFOy2rLCcIapK0a/dUHwDiGLLyV0GVyhvFyArOKtA b5oc/fpssPEbi0dWcwNUo/CmQlbMyJb6mLclo5MHC4+OjI80cNgrPGuZ8d9GJclLNuZn 7F/J5HrzNNkvieh8GBOq+Vn9mCaMKkLkNesVIgkITEdg1SL6kQ454wGghNURO7nX+Pj3 gfNQ== X-Gm-Message-State: AIkVDXI8CLnYnX6NlmMeCLyI73kzA4JL05zgcnqaiOdbkkmOcvEYPNdtKa/2hOkDNSBVJg== X-Received: by 10.223.164.66 with SMTP id e2mr4204159wra.47.1486454187937; Mon, 06 Feb 2017 23:56:27 -0800 (PST) Received: from office.vadai.me ([192.116.94.223]) by smtp.gmail.com with ESMTPSA id v196sm15176581wmv.5.2017.02.06.23.56.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 06 Feb 2017 23:56:27 -0800 (PST) From: Amir Vadai To: "David S. Miller" Cc: netdev@vger.kernel.org, Or Gerlitz , Hadar Har-Zion , Amir Vadai Subject: [PATCH net-next V3 3/3] net/act_pedit: Introduce 'add' operation Date: Tue, 7 Feb 2017 09:56:08 +0200 Message-Id: <20170207075608.8430-4-amir@vadai.me> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170207075608.8430-1-amir@vadai.me> References: <20170207075608.8430-1-amir@vadai.me> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This command could be useful to inc/dec fields. For example, to forward any TCP packet and decrease its TTL: $ tc filter add dev enp0s9 protocol ip parent ffff: \ flower ip_proto tcp \ action pedit munge ip ttl add 0xff pipe \ action mirred egress redirect dev veth0 In the example above, adding 0xff to this u8 field is actually decreasing it by one, since the operation is masked. Signed-off-by: Amir Vadai Reviewed-by: Or Gerlitz --- include/net/tc_act/tc_pedit.h | 1 + include/uapi/linux/tc_act/tc_pedit.h | 8 ++++++++ net/sched/act_pedit.c | 30 ++++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h index e076f22035a5..dfbd6ee0bc7c 100644 --- a/include/net/tc_act/tc_pedit.h +++ b/include/net/tc_act/tc_pedit.h @@ -5,6 +5,7 @@ struct tcf_pedit_key_ex { enum pedit_header_type htype; + enum pedit_cmd cmd; }; struct tcf_pedit { diff --git a/include/uapi/linux/tc_act/tc_pedit.h b/include/uapi/linux/tc_act/tc_pedit.h index 22f19eeda997..143d2b31a316 100644 --- a/include/uapi/linux/tc_act/tc_pedit.h +++ b/include/uapi/linux/tc_act/tc_pedit.h @@ -20,6 +20,7 @@ enum { enum { TCA_PEDIT_KEY_EX_HTYPE = 1, + TCA_PEDIT_KEY_EX_CMD = 2, __TCA_PEDIT_KEY_EX_MAX }; #define TCA_PEDIT_KEY_EX_MAX (__TCA_PEDIT_KEY_EX_MAX - 1) @@ -38,6 +39,13 @@ enum pedit_header_type { }; #define TCA_PEDIT_HDR_TYPE_MAX (__PEDIT_HDR_TYPE_MAX - 1) +enum pedit_cmd { + TCA_PEDIT_KEY_EX_CMD_SET = 0, + TCA_PEDIT_KEY_EX_CMD_ADD = 1, + __PEDIT_CMD_MAX, +}; +#define TCA_PEDIT_CMD_MAX (__PEDIT_CMD_MAX - 1) + struct tc_pedit_key { __u32 mask; /* AND */ __u32 val; /*XOR */ diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index fdd012bd3602..c1310472f620 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -36,6 +36,7 @@ static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { static const struct nla_policy pedit_key_ex_policy[TCA_PEDIT_KEY_EX_MAX + 1] = { [TCA_PEDIT_KEY_EX_HTYPE] = { .type = NLA_U16 }, + [TCA_PEDIT_KEY_EX_CMD] = { .type = NLA_U16 }, }; static struct tcf_pedit_key_ex *tcf_pedit_keys_ex_parse(struct nlattr *nla, @@ -75,14 +76,17 @@ static struct tcf_pedit_key_ex *tcf_pedit_keys_ex_parse(struct nlattr *nla, if (err) goto err_out; - if (!tb[TCA_PEDIT_KEY_EX_HTYPE]) { + if (!tb[TCA_PEDIT_KEY_EX_HTYPE] || + !tb[TCA_PEDIT_KEY_EX_CMD]) { err = -EINVAL; goto err_out; } k->htype = nla_get_u16(tb[TCA_PEDIT_KEY_EX_HTYPE]); + k->cmd = nla_get_u16(tb[TCA_PEDIT_KEY_EX_CMD]); - if (k->htype > TCA_PEDIT_HDR_TYPE_MAX) { + if (k->htype > TCA_PEDIT_HDR_TYPE_MAX || + k->cmd > TCA_PEDIT_CMD_MAX) { err = -EINVAL; goto err_out; } @@ -110,7 +114,8 @@ static int tcf_pedit_key_ex_dump(struct sk_buff *skb, key_start = nla_nest_start(skb, TCA_PEDIT_KEY_EX); - if (nla_put_u16(skb, TCA_PEDIT_KEY_EX_HTYPE, keys_ex->htype)) { + if (nla_put_u16(skb, TCA_PEDIT_KEY_EX_HTYPE, keys_ex->htype) || + nla_put_u16(skb, TCA_PEDIT_KEY_EX_CMD, keys_ex->cmd)) { nlmsg_trim(skb, keys_start); return -EINVAL; } @@ -280,15 +285,19 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, struct tc_pedit_key *tkey = p->tcfp_keys; struct tcf_pedit_key_ex *tkey_ex = p->tcfp_keys_ex; enum pedit_header_type htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; + enum pedit_cmd cmd = TCA_PEDIT_KEY_EX_CMD_SET; for (i = p->tcfp_nkeys; i > 0; i--, tkey++) { u32 *ptr, _data; int offset = tkey->off; int hoffset; + u32 val; int rc; if (tkey_ex) { htype = tkey_ex->htype; + cmd = tkey_ex->cmd; + tkey_ex++; } @@ -330,7 +339,20 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, if (!ptr) goto bad; /* just do it, baby */ - *ptr = ((*ptr & tkey->mask) ^ tkey->val); + switch (cmd) { + case TCA_PEDIT_KEY_EX_CMD_SET: + val = tkey->val; + break; + case TCA_PEDIT_KEY_EX_CMD_ADD: + val = (*ptr + tkey->val) & ~tkey->mask; + break; + default: + pr_info("tc filter pedit bad command (%d)\n", + cmd); + goto bad; + } + + *ptr = ((*ptr & tkey->mask) ^ val); if (ptr == &_data) skb_store_bits(skb, hoffset + offset, ptr, 4); }