From patchwork Tue Apr 2 09:27:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Hurley X-Patchwork-Id: 1074147 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="gCk3e9jH"; 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 44YP6V3yrtz9sSy for ; Tue, 2 Apr 2019 20:29:06 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 022D6DCB; Tue, 2 Apr 2019 09:28:05 +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 1D6A5DC5 for ; Tue, 2 Apr 2019 09:28:04 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-ed1-f68.google.com (mail-ed1-f68.google.com [209.85.208.68]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 3042A87 for ; Tue, 2 Apr 2019 09:28:03 +0000 (UTC) Received: by mail-ed1-f68.google.com with SMTP id q3so11023991edg.0 for ; Tue, 02 Apr 2019 02:28:03 -0700 (PDT) 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=OlW5gSGyibAjFgyyrsgdXfb+DNARrS/BDrAclna0IHg=; b=gCk3e9jHx2+XW3nF07IOb61Va7RRMNu+Q9yJeYzPcgnuKT0Scnd4r6qa7+5aLNkeKb wHAevUI2ebZ9BL0S+sax8O9mpiyr++q3zY6+pHmzi5GA4Z0GamHkEx32Wj8P47yi1Lr1 /xz3kuPdO5OPJFFyqYrFIPeg1j0CBoRLdwD9o5aMHVXMoBwrhyjek6Cy8wYUebA+8C2f XW9KQ2uPqfJLFw153Oju+W3PnW07A8ITtB1pvqPdpfT6ej30FJp9mSijX/uRioH9sWqw zPmI3lAcDnJ8aAMYxuS16IxhtA6J1KnHMp+Rrw4b4QVJsZggK46Bamfifa+G82e1CSlp 94DA== 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=OlW5gSGyibAjFgyyrsgdXfb+DNARrS/BDrAclna0IHg=; b=e2ez6aXQxxF0u5VkumaKWyTgXWaStHCFIDEaByP4cqO3z107ryYqE3Sh2KO7RaIhl6 cd6t1SfTbtso+ja7GMSCPOmrp1aOpi8En6ReBBxaS/Qdb8zerFKIh74AoracYYKcNGYa wyywejyTo2qFd2XNh9Bg94T89grpZML2q3helnoocrUwIuZqwcehLXaaj5RNdcDeNbVr haalcbC6nZa/oRfNaH7nKZTDxOEU/DnE6ig3YbuYIEgkbj9zdqoSucyiqARcZvVT56ku mcHMC2wHN6iWYphp4bMGZWiYE3X2v78BY60uSZvVf4CfZvEerNceuWIgm8IYsXmxoTkL e+fg== X-Gm-Message-State: APjAAAUZ7G1DgWLvGeC6C8KLaQo58zFQaqEzCymZVSzzK5mMB7NpVYob em8skdNzmoTs1ifiQ3SgbAOpOnBSnsI= X-Google-Smtp-Source: APXvYqzqpjO3GORF53YmjFqfUezHt1XLbhJdGuBPV8A+sDHoe8yfbxBoZAAmCSgYJQR+d9G2Wx++Tw== X-Received: by 2002:aa7:c48b:: with SMTP id m11mr33756853edq.203.1554197281405; Tue, 02 Apr 2019 02:28:01 -0700 (PDT) Received: from jhurley-Precision-Tower-3420.netronome.com ([80.76.204.157]) by smtp.gmail.com with ESMTPSA id c9sm1206021ejb.1.2019.04.02.02.27.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 02 Apr 2019 02:28:00 -0700 (PDT) From: John Hurley To: dev@openvswitch.org, roid@mellanox.com, fbl@sysclose.org, simon.horman@netronome.com Date: Tue, 2 Apr 2019 10:27:42 +0100 Message-Id: <1554197264-15502-3-git-send-email-john.hurley@netronome.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1554197264-15502-1-git-send-email-john.hurley@netronome.com> References: <1554197264-15502-1-git-send-email-john.hurley@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: oss-drivers@netronome.com Subject: [ovs-dev] [PATCH OVS 2/4] ovs-tc: allow offloading of ingress mirr TC actions to datapath 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 The TC datapath only permits the offload of mirr actions if they are egress. To offload TC actions that output to OvS internal ports, ingress mirr actions are required. At the TC layer, an ingress mirr action passes the packet back into the network stack as if it came in the action port rather than attempting to egress the port. Update OvS-TC offloads to support ingress mirr actions. To ensure packets that match these rules are properly passed into the network stack, add a TC skbedit action along with ingress mirr that sets the pkt_type to PACKET_HOST. This mirrors the functionality of the OvS internal port kernel module. Signed-off-by: John Hurley Reviewed-by: Simon Horman --- lib/netdev-tc-offloads.c | 15 +++++++++--- lib/tc.c | 62 ++++++++++++++++++++++++++++++++++++++++++------ lib/tc.h | 5 +++- 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c index f5555e4..78ad023 100644 --- a/lib/netdev-tc-offloads.c +++ b/lib/netdev-tc-offloads.c @@ -1,3 +1,4 @@ + /* * Copyright (c) 2016 Mellanox Technologies, Ltd. * @@ -52,6 +53,12 @@ struct netlink_field { int size; }; +static bool +is_internal_port(const char *type) +{ + return !strcmp(type, "internal"); +} + static struct netlink_field set_flower_map[][4] = { [OVS_KEY_ATTR_IPV4] = { { offsetof(struct ovs_key_ipv4, ipv4_src), @@ -682,8 +689,9 @@ parse_tc_flower_to_match(struct tc_flower *flower, } break; case TC_ACT_OUTPUT: { - if (action->ifindex_out) { - outport = netdev_ifindex_to_odp_port(action->ifindex_out); + if (action->out.ifindex_out) { + outport = + netdev_ifindex_to_odp_port(action->out.ifindex_out); if (!outport) { return ENOENT; } @@ -1286,7 +1294,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, odp_port_t port = nl_attr_get_odp_port(nla); struct netdev *outdev = netdev_ports_get(port, info->dpif_class); - action->ifindex_out = netdev_get_ifindex(outdev); + action->out.ifindex_out = netdev_get_ifindex(outdev); + action->out.ingress = is_internal_port(netdev_get_type(outdev)); action->type = TC_ACT_OUTPUT; flower.action_count++; netdev_close(outdev); diff --git a/lib/tc.c b/lib/tc.c index 07b50b2..3548760 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1151,14 +1152,20 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) mirred_parms = mirred_attrs[TCA_MIRRED_PARMS]; m = nl_attr_get_unspec(mirred_parms, sizeof *m); - if (m->eaction != TCA_EGRESS_REDIR && m->eaction != TCA_EGRESS_MIRROR) { + if (m->eaction != TCA_EGRESS_REDIR && m->eaction != TCA_EGRESS_MIRROR && + m->eaction != TCA_INGRESS_REDIR && m->eaction != TCA_INGRESS_MIRROR) { VLOG_ERR_RL(&error_rl, "unknown mirred action: %d, %d, %d", m->action, m->eaction, m->ifindex); return EINVAL; } action = &flower->actions[flower->action_count++]; - action->ifindex_out = m->ifindex; + action->out.ifindex_out = m->ifindex; + if (m->eaction == TCA_INGRESS_REDIR || m->eaction == TCA_INGRESS_MIRROR) { + action->out.ingress = true; + } else { + action->out.ingress = false; + } action->type = TC_ACT_OUTPUT; mirred_tm = mirred_attrs[TCA_MIRRED_TM]; @@ -1301,6 +1308,8 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower) err = nl_parse_act_pedit(act_options, flower); } else if (!strcmp(act_kind, "csum")) { nl_parse_act_csum(act_options, flower); + } else if (!strcmp(act_kind, "skbedit")) { + /* Added for TC rule only (not in OvS rule) so ignore. */ } else { VLOG_ERR_RL(&error_rl, "unknown tc action kind: %s", act_kind); err = EINVAL; @@ -1729,6 +1738,24 @@ nl_msg_put_act_drop(struct ofpbuf *request) } static void +nl_msg_put_act_skbedit_to_host(struct ofpbuf *request) +{ + ovs_be16 packet_host = 0; + size_t offset; + + nl_msg_put_string(request, TCA_ACT_KIND, "skbedit"); + offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS); + { + struct tc_skbedit s = { .action = TC_ACT_PIPE }; + + nl_msg_put_unspec(request, TCA_SKBEDIT_PARMS, &s, sizeof s); + nl_msg_put_unspec(request, TCA_SKBEDIT_PTYPE, &packet_host, + sizeof packet_host); + } + nl_msg_end_nested(request, offset); +} + +static void nl_msg_put_act_mirred(struct ofpbuf *request, int ifindex, int action, int eaction) { @@ -1916,6 +1943,7 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) uint16_t act_index = 1; struct tc_action *action; int i, ifindex = 0; + bool ingress; offset = nl_msg_start_nested(request, TCA_FLOWER_ACT); { @@ -1977,19 +2005,39 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) } break; case TC_ACT_OUTPUT: { - ifindex = action->ifindex_out; + ingress = action->out.ingress; + ifindex = action->out.ifindex_out; if (ifindex < 1) { VLOG_ERR_RL(&error_rl, "%s: invalid ifindex: %d, type: %d", __func__, ifindex, action->type); return EINVAL; } + + if (ingress) { + /* If redirecting to ingress (internal port) ensure + * pkt_type on skb is set to PACKET_HOST. */ + act_offset = nl_msg_start_nested(request, act_index++); + nl_msg_put_act_skbedit_to_host(request); + nl_msg_end_nested(request, act_offset); + } + act_offset = nl_msg_start_nested(request, act_index++); if (i == flower->action_count - 1) { - nl_msg_put_act_mirred(request, ifindex, TC_ACT_STOLEN, - TCA_EGRESS_REDIR); + if (ingress) { + nl_msg_put_act_mirred(request, ifindex, TC_ACT_STOLEN, + TCA_INGRESS_REDIR); + } else { + nl_msg_put_act_mirred(request, ifindex, TC_ACT_STOLEN, + TCA_EGRESS_REDIR); + } } else { - nl_msg_put_act_mirred(request, ifindex, TC_ACT_PIPE, - TCA_EGRESS_MIRROR); + if (ingress) { + nl_msg_put_act_mirred(request, ifindex, TC_ACT_PIPE, + TCA_INGRESS_MIRROR); + } else { + nl_msg_put_act_mirred(request, ifindex, TC_ACT_PIPE, + TCA_EGRESS_MIRROR); + } } nl_msg_put_act_cookie(request, &flower->act_cookie); nl_msg_end_nested(request, act_offset); diff --git a/lib/tc.h b/lib/tc.h index d374711..154e120 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -147,7 +147,10 @@ enum tc_action_type { struct tc_action { union { - int ifindex_out; + struct { + int ifindex_out; + bool ingress; + } out; struct { ovs_be16 vlan_push_tpid;