From patchwork Wed Jan 10 16:40:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1885046 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T9D7X5zMrz1xqk for ; Thu, 11 Jan 2024 03:40:40 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 67DB442157; Wed, 10 Jan 2024 16:40:38 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 67DB442157 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 KjEouLcq3CXX; Wed, 10 Jan 2024 16:40:37 +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 19CFE4094B; Wed, 10 Jan 2024 16:40:36 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 19CFE4094B Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E1B5DC0077; Wed, 10 Jan 2024 16:40:35 +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 D8591C0037 for ; Wed, 10 Jan 2024 16:40:33 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id A69814094B for ; Wed, 10 Jan 2024 16:40:33 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org A69814094B 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 sJyXl9cw3t7S for ; Wed, 10 Jan 2024 16:40:32 +0000 (UTC) Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by smtp4.osuosl.org (Postfix) with ESMTPS id D64494008C for ; Wed, 10 Jan 2024 16:40:31 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org D64494008C Received: by mail.gandi.net (Postfix) with ESMTPSA id 5FF97E0008; Wed, 10 Jan 2024 16:40:27 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Wed, 10 Jan 2024 11:40:10 -0500 Message-ID: <20240110164010.1810381-1-numans@ovn.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-GND-Sasl: numans@ovn.org Cc: Dumitru Ceara , shylou , Xie Liu Subject: [ovs-dev] [PATCH ovn] northd: Add option to enable conntrack for router port 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: shylou By default, OVN skips the conntrack process for router type LSP within a LS. It seems unnecessary for the LSP whose peer is l3dgw_port. Therefore, we introduce an option named 'enable_router_port_acl', which defaults to false and can be set to true to enable conntrack for the LSP whose peer is l3dgw_port. And then we can implement a gateway stateful firewall by dgw with stateful ACL. For example: prelude: R1-S1 is a l3dgw_port ovn-nbctl pg-add pg_dgw ovn-nbctl pg-set-ports pg_dgw S1-R1 ovn-nbctl acl-add pg_dgw from-lport 1002 "inport == @pg_dgw && ip4" allow-related ovn-nbctl acl-add pg_dgw to-lport 1003 "outport == @pg_dgw && ip4" allow-related ovn-nbctl lsp-set-options S1-R1 router-port=R1-S1 enable_router_port_acl=true NOTE: this option only works for the LSP whose peer is l3dgw_port. Submitted-at: https://github.com/ovn-org/ovn/pull/226 Signed-off-by: Xie Liu Acked-by: Dumitru Ceara Signed-off-by: Numan Siddique --- NEWS | 2 + northd/northd.c | 15 ++++- northd/ovn-northd.8.xml | 7 ++- ovn-nb.xml | 8 +++ tests/ovn-northd.at | 124 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 20df92cb76..5f267b4c64 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,8 @@ Post v23.09.0 - Support CIDR based MAC binding aging threshold. See ovn-nb(5) for 'mac_binding_age_threshold' for more details. - ovn-northd-ddlog has been removed. + - A new LSP option "enable_router_port_acl" has been added to enable + conntrack for the router port whose peer is l3dgw_port if set it true. OVN v23.09.0 - 15 Sep 2023 -------------------------- diff --git a/northd/northd.c b/northd/northd.c index db3cd272e1..952f8200d4 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -1612,6 +1612,9 @@ struct ovn_port { * access it from any other nodes. */ struct ovs_list lflows; + + /* Only used for the router type LSP whose peer is l3dgw_port */ + bool enable_router_port_acl; }; static bool lsp_can_be_inc_processed(const struct nbrec_logical_switch_port *); @@ -2826,6 +2829,12 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, arp_proxy, op->nbsp->name); } } + + /* Only used for the router type LSP whose peer is l3dgw_port */ + if (op->peer && is_l3dgw_port(op->peer)) { + op->enable_router_port_acl = smap_get_bool( + &op->nbsp->options, "enable_router_port_acl", false); + } } else if (op->nbrp && op->nbrp->peer && !op->l3dgw_port) { struct ovn_port *peer = ovn_port_find(ports, op->nbrp->peer); if (peer) { @@ -7207,7 +7216,11 @@ build_pre_acls(struct ovn_datapath *od, * which handles defragmentation, in order to match L4 headers. */ if (od->has_stateful_acl) { for (size_t i = 0; i < od->n_router_ports; i++) { - skip_port_from_conntrack(od, od->router_ports[i], + struct ovn_port *op = od->router_ports[i]; + if (op->enable_router_port_acl) { + continue; + } + skip_port_from_conntrack(od, op, S_SWITCH_IN_PRE_ACL, S_SWITCH_OUT_PRE_ACL, 110, lflows); } diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index 98cf7adb43..f1eb9ecb1b 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -438,7 +438,12 @@ Pre-stateful to send IP packets to the connection tracker before eventually advancing to ingress table ACLs. If special ports such as route ports or localnet ports can't use ct(), a - priority-110 flow is added to skip over stateful ACLs. Multicast, IPv6 + priority-110 flow is added to skip over stateful ACLs. This + priority-110 flow is not addd for router ports if the option + enable_router_port_acl is set to true in + column of + . Multicast, IPv6 Neighbor Discovery and MLD traffic also skips stateful ACLs. For "allow-stateless" ACLs, a flow is added to bypass setting the hint for connection tracker processing when there are stateful ACLs or LB rules; diff --git a/ovn-nb.xml b/ovn-nb.xml index b2913bdd7a..765ffcf2e6 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -1107,6 +1107,14 @@ should have a route to forward packets sent to configured proxy ARP MAC/IPs to an appropriate destination. + + + Optional. Enable conntrack for the router port whose peer is + l3dgw_port if set to true. The default value is + false. + + diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 34bd25de7b..9a0d418e46 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -10970,5 +10970,129 @@ AT_CHECK([as northd ovn-appctl -t ovn-northd status], [0], [dnl Status: active ]) +AT_CLEANUP +]) + +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([Distributed gw port enable conntrack option]) +ovn_start + +check ovn-sbctl chassis-add gw1 geneve 127.0.0.1 + +# Add a distributed router +check ovn-nbctl lr-add R1 +check ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24 +check ovn-nbctl lrp-set-gateway-chassis R1-S1 gw1 + +# Add a external network connected to R1 +check ovn-nbctl ls-add S1 +check ovn-nbctl lsp-add S1 S1-R1 +check ovn-nbctl lsp-set-type S1-R1 router +check ovn-nbctl lsp-set-addresses S1-R1 router +check ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1 +AT_CHECK([test x`ovn-nbctl lsp-get-up S1-R1` = xup]) + +# Add a external network vif +check ovn-nbctl lsp-add S1 S1-VIF +check ovn-nbctl lsp-set-addresses S1-VIF "02:ac:10:01:00:02 172.16.1.11" + +# Add the router gw port and vif to one port_group which has stateful acls +check ovn-nbctl --wait=sb pg-add pg_dgw S1-R1 S1-VIF +check ovn-nbctl acl-add pg_dgw from-lport 1002 "inport == @pg_dgw && ip4" allow-related +check ovn-nbctl acl-add pg_dgw to-lport 1003 "outport == @pg_dgw && ip4" allow-related + +# Check skip conntrack option with 'enable_router_port_acl' default (false) +AT_CHECK([ovn-sbctl dump-flows S1 | grep pre_acl | sed 's/table=./table=?/'], [0], [dnl + table=? (ls_in_pre_acl ), priority=110 , match=(eth.dst == $svc_monitor_mac), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(ip && inport == "S1-R1"), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_in_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_in_pre_acl ), priority=0 , match=(1), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.src == $svc_monitor_mac), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(ip && outport == "S1-R1"), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_out_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_out_pre_acl ), priority=0 , match=(1), action=(next;) +]) + +# Enable 'enable_router_port_acl' and check the flows +check ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1 enable_router_port_acl=true +AT_CHECK([ovn-sbctl dump-flows S1 | grep pre_acl | sed 's/table=./table=?/'], [0], [dnl + table=? (ls_in_pre_acl ), priority=110 , match=(eth.dst == $svc_monitor_mac), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_in_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_in_pre_acl ), priority=0 , match=(1), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.src == $svc_monitor_mac), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_out_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_out_pre_acl ), priority=0 , match=(1), action=(next;) +]) + +# ICMP packets from router port to external network should go to conntrack +flow_eth_in='eth.src == 02:ac:10:01:00:01 && eth.dst == 02:ac:10:01:00:02' +flow_ip_in='ip.ttl==64 && ip4.src == 172.16.10.1 && ip4.dst == 172.16.10.11' +flow_icmp='icmp4.type == 8' +flow_in="inport == \"S1-R1\" && ${flow_eth_in} && ${flow_ip_in} && ${flow_icmp}" +AT_CHECK_UNQUOTED([ovn_trace --ct est --ct est --minimal S1 "${flow_in}"], [0], [dnl +ct_next(ct_state=est|trk) { + ct_next(ct_state=est|trk) { + output("S1-VIF"); + }; +}; +]) + +# Disable 'enable_router_port_acl' and check the flows +check ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1 enable_router_port_acl=false +AT_CHECK([ovn-sbctl dump-flows S1 | grep pre_acl | sed 's/table=./table=?/'], [0], [dnl + table=? (ls_in_pre_acl ), priority=110 , match=(eth.dst == $svc_monitor_mac), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(ip && inport == "S1-R1"), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_in_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_in_pre_acl ), priority=0 , match=(1), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.src == $svc_monitor_mac), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(ip && outport == "S1-R1"), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_out_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_out_pre_acl ), priority=0 , match=(1), action=(next;) +]) + +# Clear the option 'enable_router_port_acl' and check the flows. Before that enable the option. +check ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1 enable_router_port_acl=true +AT_CHECK([ovn-sbctl dump-flows S1 | grep pre_acl | sed 's/table=./table=?/'], [0], [dnl + table=? (ls_in_pre_acl ), priority=110 , match=(eth.dst == $svc_monitor_mac), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_in_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_in_pre_acl ), priority=0 , match=(1), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.src == $svc_monitor_mac), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_out_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_out_pre_acl ), priority=0 , match=(1), action=(next;) +]) + +check ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1 +AT_CHECK([ovn-sbctl dump-flows S1 | grep pre_acl | sed 's/table=./table=?/'], [0], [dnl + table=? (ls_in_pre_acl ), priority=110 , match=(eth.dst == $svc_monitor_mac), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(ip && inport == "S1-R1"), action=(next;) + table=? (ls_in_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_in_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_in_pre_acl ), priority=0 , match=(1), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.mcast), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(eth.src == $svc_monitor_mac), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(ip && outport == "S1-R1"), action=(next;) + table=? (ls_out_pre_acl ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;) + table=? (ls_out_pre_acl ), priority=100 , match=(ip), action=(reg0[[0]] = 1; next;) + table=? (ls_out_pre_acl ), priority=0 , match=(1), action=(next;) +]) + + AT_CLEANUP ])