From patchwork Mon May 16 15:37:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eelco Chaudron X-Patchwork-Id: 1631688 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=cIS2S6OS; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4L23KJ21LHz9ryY for ; Tue, 17 May 2022 01:37:24 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id D968C82425; Mon, 16 May 2022 15:37:22 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org 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 sdTD2FwfAW72; Mon, 16 May 2022 15:37:21 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id C96DF80F50; Mon, 16 May 2022 15:37:20 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 92B01C0039; Mon, 16 May 2022 15:37:20 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 8E22CC002D for ; Mon, 16 May 2022 15:37:19 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 4C40C40360 for ; Mon, 16 May 2022 15:37:10 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp4.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rS5DMCUUOMCY for ; Mon, 16 May 2022 15:37:09 +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 smtp4.osuosl.org (Postfix) with ESMTPS id F0FEC40382 for ; Mon, 16 May 2022 15:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1652715427; 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=EM2BRQWnXZUxHt7D7onzW7yTtk7Q8SVSBEsLnuhcnmQ=; b=cIS2S6OSP/+vWLLl+ph6L8nNyxVzJE28Vkp6a0f8/OjAqontamGYIK3CCy1bpqqtm+Bocw VNgIPQXw88/UVwZmcx0em4nMbA4PhFqW4G+Dr1ZSz0T3RmjejoAbZp13rKMT7Y5AKoJOrm zgsTX0WXb1Z3h5ON/beJ4kc7lLFloww= 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-561-P_0eJ-DdPpKhwZKRw-mhrQ-1; Mon, 16 May 2022 11:37:04 -0400 X-MC-Unique: P_0eJ-DdPpKhwZKRw-mhrQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 89A58800882; Mon, 16 May 2022 15:37:04 +0000 (UTC) Received: from ebuild.redhat.com (unknown [10.39.195.113]) by smtp.corp.redhat.com (Postfix) with ESMTP id D555D7AE4; Mon, 16 May 2022 15:37:03 +0000 (UTC) From: Eelco Chaudron To: dev@openvswitch.org Date: Mon, 16 May 2022 17:37:01 +0200 Message-Id: <165271541102.991159.10324900295615304825.stgit@ebuild> In-Reply-To: <165271539292.991159.2073606707254850380.stgit@ebuild> References: <165271539292.991159.2073606707254850380.stgit@ebuild> User-Agent: StGit/1.1 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 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 v3 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 Acked-by: Roi Dayan --- 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 a41b62758..3c2e8f510 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -1564,6 +1564,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, @@ -1577,13 +1710,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; @@ -1828,120 +1958,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) { From patchwork Mon May 16 15:37:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eelco Chaudron X-Patchwork-Id: 1631690 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=Iu+RQ8GF; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4L23KW4dBzz9ryY for ; Tue, 17 May 2022 01:37:35 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 215AD82AA7; Mon, 16 May 2022 15:37:34 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org 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 6M5gPYVUKf-v; Mon, 16 May 2022 15:37:32 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id A800D80C52; Mon, 16 May 2022 15:37:31 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6E174C007A; Mon, 16 May 2022 15:37:31 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0CBE0C002D for ; Mon, 16 May 2022 15:37:30 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 0767D40B6D for ; Mon, 16 May 2022 15:37:29 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp2.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Oi1ltuW2_P7l for ; Mon, 16 May 2022 15:37:26 +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 smtp2.osuosl.org (Postfix) with ESMTPS id 790AF40B2D for ; Mon, 16 May 2022 15:37:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1652715445; 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=u4fI8Uc2aefHUHtkefAodk+XGZlp11Izy+X3mhERssE=; b=Iu+RQ8GF0AhZaNcd58OJpaiuvawCk+glbRBdMFwzA8mpWy8EdNcy5iVMPRPw1OpGKIvF4l fPHyxllOMX1iyw2ScbEMJRxtMvdpX/H5j34D9ew8WmrmIBq2FDlI0438MFZMdK4PjNH2AG d6XJAlFaUxv4v/EMkaDftkkfmzoxAFU= 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-531-Py8XDlm8PWCOPMiR_E9Krg-1; Mon, 16 May 2022 11:37:22 -0400 X-MC-Unique: Py8XDlm8PWCOPMiR_E9Krg-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 DBE1E185A7A4; Mon, 16 May 2022 15:37:21 +0000 (UTC) Received: from ebuild.redhat.com (unknown [10.39.195.113]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3075040CF8E8; Mon, 16 May 2022 15:37:21 +0000 (UTC) From: Eelco Chaudron To: dev@openvswitch.org Date: Mon, 16 May 2022 17:37:19 +0200 Message-Id: <165271542974.991159.14450088240755727368.stgit@ebuild> In-Reply-To: <165271539292.991159.2073606707254850380.stgit@ebuild> References: <165271539292.991159.2073606707254850380.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 v3 2/5] netdev-offload-tc: Move flower_to_match 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 parse_tc_flower_to_match() function to a separate function that will make recursive action handling easier. Signed-off-by: Eelco Chaudron Acked-by: Mike Pattrick Acked-by: Roi Dayan --- lib/netdev-offload-tc.c | 422 +++++++++++++++++++++++++---------------------- 1 file changed, 221 insertions(+), 201 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 3c2e8f510..f657af0fd 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -617,6 +617,226 @@ parse_tc_flower_terse_to_match(struct tc_flower *flower, return 0; } +static int +_parse_tc_flower_to_actions(struct tc_flower *flower, struct ofpbuf *buf, + int start_index, int max_index) +{ + struct tc_action *action; + int i; + + if (max_index <= 0 || max_index > flower->action_count) { + max_index = flower->action_count; + } + + for (i = start_index; i < max_index; i++) { + action = &flower->actions[i]; + + switch (action->type) { + case TC_ACT_VLAN_POP: { + nl_msg_put_flag(buf, OVS_ACTION_ATTR_POP_VLAN); + } + break; + case TC_ACT_VLAN_PUSH: { + struct ovs_action_push_vlan *push; + + push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_VLAN, + sizeof *push); + push->vlan_tpid = action->vlan.vlan_push_tpid; + push->vlan_tci = htons(action->vlan.vlan_push_id + | (action->vlan.vlan_push_prio << 13) + | VLAN_CFI); + } + break; + case TC_ACT_MPLS_POP: { + nl_msg_put_be16(buf, OVS_ACTION_ATTR_POP_MPLS, + action->mpls.proto); + } + break; + case TC_ACT_MPLS_PUSH: { + struct ovs_action_push_mpls *push; + ovs_be32 mpls_lse = 0; + + flow_set_mpls_lse_label(&mpls_lse, action->mpls.label); + flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc); + flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl); + flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos); + + push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_MPLS, + sizeof *push); + push->mpls_ethertype = action->mpls.proto; + push->mpls_lse = mpls_lse; + } + break; + case TC_ACT_MPLS_SET: { + size_t set_offset = nl_msg_start_nested(buf, + OVS_ACTION_ATTR_SET); + struct ovs_key_mpls *set_mpls; + ovs_be32 mpls_lse = 0; + + flow_set_mpls_lse_label(&mpls_lse, action->mpls.label); + flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc); + flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl); + flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos); + + set_mpls = nl_msg_put_unspec_zero(buf, OVS_KEY_ATTR_MPLS, + sizeof *set_mpls); + set_mpls->mpls_lse = mpls_lse; + nl_msg_end_nested(buf, set_offset); + } + break; + case TC_ACT_PEDIT: { + parse_flower_rewrite_to_netlink_action(buf, action); + } + break; + case TC_ACT_ENCAP: { + size_t set_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SET); + size_t tunnel_offset = + nl_msg_start_nested(buf, OVS_KEY_ATTR_TUNNEL); + + if (action->encap.id_present) { + nl_msg_put_be64(buf, OVS_TUNNEL_KEY_ATTR_ID, action->encap.id); + } + if (action->encap.ipv4.ipv4_src) { + nl_msg_put_be32(buf, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, + action->encap.ipv4.ipv4_src); + } + if (action->encap.ipv4.ipv4_dst) { + nl_msg_put_be32(buf, OVS_TUNNEL_KEY_ATTR_IPV4_DST, + action->encap.ipv4.ipv4_dst); + } + if (ipv6_addr_is_set(&action->encap.ipv6.ipv6_src)) { + nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_SRC, + &action->encap.ipv6.ipv6_src); + } + if (ipv6_addr_is_set(&action->encap.ipv6.ipv6_dst)) { + nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_DST, + &action->encap.ipv6.ipv6_dst); + } + if (action->encap.tos) { + nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TOS, + action->encap.tos); + } + if (action->encap.ttl) { + nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TTL, + action->encap.ttl); + } + if (action->encap.tp_dst) { + nl_msg_put_be16(buf, OVS_TUNNEL_KEY_ATTR_TP_DST, + action->encap.tp_dst); + } + if (!action->encap.no_csum) { + nl_msg_put_flag(buf, OVS_TUNNEL_KEY_ATTR_CSUM); + } + + parse_tc_flower_geneve_opts(action, buf); + nl_msg_end_nested(buf, tunnel_offset); + nl_msg_end_nested(buf, set_offset); + } + break; + case TC_ACT_OUTPUT: { + odp_port_t outport = 0; + + if (action->out.ifindex_out) { + outport = + netdev_ifindex_to_odp_port(action->out.ifindex_out); + if (!outport) { + return ENOENT; + } + } + nl_msg_put_u32(buf, OVS_ACTION_ATTR_OUTPUT, odp_to_u32(outport)); + } + break; + case TC_ACT_CT: { + size_t ct_offset; + + if (action->ct.clear) { + nl_msg_put_flag(buf, OVS_ACTION_ATTR_CT_CLEAR); + break; + } + + ct_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_CT); + + if (action->ct.commit) { + nl_msg_put_flag(buf, OVS_CT_ATTR_COMMIT); + } + + if (action->ct.zone) { + nl_msg_put_u16(buf, OVS_CT_ATTR_ZONE, action->ct.zone); + } + + if (action->ct.mark_mask) { + uint32_t mark_and_mask[2] = { action->ct.mark, + action->ct.mark_mask }; + nl_msg_put_unspec(buf, OVS_CT_ATTR_MARK, &mark_and_mask, + sizeof mark_and_mask); + } + + if (!ovs_u128_is_zero(action->ct.label_mask)) { + struct { + ovs_u128 key; + ovs_u128 mask; + } *ct_label; + + ct_label = nl_msg_put_unspec_uninit(buf, + OVS_CT_ATTR_LABELS, + sizeof *ct_label); + ct_label->key = action->ct.label; + ct_label->mask = action->ct.label_mask; + } + + if (action->ct.nat_type) { + size_t nat_offset = nl_msg_start_nested(buf, + OVS_CT_ATTR_NAT); + + if (action->ct.nat_type == TC_NAT_SRC) { + nl_msg_put_flag(buf, OVS_NAT_ATTR_SRC); + } else if (action->ct.nat_type == TC_NAT_DST) { + nl_msg_put_flag(buf, OVS_NAT_ATTR_DST); + } + + if (action->ct.range.ip_family == AF_INET) { + nl_msg_put_be32(buf, OVS_NAT_ATTR_IP_MIN, + action->ct.range.ipv4.min); + nl_msg_put_be32(buf, OVS_NAT_ATTR_IP_MAX, + action->ct.range.ipv4.max); + } else if (action->ct.range.ip_family == AF_INET6) { + nl_msg_put_in6_addr(buf, OVS_NAT_ATTR_IP_MIN, + &action->ct.range.ipv6.min); + nl_msg_put_in6_addr(buf, OVS_NAT_ATTR_IP_MAX, + &action->ct.range.ipv6.max); + } + + if (action->ct.range.port.min) { + nl_msg_put_u16(buf, OVS_NAT_ATTR_PROTO_MIN, + ntohs(action->ct.range.port.min)); + if (action->ct.range.port.max) { + nl_msg_put_u16(buf, OVS_NAT_ATTR_PROTO_MAX, + ntohs(action->ct.range.port.max)); + } + } + + nl_msg_end_nested(buf, nat_offset); + } + + nl_msg_end_nested(buf, ct_offset); + } + break; + case TC_ACT_GOTO: { + nl_msg_put_u32(buf, OVS_ACTION_ATTR_RECIRC, action->chain); + } + break; + } + } + return i; +} + +static void +parse_tc_flower_to_actions(struct tc_flower *flower, + struct ofpbuf *buf) +{ + _parse_tc_flower_to_actions(flower, buf, 0, 0); +} + static int parse_tc_flower_to_match(struct tc_flower *flower, struct match *match, @@ -629,9 +849,6 @@ parse_tc_flower_to_match(struct tc_flower *flower, size_t act_off; struct tc_flower_key *key = &flower->key; struct tc_flower_key *mask = &flower->mask; - odp_port_t outport = 0; - struct tc_action *action; - int i; if (terse) { return parse_tc_flower_terse_to_match(flower, match, stats, attrs); @@ -822,204 +1039,7 @@ parse_tc_flower_to_match(struct tc_flower *flower, } act_off = nl_msg_start_nested(buf, OVS_FLOW_ATTR_ACTIONS); - { - action = flower->actions; - for (i = 0; i < flower->action_count; i++, action++) { - switch (action->type) { - case TC_ACT_VLAN_POP: { - nl_msg_put_flag(buf, OVS_ACTION_ATTR_POP_VLAN); - } - break; - case TC_ACT_VLAN_PUSH: { - struct ovs_action_push_vlan *push; - - push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_VLAN, - sizeof *push); - push->vlan_tpid = action->vlan.vlan_push_tpid; - push->vlan_tci = htons(action->vlan.vlan_push_id - | (action->vlan.vlan_push_prio << 13) - | VLAN_CFI); - } - break; - case TC_ACT_MPLS_POP: { - nl_msg_put_be16(buf, OVS_ACTION_ATTR_POP_MPLS, - action->mpls.proto); - } - break; - case TC_ACT_MPLS_PUSH: { - struct ovs_action_push_mpls *push; - ovs_be32 mpls_lse = 0; - - flow_set_mpls_lse_label(&mpls_lse, action->mpls.label); - flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc); - flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl); - flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos); - - push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_MPLS, - sizeof *push); - push->mpls_ethertype = action->mpls.proto; - push->mpls_lse = mpls_lse; - } - break; - case TC_ACT_MPLS_SET: { - size_t set_offset = nl_msg_start_nested(buf, - OVS_ACTION_ATTR_SET); - struct ovs_key_mpls *set_mpls; - ovs_be32 mpls_lse = 0; - - flow_set_mpls_lse_label(&mpls_lse, action->mpls.label); - flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc); - flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl); - flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos); - - set_mpls = nl_msg_put_unspec_zero(buf, OVS_KEY_ATTR_MPLS, - sizeof *set_mpls); - set_mpls->mpls_lse = mpls_lse; - nl_msg_end_nested(buf, set_offset); - } - break; - case TC_ACT_PEDIT: { - parse_flower_rewrite_to_netlink_action(buf, action); - } - break; - case TC_ACT_ENCAP: { - size_t set_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SET); - size_t tunnel_offset = - nl_msg_start_nested(buf, OVS_KEY_ATTR_TUNNEL); - - if (action->encap.id_present) { - nl_msg_put_be64(buf, OVS_TUNNEL_KEY_ATTR_ID, action->encap.id); - } - if (action->encap.ipv4.ipv4_src) { - nl_msg_put_be32(buf, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, - action->encap.ipv4.ipv4_src); - } - if (action->encap.ipv4.ipv4_dst) { - nl_msg_put_be32(buf, OVS_TUNNEL_KEY_ATTR_IPV4_DST, - action->encap.ipv4.ipv4_dst); - } - if (ipv6_addr_is_set(&action->encap.ipv6.ipv6_src)) { - nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_SRC, - &action->encap.ipv6.ipv6_src); - } - if (ipv6_addr_is_set(&action->encap.ipv6.ipv6_dst)) { - nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_DST, - &action->encap.ipv6.ipv6_dst); - } - if (action->encap.tos) { - nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TOS, - action->encap.tos); - } - if (action->encap.ttl) { - nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TTL, - action->encap.ttl); - } - if (action->encap.tp_dst) { - nl_msg_put_be16(buf, OVS_TUNNEL_KEY_ATTR_TP_DST, - action->encap.tp_dst); - } - if (!action->encap.no_csum) { - nl_msg_put_flag(buf, OVS_TUNNEL_KEY_ATTR_CSUM); - } - - parse_tc_flower_geneve_opts(action, buf); - nl_msg_end_nested(buf, tunnel_offset); - nl_msg_end_nested(buf, set_offset); - } - break; - case TC_ACT_OUTPUT: { - if (action->out.ifindex_out) { - outport = - netdev_ifindex_to_odp_port(action->out.ifindex_out); - if (!outport) { - return ENOENT; - } - } - nl_msg_put_u32(buf, OVS_ACTION_ATTR_OUTPUT, odp_to_u32(outport)); - } - break; - case TC_ACT_CT: { - size_t ct_offset; - - if (action->ct.clear) { - nl_msg_put_flag(buf, OVS_ACTION_ATTR_CT_CLEAR); - break; - } - - ct_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_CT); - - if (action->ct.commit) { - nl_msg_put_flag(buf, OVS_CT_ATTR_COMMIT); - } - - if (action->ct.zone) { - nl_msg_put_u16(buf, OVS_CT_ATTR_ZONE, action->ct.zone); - } - - if (action->ct.mark_mask) { - uint32_t mark_and_mask[2] = { action->ct.mark, - action->ct.mark_mask }; - nl_msg_put_unspec(buf, OVS_CT_ATTR_MARK, &mark_and_mask, - sizeof mark_and_mask); - } - - if (!ovs_u128_is_zero(action->ct.label_mask)) { - struct { - ovs_u128 key; - ovs_u128 mask; - } *ct_label; - - ct_label = nl_msg_put_unspec_uninit(buf, - OVS_CT_ATTR_LABELS, - sizeof *ct_label); - ct_label->key = action->ct.label; - ct_label->mask = action->ct.label_mask; - } - - if (action->ct.nat_type) { - size_t nat_offset = nl_msg_start_nested(buf, - OVS_CT_ATTR_NAT); - - if (action->ct.nat_type == TC_NAT_SRC) { - nl_msg_put_flag(buf, OVS_NAT_ATTR_SRC); - } else if (action->ct.nat_type == TC_NAT_DST) { - nl_msg_put_flag(buf, OVS_NAT_ATTR_DST); - } - - if (action->ct.range.ip_family == AF_INET) { - nl_msg_put_be32(buf, OVS_NAT_ATTR_IP_MIN, - action->ct.range.ipv4.min); - nl_msg_put_be32(buf, OVS_NAT_ATTR_IP_MAX, - action->ct.range.ipv4.max); - } else if (action->ct.range.ip_family == AF_INET6) { - nl_msg_put_in6_addr(buf, OVS_NAT_ATTR_IP_MIN, - &action->ct.range.ipv6.min); - nl_msg_put_in6_addr(buf, OVS_NAT_ATTR_IP_MAX, - &action->ct.range.ipv6.max); - } - - if (action->ct.range.port.min) { - nl_msg_put_u16(buf, OVS_NAT_ATTR_PROTO_MIN, - ntohs(action->ct.range.port.min)); - if (action->ct.range.port.max) { - nl_msg_put_u16(buf, OVS_NAT_ATTR_PROTO_MAX, - ntohs(action->ct.range.port.max)); - } - } - - nl_msg_end_nested(buf, nat_offset); - } - - nl_msg_end_nested(buf, ct_offset); - } - break; - case TC_ACT_GOTO: { - nl_msg_put_u32(buf, OVS_ACTION_ATTR_RECIRC, action->chain); - } - break; - } - } - } + parse_tc_flower_to_actions(flower, buf); nl_msg_end_nested(buf, act_off); *actions = ofpbuf_at_assert(buf, act_off, sizeof(struct nlattr)); From patchwork Mon May 16 15:37:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eelco Chaudron X-Patchwork-Id: 1631691 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=OcaMPR7z; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4L23L81ypRz9ryY for ; Tue, 17 May 2022 01:38:08 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 69B73812B2; Mon, 16 May 2022 15:38:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org 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 CWtQ7LZ652cl; Mon, 16 May 2022 15:38:03 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id 34EE982BA7; Mon, 16 May 2022 15:38:02 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id F3747C0039; Mon, 16 May 2022 15:38:01 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 77407C002D for ; Mon, 16 May 2022 15:38:00 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 15742610CD for ; Mon, 16 May 2022 15:37:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp3.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com 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 xAtqUs7oBLLj for ; Mon, 16 May 2022 15:37:51 +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.133.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id D867B610B5 for ; Mon, 16 May 2022 15:37:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1652715469; 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=86bmDDzMioD59ARf1pMgtjlK7/4Ng7/YS/w1t+/vciw=; b=OcaMPR7z2Y13pMws3KEhRTv2e4XsShhylpw1JCeXRZfi3A/9cjIUKc1k7geubtipEGyxHc gVhCPeHDNJdcKRUoJ2KYHmdubYdpKrxeVeHDRgieZt4jDIDFPrOQRkyLYA5Tz10lzOvN4n TRxwyeOuF7XETfe5ifqHub93QYtwEbI= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-644-MVsTmF0IN8WIC9o8msoLkQ-1; Mon, 16 May 2022 11:37:46 -0400 X-MC-Unique: MVsTmF0IN8WIC9o8msoLkQ-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 3F6341C05EA9; Mon, 16 May 2022 15:37:46 +0000 (UTC) Received: from ebuild.redhat.com (unknown [10.39.195.113]) by smtp.corp.redhat.com (Postfix) with ESMTP id 47C83492C14; Mon, 16 May 2022 15:37:45 +0000 (UTC) From: Eelco Chaudron To: dev@openvswitch.org Date: Mon, 16 May 2022 17:37:42 +0200 Message-Id: <165271544707.991159.3800315046299067355.stgit@ebuild> In-Reply-To: <165271539292.991159.2073606707254850380.stgit@ebuild> References: <165271539292.991159.2073606707254850380.stgit@ebuild> User-Agent: StGit/1.1 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 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 v3 3/5] netdev-offload-tc: Handle check_pkt_len datapath action. 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" This change implements support for the check_pkt_len action using the TC police action, which supports MTU checking. Signed-off-by: Eelco Chaudron Acked-by: Mike Pattrick Acked-by: Roi Dayan --- v3: Was using TCA_CSUM_PARMS instead of TCA_POLICE_TBF. lib/netdev-offload-tc.c | 171 +++++++++++++++++- lib/tc.c | 455 +++++++++++++++++++++++++++++++++++++++++++---- lib/tc.h | 12 + 3 files changed, 594 insertions(+), 44 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index f657af0fd..9b523c5f5 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -62,6 +62,13 @@ struct chain_node { uint32_t chain; }; +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, bool more_actions, + struct tc_action **need_jump_update); + static bool is_internal_port(const char *type) { @@ -825,6 +832,45 @@ _parse_tc_flower_to_actions(struct tc_flower *flower, struct ofpbuf *buf, nl_msg_put_u32(buf, OVS_ACTION_ATTR_RECIRC, action->chain); } break; + case TC_ACT_POLICE_MTU: { + size_t offset, act_offset; + uint32_t jump; + + offset = nl_msg_start_nested(buf, + OVS_ACTION_ATTR_CHECK_PKT_LEN); + + nl_msg_put_u16(buf, OVS_CHECK_PKT_LEN_ATTR_PKT_LEN, + action->police.mtu); + + act_offset = nl_msg_start_nested( + buf, OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER); + i = _parse_tc_flower_to_actions(flower, buf, i + 1, + action->police.result_jump); + nl_msg_end_nested(buf, act_offset); + + act_offset = nl_msg_start_nested( + buf, OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL); + + jump = flower->actions[i - 1].jump_action; + if (jump == JUMP_ACTION_STOP) { + jump = max_index; + } + if (jump != 0) { + i = _parse_tc_flower_to_actions(flower, buf, i, jump); + } + nl_msg_end_nested(buf, act_offset); + + i--; + nl_msg_end_nested(buf, offset); + } + break; + } + + if (action->jump_action && action->type != TC_ACT_POLICE_MTU) { + /* If there is a jump, it means this was the end of an action + * set and we need to end this branch. */ + i++; + break; } } return i; @@ -1584,11 +1630,121 @@ parse_match_ct_state_to_flower(struct tc_flower *flower, struct match *match) } } + +static int +parse_check_pkt_len_action(struct netdev *netdev, struct tc_flower *flower, + struct offload_info *info, struct tc_action *action, + const struct nlattr *nla, bool last_action, + struct tc_action **need_jump_update, + bool *recirc_act) +{ + struct tc_action *ge_jump_update = NULL, *le_jump_update = NULL; + const struct nlattr *nl_actions; + int err, le_offset, gt_offset; + uint16_t pkt_len; + + static const struct nl_policy ovs_cpl_policy[] = { + [OVS_CHECK_PKT_LEN_ATTR_PKT_LEN] = { .type = NL_A_U16 }, + [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER] = { .type = NL_A_NESTED }, + [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL] + = { .type = NL_A_NESTED }, + }; + struct nlattr *a[ARRAY_SIZE(ovs_cpl_policy)]; + + if (!nl_parse_nested(nla, ovs_cpl_policy, a, ARRAY_SIZE(a))) { + VLOG_INFO("Received invalid formatted OVS_ACTION_ATTR_CHECK_PKT_LEN!"); + return EOPNOTSUPP; + } + + if (!a[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER] || + !a[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL]) { + VLOG_INFO("Received invalid OVS_CHECK_PKT_LEN_ATTR_ACTION_IF_*!"); + return EOPNOTSUPP; + } + + pkt_len = nl_attr_get_u16(a[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN]); + + /* Add the police mtu action first in the allocated slot. */ + action->police.mtu = pkt_len; + action->type = TC_ACT_POLICE_MTU; + le_offset = flower->action_count++; + + /* Parse and add the greater than action(s). + * NOTE: The last_action parameter means that there are no more actions + * after the if () then ... else () case. */ + nl_actions = a[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER]; + err = netdev_tc_parse_nl_actions(netdev, flower, info, + nl_attr_get(nl_actions), + nl_attr_get_size(nl_actions), + recirc_act, !last_action, + &ge_jump_update); + if (err) { + return err; + } + + /* Update goto offset for le actions */ + flower->actions[le_offset].police.result_jump = flower->action_count; + + gt_offset = flower->action_count; + + /* Parse and add the less than action(s). */ + nl_actions = a[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL]; + err = netdev_tc_parse_nl_actions(netdev, flower, info, + nl_attr_get(nl_actions), + nl_attr_get_size(nl_actions), + recirc_act, !last_action, + &le_jump_update); + + if (gt_offset == flower->action_count && last_action) { + /* No le actions where added, fix gt offset */ + flower->actions[le_offset].police.result_jump = JUMP_ACTION_STOP; + } + + /* Update goto offset for gt actions to skip the le ones. */ + if (last_action) { + flower->actions[gt_offset - 1].jump_action = JUMP_ACTION_STOP; + + if (need_jump_update) { + *need_jump_update = NULL; + } + } else { + if (gt_offset == flower->action_count) { + flower->actions[gt_offset - 1].jump_action = 0; + } else { + flower->actions[gt_offset - 1].jump_action = flower->action_count; + } + /* If we have nested if() else () the if actions jump over the else + * and will end-up in the outer else () case, which it should have + * skipped. To void this we return the "potential" inner if() goto to + * need_jump_update, so it can be updated on return! + */ + if (need_jump_update) { + *need_jump_update = &flower->actions[gt_offset - 1]; + } + } + + if (le_jump_update != NULL) { + le_jump_update->jump_action = + flower->actions[gt_offset - 1].jump_action; + } + if (ge_jump_update != NULL) { + ge_jump_update->jump_action = + flower->actions[gt_offset - 1].jump_action; + } + + if (err) { + return err; + } + + return 0; +} + 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) + bool *recirc_act, bool more_actions, + struct tc_action **need_jump_update) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); const struct nlattr *nla; @@ -1708,6 +1864,16 @@ netdev_tc_parse_nl_actions(struct netdev *netdev, struct tc_flower *flower, action->type = TC_ACT_GOTO; action->chain = 0; /* 0 is reserved and not used by recirc. */ flower->action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CHECK_PKT_LEN) { + err = parse_check_pkt_len_action(netdev, flower, info, action, nla, + nl_attr_len_pad(nla, + left) >= left + && !more_actions, + need_jump_update, + recirc_act); + if (err) { + return err; + } } else { VLOG_DBG_RL(&rl, "unsupported put action type: %d", nl_attr_type(nla)); @@ -1980,7 +2146,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, /* Parse all (nested) actions. */ err = netdev_tc_parse_nl_actions(netdev, &flower, info, - actions, actions_len, &recirc_act); + actions, actions_len, &recirc_act, + false, NULL); if (err) { return err; } diff --git a/lib/tc.c b/lib/tc.c index df73a43d4..bdaa764f9 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -994,6 +994,18 @@ nl_parse_flower_flags(struct nlattr **attrs, struct tc_flower *flower) flower->offloaded_state = nl_get_flower_offloaded_state(attrs); } +static void +nl_parse_action_pc(uint32_t action_pc, struct tc_action *action) +{ + if (action_pc == TC_ACT_STOLEN) { + action->jump_action = JUMP_ACTION_STOP; + } else if (action_pc & TC_ACT_JUMP) { + action->jump_action = action_pc & TC_ACT_EXT_VAL_MASK; + } else { + action->jump_action = 0; + } +} + static const struct nl_policy pedit_policy[] = { [TCA_PEDIT_PARMS_EX] = { .type = NL_A_UNSPEC, .min_len = sizeof(struct tc_pedit), @@ -1093,6 +1105,7 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) action->type = TC_ACT_PEDIT; + nl_parse_action_pc(pe->action, action); return 0; } @@ -1267,6 +1280,7 @@ nl_parse_act_tunnel_key(struct nlattr *options, struct tc_flower *flower) if (err) { return err; } + nl_parse_action_pc(tun->action, action); } else if (tun->t_action == TCA_TUNNEL_KEY_ACT_RELEASE) { flower->tunnel = true; } else { @@ -1303,7 +1317,11 @@ get_user_hz(void) static void nl_parse_tcf(const struct tcf_t *tm, struct tc_flower *flower) { - flower->lastused = time_msec() - (tm->lastuse * 1000 / get_user_hz()); + uint64_t lastused = time_msec() - (tm->lastuse * 1000 / get_user_hz()); + + if (flower->lastused < lastused) { + flower->lastused = lastused; + } } static int @@ -1328,6 +1346,7 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) action = &flower->actions[flower->action_count++]; action->chain = p->action & TC_ACT_EXT_VAL_MASK; action->type = TC_ACT_GOTO; + nl_parse_action_pc(p->action, action); } else if (p->action != TC_ACT_SHOT) { VLOG_ERR_RL(&error_rl, "unknown gact action: %d", p->action); return EINVAL; @@ -1386,8 +1405,9 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) mirred_tm = mirred_attrs[TCA_MIRRED_TM]; tm = nl_attr_get_unspec(mirred_tm, sizeof *tm); - nl_parse_tcf(tm, flower); + nl_parse_tcf(tm, flower); + nl_parse_action_pc(m->action, action); return 0; } @@ -1516,6 +1536,7 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) } action->type = TC_ACT_CT; + nl_parse_action_pc(ct->action, action); return 0; } @@ -1561,6 +1582,8 @@ nl_parse_act_vlan(struct nlattr *options, struct tc_flower *flower) v->action, v->v_action); return EINVAL; } + + nl_parse_action_pc(v->action, action); return 0; } @@ -1654,6 +1677,7 @@ nl_parse_act_mpls(struct nlattr *options, struct tc_flower *flower) return EINVAL; } + nl_parse_action_pc(m->action, action); return 0; } @@ -1694,9 +1718,60 @@ nl_parse_act_csum(struct nlattr *options, struct tc_flower *flower) return EINVAL; } + /* The action_pc should be set on the previous action. */ + if (flower->action_count < TCA_ACT_MAX_NUM) { + struct tc_action *action = &flower->actions[flower->action_count]; + + nl_parse_action_pc(c->action, action); + } return 0; } +static const struct nl_policy police_policy[] = { + [TCA_POLICE_TBF] = { .type = NL_A_UNSPEC, + .min_len = sizeof(struct tc_police), + .optional = false, }, + [TCA_POLICE_RESULT] = { .type = NL_A_U32, .optional = false, }, + [TCA_POLICE_TM] = { .type = NL_A_UNSPEC, + .min_len = sizeof(struct tcf_t), + .optional = false, }, +}; + +static int +nl_parse_act_police_mtu(struct nlattr *options, struct tc_flower *flower) +{ + struct nlattr *police_attrs[ARRAY_SIZE(police_policy)]; + const struct tc_police *police; + struct nlattr *police_result; + struct tc_action *action; + const struct tcf_t *tm; + uint32_t action_pc; + + if (!nl_parse_nested(options, police_policy, police_attrs, + ARRAY_SIZE(police_policy))) { + VLOG_ERR_RL(&error_rl, "Failed to parse police action options"); + return EPROTO; + } + police = nl_attr_get_unspec(police_attrs[TCA_POLICE_TBF], sizeof *police); + police_result = police_attrs[TCA_POLICE_RESULT]; + + action = &flower->actions[flower->action_count++]; + action->type = TC_ACT_POLICE_MTU; + action_pc = nl_attr_get_u32(police_result); + if (action_pc & TC_ACT_JUMP) { + action->police.result_jump = action_pc & TC_ACT_EXT_VAL_MASK; + } else { + action->police.result_jump = JUMP_ACTION_STOP; + } + action->police.mtu = police->mtu; + + tm = nl_attr_get_unspec(police_attrs[TCA_POLICE_TM], sizeof *tm); + nl_parse_tcf(tm, flower); + nl_parse_action_pc(police->action, action); + return 0; +} + + static const struct nl_policy act_policy[] = { [TCA_ACT_KIND] = { .type = NL_A_STRING, .optional = false, }, [TCA_ACT_COOKIE] = { .type = NL_A_UNSPEC, .optional = true, }, @@ -1715,7 +1790,7 @@ static const struct nl_policy stats_policy[] = { static int nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, - bool terse) + bool terse, bool *csum) { struct nlattr *act_options; struct nlattr *act_stats; @@ -1737,6 +1812,7 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, return EPROTO; } + *csum = false; act_kind = nl_attr_get_string(action_attrs[TCA_ACT_KIND]); act_options = action_attrs[TCA_ACT_OPTIONS]; act_cookie = action_attrs[TCA_ACT_COOKIE]; @@ -1757,10 +1833,13 @@ 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); + *csum = true; } else if (!strcmp(act_kind, "skbedit")) { /* Added for TC rule only (not in OvS rule) so ignore. */ } else if (!strcmp(act_kind, "ct")) { nl_parse_act_ct(act_options, flower); + } else if (!strcmp(act_kind, "police")) { + nl_parse_act_police_mtu(act_options, flower); } else { VLOG_ERR_RL(&error_rl, "unknown tc action kind: %s", act_kind); err = EINVAL; @@ -1818,6 +1897,10 @@ nl_parse_flower_actions(struct nlattr **attrs, struct tc_flower *flower, static struct nl_policy actions_orders_policy[TCA_ACT_MAX_NUM + 1] = {}; struct nlattr *actions_orders[ARRAY_SIZE(actions_orders_policy)]; const int max_size = ARRAY_SIZE(actions_orders_policy); + int previous_action_count = 0; + bool need_jump_adjust = false; + int jump_adjust = 0; + bool csum = false; for (int i = TCA_ACT_MIN_PRIO; i < max_size; i++) { actions_orders_policy[i].type = NL_A_NESTED; @@ -1838,7 +1921,70 @@ nl_parse_flower_actions(struct nlattr **attrs, struct tc_flower *flower, VLOG_DBG_RL(&error_rl, "Can only support %d actions", TCA_ACT_MAX_NUM); return EOPNOTSUPP; } - err = nl_parse_single_action(actions_orders[i], flower, terse); + err = nl_parse_single_action(actions_orders[i], flower, terse, + &csum); + + if (flower->action_count == previous_action_count) { + + struct tc_action *action; + + /* We had no update on the TC action count, which means + * we had a none TC type action. So need to adjust existing + * jump offsets. */ + jump_adjust++; + + if (need_jump_adjust || (csum && flower->action_count > 0)) { + + if (csum && flower->action_count > 0) { + /* The csum action is special as it might carry + * a jump count for the previous TC_ACT and therefore + * should be adjusted with jump_adjust as it got + * copied. */ + action = &flower->actions[flower->action_count - 1]; + if (action->jump_action + && action->jump_action != JUMP_ACTION_STOP) { + action->jump_action -= (jump_adjust - 1); + } + } + + for (int j = 0; j < flower->action_count; j++) { + action = &flower->actions[j]; + + if (action->type == TC_ACT_POLICE_MTU + && action->police.result_jump != JUMP_ACTION_STOP + && (action->police.result_jump - 1) > + flower->action_count) { + + action->police.result_jump--; + } + + if (action->jump_action + && action->jump_action != JUMP_ACTION_STOP + && (action->jump_action - 1) > + flower->action_count) { + + action->jump_action--; + } + } + } + } else { + struct tc_action *action; + + action = &flower->actions[previous_action_count]; + if (action->type == TC_ACT_POLICE_MTU && + action->police.result_jump != JUMP_ACTION_STOP) { + action->police.result_jump -= jump_adjust; + need_jump_adjust = true; + } + + if (action->jump_action + && action->jump_action != JUMP_ACTION_STOP) { + action->jump_action -= jump_adjust; + need_jump_adjust = true; + } + + previous_action_count = flower->action_count; + } if (err) { return err; @@ -2031,14 +2177,14 @@ tc_get_tc_cls_policy(enum tc_offload_policy policy) } static void -nl_msg_put_act_csum(struct ofpbuf *request, uint32_t flags) +nl_msg_put_act_csum(struct ofpbuf *request, uint32_t flags, uint32_t action_pc) { size_t offset; nl_msg_put_string(request, TCA_ACT_KIND, "csum"); offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS); { - struct tc_csum parm = { .action = TC_ACT_PIPE, + struct tc_csum parm = { .action = action_pc, .update_flags = flags }; nl_msg_put_unspec(request, TCA_CSUM_PARMS, &parm, sizeof parm); @@ -2048,7 +2194,7 @@ nl_msg_put_act_csum(struct ofpbuf *request, uint32_t flags) static void nl_msg_put_act_pedit(struct ofpbuf *request, struct tc_pedit *parm, - struct tc_pedit_key_ex *ex) + struct tc_pedit_key_ex *ex, uint32_t action_pc) { size_t ksize = sizeof *parm + parm->nkeys * sizeof(struct tc_pedit_key); size_t offset, offset_keys_ex, offset_key; @@ -2057,7 +2203,7 @@ nl_msg_put_act_pedit(struct ofpbuf *request, struct tc_pedit *parm, nl_msg_put_string(request, TCA_ACT_KIND, "pedit"); offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS); { - parm->action = TC_ACT_PIPE; + parm->action = action_pc; nl_msg_put_unspec(request, TCA_PEDIT_PARMS_EX, parm, ksize); offset_keys_ex = nl_msg_start_nested(request, TCA_PEDIT_KEYS_EX); @@ -2074,14 +2220,14 @@ nl_msg_put_act_pedit(struct ofpbuf *request, struct tc_pedit *parm, static void nl_msg_put_act_push_vlan(struct ofpbuf *request, ovs_be16 tpid, - uint16_t vid, uint8_t prio) + uint16_t vid, uint8_t prio, uint32_t action_pc) { size_t offset; nl_msg_put_string(request, TCA_ACT_KIND, "vlan"); offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS); { - struct tc_vlan parm = { .action = TC_ACT_PIPE, + struct tc_vlan parm = { .action = action_pc, .v_action = TCA_VLAN_ACT_PUSH }; nl_msg_put_unspec(request, TCA_VLAN_PARMS, &parm, sizeof parm); @@ -2093,14 +2239,14 @@ nl_msg_put_act_push_vlan(struct ofpbuf *request, ovs_be16 tpid, } static void -nl_msg_put_act_pop_vlan(struct ofpbuf *request) +nl_msg_put_act_pop_vlan(struct ofpbuf *request, uint32_t action_pc) { size_t offset; nl_msg_put_string(request, TCA_ACT_KIND, "vlan"); offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS); { - struct tc_vlan parm = { .action = TC_ACT_PIPE, + struct tc_vlan parm = { .action = action_pc, .v_action = TCA_VLAN_ACT_POP }; nl_msg_put_unspec(request, TCA_VLAN_PARMS, &parm, sizeof parm); @@ -2109,14 +2255,15 @@ nl_msg_put_act_pop_vlan(struct ofpbuf *request) } static void -nl_msg_put_act_pop_mpls(struct ofpbuf *request, ovs_be16 proto) +nl_msg_put_act_pop_mpls(struct ofpbuf *request, ovs_be16 proto, + uint32_t action_pc) { size_t offset; nl_msg_put_string(request, TCA_ACT_KIND, "mpls"); offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS | NLA_F_NESTED); { - struct tc_mpls parm = { .action = TC_ACT_PIPE, + struct tc_mpls parm = { .action = action_pc, .m_action = TCA_MPLS_ACT_POP }; nl_msg_put_unspec(request, TCA_MPLS_PARMS, &parm, sizeof parm); @@ -2127,14 +2274,15 @@ nl_msg_put_act_pop_mpls(struct ofpbuf *request, ovs_be16 proto) static void nl_msg_put_act_push_mpls(struct ofpbuf *request, ovs_be16 proto, - uint32_t label, uint8_t tc, uint8_t ttl, uint8_t bos) + uint32_t label, uint8_t tc, uint8_t ttl, uint8_t bos, + uint32_t action_pc) { size_t offset; nl_msg_put_string(request, TCA_ACT_KIND, "mpls"); offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS | NLA_F_NESTED); { - struct tc_mpls parm = { .action = TC_ACT_PIPE, + struct tc_mpls parm = { .action = action_pc, .m_action = TCA_MPLS_ACT_PUSH }; nl_msg_put_unspec(request, TCA_MPLS_PARMS, &parm, sizeof parm); @@ -2149,14 +2297,14 @@ nl_msg_put_act_push_mpls(struct ofpbuf *request, ovs_be16 proto, static void nl_msg_put_act_set_mpls(struct ofpbuf *request, uint32_t label, uint8_t tc, - uint8_t ttl, uint8_t bos) + uint8_t ttl, uint8_t bos, uint32_t action_pc) { size_t offset; nl_msg_put_string(request, TCA_ACT_KIND, "mpls"); offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS | NLA_F_NESTED); { - struct tc_mpls parm = { .action = TC_ACT_PIPE, + struct tc_mpls parm = { .action = action_pc, .m_action = TCA_MPLS_ACT_MODIFY }; nl_msg_put_unspec(request, TCA_MPLS_PARMS, &parm, sizeof parm); @@ -2225,14 +2373,14 @@ nl_msg_put_act_tunnel_key_set(struct ofpbuf *request, bool id_present, struct in6_addr *ipv6_dst, ovs_be16 tp_dst, uint8_t tos, uint8_t ttl, struct tun_metadata tun_metadata, - uint8_t no_csum) + uint8_t no_csum, uint32_t action_pc) { size_t offset; nl_msg_put_string(request, TCA_ACT_KIND, "tunnel_key"); offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS); { - struct tc_tunnel_key tun = { .action = TC_ACT_PIPE, + struct tc_tunnel_key tun = { .action = action_pc, .t_action = TCA_TUNNEL_KEY_ACT_SET }; nl_msg_put_unspec(request, TCA_TUNNEL_KEY_PARMS, &tun, sizeof tun); @@ -2285,7 +2433,8 @@ nl_msg_put_act_gact(struct ofpbuf *request, uint32_t chain) } static void -nl_msg_put_act_ct(struct ofpbuf *request, struct tc_action *action) +nl_msg_put_act_ct(struct ofpbuf *request, struct tc_action *action, + uint32_t action_pc) { uint16_t ct_action = 0; size_t offset; @@ -2294,7 +2443,7 @@ nl_msg_put_act_ct(struct ofpbuf *request, struct tc_action *action) offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS | NLA_F_NESTED); { struct tc_ct ct = { - .action = TC_ACT_PIPE, + .action = action_pc, }; if (!action->ct.clear) { @@ -2499,10 +2648,57 @@ csum_update_flag(struct tc_flower *flower, return EOPNOTSUPP; } +static bool +rewrite_pedits_need_csum_update(struct tc_action *action) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(flower_pedit_map); i++) { + struct flower_key_to_pedit *m = &flower_pedit_map[i]; + ovs_be32 *mask, *data, first_word_mask, last_word_mask; + int cnt = 0, cur_offset = 0; + + if (!m->size) { + continue; + } + + calc_offsets(action, m, &cur_offset, &cnt, &last_word_mask, + &first_word_mask, &mask, &data); + + for (j = 0; j < cnt; j++, mask++) { + ovs_be32 mask_word = *mask; + + if (j == 0) { + mask_word &= first_word_mask; + } + if (j == cnt - 1) { + mask_word &= last_word_mask; + } + if (!mask_word) { + continue; + } + + switch (m->htype) { + case TCA_PEDIT_KEY_EX_HDR_TYPE_IP4: + case TCA_PEDIT_KEY_EX_HDR_TYPE_IP6: + case TCA_PEDIT_KEY_EX_HDR_TYPE_TCP: + case TCA_PEDIT_KEY_EX_HDR_TYPE_UDP: + return true; + case TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK: + case TCA_PEDIT_KEY_EX_HDR_TYPE_ETH: + case __PEDIT_HDR_TYPE_MAX: + break; + } + } + } + return false; +} + static int nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, struct tc_flower *flower, - struct tc_action *action) + struct tc_action *action, + uint32_t action_pc) { struct { struct tc_pedit sel; @@ -2569,7 +2765,8 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, } } } - nl_msg_put_act_pedit(request, &sel.sel, sel.keys_ex); + nl_msg_put_act_pedit(request, &sel.sel, sel.keys_ex, + flower->csum_update_flags ? TC_ACT_PIPE : action_pc); return 0; } @@ -2590,7 +2787,7 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index) * last pedit action. */ static void nl_msg_put_csum_act(struct ofpbuf *request, struct tc_flower *flower, - uint16_t *act_index) + uint32_t action_pc, uint16_t *act_index) { size_t act_offset; @@ -2600,7 +2797,7 @@ nl_msg_put_csum_act(struct ofpbuf *request, struct tc_flower *flower, } act_offset = nl_msg_start_nested(request, (*act_index)++); - nl_msg_put_act_csum(request, flower->csum_update_flags); + nl_msg_put_act_csum(request, flower->csum_update_flags, action_pc); nl_msg_put_act_flags(request); nl_msg_end_nested(request, act_offset); @@ -2608,6 +2805,124 @@ nl_msg_put_csum_act(struct ofpbuf *request, struct tc_flower *flower, flower->csum_update_flags = 0; } +static int +get_action_index_for_tc_actions(struct tc_flower *flower, uint16_t act_index, + struct tc_action *action, int action_count, + bool tunnel_key_released) +{ + bool need_csum = false; + + if (action_count < 0) { + /* Only forward jumps are supported */ + return -EINVAL; + } + + for (int i = 0; i < action_count; i++, action++) { + if (action->type != TC_ACT_PEDIT && need_csum) { + need_csum = false; + act_index++; + } + + switch (action->type) { + + case TC_ACT_OUTPUT: + if (!tunnel_key_released && flower->tunnel) { + act_index++; + tunnel_key_released = true; + } + if (action->out.ingress) { + act_index++; + } + act_index++; + break; + + case TC_ACT_ENCAP: + if (!tunnel_key_released && flower->tunnel) { + act_index++; + tunnel_key_released = true; + } + act_index++; + break; + + case TC_ACT_PEDIT: + if (!need_csum) { + need_csum = rewrite_pedits_need_csum_update(action); + } + if (i == (action_count - 1) && need_csum) { + need_csum = false; + act_index++; + } + act_index++; + break; + + case TC_ACT_POLICE_MTU: + case TC_ACT_VLAN_POP: + case TC_ACT_VLAN_PUSH: + case TC_ACT_MPLS_POP: + case TC_ACT_MPLS_PUSH: + case TC_ACT_MPLS_SET: + case TC_ACT_GOTO: + case TC_ACT_CT: + /* Increase act_index by one if we are sure this type of action + * will only add one tc action in the kernel. */ + act_index++; + break; + + /* If we can't determine how many tc actions will be added by the + * kernel return -EOPNOTSUPP. + * + * Please do NOT add a default case. */ + } + } + + return act_index; +} + +static int +nl_msg_put_act_police_mtu(struct ofpbuf *request, struct tc_flower *flower, + struct tc_action *action, uint32_t action_pc, + int action_index, uint16_t act_index, bool released) +{ + uint32_t tc_action; + size_t offset; + + if (action->police.result_jump != JUMP_ACTION_STOP) { + int jump_index; + int action_count = action->police.result_jump - action_index - 1; + + jump_index = get_action_index_for_tc_actions(flower, + act_index - 1, + action + 1, + action_count, + released); + if (jump_index < 0) { + return -jump_index; + } + tc_action = TC_ACT_JUMP | (jump_index & TC_ACT_EXT_VAL_MASK); + } else { + tc_action = TC_ACT_STOLEN; + } + + nl_msg_put_string(request, TCA_ACT_KIND, "police"); + offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS); + { + struct tc_police p = { .action = action_pc, + .mtu = action->police.mtu }; + + nl_msg_put_unspec(request, TCA_POLICE_TBF, &p, sizeof p); + + /* The value in jump_action is the total number of TC_ACT_* + * we need to jump, not the actual number of TCA_ACT_KIND + * (act_index) actions. As certain TC_ACT_* actions can be + * translated into multiple TCA_ACT_KIND ones. + * + * See nl_msg_put_flower_acts() below for more details. */ + nl_msg_put_u32(request, TCA_POLICE_RESULT, tc_action); + } + nl_msg_end_nested(request, offset); + return 0; +} + static int nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) { @@ -2621,17 +2936,59 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) offset = nl_msg_start_nested(request, TCA_FLOWER_ACT); { int error; + uint32_t prev_action_pc = TC_ACT_PIPE; action = flower->actions; for (i = 0; i < flower->action_count; i++, action++) { - if (action->type != TC_ACT_PEDIT) { - nl_msg_put_csum_act(request, flower, &act_index); + uint32_t action_pc; /* Programmatic Control */ + + if (!action->jump_action) { + action_pc = TC_ACT_PIPE; + } else if (action->jump_action == JUMP_ACTION_STOP) { + action_pc = TC_ACT_STOLEN; + } else { + /* The value in jump_action is the total number of TC_ACT_* + * we need to jump, not the actual number of TCA_ACT_KIND + * (act_index) actions. As certain TC_ACT_* actions can be + * translated into multiple TCA_ACT_KIND ones. + * + * If we can determine the number of actual actions being + * inserted we will update the count, if not we will return + * -EOPNOTSUPP. + */ + int jump_index; + int act_index_start = act_index - 1; + int action_count = (action->jump_action & + TC_ACT_EXT_VAL_MASK) - i; + + if (flower->csum_update_flags && + (action->type != TC_ACT_PEDIT + || prev_action_pc & TC_ACT_JUMP)) { + act_index_start++; + } + + jump_index = get_action_index_for_tc_actions(flower, + act_index_start, + action, + action_count, + released); + if (jump_index < 0) { + return -jump_index; + } + + action_pc = TC_ACT_JUMP | jump_index; } + + if (action->type != TC_ACT_PEDIT || prev_action_pc & TC_ACT_JUMP) { + nl_msg_put_csum_act(request, flower, prev_action_pc, + &act_index); + } + switch (action->type) { case TC_ACT_PEDIT: { act_offset = nl_msg_start_nested(request, act_index++); error = nl_msg_put_flower_rewrite_pedits(request, flower, - action); + action, action_pc); if (error) { return error; } @@ -2639,7 +2996,8 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) if (i == flower->action_count - 1) { /* If this is the last action check csum calc again. */ - nl_msg_put_csum_act(request, flower, &act_index); + nl_msg_put_csum_act(request, flower, action_pc, + &act_index); } } break; @@ -2660,14 +3018,15 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) action->encap.tos, action->encap.ttl, action->encap.data, - action->encap.no_csum); + action->encap.no_csum, + action_pc); nl_msg_put_act_flags(request); nl_msg_end_nested(request, act_offset); } break; case TC_ACT_VLAN_POP: { act_offset = nl_msg_start_nested(request, act_index++); - nl_msg_put_act_pop_vlan(request); + nl_msg_put_act_pop_vlan(request, action_pc); nl_msg_put_act_flags(request); nl_msg_end_nested(request, act_offset); } @@ -2677,14 +3036,16 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) nl_msg_put_act_push_vlan(request, action->vlan.vlan_push_tpid, action->vlan.vlan_push_id, - action->vlan.vlan_push_prio); + action->vlan.vlan_push_prio, + action_pc); nl_msg_put_act_flags(request); nl_msg_end_nested(request, act_offset); } break; case TC_ACT_MPLS_POP: { act_offset = nl_msg_start_nested(request, act_index++); - nl_msg_put_act_pop_mpls(request, action->mpls.proto); + nl_msg_put_act_pop_mpls(request, action->mpls.proto, + action_pc); nl_msg_end_nested(request, act_offset); } break; @@ -2692,7 +3053,8 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) act_offset = nl_msg_start_nested(request, act_index++); nl_msg_put_act_push_mpls(request, action->mpls.proto, action->mpls.label, action->mpls.tc, - action->mpls.ttl, action->mpls.bos); + action->mpls.ttl, action->mpls.bos, + action_pc); nl_msg_end_nested(request, act_offset); } break; @@ -2700,7 +3062,7 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) act_offset = nl_msg_start_nested(request, act_index++); nl_msg_put_act_set_mpls(request, action->mpls.label, action->mpls.tc, action->mpls.ttl, - action->mpls.bos); + action->mpls.bos, action_pc); nl_msg_end_nested(request, act_offset); } break; @@ -2735,12 +3097,13 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) nl_msg_put_act_mirred(request, ifindex, TC_ACT_STOLEN, TCA_EGRESS_REDIR); } + action->jump_action = JUMP_ACTION_STOP; } else { if (ingress) { - nl_msg_put_act_mirred(request, ifindex, TC_ACT_PIPE, + nl_msg_put_act_mirred(request, ifindex, action_pc, TCA_INGRESS_MIRROR); } else { - nl_msg_put_act_mirred(request, ifindex, TC_ACT_PIPE, + nl_msg_put_act_mirred(request, ifindex, action_pc, TCA_EGRESS_MIRROR); } } @@ -2768,12 +3131,26 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) break; case TC_ACT_CT: { act_offset = nl_msg_start_nested(request, act_index++); - nl_msg_put_act_ct(request, action); + nl_msg_put_act_ct(request, action, action_pc); nl_msg_put_act_cookie(request, &flower->act_cookie); nl_msg_end_nested(request, act_offset); } break; + case TC_ACT_POLICE_MTU: { + act_offset = nl_msg_start_nested(request, act_index++); + if (nl_msg_put_act_police_mtu(request, flower, action, + action_pc, i, act_index, + released)) { + return -EOPNOTSUPP; + } + nl_msg_put_act_cookie(request, &flower->act_cookie); + nl_msg_put_act_flags(request); + nl_msg_end_nested(request, act_offset); + } + break; } + + prev_action_pc = action_pc; } } diff --git a/lib/tc.h b/lib/tc.h index d6cdddd16..7ccd71d01 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -174,6 +174,7 @@ enum tc_action_type { TC_ACT_MPLS_SET, TC_ACT_GOTO, TC_ACT_CT, + TC_ACT_POLICE_MTU, }; enum nat_type { @@ -256,14 +257,19 @@ struct tc_action { bool force; bool commit; } ct; - struct { struct tc_flower_key key; struct tc_flower_key mask; } rewrite; - }; + struct { + uint32_t result_jump; + uint16_t mtu; + } police; + }; - enum tc_action_type type; + enum tc_action_type type; + uint32_t jump_action; +#define JUMP_ACTION_STOP 0xffffffff }; /* assert that if we overflow with a masked write of uint32_t to the last byte From patchwork Mon May 16 15:38:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eelco Chaudron X-Patchwork-Id: 1631692 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=CBw+IkdP; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4L23LT2ZkQz9ryY for ; Tue, 17 May 2022 01:38:25 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 4782E418E3; Mon, 16 May 2022 15:38:23 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id c9IDSVpuOMeC; Mon, 16 May 2022 15:38:21 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id A29F74189A; Mon, 16 May 2022 15:38:20 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 568C8C007A; Mon, 16 May 2022 15:38:20 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0D80DC002D for ; Mon, 16 May 2022 15:38:19 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 73F2D40B7E for ; Mon, 16 May 2022 15:38:13 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp2.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id l041RxIDx6Y1 for ; Mon, 16 May 2022 15:38:12 +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.133.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id 8F98340B1E for ; Mon, 16 May 2022 15:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1652715491; 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=nx+rhGYTGZIxO0Uvsie40fDA4HzmBHxqtgSo5yErfcw=; b=CBw+IkdPRBteVmDVGlT9nuY7inPcsahahL25mpiCqLO2PzWG8yg/z55Rwy/AkuygCrthm6 aepkQby+9OFN/hn2v0tUFbXIFy2Yod89Kn4RM2l2UaXmO72Yl6yaB9jK85EvJg4DnhfkoJ ltTYJbVFDoFk2ymdBGBWSV4cEexrgBs= 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-384-oe2lmWHsNj2SEiWhexu8Sw-1; Mon, 16 May 2022 11:38:08 -0400 X-MC-Unique: oe2lmWHsNj2SEiWhexu8Sw-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0CFBE811E7A; Mon, 16 May 2022 15:38:08 +0000 (UTC) Received: from ebuild.redhat.com (unknown [10.39.195.113]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6F8F1492C14; Mon, 16 May 2022 15:38:07 +0000 (UTC) From: Eelco Chaudron To: dev@openvswitch.org Date: Mon, 16 May 2022 17:38:04 +0200 Message-Id: <165271547144.991159.143404720230756066.stgit@ebuild> In-Reply-To: <165271539292.991159.2073606707254850380.stgit@ebuild> References: <165271539292.991159.2073606707254850380.stgit@ebuild> User-Agent: StGit/1.1 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 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 v3 4/5] system-offloads-traffic: Properly initialize offload before testing. 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" This patch will properly initialize offload, as it requires the setting to be enabled before starting ovs-vswitchd (or do a restart once configured). Signed-off-by: Eelco Chaudron Acked-by: Mike Pattrick Acked-by: Roi Dayan --- v2: - Unified all the OVS_TRAFFIC_VSWITCHD_START macro's tests/ofproto-macros.at | 6 +++++- tests/system-kmod-macros.at | 4 ++-- tests/system-offloads-traffic.at | 9 +++------ tests/system-tso-macros.at | 4 ++-- tests/system-userspace-macros.at | 4 ++-- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at index 7051d9539..de6bd6c2e 100644 --- a/tests/ofproto-macros.at +++ b/tests/ofproto-macros.at @@ -138,7 +138,7 @@ m4_divert_pop([PREPARE_TESTS]) m4_define([TESTABLE_LOG], [-vPATTERN:ANY:'%c|%p|%m']) -# _OVS_VSWITCHD_START([vswitchd-aux-args]) +# _OVS_VSWITCHD_START([vswitchd-aux-args] [dbinit-aux-args] [pre-vswitchd-commands]) # # Creates an empty database and starts ovsdb-server. # Starts ovs-vswitchd, with additional arguments 'vswitchd-aux-args'. @@ -159,6 +159,9 @@ m4_define([_OVS_VSWITCHD_START], dnl Initialize database. AT_CHECK([ovs-vsctl --no-wait init $2]) + dnl Run extra commands before ovs-vswitchd starts. + AT_CHECK([:; $3]) + dnl Start ovs-vswitchd. AT_CHECK([ovs-vswitchd $1 --detach --no-chdir --pidfile --log-file -vvconn -vofproto_dpif -vunixctl], [0], [], [stderr]) AT_CAPTURE_FILE([ovs-vswitchd.log]) @@ -174,6 +177,7 @@ m4_define([_OVS_VSWITCHD_START], /ofproto|INFO|datapath ID changed to fedcba9876543210/d /dpdk|INFO|DPDK Disabled - Use other_config:dpdk-init to enable/d /netlink_socket|INFO|netlink: could not enable listening to all nsid/d +/netdev_offload|INFO|netdev: Flow API Enabled/d /probe tc:/d /setting extended ack support failed/d /tc: Using policy/d']]) diff --git a/tests/system-kmod-macros.at b/tests/system-kmod-macros.at index 86d633ac4..a8eadc483 100644 --- a/tests/system-kmod-macros.at +++ b/tests/system-kmod-macros.at @@ -4,7 +4,7 @@ # appropriate type and properties m4_define([_ADD_BR], [[add-br $1 -- set Bridge $1 protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14,OpenFlow15 fail-mode=secure ]]) -# OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], [=override]) +# OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], [pre-vswitchd-commands]) # # Creates a database and starts ovsdb-server, starts ovs-vswitchd # connected to that database, calls ovs-vsctl to create a bridge named @@ -24,7 +24,7 @@ m4_define([OVS_TRAFFIC_VSWITCHD_START], ]) on_exit 'ovs-dpctl del-dp ovs-system' on_exit 'ovs-appctl dpctl/flush-conntrack' - _OVS_VSWITCHD_START([]) + _OVS_VSWITCHD_START([], [], [$3]) dnl Add bridges, ports, etc. AT_CHECK([ovs-vsctl -- _ADD_BR([br0]) -- $1 m4_if([$2], [], [], [| uuidfilt])], [0], [$2]) ]) diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at index 80bc1dd5c..705a50079 100644 --- a/tests/system-offloads-traffic.at +++ b/tests/system-offloads-traffic.at @@ -39,9 +39,8 @@ AT_CLEANUP AT_SETUP([offloads - ping between two ports - offloads enabled]) -OVS_TRAFFIC_VSWITCHD_START() +OVS_TRAFFIC_VSWITCHD_START([], [], [ovs-vsctl --no-wait set Open_vSwitch . other_config:hw-offload=true]) -AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=true]) AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) ADD_NAMESPACES(at_ns0, at_ns1) @@ -97,8 +96,7 @@ AT_CLEANUP AT_SETUP([offloads - set ingress_policing_rate and ingress_policing_burst - offloads enabled]) AT_KEYWORDS([ingress_policing]) AT_SKIP_IF([test $HAVE_TC = "no"]) -OVS_TRAFFIC_VSWITCHD_START() -AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=true]) +OVS_TRAFFIC_VSWITCHD_START([], [], [ovs-vsctl --no-wait set Open_vSwitch . other_config:hw-offload=true]) AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) ADD_NAMESPACES(at_ns0) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") @@ -146,8 +144,7 @@ AT_CLEANUP AT_SETUP([offloads - set ingress_policing_kpkts_rate and ingress_policing_kpkts_burst - offloads enabled]) AT_KEYWORDS([ingress_policing_kpkts]) AT_SKIP_IF([test $SUPPORT_TC_INGRESS_PPS = "no"]) -OVS_TRAFFIC_VSWITCHD_START() -AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=true]) +OVS_TRAFFIC_VSWITCHD_START([], [], [ovs-vsctl --no-wait set Open_vSwitch . other_config:hw-offload=true]) AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) ADD_NAMESPACES(at_ns0) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") diff --git a/tests/system-tso-macros.at b/tests/system-tso-macros.at index 1a8004761..1881c28fb 100644 --- a/tests/system-tso-macros.at +++ b/tests/system-tso-macros.at @@ -4,7 +4,7 @@ # appropriate type and properties m4_define([_ADD_BR], [[add-br $1 -- set Bridge $1 datapath_type="netdev" protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14,OpenFlow15 fail-mode=secure ]]) -# OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], [=override]) +# OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], [pre-vswitchd-commands]) # # Creates a database and starts ovsdb-server, starts ovs-vswitchd # connected to that database, calls ovs-vsctl to create a bridge named @@ -15,7 +15,7 @@ m4_define([_ADD_BR], [[add-br $1 -- set Bridge $1 datapath_type="netdev" protoco m4_define([OVS_TRAFFIC_VSWITCHD_START], [ OVS_WAIT_WHILE([ip link show ovs-netdev]) - _OVS_VSWITCHD_START([--disable-system]) + _OVS_VSWITCHD_START([--disable-system] [] [$3]) dnl Add bridges, ports, etc. OVS_WAIT_WHILE([ip link show br0]) AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:userspace-tso-enable=true]) diff --git a/tests/system-userspace-macros.at b/tests/system-userspace-macros.at index f639ba53a..24ece8e5c 100644 --- a/tests/system-userspace-macros.at +++ b/tests/system-userspace-macros.at @@ -4,7 +4,7 @@ # appropriate type and properties m4_define([_ADD_BR], [[add-br $1 -- set Bridge $1 datapath_type="netdev" protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14,OpenFlow15 fail-mode=secure ]]) -# OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], [=override]) +# OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], [pre-vswitchd-commands]) # # Creates a database and starts ovsdb-server, starts ovs-vswitchd # connected to that database, calls ovs-vsctl to create a bridge named @@ -15,7 +15,7 @@ m4_define([_ADD_BR], [[add-br $1 -- set Bridge $1 datapath_type="netdev" protoco m4_define([OVS_TRAFFIC_VSWITCHD_START], [ OVS_WAIT_WHILE([ip link show ovs-netdev]) - _OVS_VSWITCHD_START([--disable-system]) + _OVS_VSWITCHD_START([--disable-system] [] [$3]) dnl Add bridges, ports, etc. OVS_WAIT_WHILE([ip link show br0]) AT_CHECK([ovs-vsctl -- _ADD_BR([br0]) -- $1 m4_if([$2], [], [], [| uuidfilt])], [0], [$2]) From patchwork Mon May 16 15:38:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eelco Chaudron X-Patchwork-Id: 1631693 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=XhIECn3y; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4L23M31KDdz9ryY for ; Tue, 17 May 2022 01:38:55 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 639234189C; Mon, 16 May 2022 15:38:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0PU5qLSW_4F8; Mon, 16 May 2022 15:38:51 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTPS id 781AF4033C; Mon, 16 May 2022 15:38:50 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 475DFC0039; Mon, 16 May 2022 15:38:50 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id B1C06C002D for ; Mon, 16 May 2022 15:38:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 6474C418C2 for ; Mon, 16 May 2022 15:38:38 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SrdWXEdGorrQ for ; Mon, 16 May 2022 15:38:36 +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 smtp4.osuosl.org (Postfix) with ESMTPS id 2B8C941728 for ; Mon, 16 May 2022 15:38:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1652715514; 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=ioprmFUxDIXk0FMgOCKsKh6ANytnt/HupdDOCMxuOo4=; b=XhIECn3yHTpCvE/BZchZHjDFu+8wgl/4NBc0MhCMCz0zNzSmTW2PPWcff6UDF7gwOMUiZZ unzl4KW/MEKuii9p5jNlUDq0gNy8E3kuwGvLCRMkp9RaNAN6Y12aqsUM/BOZ0ftMj/rp/y apIXyLj4H5p9WvhSmUhb11aWQduO6oo= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-307-nt7AIkUVPdWb6GzjdT-bOA-1; Mon, 16 May 2022 11:38:33 -0400 X-MC-Unique: nt7AIkUVPdWb6GzjdT-bOA-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 534031C05EAB; Mon, 16 May 2022 15:38:33 +0000 (UTC) Received: from ebuild.redhat.com (unknown [10.39.195.113]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7F27254B08F; Mon, 16 May 2022 15:38:32 +0000 (UTC) From: Eelco Chaudron To: dev@openvswitch.org Date: Mon, 16 May 2022 17:38:29 +0200 Message-Id: <165271549323.991159.11630344372482125224.stgit@ebuild> In-Reply-To: <165271539292.991159.2073606707254850380.stgit@ebuild> References: <165271539292.991159.2073606707254850380.stgit@ebuild> User-Agent: StGit/1.1 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 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 v3 5/5] tests: Add check_pkt_len action test to system-offload-traffic. 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" Signed-off-by: Eelco Chaudron Acked-by: Mike Pattrick Acked-by: Roi Dayan --- v2: - Added section in the NEWS document NEWS | 2 tests/system-offloads-traffic.at | 413 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 414 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5bc8e6566..eeb23a58d 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ Post-v2.17.0 - OVSDB: * 'relay' service model now supports transaction history, i.e. honors the 'last-txn-id' field in 'monitor_cond_since' requests from clients. + - Linux datapath: + * Add support for offloading the check_pkt_len action. v2.17.0 - 17 Feb 2022 diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at index 705a50079..4cde53e2e 100644 --- a/tests/system-offloads-traffic.at +++ b/tests/system-offloads-traffic.at @@ -4,7 +4,20 @@ AT_BANNER([datapath offloads]) # # Normilizes output ports, recirc_id, packets and macs. # -m4_define([DUMP_CLEAN_SORTED], [sed -e 's/used:[[0-9]].[[0-9]]*s/used:0.001s/;s/eth(src=[[a-z0-9:]]*,dst=[[a-z0-9:]]*)/eth(macs)/;s/actions:[[0-9,]]*/actions:output/;s/recirc_id(0),//' | sort]) +m4_define([DUMP_CLEAN_SORTED], [sed -e 's/used:\([[0-9.]]*s\|never\)/used:0.001s/;s/eth(src=[[a-z0-9:]]*,dst=[[a-z0-9:]]*)/eth(macs)/;s/actions:[[0-9,]]\+/actions:output/;s/recirc_id(0),//' | sort]) + + +# AT_CHECK_ACTIONS([ACTIONS]) +# +# This extracts and matches the action for IPv4 rules for ingress port p0 +# +m4_define([AT_CHECK_ACTIONS], [ + AT_CHECK([ovs-appctl dpctl/dump-flows type=tc,offloaded | + sed -n 's/^.*in_port(2),eth(.*),eth_type(0x0800).*actions:\(.*\)/\1/p' | + tr -d '\n'], + [0], [$1]) +]) + AT_SETUP([offloads - ping between two ports - offloads disabled]) OVS_TRAFFIC_VSWITCHD_START() @@ -165,3 +178,401 @@ matchall ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP + + +AT_SETUP([offloads - check_pkt_len action - offloads disabled]) +OVS_TRAFFIC_VSWITCHD_START() + +ADD_NAMESPACES(at_ns1, at_ns2, at_ns3, at_ns4) + +ADD_VETH(p1, at_ns1, br0, "10.1.1.1/24") +ADD_VETH(p2, at_ns2, br0, "10.1.1.2/24") +ADD_VETH(p3, at_ns3, br0, "10.1.1.3/24") +ADD_VETH(p4, at_ns4, br0, "10.1.1.4/24") + +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x1 actions=output:3 +table=4,in_port=1,reg0=0x0 actions=output:4 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) + +NS_CHECK_EXEC([at_ns3], [tcpdump -l -n -U -i p3 dst 10.1.1.2 and icmp > p3.pcap 2>/dev/null &]) +NS_CHECK_EXEC([at_ns4], [tcpdump -l -n -U -i p4 dst 10.1.1.2 and icmp > p4.pcap 2>/dev/null &]) +sleep 1 + +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 1024 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED], [0], [dnl +in_port(2),eth(),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:11614, used:0.001s, actions:check_pkt_len(size=200,gt(4),le(5)),3 +in_port(3),eth(),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:11614, used:0.001s, actions:output +]) + +AT_CHECK([ovs-appctl dpctl/dump-flows type=ovs | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED], [0], [dnl +in_port(2),eth(),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:11614, used:0.001s, actions:check_pkt_len(size=200,gt(4),le(5)),3 +in_port(3),eth(),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:11614, used:0.001s, actions:output +]) + +AT_CHECK([ovs-appctl dpctl/dump-flows type=tc,offloaded], [0], []) + +AT_CHECK([test $(ovs-appctl upcall/show | grep -c "offloaded flows") -eq 0], [0], [ignore]) + +OVS_TRAFFIC_VSWITCHD_STOP + +AT_CHECK([cat p3.pcap | awk '{print $NF}' | uniq -c | awk '{$1=$1;print}'], [0], [dnl +10 1032 +]) +AT_CHECK([cat p4.pcap | awk '{print $NF}' | uniq -c | awk '{$1=$1;print}'], [0], [dnl +10 72 +]) + +AT_CLEANUP + + +AT_SETUP([offloads - check_pkt_len action - offloads enabled]) +OVS_TRAFFIC_VSWITCHD_START([], [], [ovs-vsctl --no-wait set Open_vSwitch . other_config:hw-offload=true]) + +ADD_NAMESPACES(at_ns1, at_ns2, at_ns3, at_ns4) + +ADD_VETH(p1, at_ns1, br0, "10.1.1.1/24") +ADD_VETH(p2, at_ns2, br0, "10.1.1.2/24") +ADD_VETH(p3, at_ns3, br0, "10.1.1.3/24") +ADD_VETH(p4, at_ns4, br0, "10.1.1.4/24") + +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x1 actions=output:3 +table=4,in_port=1,reg0=0x0 actions=output:4 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) + +NS_CHECK_EXEC([at_ns3], [tcpdump -l -n -U -i p3 dst 10.1.1.2 and icmp > p3.pcap 2>/dev/null &]) +NS_CHECK_EXEC([at_ns4], [tcpdump -l -n -U -i p4 dst 10.1.1.2 and icmp > p4.pcap 2>/dev/null &]) +sleep 1 + +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 1024 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED | sed 's/bytes:11348/bytes:11614/'], [0], [dnl +in_port(2),eth(),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:11614, used:0.001s, actions:check_pkt_len(size=200,gt(4),le(5)),3 +in_port(3),eth(),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:11614, used:0.001s, actions:output +]) + +AT_CHECK([ovs-appctl dpctl/dump-flows type=ovs | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED], [0], []) + +AT_CHECK([ovs-appctl dpctl/dump-flows type=tc,offloaded | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED | sed 's/bytes:11348/bytes:11614/'], [0], [dnl +in_port(2),eth(),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:11614, used:0.001s, actions:check_pkt_len(size=200,gt(4),le(5)),3 +in_port(3),eth(),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:11614, used:0.001s, actions:output +]) + +AT_CHECK([ovs-appctl upcall/show | grep -E "offloaded flows : [[1-9]]"], [0], [ignore]) + +sleep 1 +AT_CHECK([cat p3.pcap | awk '{print $NF}' | uniq -c | awk '{$1=$1;print}'], [0], [dnl +10 1032 +]) +AT_CHECK([cat p4.pcap | awk '{print $NF}' | uniq -c | awk '{$1=$1;print}'], [0], [dnl +10 72 +]) + + +# This test verifies the total packet counters work when individual branches +# are taken. + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=4,in_port=1,reg0=0x1 actions=output:2 +table=4,in_port=1,reg0=0x0 actions=output:2 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) + +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 1024 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED | sed 's/bytes:11440/bytes:11720/'], [0], [dnl +in_port(2),eth(),eth_type(0x0800),ipv4(frag=no), packets:20, bytes:11720, used:0.001s, actions:check_pkt_len(size=200,gt(3),le(3)) +in_port(3),eth(),eth_type(0x0800),ipv4(frag=no), packets:20, bytes:11720, used:0.001s, actions:output +]) + + +# The remaining tests are just to make sure the datapath flow actions are +# encoded/decoded the right way. + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=4,in_port=1,reg0=0x1 actions=output:4 +table=4,in_port=1,reg0=0x0 actions=output:2 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(5),le(3))]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=4,in_port=1,reg0=0x0 actions=output:2 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(drop),le(3))]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=4,in_port=1,reg0=0x1 actions=output:2 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 1024 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(3),le(drop))]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=4,in_port=1,reg0=0x0 actions=output:2,3 +table=4,in_port=1,reg0=0x1 actions=output:2,4 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 1024 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(3,5),le(3,4))]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x1 actions=mod_nw_tos:4,output:3 +table=4,in_port=1,reg0=0x0 actions=mod_nw_tos:8,output:4 +]) + +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) + +NS_CHECK_EXEC([at_ns3], [tcpdump -l -n -U -i p3 dst 10.1.1.2 and icmp > p3_2.pcap 2>/dev/null &]) +NS_CHECK_EXEC([at_ns4], [tcpdump -l -n -U -i p4 dst 10.1.1.2 and icmp > p4_2.pcap 2>/dev/null &]) +sleep 1 + +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 1024 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +AT_CHECK([ovs-appctl dpctl/dump-flows type=tc,offloaded | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED | sed -e 's/bytes:11348/bytes:11614/' -e 's/bytes:11440/bytes:11720/'], [0], [dnl +in_port(2),eth(),eth_type(0x0800),ipv4(proto=1,tos=0/0xfc,frag=no), packets:19, bytes:11614, used:0.001s, actions:check_pkt_len(size=200,gt(set(ipv4(tos=0x4/0xfc)),4),le(set(ipv4(tos=0x8/0xfc)),5)),3 +in_port(3),eth(),eth_type(0x0800),ipv4(frag=no), packets:20, bytes:11720, used:0.001s, actions:output +]) + +sleep 1 +AT_CHECK([cat p3_2.pcap | awk '{print $NF}' | uniq -c | awk '{$1=$1;print}'], [0], [dnl +10 1032 +]) +AT_CHECK([cat p4_2.pcap | awk '{print $NF}' | uniq -c | awk '{$1=$1;print}'], [0], [dnl +10 72 +]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x1 actions=mod_nw_tos:4,output:3 +table=4,in_port=1,reg0=0x0 actions=mod_dl_src:00:11:11:11:11:11,output:4 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(set(ipv4(tos=0x4/0xfc)),4),le(set(eth(src=00:11:11:11:11:11)),5)),3]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x1 actions=mod_dl_src:00:11:11:11:11:11,output:3 +table=4,in_port=1,reg0=0x0 actions=mod_nw_tos:8,output:4 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(set(eth(src=00:11:11:11:11:11)),4),le(set(ipv4(tos=0x8/0xfc)),5)),3]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x1 actions=output:br0 +table=4,in_port=1,reg0=0x0 actions=output:br0 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(1),le(1)),3]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x1 actions=output:br0 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(1),le(drop)),3]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x0 actions=output:br0 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 1024 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) + +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(drop),le(1)),3]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(drop),le(drop)),3]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x1 actions=check_pkt_larger(400)->NXM_NX_REG0[[0]],resubmit(,5) +table=4,in_port=1,reg0=0x0 actions=output:4 +table=5,in_port=1,reg0=0x1 actions=output:4 +table=5,in_port=1,reg0=0x0 actions=output:3 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(check_pkt_len(size=400,gt(5),le(4))),le(5)),3]) + + +AT_CHECK([ovs-appctl revalidator/wait], [0]) +AT_CHECK([ovs-ofctl del-flows br0]) +AT_DATA([flows.txt], [dnl +table=0,in_port=2 actions=output:1 +table=0,in_port=1 actions=load:0x1->NXM_NX_REG1[[]],resubmit(,1),load:0x2->NXM_NX_REG1[[]],resubmit(,1) +table=1,in_port=1,reg1=0x1 actions=check_pkt_larger(200)->NXM_NX_REG0[[0]],resubmit(,4) +table=1,in_port=1,reg1=0x2 actions=output:2 +table=4,in_port=1,reg0=0x0 actions=check_pkt_larger(100)->NXM_NX_REG0[[0]],resubmit(,5) +table=4,in_port=1,reg0=0x1 actions=output:4 +table=5,in_port=1,reg0=0x1 actions=output:4 +table=5,in_port=1,reg0=0x0 actions=output:3 +]) +AT_CHECK([ovs-ofctl --protocols=OpenFlow10 add-flows br0 flows.txt]) +sleep 1 +NS_CHECK_EXEC([at_ns1], [ping -q -c 10 -i 0.1 -w 2 -s 64 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +], [], [ovs-appctl dpctl/dump-flows; ovs-ofctl dump-flows br0]) +AT_CHECK_ACTIONS([check_pkt_len(size=200,gt(5),le(check_pkt_len(size=100,gt(5),le(4)))),3]) + + +OVS_TRAFFIC_VSWITCHD_STOP + +AT_CLEANUP