From patchwork Mon Oct 5 17:49:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1376931 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C4txR134gz9sXW for ; Tue, 6 Oct 2020 08:28:09 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 10F7020515; Mon, 5 Oct 2020 17:49:34 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Mdgq7FCSI0UC; Mon, 5 Oct 2020 17:49:26 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id DC5E620381; Mon, 5 Oct 2020 17:49:25 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id CA2F5C016F; Mon, 5 Oct 2020 17:49:25 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 90970C016F for ; Mon, 5 Oct 2020 17:49:24 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 80881870EB for ; Mon, 5 Oct 2020 17:49:24 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Jb6S2ZNMsj6c for ; Mon, 5 Oct 2020 17:49:22 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by hemlock.osuosl.org (Postfix) with ESMTPS id 36DAE870EA for ; Mon, 5 Oct 2020 17:49:22 +0000 (UTC) X-Originating-IP: 27.7.100.13 Received: from nusiddiq.home.org.com (unknown [27.7.100.13]) (Authenticated sender: numans@ovn.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 04C7F1C0004; Mon, 5 Oct 2020 17:49:17 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Mon, 5 Oct 2020 23:19:11 +0530 Message-Id: <20201005174911.4169332-1-numans@ovn.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201005174829.4169091-1-numans@ovn.org> References: <20201005174829.4169091-1-numans@ovn.org> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn 1/5] northd: Use 'enum ovn_stage' for the table value in the 'next' OVN 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" From: Numan Siddique Multiple places in ovn-northd.c hard codes the table value in the next() OVN action. This patch changes those occurrences to use ovn_stage_get_table('enum ovn_stage' value). Hard coding of the table number can result in errors if new stages are added (like the patch [1] which added new stages - ls_in_acl_hint and ls_out_acl_hint). After the patch [1], the table number was wrong for reject ACLs associated in ingress logical switch pipeline stage. Although this didn't result in any packet drops. This patch avoids such cases in the future. This patch also adds a new test case in ovn-northd.at for reject ACL flows. [1] - 209ea46bbf9d("ovn-northd: Reduce number of flows generated for stateful ACLs.") Signed-off-by: Numan Siddique Acked-by: Dumitru Ceara --- northd/ovn-northd.c | 36 ++++--- tests/ovn-northd.at | 247 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 17 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 91da319415..d5fd7da03a 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -5411,6 +5411,12 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, struct ds actions = DS_EMPTY_INITIALIZER; bool ingress = (stage == S_SWITCH_IN_ACL); + char *next_action = + xasprintf("next(pipeline=%s,table=%d);", + ingress ? "egress": "ingress", + ingress ? ovn_stage_get_table(S_SWITCH_OUT_QOS_MARK) + : ovn_stage_get_table(S_SWITCH_IN_L2_LKUP)); + /* TCP */ build_acl_log(&actions, acl); if (extra_match->length > 0) { @@ -5419,9 +5425,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, ds_put_format(&match, "ip4 && tcp && (%s)", acl->match); ds_put_format(&actions, "reg0 = 0; " "eth.dst <-> eth.src; ip4.dst <-> ip4.src; " - "tcp_reset { outport <-> inport; %s };", - ingress ? "next(pipeline=egress,table=5);" - : "next(pipeline=ingress,table=20);"); + "tcp_reset { outport <-> inport; %s };", next_action); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET + 10, ds_cstr(&match), ds_cstr(&actions), stage_hint); @@ -5434,9 +5438,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, ds_put_format(&match, "ip6 && tcp && (%s)", acl->match); ds_put_format(&actions, "reg0 = 0; " "eth.dst <-> eth.src; ip6.dst <-> ip6.src; " - "tcp_reset { outport <-> inport; %s };", - ingress ? "next(pipeline=egress,table=5);" - : "next(pipeline=ingress,table=20);"); + "tcp_reset { outport <-> inport; %s };", next_action); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET + 10, ds_cstr(&match), ds_cstr(&actions), stage_hint); @@ -5454,9 +5456,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, } ds_put_format(&actions, "reg0 = 0; " "icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; " - "outport <-> inport; %s };", - ingress ? "next(pipeline=egress,table=5);" - : "next(pipeline=ingress,table=20);"); + "outport <-> inport; %s };", next_action); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, ds_cstr(&match), ds_cstr(&actions), stage_hint); @@ -5472,13 +5472,12 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, } ds_put_format(&actions, "reg0 = 0; icmp6 { " "eth.dst <-> eth.src; ip6.dst <-> ip6.src; " - "outport <-> inport; %s };", - ingress ? "next(pipeline=egress,table=5);" - : "next(pipeline=ingress,table=20);"); + "outport <-> inport; %s };", next_action); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, ds_cstr(&match), ds_cstr(&actions), stage_hint); + free(next_action); ds_destroy(&match); ds_destroy(&actions); } @@ -9820,7 +9819,8 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_put_format(&actions, "reg%d = 0; ", j); } ds_put_format(&actions, REGBIT_EGRESS_LOOPBACK" = 1; " - "next(pipeline=ingress, table=0); };"); + "next(pipeline=ingress, table=%d); };", + ovn_stage_get_table(S_SWITCH_IN_PORT_SEC_L2)); ovn_lflow_add_with_hint(lflows, od, S_ROUTER_OUT_EGR_LOOP, 100, ds_cstr(&match), ds_cstr(&actions), &nat->header_); @@ -11006,10 +11006,11 @@ build_check_pkt_len_flows_for_lrouter( "icmp4.type = 3; /* Destination Unreachable. */ " "icmp4.code = 4; /* Frag Needed and DF was Set. */ " "icmp4.frag_mtu = %d; " - "next(pipeline=ingress, table=0); };", + "next(pipeline=ingress, table=%d); };", rp->lrp_networks.ea_s, rp->lrp_networks.ipv4_addrs[0].addr_s, - gw_mtu); + gw_mtu, + ovn_stage_get_table(S_SWITCH_IN_PORT_SEC_L2)); ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_LARGER_PKTS, 50, ds_cstr(match), ds_cstr(actions), @@ -11034,10 +11035,11 @@ build_check_pkt_len_flows_for_lrouter( "icmp6.type = 2; /* Packet Too Big. */ " "icmp6.code = 0; " "icmp6.frag_mtu = %d; " - "next(pipeline=ingress, table=0); };", + "next(pipeline=ingress, table=%d); };", rp->lrp_networks.ea_s, rp->lrp_networks.ipv6_addrs[0].addr_s, - gw_mtu); + gw_mtu, + ovn_stage_get_table(S_SWITCH_IN_PORT_SEC_L2)); ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_LARGER_PKTS, 50, ds_cstr(match), ds_cstr(actions), diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index c36c580867..d020d3921a 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -2029,3 +2029,250 @@ ovn-nbctl --wait=sb set NB_Global . options:ignore_lsp_down=true AT_CHECK([ovn-sbctl lflow-list | grep arp | grep 10\.0\.0\.1], [0], [ignore]) AT_CLEANUP + +AT_SETUP([ovn-northd -- reject ACL]) +ovn_start + +ovn-nbctl ls-add sw0 +ovn-nbctl lsp-add sw0 sw0-p1 + +ovn-nbctl ls-add sw1 +ovn-nbctl lsp-add sw1 sw1-p1 + +ovn-nbctl pg-add pg0 sw0-p1 sw1-p1 +ovn-nbctl acl-add pg0 from-lport 1002 "inport == @pg0 && ip4 && tcp && tcp.dst == 80" reject +ovn-nbctl acl-add pg0 to-lport 1003 "outport == @pg0 && ip6 && udp" reject + +ovn-nbctl --wait=hv sync + +AT_CHECK([ovn-sbctl lflow-list sw0 | grep "ls_in_acl" | grep pg0 | sort], [0], [dnl + table=7 (ls_in_acl ), priority=2002 , dnl +match=(ip4 && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=egress,table=6); };) + table=7 (ls_in_acl ), priority=2002 , dnl +match=(ip6 && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=egress,table=6); };) + table=7 (ls_in_acl ), priority=2012 , dnl +match=(ip4 && tcp && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=egress,table=6); };) + table=7 (ls_in_acl ), priority=2012 , dnl +match=(ip6 && tcp && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=egress,table=6); };) +]) + +AT_CHECK([ovn-sbctl lflow-list sw1 | grep "ls_in_acl" | grep pg0 | sort], [0], [dnl + table=7 (ls_in_acl ), priority=2002 , dnl +match=(ip4 && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=egress,table=6); };) + table=7 (ls_in_acl ), priority=2002 , dnl +match=(ip6 && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=egress,table=6); };) + table=7 (ls_in_acl ), priority=2012 , dnl +match=(ip4 && tcp && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=egress,table=6); };) + table=7 (ls_in_acl ), priority=2012 , dnl +match=(ip6 && tcp && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=egress,table=6); };) +]) + +AT_CHECK([ovn-sbctl lflow-list sw0 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl + table=5 (ls_out_acl ), priority=2003 , dnl +match=(ip4 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=(ip6 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=(ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=(ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +]) + +AT_CHECK([ovn-sbctl lflow-list sw1 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl + table=5 (ls_out_acl ), priority=2003 , dnl +match=(ip4 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=(ip6 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=(ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=(ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +]) + +ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && udp" reject + +AT_CHECK([ovn-sbctl lflow-list sw0 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl + table=5 (ls_out_acl ), priority=2002 , dnl +match=(ip4 && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2002 , dnl +match=(ip6 && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=(ip4 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=(ip6 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=(ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=(ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=(ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=(ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +]) + +AT_CHECK([ovn-sbctl lflow-list sw1 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl + table=5 (ls_out_acl ), priority=2002 , dnl +match=(ip4 && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2002 , dnl +match=(ip6 && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=(ip4 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=(ip6 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=(ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=(ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=(ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=(ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +]) + +ovn-nbctl --wait=sb acl-add pg0 to-lport 1001 "outport == @pg0 && ip" allow-related + +AT_CHECK([ovn-sbctl lflow-list sw0 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl + table=5 (ls_out_acl ), priority=2001 , dnl +match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), dnl +action=(reg0[[1]] = 1; next;) + table=5 (ls_out_acl ), priority=2001 , dnl +match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;) + table=5 (ls_out_acl ), priority=2002 , dnl +match=((reg0[[10]] == 1) && ip4 && (outport == @pg0 && ip4 && udp)), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2002 , dnl +match=((reg0[[10]] == 1) && ip6 && (outport == @pg0 && ip4 && udp)), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2002 , dnl +match=((reg0[[9]] == 1) && ip4 && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2002 , dnl +match=((reg0[[9]] == 1) && ip6 && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=((reg0[[10]] == 1) && ip4 && (outport == @pg0 && ip6 && udp)), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=((reg0[[10]] == 1) && ip6 && (outport == @pg0 && ip6 && udp)), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=((reg0[[9]] == 1) && ip4 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=((reg0[[9]] == 1) && ip6 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=((reg0[[10]] == 1) && ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=((reg0[[10]] == 1) && ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=((reg0[[9]] == 1) && ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=((reg0[[9]] == 1) && ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=((reg0[[10]] == 1) && ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=((reg0[[10]] == 1) && ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=((reg0[[9]] == 1) && ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=((reg0[[9]] == 1) && ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +]) + +AT_CHECK([ovn-sbctl lflow-list sw1 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl + table=5 (ls_out_acl ), priority=2001 , dnl +match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), dnl +action=(reg0[[1]] = 1; next;) + table=5 (ls_out_acl ), priority=2001 , dnl +match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;) + table=5 (ls_out_acl ), priority=2002 , dnl +match=((reg0[[10]] == 1) && ip4 && (outport == @pg0 && ip4 && udp)), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2002 , dnl +match=((reg0[[10]] == 1) && ip6 && (outport == @pg0 && ip4 && udp)), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2002 , dnl +match=((reg0[[9]] == 1) && ip4 && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2002 , dnl +match=((reg0[[9]] == 1) && ip6 && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=((reg0[[10]] == 1) && ip4 && (outport == @pg0 && ip6 && udp)), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=((reg0[[10]] == 1) && ip6 && (outport == @pg0 && ip6 && udp)), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=((reg0[[9]] == 1) && ip4 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2003 , dnl +match=((reg0[[9]] == 1) && ip6 && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=((reg0[[10]] == 1) && ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=((reg0[[10]] == 1) && ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=((reg0[[9]] == 1) && ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2012 , dnl +match=((reg0[[9]] == 1) && ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=((reg0[[10]] == 1) && ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=((reg0[[10]] == 1) && ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=((reg0[[9]] == 1) && ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) + table=5 (ls_out_acl ), priority=2013 , dnl +match=((reg0[[9]] == 1) && ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl +action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +]) + +AT_CLEANUP From patchwork Mon Oct 5 17:49:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1376979 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C4vnH4v7Wz9sTf for ; Tue, 6 Oct 2020 09:06:11 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 4E2E987100; Mon, 5 Oct 2020 17:49:32 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wrqRQ2rCFXHp; Mon, 5 Oct 2020 17:49:31 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 01BE2870EB; Mon, 5 Oct 2020 17:49:31 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id EAC45C016F; Mon, 5 Oct 2020 17:49:30 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id BC10FC0051 for ; Mon, 5 Oct 2020 17:49:29 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id B9610870FA for ; Mon, 5 Oct 2020 17:49:29 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id s5Pum195ZPjf for ; Mon, 5 Oct 2020 17:49:29 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by hemlock.osuosl.org (Postfix) with ESMTPS id ADC65870EB for ; Mon, 5 Oct 2020 17:49:28 +0000 (UTC) X-Originating-IP: 27.7.100.13 Received: from nusiddiq.home.org.com (unknown [27.7.100.13]) (Authenticated sender: numans@ovn.org) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 52ED62000D; Mon, 5 Oct 2020 17:49:23 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Mon, 5 Oct 2020 23:19:19 +0530 Message-Id: <20201005174919.4169397-1-numans@ovn.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201005174829.4169091-1-numans@ovn.org> References: <20201005174829.4169091-1-numans@ovn.org> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn 2/5] ovn-trace: Don't assert for next(stage=ingress, ..). 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" From: Numan Siddique The commit [1] allowed next action to advance from ingress to egress pipeline, but ovn-trace was not modified to handle this condition. Also corrected the ovntrace node format message as per the next stage. [1] - b4b68177eb2f("Fix conntrack entry leaks because of TCP RST packets not sent to conntrack.") Fixes: b4b68177eb2f("Fix conntrack entry leaks because of TCP RST packets not sent to conntrack.") Signed-off-by: Numan Siddique Acked-by: Dumitru Ceara --- utilities/ovn-trace.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c index 33afc4f43c..0920ae1599 100644 --- a/utilities/ovn-trace.c +++ b/utilities/ovn-trace.c @@ -1888,12 +1888,15 @@ execute_next(const struct ovnact_next *next, enum ovnact_pipeline pipeline, struct ovs_list *super) { if (pipeline != next->pipeline) { - ovs_assert(next->pipeline == OVNACT_P_INGRESS); - - uint16_t in_key = uflow->regs[MFF_LOG_INPORT - MFF_REG0]; + uint16_t key = next->pipeline == OVNACT_P_INGRESS + ? uflow->regs[MFF_LOG_INPORT - MFF_REG0] + : uflow->regs[MFF_LOG_OUTPORT - MFF_REG0]; struct ovntrace_node *node = ovntrace_node_append( - super, OVNTRACE_NODE_PIPELINE, "ingress(dp=\"%s\", inport=\"%s\")", - dp->friendly_name, ovntrace_port_key_to_name(dp, in_key)); + super, OVNTRACE_NODE_PIPELINE, "%s(dp=\"%s\", %s=\"%s\")", + next->pipeline == OVNACT_P_INGRESS ? "ingress" : "egress", + dp->friendly_name, + next->pipeline == OVNACT_P_INGRESS ? "inport" : "outport", + ovntrace_port_key_to_name(dp, key)); super = &node->subs; } trace__(dp, uflow, next->ltable, next->pipeline, super); From patchwork Mon Oct 5 17:49:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1376937 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C4txq0WXZzB3xG for ; Tue, 6 Oct 2020 08:28:30 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id F2DA6859F4; Mon, 5 Oct 2020 17:49:40 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1hzbNWpGOXeB; Mon, 5 Oct 2020 17:49:39 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 01EF5859BA; Mon, 5 Oct 2020 17:49:39 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id C542FC07FF; Mon, 5 Oct 2020 17:49:38 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id A047EC0051 for ; Mon, 5 Oct 2020 17:49:37 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 8FD1187104 for ; Mon, 5 Oct 2020 17:49:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rfX5q4Jgl64W for ; Mon, 5 Oct 2020 17:49:36 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by hemlock.osuosl.org (Postfix) with ESMTPS id 0B40387102 for ; Mon, 5 Oct 2020 17:49:35 +0000 (UTC) Received: from nusiddiq.home.org.com (unknown [27.7.100.13]) (Authenticated sender: numans@ovn.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id A229410000B; Mon, 5 Oct 2020 17:49:31 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Mon, 5 Oct 2020 23:19:25 +0530 Message-Id: <20201005174925.4169461-1-numans@ovn.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201005174829.4169091-1-numans@ovn.org> References: <20201005174829.4169091-1-numans@ovn.org> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn 3/5] actions: Add a new OVN action - reject {}. 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" From: Numan Siddique This action is similar to tcp_reset and icmp4/icmp6 action. If the matching packet is an IPv4 of IPv6 TCP packet, it sends out TCP RST packet else it sends out ICMPv4 or ICMPv6 Destination unreachable packet. A future patch will make use of this action for reject ACL. Signed-off-by: Numan Siddique --- controller/pinctrl.c | 17 +++++++++++++++++ include/ovn/actions.h | 9 ++++++++- lib/actions.c | 22 ++++++++++++++++++++++ ovn-sb.xml | 10 ++++++++++ tests/ovn.at | 12 ++++++++++++ utilities/ovn-trace.c | 22 ++++++++++++++++++++++ 6 files changed, 91 insertions(+), 1 deletion(-) diff --git a/controller/pinctrl.c b/controller/pinctrl.c index 0a7020533b..631d058458 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -1670,6 +1670,18 @@ pinctrl_handle_tcp_reset(struct rconn *swconn, const struct flow *ip_flow, dp_packet_uninit(&packet); } +static void +pinctrl_handle_reject(struct rconn *swconn, const struct flow *ip_flow, + struct dp_packet *pkt_in, + const struct match *md, struct ofpbuf *userdata) +{ + if (ip_flow->nw_proto == IPPROTO_TCP) { + pinctrl_handle_tcp_reset(swconn, ip_flow, pkt_in, md, userdata); + } else { + pinctrl_handle_icmp(swconn, ip_flow, pkt_in, md, userdata, true); + } +} + static bool is_dhcp_flags_broadcast(ovs_be16 flags) { @@ -2787,6 +2799,11 @@ process_packet_in(struct rconn *swconn, const struct ofp_header *msg) &userdata); break; + case ACTION_OPCODE_REJECT: + pinctrl_handle_reject(swconn, &headers, &packet, &pin.flow_metadata, + &userdata); + break; + case ACTION_OPCODE_PUT_ICMP4_FRAG_MTU: case ACTION_OPCODE_PUT_ICMP6_FRAG_MTU: pinctrl_handle_put_icmp_frag_mtu(swconn, &headers, &packet, &pin, diff --git a/include/ovn/actions.h b/include/ovn/actions.h index 636cb4bc1a..b4e5acabb9 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -95,7 +95,8 @@ struct ovn_extend_table; OVNACT(HANDLE_SVC_CHECK, ovnact_handle_svc_check) \ OVNACT(FWD_GROUP, ovnact_fwd_group) \ OVNACT(DHCP6_REPLY, ovnact_null) \ - OVNACT(ICMP6_ERROR, ovnact_nest) + OVNACT(ICMP6_ERROR, ovnact_nest) \ + OVNACT(REJECT, ovnact_nest) \ /* enum ovnact_type, with a member OVNACT_ for each action. */ enum OVS_PACKED_ENUM ovnact_type { @@ -605,6 +606,12 @@ enum action_opcode { /* MTU value (to put in the icmp6 header field - frag_mtu) follow the * action header. */ ACTION_OPCODE_PUT_ICMP6_FRAG_MTU, + + /* "reject { ...actions... }". + * + * The actions, in OpenFlow 1.3 format, follow the action_header. + */ + ACTION_OPCODE_REJECT, }; /* Header. */ diff --git a/lib/actions.c b/lib/actions.c index 5fe0a3897e..1e1bdeff24 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -1386,6 +1386,12 @@ parse_CLONE(struct action_context *ctx) parse_nested_action(ctx, OVNACT_CLONE, NULL, WR_DEFAULT); } +static void +parse_REJECT(struct action_context *ctx) +{ + parse_nested_action(ctx, OVNACT_REJECT, NULL, ctx->scope); +} + static void format_nested_action(const struct ovnact_nest *on, const char *name, struct ds *s) @@ -1479,6 +1485,12 @@ format_TRIGGER_EVENT(const struct ovnact_controller_event *event, ds_put_cstr(s, ");"); } +static void +format_REJECT(const struct ovnact_nest *nest, struct ds *s) +{ + format_nested_action(nest, "reject", s); +} + static void encode_nested_actions(const struct ovnact_nest *on, const struct ovnact_encode_params *ep, @@ -1560,6 +1572,14 @@ encode_TCP_RESET(const struct ovnact_nest *on, encode_nested_actions(on, ep, ACTION_OPCODE_TCP_RESET, ofpacts); } +static void +encode_REJECT(const struct ovnact_nest *on, + const struct ovnact_encode_params *ep, + struct ofpbuf *ofpacts) +{ + encode_nested_actions(on, ep, ACTION_OPCODE_REJECT, ofpacts); +} + static void encode_ND_NA(const struct ovnact_nest *on, const struct ovnact_encode_params *ep, @@ -3567,6 +3587,8 @@ parse_action(struct action_context *ctx) parse_fwd_group_action(ctx); } else if (lexer_match_id(ctx->lexer, "handle_dhcpv6_reply")) { ovnact_put_DHCP6_REPLY(ctx->ovnacts); + } else if (lexer_match_id(ctx->lexer, "reject")) { + parse_REJECT(ctx); } else { lexer_syntax_error(ctx->lexer, "expecting action"); } diff --git a/ovn-sb.xml b/ovn-sb.xml index 59888a1553..2fc84f54ee 100644 --- a/ovn-sb.xml +++ b/ovn-sb.xml @@ -2191,6 +2191,16 @@ tcp.flags = RST;

Prerequisite: tcp

+
reject { action; ... };
+
+

+ If the original packet is IPv4 or IPv6 TCP packet, it replaces it + with IPv4 or IPv6 TCP RST packet and executes the inner actions. + Otherwise it replaces it with an ICMPv4 or ICMPv6 packet and + executes the inner actions. +

+
+
trigger_event;

diff --git a/tests/ovn.at b/tests/ovn.at index 7769b69ed0..d849425f00 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -1593,6 +1593,18 @@ tcp_reset { }; encodes as controller(userdata=00.00.00.0b.00.00.00.00) has prereqs tcp +# reject +reject { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output; + encodes as controller(userdata=00.00.00.16.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64) + +reject { eth.dst <-> eth.src; ip4.src <-> ip4.dst; output; }; + encodes as controller(userdata=00.00.00.16.00.00.00.00.ff.ff.00.18.00.00.23.20.00.1b.00.00.00.00.04.06.00.30.00.00.00.00.00.00.ff.ff.00.18.00.00.23.20.00.1b.00.00.00.00.02.06.00.30.00.00.00.00.00.00.ff.ff.00.18.00.00.23.20.00.1c.00.00.00.00.04.06.00.30.00.00.00.00.00.00.ff.ff.00.18.00.00.23.20.00.1c.00.00.00.00.02.06.00.30.00.00.00.00.00.00.ff.ff.00.18.00.00.23.20.00.1b.00.00.00.00.10.04.00.20.00.00.00.00.00.00.ff.ff.00.18.00.00.23.20.00.1b.00.00.00.00.0e.04.00.20.00.00.00.00.00.00.ff.ff.00.18.00.00.23.20.00.1c.00.00.00.00.10.04.00.20.00.00.00.00.00.00.ff.ff.00.18.00.00.23.20.00.1c.00.00.00.00.0e.04.00.20.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00) + has prereqs eth.type == 0x800 && eth.type == 0x800 + +reject { }; + formats as reject { drop; }; + encodes as controller(userdata=00.00.00.16.00.00.00.00) + # trigger_event trigger_event(event = "empty_lb_backends", vip = "10.0.0.1:80", protocol = "tcp", load_balancer = "12345678-abcd-9876-fedc-11119f8e7d6c"); encodes as controller(userdata=00.00.00.0f.00.00.00.00.00.00.00.00.00.01.00.0b.31.30.2e.30.2e.30.2e.31.3a.38.30.00.02.00.03.74.63.70.00.03.00.24.31.32.33.34.35.36.37.38.2d.61.62.63.64.2d.39.38.37.36.2d.66.65.64.63.2d.31.31.31.31.39.66.38.65.37.64.36.63) diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c index 0920ae1599..38aee6081b 100644 --- a/utilities/ovn-trace.c +++ b/utilities/ovn-trace.c @@ -1711,6 +1711,23 @@ execute_tcp_reset(const struct ovnact_nest *on, table_id, pipeline, &node->subs); } +static void +execute_reject(const struct ovnact_nest *on, + const struct ovntrace_datapath *dp, + const struct flow *uflow, uint8_t table_id, + enum ovnact_pipeline pipeline, struct ovs_list *super) +{ + if (uflow->nw_proto == IPPROTO_TCP) { + execute_tcp_reset(on, dp, uflow, table_id, pipeline, super); + } else { + if (get_dl_type(uflow) == htons(ETH_TYPE_IP)) { + execute_icmp4(on, dp, uflow, table_id, pipeline, super); + } else { + execute_icmp6(on, dp, uflow, table_id, pipeline, super); + } + } +} + static void execute_get_mac_bind(const struct ovnact_get_mac_bind *bind, const struct ovntrace_datapath *dp, @@ -2347,6 +2364,11 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len, execute_ovnfield_load(ovnact_get_OVNFIELD_LOAD(a), super); break; + case OVNACT_REJECT: + execute_reject(ovnact_get_REJECT(a), dp, uflow, table_id, + pipeline, super); + break; + case OVNACT_TRIGGER_EVENT: break; From patchwork Mon Oct 5 17:49:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1376930 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C4txR33HFzB3x6 for ; Tue, 6 Oct 2020 08:28:08 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id A48BB20535; Mon, 5 Oct 2020 17:50:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DegBP4KkfMJx; Mon, 5 Oct 2020 17:50:18 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 4B22920523; Mon, 5 Oct 2020 17:49:55 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2991EC0051; Mon, 5 Oct 2020 17:49:55 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 053BEC016F for ; Mon, 5 Oct 2020 17:49:54 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id E163D86718 for ; Mon, 5 Oct 2020 17:49:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YNfRcMVYkZH7 for ; Mon, 5 Oct 2020 17:49:44 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by whitealder.osuosl.org (Postfix) with ESMTPS id D8DAA866FE for ; Mon, 5 Oct 2020 17:49:42 +0000 (UTC) X-Originating-IP: 27.7.100.13 Received: from nusiddiq.home.org.com (unknown [27.7.100.13]) (Authenticated sender: numans@ovn.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id DE8521C0004; Mon, 5 Oct 2020 17:49:39 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Mon, 5 Oct 2020 23:19:33 +0530 Message-Id: <20201005174933.4169535-1-numans@ovn.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201005174829.4169091-1-numans@ovn.org> References: <20201005174829.4169091-1-numans@ovn.org> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn 4/5] actions: Add new OVN logical fields 'ip.src' and ip.dst'. 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" From: Numan Siddique Thee new fields are version independent and these can be used in any OVN action. Right now the usage of these fields are restricted to exchanging the IP source and destination fields. Eg. reject {... ip.src <-> ip.dst ... }; "ip.src <-> ip.dst" translates to controller action with "pause" flag set. When pinctrl thread receives the packet in, it checks the IP version of the packet and either does - "ip4.src <-> ip4.dst" or "ip6.src <-> ip6.dst" and resumes the packet to continue with the pipeline. Upcoming patch will make use of these fields. Signed-off-by: Numan Siddique --- controller/pinctrl.c | 49 +++++++++++++++ include/ovn/actions.h | 4 ++ include/ovn/logical-fields.h | 18 ++++++ lib/actions.c | 115 +++++++++++++++++++++++++++++++++++ lib/logical-fields.c | 10 +++ ovn-sb.xml | 37 +++++++++++ tests/ovn.at | 27 ++++++++ utilities/ovn-trace.c | 28 +++++++++ 8 files changed, 288 insertions(+) diff --git a/controller/pinctrl.c b/controller/pinctrl.c index 631d058458..bc16a82404 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -233,6 +233,11 @@ static void pinctrl_handle_put_icmp_frag_mtu(struct rconn *swconn, struct ofputil_packet_in *pin, struct ofpbuf *userdata, struct ofpbuf *continuation); +static void pinctrl_handle_swap_src_dst_ip(struct rconn *swconn, + const struct flow *in_flow, + struct dp_packet *pkt_in, + struct ofputil_packet_in *pin, + struct ofpbuf *continuation); static void pinctrl_handle_event(struct ofpbuf *userdata) OVS_REQUIRES(pinctrl_mutex); @@ -2835,6 +2840,11 @@ process_packet_in(struct rconn *swconn, const struct ofp_header *msg) ovs_mutex_unlock(&pinctrl_mutex); break; + case ACTION_OPCODE_SWAP_SRC_DST_IP: + pinctrl_handle_swap_src_dst_ip(swconn, &headers, &packet, &pin, + &continuation); + break; + default: VLOG_WARN_RL(&rl, "unrecognized packet-in opcode %"PRIu32, ntohl(ah->opcode)); @@ -6508,3 +6518,42 @@ pinctrl_handle_svc_check(struct rconn *swconn, const struct flow *ip_flow, svc_mon->next_send_time = time_msec() + svc_mon->interval; } } + +static void +pinctrl_handle_swap_src_dst_ip(struct rconn *swconn, + const struct flow *in_flow, + struct dp_packet *pkt_in, + struct ofputil_packet_in *pin, + struct ofpbuf *continuation) +{ + enum ofp_version version = rconn_get_version(swconn); + enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version); + struct dp_packet *pkt_out; + + pkt_out = dp_packet_clone(pkt_in); + pkt_out->l2_5_ofs = pkt_in->l2_5_ofs; + pkt_out->l2_pad_size = pkt_in->l2_pad_size; + pkt_out->l3_ofs = pkt_in->l3_ofs; + pkt_out->l4_ofs = pkt_in->l4_ofs; + + if (get_dl_type(in_flow) == htons(ETH_TYPE_IP)) { + /* IPv4 packet. Swap nw_src with nw_dst. */ + packet_set_ipv4(pkt_out, in_flow->nw_dst, in_flow->nw_src, + in_flow->nw_tos, in_flow->nw_ttl); + } else { + /* IPv6 packet. Swap ip6_src with ip6_dst. + * We could also use packet_set_ipv6() here, but that would require + * to extract the 'tc' and 'label' from in_nh->ip6_flow which seems + * unnecessary. */ + struct ovs_16aligned_ip6_hdr *out_nh = dp_packet_l3(pkt_out); + union ovs_16aligned_in6_addr tmp = out_nh->ip6_src; + out_nh->ip6_src = out_nh->ip6_dst; + out_nh->ip6_dst = tmp; + } + + pin->packet = dp_packet_data(pkt_out); + pin->packet_len = dp_packet_size(pkt_out); + + queue_msg(swconn, ofputil_encode_resume(pin, continuation, proto)); + dp_packet_delete(pkt_out); +} diff --git a/include/ovn/actions.h b/include/ovn/actions.h index b4e5acabb9..bf1fe848b7 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -97,6 +97,7 @@ struct ovn_extend_table; OVNACT(DHCP6_REPLY, ovnact_null) \ OVNACT(ICMP6_ERROR, ovnact_nest) \ OVNACT(REJECT, ovnact_nest) \ + OVNACT(OVNFIELD_EXCHANGE, ovnact_move) \ /* enum ovnact_type, with a member OVNACT_ for each action. */ enum OVS_PACKED_ENUM ovnact_type { @@ -612,6 +613,9 @@ enum action_opcode { * The actions, in OpenFlow 1.3 format, follow the action_header. */ ACTION_OPCODE_REJECT, + + /* ip.src <-> ip.dst */ + ACTION_OPCODE_SWAP_SRC_DST_IP, }; /* Header. */ diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h index ac6f2f909b..bb6daa50ca 100644 --- a/include/ovn/logical-fields.h +++ b/include/ovn/logical-fields.h @@ -116,6 +116,24 @@ enum ovn_field_id { */ OVN_ICMP6_FRAG_MTU, + /* + * Name: "ip.src" + * Type: be128 + * Description: Sets the field MFF_IPV4_SRC if eth.type == 0x800 (IPv4) + * or sets the field MFF_IPV6_SRC if + * eth.type == 0x86dd (IPV6). + */ + OVN_IP_SRC, + + /* + * Name: "ip.dst" + * Type: be128 + * Description: Sets the field MFF_IPV4_DST if eth.type == 0x800 (IPv4) + * or sets the field MFF_IPV6_DST if + * eth.type == 0x86dd (IPV6). + */ + OVN_IP_DST, + OVN_FIELD_N_IDS }; diff --git a/lib/actions.c b/lib/actions.c index 1e1bdeff24..da583f9c93 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -371,12 +371,35 @@ ovnact_next_free(struct ovnact_next *a OVS_UNUSED) { } +static bool +check_ovnfield_load(struct action_context *ctx, const struct expr_field *field) +{ + switch (field->symbol->ovn_field->id) { + case OVN_ICMP4_FRAG_MTU: + case OVN_ICMP6_FRAG_MTU: + return true; + + case OVN_IP_SRC: + case OVN_IP_DST: + lexer_error(ctx->lexer, "Can't load a value to ovn field (%s).", + field->symbol->name); + return false; + + case OVN_FIELD_N_IDS: + default: + OVS_NOT_REACHED(); + } +} + static void parse_LOAD(struct action_context *ctx, const struct expr_field *lhs) { size_t ofs = ctx->ovnacts->size; struct ovnact_load *load; if (lhs->symbol->ovn_field) { + if (!check_ovnfield_load(ctx, lhs)) { + return; + } load = ovnact_put_OVNFIELD_LOAD(ctx->ovnacts); } else { load = ovnact_put_LOAD(ctx->ovnacts); @@ -474,6 +497,43 @@ format_EXCHANGE(const struct ovnact_move *move, struct ds *s) format_assignment(move, "<->", s); } +static void +parse_ovnfield_exchange(struct action_context *ctx, + const struct expr_field *lhs, + const struct expr_field *rhs) +{ + if (!lhs->symbol->ovn_field || !rhs->symbol->ovn_field) { + lexer_error(ctx->lexer, + "Can't exchange ovn field with non ovn field (%s <-> %s).", + lhs->symbol->name, rhs->symbol->name); + return; + } + + if (lhs->symbol->ovn_field->id != OVN_IP_SRC && + lhs->symbol->ovn_field->id != OVN_IP_DST) { + lexer_error(ctx->lexer, + "Can't exchange ovn field (%s) with ovn field (%s).", + lhs->symbol->name, rhs->symbol->name); + } + + if (rhs->symbol->ovn_field->id != OVN_IP_SRC && + rhs->symbol->ovn_field->id != OVN_IP_DST) { + lexer_error(ctx->lexer, + "Can't exchange ovn field (%s) with ovn field (%s).", + lhs->symbol->name, rhs->symbol->name); + } + + if (lhs->symbol->ovn_field->id == rhs->symbol->ovn_field->id) { + lexer_error(ctx->lexer, + "Can't exchange ovn field (%s) with ovn field (%s).", + lhs->symbol->name, rhs->symbol->name); + } + + struct ovnact_move *move = ovnact_put_OVNFIELD_EXCHANGE(ctx->ovnacts); + move->lhs = *lhs; + move->rhs = *rhs; +} + static void parse_assignment_action(struct action_context *ctx, bool exchange, const struct expr_field *lhs) @@ -483,6 +543,11 @@ parse_assignment_action(struct action_context *ctx, bool exchange, return; } + if (exchange && (lhs->symbol->ovn_field || rhs.symbol->ovn_field)) { + parse_ovnfield_exchange(ctx, lhs, &rhs); + return; + } + const struct expr_symbol *ls = lhs->symbol; const struct expr_symbol *rs = rhs.symbol; if ((ls->width != 0) != (rs->width != 0)) { @@ -3128,6 +3193,8 @@ format_OVNFIELD_LOAD(const struct ovnact_load *load , struct ds *s) ntohs(load->imm.value.be16_int)); break; + case OVN_IP_SRC: + case OVN_IP_DST: case OVN_FIELD_N_IDS: default: OVS_NOT_REACHED(); @@ -3157,6 +3224,9 @@ encode_OVNFIELD_LOAD(const struct ovnact_load *load, encode_finish_controller_op(oc_offset, ofpacts); break; } + + case OVN_IP_SRC: + case OVN_IP_DST: case OVN_FIELD_N_IDS: default: OVS_NOT_REACHED(); @@ -3451,6 +3521,51 @@ ovnact_fwd_group_free(struct ovnact_fwd_group *fwd_group) free(fwd_group->child_ports); } +static void +format_OVNFIELD_EXCHANGE(const struct ovnact_move *move , struct ds *s) +{ + const struct ovn_field *lhs = ovn_field_from_name(move->lhs.symbol->name); + const struct ovn_field *rhs = ovn_field_from_name(move->rhs.symbol->name); + switch (lhs->id) { + case OVN_IP_SRC: + case OVN_IP_DST: + break; + + case OVN_ICMP4_FRAG_MTU: + case OVN_ICMP6_FRAG_MTU: + case OVN_FIELD_N_IDS: + default: + OVS_NOT_REACHED(); + } + + switch (rhs->id) { + case OVN_IP_SRC: + case OVN_IP_DST: + break; + + case OVN_ICMP4_FRAG_MTU: + case OVN_ICMP6_FRAG_MTU: + case OVN_FIELD_N_IDS: + default: + OVS_NOT_REACHED(); + } + + ds_put_format(s, "%s <-> %s;", lhs->name, rhs->name); +} + +static void +encode_OVNFIELD_EXCHANGE(const struct ovnact_move *move OVS_UNUSED, + const struct ovnact_encode_params *ep OVS_UNUSED, + struct ofpbuf *ofpacts OVS_UNUSED) +{ + /* Right now we only support exchanging the IPs in + * OVN fields (ip.src <-> ip.dst). */ + size_t oc_offset = + encode_start_controller_op(ACTION_OPCODE_SWAP_SRC_DST_IP, + true, NX_CTLR_NO_METER, ofpacts); + encode_finish_controller_op(oc_offset, ofpacts); +} + /* Parses an assignment or exchange or put_dhcp_opts action. */ static void parse_set_action(struct action_context *ctx) diff --git a/lib/logical-fields.c b/lib/logical-fields.c index bf61df7719..d6f1981f52 100644 --- a/lib/logical-fields.c +++ b/lib/logical-fields.c @@ -33,6 +33,14 @@ const struct ovn_field ovn_fields[OVN_FIELD_N_IDS] = { OVN_ICMP6_FRAG_MTU, "icmp6.frag_mtu", 4, 32, + }, { + OVN_IP_SRC, + "ip.src", + 16, 128, + }, { + OVN_IP_DST, + "ip.dst", + 16, 128, }, }; @@ -271,6 +279,8 @@ ovn_init_symtab(struct shash *symtab) expr_symtab_add_ovn_field(symtab, "icmp4.frag_mtu", OVN_ICMP4_FRAG_MTU); expr_symtab_add_ovn_field(symtab, "icmp6.frag_mtu", OVN_ICMP6_FRAG_MTU); + expr_symtab_add_ovn_field(symtab, "ip.src", OVN_IP_SRC); + expr_symtab_add_ovn_field(symtab, "ip.dst", OVN_IP_DST); } const char * diff --git a/ovn-sb.xml b/ovn-sb.xml index 2fc84f54ee..73ee543bfe 100644 --- a/ovn-sb.xml +++ b/ovn-sb.xml @@ -1258,6 +1258,43 @@ except that the two values are exchanged instead of copied. Both field1 and field2 must modifiable.

+ +

+ OVN supports exchange of below OVN logical fields. +

+ +
    +
  • + ip.src + ip.dst +

    + These fields can be used to refer to IP source and destination + fields which are IP version independent. These fields can be + used only for exchange of values. +

    +
  • + +
  • +

    + Below are few examples: +

    + +

    + match = "ip && tcp" + action = "ip.src <-> ip.dst; next;" +

    + +

    + match = "ip4 || ip6" + action = reject { ip.src <-> ip.dst; } next;" +

    + +

    + match = "ip && (tcp || udp)" + action = "ip.src <-> ip.dst; next;" +

    +
  • +
ip.ttl--;
diff --git a/tests/ovn.at b/tests/ovn.at index d849425f00..9fb22c03d3 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -1605,6 +1605,33 @@ reject { }; formats as reject { drop; }; encodes as controller(userdata=00.00.00.16.00.00.00.00) +ip.src <-> ip.dst; + encodes as controller(userdata=00.00.00.17.00.00.00.00,pause) + +ip.src <-> ip.dst + Syntax error at end of input expecting `;'. + +ip.src = 10.0.0.10; + Can't load a value to ovn field (ip.src). + +ip.dst = aef0::4; + Can't load a value to ovn field (ip.dst). + +ip.src <-> ip4.dst; + Can't exchange ovn field with non ovn field (ip.src <-> ip4.dst). + +ip6.src <-> ip.dst; + Can't exchange ovn field with non ovn field (ip6.src <-> ip.dst). + +ip.src <-> icmp4.frag_mtu; + Can't exchange ovn field (ip.src) with ovn field (icmp4.frag_mtu). + +icmp6.frag_mtu <-> ip.dst; + Can't exchange ovn field (icmp6.frag_mtu) with ovn field (ip.dst). + +ip.src <-> ip.src; + Can't exchange ovn field (ip.src) with ovn field (ip.src). + # trigger_event trigger_event(event = "empty_lb_backends", vip = "10.0.0.1:80", protocol = "tcp", load_balancer = "12345678-abcd-9876-fedc-11119f8e7d6c"); encodes as controller(userdata=00.00.00.0f.00.00.00.00.00.00.00.00.00.01.00.0b.31.30.2e.30.2e.30.2e.31.3a.38.30.00.02.00.03.74.63.70.00.03.00.24.31.32.33.34.35.36.37.38.2d.61.62.63.64.2d.39.38.37.36.2d.66.65.64.63.2d.31.31.31.31.39.66.38.65.37.64.36.63) diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c index 38aee6081b..ed7d8bf278 100644 --- a/utilities/ovn-trace.c +++ b/utilities/ovn-trace.c @@ -2147,12 +2147,35 @@ execute_ovnfield_load(const struct ovnact_load *load, ntohs(load->imm.value.be16_int)); break; } + + case OVN_IP_SRC: + case OVN_IP_DST: case OVN_FIELD_N_IDS: default: OVS_NOT_REACHED(); } } +static void +execute_ovnfield_exchange(const struct ovnact_move *move OVS_UNUSED, + struct flow *uflow, + struct ovs_list *super) +{ + /* Right now we support exchanging of ip.src with ip.dst. */ + ovntrace_node_append(super, OVNTRACE_NODE_MODIFY, + "ip.src <-> ip.dst"); + + if (get_dl_type(uflow) == htons(ETH_TYPE_IP)) { + ovs_be32 tmp = uflow->nw_dst; + uflow->nw_dst = uflow->nw_src; + uflow->nw_src = tmp; + } else { + struct in6_addr tmp = uflow->ipv6_dst; + uflow->ipv6_dst = uflow->ipv6_src; + uflow->ipv6_src = tmp; + } +} + static void trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len, const struct ovntrace_datapath *dp, struct flow *uflow, @@ -2369,6 +2392,11 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len, pipeline, super); break; + case OVNACT_OVNFIELD_EXCHANGE: + execute_ovnfield_exchange(ovnact_get_OVNFIELD_EXCHANGE(a), + uflow, super); + break; + case OVNACT_TRIGGER_EVENT: break; From patchwork Mon Oct 5 17:49:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1376980 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C4vnH6TzZz9sTs for ; Tue, 6 Oct 2020 09:06:11 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 166C98713B; Mon, 5 Oct 2020 17:50:06 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id djukJrVbtBag; Mon, 5 Oct 2020 17:49:59 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 810BE8712E; Mon, 5 Oct 2020 17:49:56 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5BF4FC0895; Mon, 5 Oct 2020 17:49:56 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id A6A9CC016F for ; Mon, 5 Oct 2020 17:49:54 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id A10BB87102 for ; Mon, 5 Oct 2020 17:49:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8tir4+fiE80f for ; Mon, 5 Oct 2020 17:49:52 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by hemlock.osuosl.org (Postfix) with ESMTPS id 8516E87109 for ; Mon, 5 Oct 2020 17:49:51 +0000 (UTC) X-Originating-IP: 27.7.100.13 Received: from nusiddiq.home.org.com (unknown [27.7.100.13]) (Authenticated sender: numans@ovn.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id 19E2CE0002; Mon, 5 Oct 2020 17:49:46 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Mon, 5 Oct 2020 23:19:41 +0530 Message-Id: <20201005174941.4169599-1-numans@ovn.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201005174829.4169091-1-numans@ovn.org> References: <20201005174829.4169091-1-numans@ovn.org> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn 5/5] ovn-northd: Optimize logical flow generation for reject ACLs. 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" From: Numan Siddique ovn-northd adds below lflows for a reject ACL with a match - M match = (ip4 && tcp && 'M') action = tcp_reject{} match = (ip6 && tcp && 'M') action = tcp_reject{} match = (ip4 && 'M') action = icmp4{} match = (ip6 && 'M') action = icmp6{} This approach has a couple of problems: - ovn-controller can reject the lflows if there are invalid matches. Eg. If match 'M' is - 'ip4 && udp'. - In a large scale deployment, this could result in lot of invalid logical flows and increase the size of the SB DB. This patch addresses this problem by using newly added reject OVN action. With this patch, there will be just one lflow for each reject ACL. Signed-off-by: Numan Siddique --- northd/ovn-northd.c | 50 +---------- tests/ovn-northd.at | 214 +++++++------------------------------------- tests/system-ovn.at | 46 +++++++++- 3 files changed, 81 insertions(+), 229 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index d5fd7da03a..12a27611cc 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -5422,57 +5422,15 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, if (extra_match->length > 0) { ds_put_format(&match, "(%s) && ", extra_match->string); } - ds_put_format(&match, "ip4 && tcp && (%s)", acl->match); - ds_put_format(&actions, "reg0 = 0; " - "eth.dst <-> eth.src; ip4.dst <-> ip4.src; " - "tcp_reset { outport <-> inport; %s };", next_action); - ovn_lflow_add_with_hint(lflows, od, stage, - acl->priority + OVN_ACL_PRI_OFFSET + 10, - ds_cstr(&match), ds_cstr(&actions), stage_hint); - ds_clear(&match); - ds_clear(&actions); - build_acl_log(&actions, acl); - if (extra_match->length > 0) { - ds_put_format(&match, "(%s) && ", extra_match->string); - } - ds_put_format(&match, "ip6 && tcp && (%s)", acl->match); - ds_put_format(&actions, "reg0 = 0; " - "eth.dst <-> eth.src; ip6.dst <-> ip6.src; " - "tcp_reset { outport <-> inport; %s };", next_action); - ovn_lflow_add_with_hint(lflows, od, stage, - acl->priority + OVN_ACL_PRI_OFFSET + 10, - ds_cstr(&match), ds_cstr(&actions), stage_hint); + ds_put_cstr(&match, acl->match); - /* IP traffic */ - ds_clear(&match); - ds_clear(&actions); - build_acl_log(&actions, acl); - if (extra_match->length > 0) { - ds_put_format(&match, "(%s) && ", extra_match->string); - } - ds_put_format(&match, "ip4 && (%s)", acl->match); if (extra_actions->length > 0) { ds_put_format(&actions, "%s ", extra_actions->string); } + ds_put_format(&actions, "reg0 = 0; " - "icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; " - "outport <-> inport; %s };", next_action); - ovn_lflow_add_with_hint(lflows, od, stage, - acl->priority + OVN_ACL_PRI_OFFSET, - ds_cstr(&match), ds_cstr(&actions), stage_hint); - ds_clear(&match); - ds_clear(&actions); - build_acl_log(&actions, acl); - if (extra_match->length > 0) { - ds_put_format(&match, "(%s) && ", extra_match->string); - } - ds_put_format(&match, "ip6 && (%s)", acl->match); - if (extra_actions->length > 0) { - ds_put_format(&actions, "%s ", extra_actions->string); - } - ds_put_format(&actions, "reg0 = 0; icmp6 { " - "eth.dst <-> eth.src; ip6.dst <-> ip6.src; " - "outport <-> inport; %s };", next_action); + "reject { eth.dst <-> eth.src; ip.dst <-> ip.src; " + "outport <-> inport; %s };", next_action); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, ds_cstr(&match), ds_cstr(&actions), stage_hint); diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index d020d3921a..fe92a99533 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -2047,232 +2047,86 @@ ovn-nbctl --wait=hv sync AT_CHECK([ovn-sbctl lflow-list sw0 | grep "ls_in_acl" | grep pg0 | sort], [0], [dnl table=7 (ls_in_acl ), priority=2002 , dnl -match=(ip4 && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=egress,table=6); };) - table=7 (ls_in_acl ), priority=2002 , dnl -match=(ip6 && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=egress,table=6); };) - table=7 (ls_in_acl ), priority=2012 , dnl -match=(ip4 && tcp && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=egress,table=6); };) - table=7 (ls_in_acl ), priority=2012 , dnl -match=(ip6 && tcp && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=egress,table=6); };) +match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=egress,table=6); };) ]) AT_CHECK([ovn-sbctl lflow-list sw1 | grep "ls_in_acl" | grep pg0 | sort], [0], [dnl table=7 (ls_in_acl ), priority=2002 , dnl -match=(ip4 && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=egress,table=6); };) - table=7 (ls_in_acl ), priority=2002 , dnl -match=(ip6 && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=egress,table=6); };) - table=7 (ls_in_acl ), priority=2012 , dnl -match=(ip4 && tcp && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=egress,table=6); };) - table=7 (ls_in_acl ), priority=2012 , dnl -match=(ip6 && tcp && (inport == @pg0 && ip4 && tcp && tcp.dst == 80)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=egress,table=6); };) +match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=egress,table=6); };) ]) AT_CHECK([ovn-sbctl lflow-list sw0 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl table=5 (ls_out_acl ), priority=2003 , dnl -match=(ip4 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2003 , dnl -match=(ip6 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=(ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=(ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +match=(outport == @pg0 && ip6 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) ]) AT_CHECK([ovn-sbctl lflow-list sw1 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl table=5 (ls_out_acl ), priority=2003 , dnl -match=(ip4 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2003 , dnl -match=(ip6 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=(ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=(ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +match=(outport == @pg0 && ip6 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) ]) ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && udp" reject AT_CHECK([ovn-sbctl lflow-list sw0 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl table=5 (ls_out_acl ), priority=2002 , dnl -match=(ip4 && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2002 , dnl -match=(ip6 && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2003 , dnl -match=(ip4 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) +match=(outport == @pg0 && ip4 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) table=5 (ls_out_acl ), priority=2003 , dnl -match=(ip6 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=(ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=(ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=(ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=(ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +match=(outport == @pg0 && ip6 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) ]) AT_CHECK([ovn-sbctl lflow-list sw1 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl table=5 (ls_out_acl ), priority=2002 , dnl -match=(ip4 && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2002 , dnl -match=(ip6 && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2003 , dnl -match=(ip4 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) +match=(outport == @pg0 && ip4 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) table=5 (ls_out_acl ), priority=2003 , dnl -match=(ip6 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=(ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=(ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=(ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=(ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +match=(outport == @pg0 && ip6 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) ]) ovn-nbctl --wait=sb acl-add pg0 to-lport 1001 "outport == @pg0 && ip" allow-related AT_CHECK([ovn-sbctl lflow-list sw0 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl table=5 (ls_out_acl ), priority=2001 , dnl -match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), dnl -action=(reg0[[1]] = 1; next;) +match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;) table=5 (ls_out_acl ), priority=2001 , dnl match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;) table=5 (ls_out_acl ), priority=2002 , dnl -match=((reg0[[10]] == 1) && ip4 && (outport == @pg0 && ip4 && udp)), dnl -action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) +match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) table=5 (ls_out_acl ), priority=2002 , dnl -match=((reg0[[10]] == 1) && ip6 && (outport == @pg0 && ip4 && udp)), dnl -action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2002 , dnl -match=((reg0[[9]] == 1) && ip4 && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2002 , dnl -match=((reg0[[9]] == 1) && ip6 && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2003 , dnl -match=((reg0[[10]] == 1) && ip4 && (outport == @pg0 && ip6 && udp)), dnl -action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2003 , dnl -match=((reg0[[10]] == 1) && ip6 && (outport == @pg0 && ip6 && udp)), dnl -action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) +match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) table=5 (ls_out_acl ), priority=2003 , dnl -match=((reg0[[9]] == 1) && ip4 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) +match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) table=5 (ls_out_acl ), priority=2003 , dnl -match=((reg0[[9]] == 1) && ip6 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=((reg0[[10]] == 1) && ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=((reg0[[10]] == 1) && ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=((reg0[[9]] == 1) && ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=((reg0[[9]] == 1) && ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=((reg0[[10]] == 1) && ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=((reg0[[10]] == 1) && ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=((reg0[[9]] == 1) && ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=((reg0[[9]] == 1) && ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) ]) AT_CHECK([ovn-sbctl lflow-list sw1 | grep "ls_out_acl" | grep pg0 | sort], [0], [dnl table=5 (ls_out_acl ), priority=2001 , dnl -match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), dnl -action=(reg0[[1]] = 1; next;) +match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;) table=5 (ls_out_acl ), priority=2001 , dnl match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;) table=5 (ls_out_acl ), priority=2002 , dnl -match=((reg0[[10]] == 1) && ip4 && (outport == @pg0 && ip4 && udp)), dnl -action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) +match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) table=5 (ls_out_acl ), priority=2002 , dnl -match=((reg0[[10]] == 1) && ip6 && (outport == @pg0 && ip4 && udp)), dnl -action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2002 , dnl -match=((reg0[[9]] == 1) && ip4 && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2002 , dnl -match=((reg0[[9]] == 1) && ip6 && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2003 , dnl -match=((reg0[[10]] == 1) && ip4 && (outport == @pg0 && ip6 && udp)), dnl -action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2003 , dnl -match=((reg0[[10]] == 1) && ip6 && (outport == @pg0 && ip6 && udp)), dnl -action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) +match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) table=5 (ls_out_acl ), priority=2003 , dnl -match=((reg0[[9]] == 1) && ip4 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp4 { eth.dst <-> eth.src; ip4.dst <-> ip4.src; outport <-> inport; next(pipeline=ingress,table=20); };) +match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), dnl +action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) table=5 (ls_out_acl ), priority=2003 , dnl -match=((reg0[[9]] == 1) && ip6 && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; icmp6 { eth.dst <-> eth.src; ip6.dst <-> ip6.src; outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=((reg0[[10]] == 1) && ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=((reg0[[10]] == 1) && ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=((reg0[[9]] == 1) && ip4 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2012 , dnl -match=((reg0[[9]] == 1) && ip6 && tcp && (outport == @pg0 && ip4 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=((reg0[[10]] == 1) && ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=((reg0[[10]] == 1) && ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=((reg0[[9]] == 1) && ip4 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip4.dst <-> ip4.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) - table=5 (ls_out_acl ), priority=2013 , dnl -match=((reg0[[9]] == 1) && ip6 && tcp && (outport == @pg0 && ip6 && udp)), dnl -action=(reg0 = 0; eth.dst <-> eth.src; ip6.dst <-> ip6.src; tcp_reset { outport <-> inport; next(pipeline=ingress,table=20); };) +match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), dnl +action=(reg0 = 0; reject { eth.dst <-> eth.src; ip.dst <-> ip.src; outport <-> inport; next(pipeline=ingress,table=20); };) ]) AT_CLEANUP diff --git a/tests/system-ovn.at b/tests/system-ovn.at index 420610f89f..b8e6ea32a8 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -4473,9 +4473,6 @@ ovn-nbctl lsp-add sw0 sw0-p2-rej ovn-nbctl lsp-set-addresses sw0-p2-rej "50:54:00:00:00:04 10.0.0.4 aef0::4" ovn-nbctl lsp-set-port-security sw0-p2-rej "50:54:00:00:00:04 10.0.0.4 aef0::4" -#ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p1\" && tcp && tcp.dst == 80" reject -#ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p2\" && ip6 && tcp && tcp.dst == 80" reject - # Create port group and ACLs for sw0 ports. ovn-nbctl pg-add pg0_drop sw0-p1-rej sw0-p2-rej ovn-nbctl acl-add pg0_drop from-lport 1001 "inport == @pg0_drop && ip" drop @@ -4638,6 +4635,49 @@ aef0::3 udp port objcall" | uniq | wc -l) test $c -eq 1 ]) +# Delete all the ACLs of pg0 and add the ACL with a generic match with reject action. +ovn-nbctl pg-del pg0 +ovn-nbctl pg-add pg0 sw0-p1-rej sw0-p2-rej +ovn-nbctl --log acl-add pg0 from-lport 1004 "inport == @pg0 && ip && (tcp || udp)" reject + +OVS_WAIT_UNTIL([ + ip netns exec sw0-p1-rej nc 10.0.0.4 80 2> r + res=$(cat r) + echo "result = $res" + test "$res" = "Ncat: Connection refused." +]) + +OVS_WAIT_UNTIL([ + ip netns exec sw0-p2-rej nc -6 aef0::3 80 2> r + res=$(cat r) + test "$res" = "Ncat: Connection refused." +]) + +rm -f *.pcap + +NS_CHECK_EXEC([sw0-p1-rej], [tcpdump -n -c 1 -i sw0-p1-rej icmp > sw0-p1-rej-icmp.pcap &], [0]) + +printf '.%.0s' {1..100} > foo +OVS_WAIT_UNTIL([ + ip netns exec sw0-p1-rej nc -u 10.0.0.4 90 < foo + c=$(cat sw0-p1-rej-icmp.pcap | grep \ +"10.0.0.4 > 10.0.0.3: ICMP 10.0.0.4 udp port dnsix unreachable" | uniq | wc -l) + test $c -eq 1 +]) + +rm -f *.pcap +# Now test for IPv6 UDP. +NS_CHECK_EXEC([sw0-p2-rej], [tcpdump -n -c 1 -i sw0-p2-rej icmp6 > sw0-p2-rej-icmp6.pcap &], [0]) + +OVS_WAIT_UNTIL([ + ip netns exec sw0-p2-rej nc -u -6 aef0::3 90 < foo + c=$(cat sw0-p2-rej-icmp6.pcap | grep \ +"IP6 aef0::3 > aef0::4: ICMP6, destination unreachable, unreachable port, \ +aef0::3 udp port dnsix" | uniq | wc -l) + test $c -eq 1 +]) + + OVS_APP_EXIT_AND_WAIT([ovn-controller]) as ovn-sb