From patchwork Mon Mar 28 11:09:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eelco Chaudron X-Patchwork-Id: 1610097 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=FgFtjjDZ; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KRqjg609Wz9sFy for ; Mon, 28 Mar 2022 22:10:15 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 617C660FD5; Mon, 28 Mar 2022 11:10:11 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RujeTl_xywS9; Mon, 28 Mar 2022 11:10:10 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id 207F860E32; Mon, 28 Mar 2022 11:10:09 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E7FA6C0033; Mon, 28 Mar 2022 11:10:08 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id EA231C0012 for ; Mon, 28 Mar 2022 11:10:07 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id E4D1681CC3 for ; Mon, 28 Mar 2022 11:10:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp1.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wpBJznXu5g6K for ; Mon, 28 Mar 2022 11:10:03 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id E1B5181CAD for ; Mon, 28 Mar 2022 11:10:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1648465801; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XRVympxR1k2UWaY+/Dr5fs68HhTnYw8e7L1WDamtGGQ=; b=FgFtjjDZBWu6TubcKYX+P7NwO3nTrsCqXl/pm6MHFcuKQ8p14yCL9WpZoIIEQAPwsNNsEU 9YZ6PAzc+vzSj5ndJPTMgELKmEfaA5nkWtMP+DripWDwDc5gkR3KK29m+/4aAScGtSXbiy bt5g2L6NGsuf/5wND9QU+sp6VAe6gGg= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-117-Ut0GGElzPAGXYVQNibc1Yw-1; Mon, 28 Mar 2022 07:09:53 -0400 X-MC-Unique: Ut0GGElzPAGXYVQNibc1Yw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7CAB9804191; Mon, 28 Mar 2022 11:09:53 +0000 (UTC) Received: from ebuild.redhat.com (unknown [10.39.195.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id E758D40CF8FB; Mon, 28 Mar 2022 11:09:52 +0000 (UTC) From: Eelco Chaudron To: dev@openvswitch.org Date: Mon, 28 Mar 2022 13:09:49 +0200 Message-Id: <164846578902.1420472.12918081283692712869.stgit@ebuild> In-Reply-To: <164846573679.1420472.17794552134937724311.stgit@ebuild> References: <164846573679.1420472.17794552134937724311.stgit@ebuild> User-Agent: StGit/1.1 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=echaudro@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH 1/5] netdev-offload-tc: Move flow_put action handling to isolated function. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Move handling of the individual actions in the netdev_tc_flow_put() function to a separate function that will make recursive action handling easier. Signed-off-by: Eelco Chaudron Acked-by: Mike Pattrick --- lib/netdev-offload-tc.c | 255 +++++++++++++++++++++++++---------------------- 1 file changed, 138 insertions(+), 117 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 12d0a9af3..ae6f1134d 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -1558,6 +1558,139 @@ parse_match_ct_state_to_flower(struct tc_flower *flower, struct match *match) } } +static int +netdev_tc_parse_nl_actions(struct netdev *netdev, struct tc_flower *flower, + struct offload_info *info, + const struct nlattr *actions, size_t actions_len, + bool *recirc_act) +{ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); + const struct nlattr *nla; + size_t left; + + NL_ATTR_FOR_EACH (nla, left, actions, actions_len) { + struct tc_action *action; + int err; + + if (flower->action_count >= TCA_ACT_MAX_NUM) { + VLOG_DBG_RL(&rl, "Can only support %d actions", TCA_ACT_MAX_NUM); + return EOPNOTSUPP; + } + + action = &flower->actions[flower->action_count]; + + if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) { + odp_port_t port = nl_attr_get_odp_port(nla); + struct netdev *outdev = netdev_ports_get( + port, netdev_get_dpif_type(netdev)); + + if (!outdev) { + VLOG_DBG_RL(&rl, "Can't find netdev for output port %d", port); + return ENODEV; + } + + if (!netdev_flow_api_equals(netdev, outdev)) { + VLOG_DBG_RL(&rl, + "Flow API provider mismatch between ingress (%s) " + "and egress (%s) ports", + netdev_get_name(netdev), netdev_get_name(outdev)); + netdev_close(outdev); + return EOPNOTSUPP; + } + + action->out.ifindex_out = netdev_get_ifindex(outdev); + if (action->out.ifindex_out < 0) { + VLOG_DBG_RL(&rl, + "Can't find ifindex for output port %s, error %d", + netdev_get_name(outdev), action->out.ifindex_out); + netdev_close(outdev); + return -action->out.ifindex_out; + } + + action->out.ingress = is_internal_port(netdev_get_type(outdev)); + action->type = TC_ACT_OUTPUT; + flower->action_count++; + netdev_close(outdev); + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_PUSH_VLAN) { + const struct ovs_action_push_vlan *vlan_push = nl_attr_get(nla); + + action->vlan.vlan_push_tpid = vlan_push->vlan_tpid; + action->vlan.vlan_push_id = vlan_tci_to_vid(vlan_push->vlan_tci); + action->vlan.vlan_push_prio = vlan_tci_to_pcp(vlan_push->vlan_tci); + action->type = TC_ACT_VLAN_PUSH; + flower->action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_VLAN) { + action->type = TC_ACT_VLAN_POP; + flower->action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_PUSH_MPLS) { + const struct ovs_action_push_mpls *mpls_push = nl_attr_get(nla); + + action->mpls.proto = mpls_push->mpls_ethertype; + action->mpls.label = mpls_lse_to_label(mpls_push->mpls_lse); + action->mpls.tc = mpls_lse_to_tc(mpls_push->mpls_lse); + action->mpls.ttl = mpls_lse_to_ttl(mpls_push->mpls_lse); + action->mpls.bos = mpls_lse_to_bos(mpls_push->mpls_lse); + action->type = TC_ACT_MPLS_PUSH; + flower->action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_MPLS) { + action->mpls.proto = nl_attr_get_be16(nla); + action->type = TC_ACT_MPLS_POP; + flower->action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SET) { + const struct nlattr *set = nl_attr_get(nla); + const size_t set_len = nl_attr_get_size(nla); + + err = parse_put_flow_set_action(flower, action, set, set_len); + if (err) { + return err; + } + if (action->type == TC_ACT_ENCAP) { + action->encap.tp_dst = info->tp_dst_port; + action->encap.no_csum = !info->tunnel_csum_on; + } + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SET_MASKED) { + const struct nlattr *set = nl_attr_get(nla); + const size_t set_len = nl_attr_get_size(nla); + + err = parse_put_flow_set_masked_action(flower, action, set, + set_len, true); + if (err) { + return err; + } + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CT) { + const struct nlattr *ct = nl_attr_get(nla); + const size_t ct_len = nl_attr_get_size(nla); + + if (!ct_state_support) { + return -EOPNOTSUPP; + } + + err = parse_put_flow_ct_action(flower, action, ct, ct_len); + if (err) { + return err; + } + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CT_CLEAR) { + action->type = TC_ACT_CT; + action->ct.clear = true; + flower->action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_RECIRC) { + action->type = TC_ACT_GOTO; + action->chain = nl_attr_get_u32(nla); + flower->action_count++; + *recirc_act = true; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_DROP) { + action->type = TC_ACT_GOTO; + action->chain = 0; /* 0 is reserved and not used by recirc. */ + flower->action_count++; + } else { + VLOG_DBG_RL(&rl, "unsupported put action type: %d", + nl_attr_type(nla)); + return EOPNOTSUPP; + } + } + return 0; +} + static int netdev_tc_flow_put(struct netdev *netdev, struct match *match, struct nlattr *actions, size_t actions_len, @@ -1571,13 +1704,10 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, struct flow *mask = &match->wc.masks; const struct flow_tnl *tnl = &match->flow.tunnel; const struct flow_tnl *tnl_mask = &mask->tunnel; - struct tc_action *action; bool recirc_act = false; uint32_t block_id = 0; - struct nlattr *nla; struct tcf_id id; uint32_t chain; - size_t left; int prio = 0; int ifindex; int err; @@ -1822,120 +1952,11 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, return err; } - NL_ATTR_FOR_EACH(nla, left, actions, actions_len) { - if (flower.action_count >= TCA_ACT_MAX_NUM) { - VLOG_DBG_RL(&rl, "Can only support %d actions", TCA_ACT_MAX_NUM); - return EOPNOTSUPP; - } - action = &flower.actions[flower.action_count]; - if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) { - odp_port_t port = nl_attr_get_odp_port(nla); - struct netdev *outdev = netdev_ports_get( - port, netdev_get_dpif_type(netdev)); - - if (!outdev) { - VLOG_DBG_RL(&rl, "Can't find netdev for output port %d", port); - return ENODEV; - } - - if (!netdev_flow_api_equals(netdev, outdev)) { - VLOG_DBG_RL(&rl, - "Flow API provider mismatch between ingress (%s) " - "and egress (%s) ports", - netdev_get_name(netdev), netdev_get_name(outdev)); - netdev_close(outdev); - return EOPNOTSUPP; - } - - action->out.ifindex_out = netdev_get_ifindex(outdev); - if (action->out.ifindex_out < 0) { - VLOG_DBG_RL(&rl, - "Can't find ifindex for output port %s, error %d", - netdev_get_name(outdev), action->out.ifindex_out); - netdev_close(outdev); - return -action->out.ifindex_out; - } - - action->out.ingress = is_internal_port(netdev_get_type(outdev)); - action->type = TC_ACT_OUTPUT; - flower.action_count++; - netdev_close(outdev); - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_PUSH_VLAN) { - const struct ovs_action_push_vlan *vlan_push = nl_attr_get(nla); - - action->vlan.vlan_push_tpid = vlan_push->vlan_tpid; - action->vlan.vlan_push_id = vlan_tci_to_vid(vlan_push->vlan_tci); - action->vlan.vlan_push_prio = vlan_tci_to_pcp(vlan_push->vlan_tci); - action->type = TC_ACT_VLAN_PUSH; - flower.action_count++; - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_VLAN) { - action->type = TC_ACT_VLAN_POP; - flower.action_count++; - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_PUSH_MPLS) { - const struct ovs_action_push_mpls *mpls_push = nl_attr_get(nla); - - action->mpls.proto = mpls_push->mpls_ethertype; - action->mpls.label = mpls_lse_to_label(mpls_push->mpls_lse); - action->mpls.tc = mpls_lse_to_tc(mpls_push->mpls_lse); - action->mpls.ttl = mpls_lse_to_ttl(mpls_push->mpls_lse); - action->mpls.bos = mpls_lse_to_bos(mpls_push->mpls_lse); - action->type = TC_ACT_MPLS_PUSH; - flower.action_count++; - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_MPLS) { - action->mpls.proto = nl_attr_get_be16(nla); - action->type = TC_ACT_MPLS_POP; - flower.action_count++; - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SET) { - const struct nlattr *set = nl_attr_get(nla); - const size_t set_len = nl_attr_get_size(nla); - - err = parse_put_flow_set_action(&flower, action, set, set_len); - if (err) { - return err; - } - if (action->type == TC_ACT_ENCAP) { - action->encap.tp_dst = info->tp_dst_port; - action->encap.no_csum = !info->tunnel_csum_on; - } - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SET_MASKED) { - const struct nlattr *set = nl_attr_get(nla); - const size_t set_len = nl_attr_get_size(nla); - - err = parse_put_flow_set_masked_action(&flower, action, set, - set_len, true); - if (err) { - return err; - } - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CT) { - const struct nlattr *ct = nl_attr_get(nla); - const size_t ct_len = nl_attr_get_size(nla); - - if (!ct_state_support) { - return -EOPNOTSUPP; - } - - err = parse_put_flow_ct_action(&flower, action, ct, ct_len); - if (err) { - return err; - } - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CT_CLEAR) { - action->type = TC_ACT_CT; - action->ct.clear = true; - flower.action_count++; - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_RECIRC) { - action->type = TC_ACT_GOTO; - action->chain = nl_attr_get_u32(nla); - flower.action_count++; - recirc_act = true; - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_DROP) { - action->type = TC_ACT_GOTO; - action->chain = 0; /* 0 is reserved and not used by recirc. */ - flower.action_count++; - } else { - VLOG_DBG_RL(&rl, "unsupported put action type: %d", - nl_attr_type(nla)); - return EOPNOTSUPP; - } + /* Parse all (nested) actions. */ + err = netdev_tc_parse_nl_actions(netdev, &flower, info, + actions, actions_len, &recirc_act); + if (err) { + return err; } if ((chain || recirc_act) && !info->recirc_id_shared_with_tc) {