On Wed, Jan 10, 2024 at 11:41 AM <[email protected]> wrote:
>
> From: shylou <[email protected]>
>
> 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 <[email protected]>
> Acked-by: Dumitru Ceara <[email protected]>
> Signed-off-by: Numan Siddique <[email protected]>
Thanks. Applied the patch to the main branch.
Numan
> ---
> 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 @@
> <code>Pre-stateful</code> to send IP packets to the connection tracker
> before eventually advancing to ingress table <code>ACLs</code>. 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
> + <ref column="options:enable_router_port_acl"
> + table="Logical_Switch_Port" db="OVN_Northbound"/> column of
> + <ref table="Logical_Switch_Port" db="OVN_Northbound"/>. 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.
> </column>
> +
> + <column name="options" key="enable_router_port_acl"
> + type='{"type": "boolean"}'>
> + Optional. Enable conntrack for the router port whose peer is
> + l3dgw_port if set to <code>true</code>. The default value is
> + <code>false</code>.
> + </column>
> +
> </group>
>
> <group title="Options for localnet ports">
> 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
> ])
> --
> 2.43.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev