diff mbox series

[ovs-dev,2/2] tests: Move SCTP test from kernel only to general OVN system tests.

Message ID 170135389734.897835.12143841922080445670.stgit@ebuild
State Accepted
Headers show
Series [ovs-dev,1/2] tests: Remove 'protoinfo' from the conntrack entries for SCTP tests. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes success github build: passed

Commit Message

Eelco Chaudron Nov. 30, 2023, 2:18 p.m. UTC
This patch moves the SCTP test from the kernel only, to the general OVN
system tests, enabling its execution in both the system-userspace and
system-dpdk test scenarios.

Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
---
 tests/system-ovn-kmod.at |  215 ----------------------------------------------
 tests/system-ovn.at      |  211 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 211 insertions(+), 215 deletions(-)

Comments

Simon Horman Dec. 1, 2023, 2:28 p.m. UTC | #1
On Thu, Nov 30, 2023 at 03:18:22PM +0100, Eelco Chaudron wrote:
> This patch moves the SCTP test from the kernel only, to the general OVN
> system tests, enabling its execution in both the system-userspace and
> system-dpdk test scenarios.
> 
> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>

Acked-by: Simon Horman <horms@ovn.org>
Mark Michelson Dec. 4, 2023, 6:57 p.m. UTC | #2
Thanks for the updates, Eelco. What is the minimum OVS version required 
for the SCTP load balancer test to pass when using the userspace 
datapath? This will help me to backport this series to the proper OVN 
branches.

On 11/30/23 09:18, Eelco Chaudron wrote:
> This patch moves the SCTP test from the kernel only, to the general OVN
> system tests, enabling its execution in both the system-userspace and
> system-dpdk test scenarios.
> 
> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
> ---
>   tests/system-ovn-kmod.at |  215 ----------------------------------------------
>   tests/system-ovn.at      |  211 +++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 211 insertions(+), 215 deletions(-)
> 
> diff --git a/tests/system-ovn-kmod.at b/tests/system-ovn-kmod.at
> index 9eaf07147..f777376c6 100644
> --- a/tests/system-ovn-kmod.at
> +++ b/tests/system-ovn-kmod.at
> @@ -1,220 +1,5 @@
>   AT_BANNER([system-ovn-kmod])
>   
> -# SCTP and userspace conntrack do not mix. Therefore this
> -# test only can be run with kernel datapath. Otherwise,
> -# this is mostly a copy of existing load balancer tests
> -# in system-ovn.at
> -AT_SETUP([load balancing in gateway router - SCTP])
> -AT_SKIP_IF([test $HAVE_SCTP = no])
> -AT_SKIP_IF([test $HAVE_NC = no])
> -AT_KEYWORDS([ovnlb sctp])
> -
> -# Make sure the SCTP kernel module is loaded.
> -LOAD_MODULE([sctp])
> -
> -CHECK_CONNTRACK()
> -CHECK_CONNTRACK_NAT()
> -ovn_start
> -OVS_TRAFFIC_VSWITCHD_START()
> -ADD_BR([br-int])
> -
> -# Set external-ids in br-int needed for ovn-controller
> -ovs-vsctl \
> -        -- set Open_vSwitch . external-ids:system-id=hv1 \
> -        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> -        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
> -        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
> -        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
> -
> -# Start ovn-controller
> -start_daemon ovn-controller
> -
> -# Logical network:
> -# Two LRs - R1 and R2 that are connected to each other via LS "join"
> -# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
> -# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
> -# to it.  R2 is a gateway router on which we add load-balancing rules.
> -#
> -#    foo -- R1 -- join - R2 -- alice
> -#           |
> -#    bar ----
> -
> -ovn-nbctl create Logical_Router name=R1
> -ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
> -
> -ovn-nbctl ls-add foo
> -ovn-nbctl ls-add bar
> -ovn-nbctl ls-add alice
> -ovn-nbctl ls-add join
> -
> -# Connect foo to R1
> -ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
> -ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
> -    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
> -
> -# Connect bar to R1
> -ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
> -ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
> -    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
> -
> -# Connect alice to R2
> -ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
> -ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
> -    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
> -
> -# Connect R1 to join
> -ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
> -ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
> -    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
> -
> -# Connect R2 to join
> -ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
> -ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
> -    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
> -
> -# Static routes.
> -ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
> -ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
> -
> -# Logical port 'foo1' in switch 'foo'.
> -ADD_NAMESPACES(foo1)
> -ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
> -         "192.168.1.1")
> -ovn-nbctl lsp-add foo foo1 \
> --- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
> -
> -# Logical port 'alice1' in switch 'alice'.
> -ADD_NAMESPACES(alice1)
> -ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
> -         "172.16.1.1")
> -ovn-nbctl lsp-add alice alice1 \
> --- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
> -
> -# Logical port 'bar1' in switch 'bar'.
> -ADD_NAMESPACES(bar1)
> -ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
> -"192.168.2.1")
> -ovn-nbctl lsp-add bar bar1 \
> --- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
> -
> -# Config OVN load-balancer with a VIP.
> -uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
> -ovn-nbctl set logical_router R2 load_balancer=$uuid
> -
> -# Config OVN load-balancer with another VIP (this time with ports).
> -ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
> -
> -# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
> -ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
> -    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
> -
> -# Wait for ovn-controller to catch up.
> -ovn-nbctl --wait=hv sync
> -OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
> -grep 'nat(dst=192.168.2.2:12345)'])
> -
> -# Start webservers in 'foo1', 'bar1'.
> -OVS_START_L7([foo1], [sctp])
> -OVS_START_L7([bar1], [sctp])
> -
> -on_exit "ovs-ofctl -O OpenFlow13 dump-flows br-int"
> -
> -dnl Should work with the virtual IP address through NAT
> -for i in `seq 1 20`; do
> -    echo Request $i
> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.1 12345 > client$i.log])
> -done
> -
> -dnl Each server should have at least one connection.
> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
> -sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
> -sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
> -])
> -
> -dnl Test load-balancing that includes L4 ports in NAT.
> -for i in `seq 1 20`; do
> -    echo Request $i
> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
> -done
> -
> -dnl Each server should have at least one connection.
> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
> -])
> -
> -check_est_flows () {
> -    n=$(ovs-ofctl dump-flows br-int table=15 | grep "+est" \
> -        | grep "ct_mark=$1" | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p')
> -
> -    echo "n_packets=$n"
> -    test -n "$n" && test "$n" != "0"
> -}
> -
> -OVS_WAIT_UNTIL([check_est_flows 0x2], [check established flows])
> -
> -
> -ovn-nbctl set logical_router R2 options:lb_force_snat_ip="20.0.0.2"
> -
> -# Destroy the load balancer and create again. ovn-controller will
> -# clear the OF flows and re add again and clears the n_packets
> -# for these flows.
> -ovn-nbctl destroy load_balancer $uuid
> -uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
> -ovn-nbctl set logical_router R2 load_balancer=$uuid
> -
> -check ovs-appctl dpctl/flush-conntrack
> -
> -# Config OVN load-balancer with another VIP (this time with ports).
> -ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
> -
> -ovn-nbctl list load_balancer
> -ovn-sbctl dump-flows R2
> -OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=45 | grep 'nat(src=20.0.0.2)'])
> -
> -dnl Test load-balancing that includes L4 ports in NAT.
> -for i in `seq 1 20`; do
> -    echo Request $i
> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
> -done
> -
> -dnl Each server should have at least one connection.
> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
> -])
> -
> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) |
> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
> -sctp,orig=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
> -sctp,orig=(src=172.16.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
> -])
> -
> -OVS_WAIT_UNTIL([check_est_flows 0xa], [check established flows])
> -
> -OVS_APP_EXIT_AND_WAIT([ovn-controller])
> -
> -as ovn-sb
> -OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> -
> -as ovn-nb
> -OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> -
> -as northd
> -OVS_APP_EXIT_AND_WAIT([ovn-northd])
> -
> -as
> -OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
> -/connection dropped.*/d"])
> -AT_CLEANUP
> -
>   OVN_FOR_EACH_NORTHD([
>   AT_SETUP([load balancing affinity sessions - IPv4])
>   AT_KEYWORDS([ovnlb])
> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> index c45452607..871ffb14d 100644
> --- a/tests/system-ovn.at
> +++ b/tests/system-ovn.at
> @@ -11819,3 +11819,214 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>   /connection dropped.*/d"])
>   AT_CLEANUP
>   ])
> +
> +AT_SETUP([load balancing in gateway router - SCTP])
> +AT_SKIP_IF([test $HAVE_SCTP = no])
> +AT_SKIP_IF([test $HAVE_NC = no])
> +AT_KEYWORDS([ovnlb sctp])
> +
> +# Make sure the SCTP kernel module is loaded.
> +LOAD_MODULE([sctp])
> +
> +CHECK_CONNTRACK()
> +CHECK_CONNTRACK_NAT()
> +ovn_start
> +OVS_TRAFFIC_VSWITCHD_START()
> +ADD_BR([br-int])
> +
> +# Set external-ids in br-int needed for ovn-controller.
> +ovs-vsctl \
> +        -- set Open_vSwitch . external-ids:system-id=hv1 \
> +        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> +        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
> +        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
> +        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
> +
> +# Start the ovn-controller.
> +start_daemon ovn-controller
> +
> +# Logical network:
> +# Two LRs - R1 and R2 that are connected to each other via LS "join"
> +# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
> +# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
> +# to it.  R2 is a gateway router on which we add load-balancing rules.
> +#
> +#    foo -- R1 -- join - R2 -- alice
> +#           |
> +#    bar ----
> +
> +ovn-nbctl create Logical_Router name=R1
> +ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
> +
> +ovn-nbctl ls-add foo
> +ovn-nbctl ls-add bar
> +ovn-nbctl ls-add alice
> +ovn-nbctl ls-add join
> +
> +# Connect foo to R1
> +ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
> +ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
> +    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
> +
> +# Connect bar to R1
> +ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
> +ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
> +    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
> +
> +# Connect alice to R2
> +ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
> +ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
> +    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
> +
> +# Connect R1 to join
> +ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
> +ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
> +    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
> +
> +# Connect R2 to join
> +ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
> +ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
> +    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
> +
> +# Static routes.
> +ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
> +ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
> +
> +# Logical port 'foo1' in switch 'foo'.
> +ADD_NAMESPACES(foo1)
> +ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
> +         "192.168.1.1")
> +ovn-nbctl lsp-add foo foo1 \
> +-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
> +
> +# Logical port 'alice1' in switch 'alice'.
> +ADD_NAMESPACES(alice1)
> +ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
> +         "172.16.1.1")
> +ovn-nbctl lsp-add alice alice1 \
> +-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
> +
> +# Logical port 'bar1' in switch 'bar'.
> +ADD_NAMESPACES(bar1)
> +ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
> +"192.168.2.1")
> +ovn-nbctl lsp-add bar bar1 \
> +-- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
> +
> +# Config OVN load-balancer with a VIP.
> +uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
> +ovn-nbctl set logical_router R2 load_balancer=$uuid
> +
> +# Config OVN load-balancer with another VIP (this time with ports).
> +ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
> +
> +# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
> +ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
> +    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
> +
> +# Wait for ovn-controller to catch up.
> +ovn-nbctl --wait=hv sync
> +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
> +grep 'nat(dst=192.168.2.2:12345)'])
> +
> +# Start webservers in 'foo1', 'bar1'.
> +OVS_START_L7([foo1], [sctp])
> +OVS_START_L7([bar1], [sctp])
> +
> +on_exit "ovs-ofctl -O OpenFlow13 dump-flows br-int"
> +
> +dnl Should work with the virtual IP address through NAT
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.1 12345 > client$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
> +sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
> +sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
> +])
> +
> +dnl Test load-balancing that includes L4 ports in NAT.
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
> +])
> +
> +check_est_flows () {
> +    n=$(ovs-ofctl dump-flows br-int table=15 | grep "+est" \
> +        | grep "ct_mark=$1" | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p')
> +
> +    echo "n_packets=$n"
> +    test -n "$n" && test "$n" != "0"
> +}
> +
> +OVS_WAIT_UNTIL([check_est_flows 0x2], [check established flows])
> +
> +
> +ovn-nbctl set logical_router R2 options:lb_force_snat_ip="20.0.0.2"
> +
> +# Destroy the load balancer and create again. ovn-controller will
> +# clear the OF flows and re add again and clears the n_packets
> +# for these flows.
> +ovn-nbctl destroy load_balancer $uuid
> +uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
> +ovn-nbctl set logical_router R2 load_balancer=$uuid
> +
> +check ovs-appctl dpctl/flush-conntrack
> +
> +# Config OVN load-balancer with another VIP (this time with ports).
> +ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
> +
> +ovn-nbctl list load_balancer
> +ovn-sbctl dump-flows R2
> +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=45 | grep 'nat(src=20.0.0.2)'])
> +
> +dnl Test load-balancing that includes L4 ports in NAT.
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
> +])
> +
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) |
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
> +sctp,orig=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
> +sctp,orig=(src=172.16.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
> +])
> +
> +OVS_WAIT_UNTIL([check_est_flows 0xa], [check established flows])
> +
> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
> +
> +as ovn-sb
> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> +
> +as ovn-nb
> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> +
> +as northd
> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
> +
> +as
> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
> +/connection dropped.*/d"])
> +AT_CLEANUP
> 
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
Eelco Chaudron Dec. 5, 2023, 7:52 a.m. UTC | #3
On 4 Dec 2023, at 19:57, Mark Michelson wrote:

> Thanks for the updates, Eelco. What is the minimum OVS version required for the SCTP load balancer test to pass when using the userspace datapath? This will help me to backport this series to the proper OVN branches.

Hi Mark,

It’s in 3.2 and above:

  $ git tag --contains 501f665a5a4b3eafa75f020ab77c1d62f7840172
  v3.2.0
  v3.2.1

Cheers,

Eelco


> On 11/30/23 09:18, Eelco Chaudron wrote:
>> This patch moves the SCTP test from the kernel only, to the general OVN
>> system tests, enabling its execution in both the system-userspace and
>> system-dpdk test scenarios.
>>
>> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
>> ---
>>   tests/system-ovn-kmod.at |  215 ----------------------------------------------
>>   tests/system-ovn.at      |  211 +++++++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 211 insertions(+), 215 deletions(-)
>>
>> diff --git a/tests/system-ovn-kmod.at b/tests/system-ovn-kmod.at
>> index 9eaf07147..f777376c6 100644
>> --- a/tests/system-ovn-kmod.at
>> +++ b/tests/system-ovn-kmod.at
>> @@ -1,220 +1,5 @@
>>   AT_BANNER([system-ovn-kmod])
>>  -# SCTP and userspace conntrack do not mix. Therefore this
>> -# test only can be run with kernel datapath. Otherwise,
>> -# this is mostly a copy of existing load balancer tests
>> -# in system-ovn.at
>> -AT_SETUP([load balancing in gateway router - SCTP])
>> -AT_SKIP_IF([test $HAVE_SCTP = no])
>> -AT_SKIP_IF([test $HAVE_NC = no])
>> -AT_KEYWORDS([ovnlb sctp])
>> -
>> -# Make sure the SCTP kernel module is loaded.
>> -LOAD_MODULE([sctp])
>> -
>> -CHECK_CONNTRACK()
>> -CHECK_CONNTRACK_NAT()
>> -ovn_start
>> -OVS_TRAFFIC_VSWITCHD_START()
>> -ADD_BR([br-int])
>> -
>> -# Set external-ids in br-int needed for ovn-controller
>> -ovs-vsctl \
>> -        -- set Open_vSwitch . external-ids:system-id=hv1 \
>> -        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
>> -        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
>> -        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
>> -        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
>> -
>> -# Start ovn-controller
>> -start_daemon ovn-controller
>> -
>> -# Logical network:
>> -# Two LRs - R1 and R2 that are connected to each other via LS "join"
>> -# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
>> -# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
>> -# to it.  R2 is a gateway router on which we add load-balancing rules.
>> -#
>> -#    foo -- R1 -- join - R2 -- alice
>> -#           |
>> -#    bar ----
>> -
>> -ovn-nbctl create Logical_Router name=R1
>> -ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
>> -
>> -ovn-nbctl ls-add foo
>> -ovn-nbctl ls-add bar
>> -ovn-nbctl ls-add alice
>> -ovn-nbctl ls-add join
>> -
>> -# Connect foo to R1
>> -ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
>> -ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
>> -    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
>> -
>> -# Connect bar to R1
>> -ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
>> -ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
>> -    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
>> -
>> -# Connect alice to R2
>> -ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
>> -ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
>> -    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
>> -
>> -# Connect R1 to join
>> -ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
>> -ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
>> -    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
>> -
>> -# Connect R2 to join
>> -ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
>> -ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
>> -    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
>> -
>> -# Static routes.
>> -ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
>> -ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
>> -
>> -# Logical port 'foo1' in switch 'foo'.
>> -ADD_NAMESPACES(foo1)
>> -ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
>> -         "192.168.1.1")
>> -ovn-nbctl lsp-add foo foo1 \
>> --- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
>> -
>> -# Logical port 'alice1' in switch 'alice'.
>> -ADD_NAMESPACES(alice1)
>> -ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
>> -         "172.16.1.1")
>> -ovn-nbctl lsp-add alice alice1 \
>> --- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
>> -
>> -# Logical port 'bar1' in switch 'bar'.
>> -ADD_NAMESPACES(bar1)
>> -ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
>> -"192.168.2.1")
>> -ovn-nbctl lsp-add bar bar1 \
>> --- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
>> -
>> -# Config OVN load-balancer with a VIP.
>> -uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
>> -ovn-nbctl set logical_router R2 load_balancer=$uuid
>> -
>> -# Config OVN load-balancer with another VIP (this time with ports).
>> -ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
>> -
>> -# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
>> -ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
>> -    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
>> -
>> -# Wait for ovn-controller to catch up.
>> -ovn-nbctl --wait=hv sync
>> -OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
>> -grep 'nat(dst=192.168.2.2:12345)'])
>> -
>> -# Start webservers in 'foo1', 'bar1'.
>> -OVS_START_L7([foo1], [sctp])
>> -OVS_START_L7([bar1], [sctp])
>> -
>> -on_exit "ovs-ofctl -O OpenFlow13 dump-flows br-int"
>> -
>> -dnl Should work with the virtual IP address through NAT
>> -for i in `seq 1 20`; do
>> -    echo Request $i
>> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.1 12345 > client$i.log])
>> -done
>> -
>> -dnl Each server should have at least one connection.
>> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
>> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>> -])
>> -
>> -dnl Test load-balancing that includes L4 ports in NAT.
>> -for i in `seq 1 20`; do
>> -    echo Request $i
>> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
>> -done
>> -
>> -dnl Each server should have at least one connection.
>> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
>> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>> -])
>> -
>> -check_est_flows () {
>> -    n=$(ovs-ofctl dump-flows br-int table=15 | grep "+est" \
>> -        | grep "ct_mark=$1" | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p')
>> -
>> -    echo "n_packets=$n"
>> -    test -n "$n" && test "$n" != "0"
>> -}
>> -
>> -OVS_WAIT_UNTIL([check_est_flows 0x2], [check established flows])
>> -
>> -
>> -ovn-nbctl set logical_router R2 options:lb_force_snat_ip="20.0.0.2"
>> -
>> -# Destroy the load balancer and create again. ovn-controller will
>> -# clear the OF flows and re add again and clears the n_packets
>> -# for these flows.
>> -ovn-nbctl destroy load_balancer $uuid
>> -uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
>> -ovn-nbctl set logical_router R2 load_balancer=$uuid
>> -
>> -check ovs-appctl dpctl/flush-conntrack
>> -
>> -# Config OVN load-balancer with another VIP (this time with ports).
>> -ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
>> -
>> -ovn-nbctl list load_balancer
>> -ovn-sbctl dump-flows R2
>> -OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=45 | grep 'nat(src=20.0.0.2)'])
>> -
>> -dnl Test load-balancing that includes L4 ports in NAT.
>> -for i in `seq 1 20`; do
>> -    echo Request $i
>> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
>> -done
>> -
>> -dnl Each server should have at least one connection.
>> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
>> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
>> -])
>> -
>> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) |
>> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>> -sctp,orig=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
>> -sctp,orig=(src=172.16.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
>> -])
>> -
>> -OVS_WAIT_UNTIL([check_est_flows 0xa], [check established flows])
>> -
>> -OVS_APP_EXIT_AND_WAIT([ovn-controller])
>> -
>> -as ovn-sb
>> -OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>> -
>> -as ovn-nb
>> -OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>> -
>> -as northd
>> -OVS_APP_EXIT_AND_WAIT([ovn-northd])
>> -
>> -as
>> -OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>> -/connection dropped.*/d"])
>> -AT_CLEANUP
>> -
>>   OVN_FOR_EACH_NORTHD([
>>   AT_SETUP([load balancing affinity sessions - IPv4])
>>   AT_KEYWORDS([ovnlb])
>> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
>> index c45452607..871ffb14d 100644
>> --- a/tests/system-ovn.at
>> +++ b/tests/system-ovn.at
>> @@ -11819,3 +11819,214 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>>   /connection dropped.*/d"])
>>   AT_CLEANUP
>>   ])
>> +
>> +AT_SETUP([load balancing in gateway router - SCTP])
>> +AT_SKIP_IF([test $HAVE_SCTP = no])
>> +AT_SKIP_IF([test $HAVE_NC = no])
>> +AT_KEYWORDS([ovnlb sctp])
>> +
>> +# Make sure the SCTP kernel module is loaded.
>> +LOAD_MODULE([sctp])
>> +
>> +CHECK_CONNTRACK()
>> +CHECK_CONNTRACK_NAT()
>> +ovn_start
>> +OVS_TRAFFIC_VSWITCHD_START()
>> +ADD_BR([br-int])
>> +
>> +# Set external-ids in br-int needed for ovn-controller.
>> +ovs-vsctl \
>> +        -- set Open_vSwitch . external-ids:system-id=hv1 \
>> +        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
>> +        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
>> +        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
>> +        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
>> +
>> +# Start the ovn-controller.
>> +start_daemon ovn-controller
>> +
>> +# Logical network:
>> +# Two LRs - R1 and R2 that are connected to each other via LS "join"
>> +# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
>> +# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
>> +# to it.  R2 is a gateway router on which we add load-balancing rules.
>> +#
>> +#    foo -- R1 -- join - R2 -- alice
>> +#           |
>> +#    bar ----
>> +
>> +ovn-nbctl create Logical_Router name=R1
>> +ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
>> +
>> +ovn-nbctl ls-add foo
>> +ovn-nbctl ls-add bar
>> +ovn-nbctl ls-add alice
>> +ovn-nbctl ls-add join
>> +
>> +# Connect foo to R1
>> +ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
>> +ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
>> +    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
>> +
>> +# Connect bar to R1
>> +ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
>> +ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
>> +    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
>> +
>> +# Connect alice to R2
>> +ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
>> +ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
>> +    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
>> +
>> +# Connect R1 to join
>> +ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
>> +ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
>> +    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
>> +
>> +# Connect R2 to join
>> +ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
>> +ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
>> +    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
>> +
>> +# Static routes.
>> +ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
>> +ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
>> +
>> +# Logical port 'foo1' in switch 'foo'.
>> +ADD_NAMESPACES(foo1)
>> +ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
>> +         "192.168.1.1")
>> +ovn-nbctl lsp-add foo foo1 \
>> +-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
>> +
>> +# Logical port 'alice1' in switch 'alice'.
>> +ADD_NAMESPACES(alice1)
>> +ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
>> +         "172.16.1.1")
>> +ovn-nbctl lsp-add alice alice1 \
>> +-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
>> +
>> +# Logical port 'bar1' in switch 'bar'.
>> +ADD_NAMESPACES(bar1)
>> +ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
>> +"192.168.2.1")
>> +ovn-nbctl lsp-add bar bar1 \
>> +-- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
>> +
>> +# Config OVN load-balancer with a VIP.
>> +uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
>> +ovn-nbctl set logical_router R2 load_balancer=$uuid
>> +
>> +# Config OVN load-balancer with another VIP (this time with ports).
>> +ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
>> +
>> +# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
>> +ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
>> +    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
>> +
>> +# Wait for ovn-controller to catch up.
>> +ovn-nbctl --wait=hv sync
>> +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
>> +grep 'nat(dst=192.168.2.2:12345)'])
>> +
>> +# Start webservers in 'foo1', 'bar1'.
>> +OVS_START_L7([foo1], [sctp])
>> +OVS_START_L7([bar1], [sctp])
>> +
>> +on_exit "ovs-ofctl -O OpenFlow13 dump-flows br-int"
>> +
>> +dnl Should work with the virtual IP address through NAT
>> +for i in `seq 1 20`; do
>> +    echo Request $i
>> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.1 12345 > client$i.log])
>> +done
>> +
>> +dnl Each server should have at least one connection.
>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
>> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>> +])
>> +
>> +dnl Test load-balancing that includes L4 ports in NAT.
>> +for i in `seq 1 20`; do
>> +    echo Request $i
>> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
>> +done
>> +
>> +dnl Each server should have at least one connection.
>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
>> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>> +])
>> +
>> +check_est_flows () {
>> +    n=$(ovs-ofctl dump-flows br-int table=15 | grep "+est" \
>> +        | grep "ct_mark=$1" | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p')
>> +
>> +    echo "n_packets=$n"
>> +    test -n "$n" && test "$n" != "0"
>> +}
>> +
>> +OVS_WAIT_UNTIL([check_est_flows 0x2], [check established flows])
>> +
>> +
>> +ovn-nbctl set logical_router R2 options:lb_force_snat_ip="20.0.0.2"
>> +
>> +# Destroy the load balancer and create again. ovn-controller will
>> +# clear the OF flows and re add again and clears the n_packets
>> +# for these flows.
>> +ovn-nbctl destroy load_balancer $uuid
>> +uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
>> +ovn-nbctl set logical_router R2 load_balancer=$uuid
>> +
>> +check ovs-appctl dpctl/flush-conntrack
>> +
>> +# Config OVN load-balancer with another VIP (this time with ports).
>> +ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
>> +
>> +ovn-nbctl list load_balancer
>> +ovn-sbctl dump-flows R2
>> +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=45 | grep 'nat(src=20.0.0.2)'])
>> +
>> +dnl Test load-balancing that includes L4 ports in NAT.
>> +for i in `seq 1 20`; do
>> +    echo Request $i
>> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
>> +done
>> +
>> +dnl Each server should have at least one connection.
>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
>> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
>> +])
>> +
>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) |
>> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>> +sctp,orig=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
>> +sctp,orig=(src=172.16.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
>> +])
>> +
>> +OVS_WAIT_UNTIL([check_est_flows 0xa], [check established flows])
>> +
>> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
>> +
>> +as ovn-sb
>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>> +
>> +as ovn-nb
>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>> +
>> +as northd
>> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
>> +
>> +as
>> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>> +/connection dropped.*/d"])
>> +AT_CLEANUP
>>
>> _______________________________________________
>> dev mailing list
>> dev@openvswitch.org
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
Dumitru Ceara Dec. 7, 2023, 12:30 p.m. UTC | #4
On 12/5/23 08:52, Eelco Chaudron wrote:
> 
> 
> On 4 Dec 2023, at 19:57, Mark Michelson wrote:
> 
>> Thanks for the updates, Eelco. What is the minimum OVS version required for the SCTP load balancer test to pass when using the userspace datapath? This will help me to backport this series to the proper OVN branches.
> 
> Hi Mark,
> 
> It’s in 3.2 and above:
> 
>   $ git tag --contains 501f665a5a4b3eafa75f020ab77c1d62f7840172
>   v3.2.0
>   v3.2.1
> 

Thanks, Eelco, Mark and Simon!  I applied this to main and branch-23.09.

Regards,
Dumitru

> Cheers,
> 
> Eelco
> 
> 
>> On 11/30/23 09:18, Eelco Chaudron wrote:
>>> This patch moves the SCTP test from the kernel only, to the general OVN
>>> system tests, enabling its execution in both the system-userspace and
>>> system-dpdk test scenarios.
>>>
>>> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
>>> ---
>>>   tests/system-ovn-kmod.at |  215 ----------------------------------------------
>>>   tests/system-ovn.at      |  211 +++++++++++++++++++++++++++++++++++++++++++++
>>>   2 files changed, 211 insertions(+), 215 deletions(-)
>>>
>>> diff --git a/tests/system-ovn-kmod.at b/tests/system-ovn-kmod.at
>>> index 9eaf07147..f777376c6 100644
>>> --- a/tests/system-ovn-kmod.at
>>> +++ b/tests/system-ovn-kmod.at
>>> @@ -1,220 +1,5 @@
>>>   AT_BANNER([system-ovn-kmod])
>>>  -# SCTP and userspace conntrack do not mix. Therefore this
>>> -# test only can be run with kernel datapath. Otherwise,
>>> -# this is mostly a copy of existing load balancer tests
>>> -# in system-ovn.at
>>> -AT_SETUP([load balancing in gateway router - SCTP])
>>> -AT_SKIP_IF([test $HAVE_SCTP = no])
>>> -AT_SKIP_IF([test $HAVE_NC = no])
>>> -AT_KEYWORDS([ovnlb sctp])
>>> -
>>> -# Make sure the SCTP kernel module is loaded.
>>> -LOAD_MODULE([sctp])
>>> -
>>> -CHECK_CONNTRACK()
>>> -CHECK_CONNTRACK_NAT()
>>> -ovn_start
>>> -OVS_TRAFFIC_VSWITCHD_START()
>>> -ADD_BR([br-int])
>>> -
>>> -# Set external-ids in br-int needed for ovn-controller
>>> -ovs-vsctl \
>>> -        -- set Open_vSwitch . external-ids:system-id=hv1 \
>>> -        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
>>> -        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
>>> -        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
>>> -        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
>>> -
>>> -# Start ovn-controller
>>> -start_daemon ovn-controller
>>> -
>>> -# Logical network:
>>> -# Two LRs - R1 and R2 that are connected to each other via LS "join"
>>> -# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
>>> -# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
>>> -# to it.  R2 is a gateway router on which we add load-balancing rules.
>>> -#
>>> -#    foo -- R1 -- join - R2 -- alice
>>> -#           |
>>> -#    bar ----
>>> -
>>> -ovn-nbctl create Logical_Router name=R1
>>> -ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
>>> -
>>> -ovn-nbctl ls-add foo
>>> -ovn-nbctl ls-add bar
>>> -ovn-nbctl ls-add alice
>>> -ovn-nbctl ls-add join
>>> -
>>> -# Connect foo to R1
>>> -ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
>>> -ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
>>> -    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
>>> -
>>> -# Connect bar to R1
>>> -ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
>>> -ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
>>> -    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
>>> -
>>> -# Connect alice to R2
>>> -ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
>>> -ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
>>> -    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
>>> -
>>> -# Connect R1 to join
>>> -ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
>>> -ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
>>> -    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
>>> -
>>> -# Connect R2 to join
>>> -ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
>>> -ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
>>> -    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
>>> -
>>> -# Static routes.
>>> -ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
>>> -ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
>>> -
>>> -# Logical port 'foo1' in switch 'foo'.
>>> -ADD_NAMESPACES(foo1)
>>> -ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
>>> -         "192.168.1.1")
>>> -ovn-nbctl lsp-add foo foo1 \
>>> --- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
>>> -
>>> -# Logical port 'alice1' in switch 'alice'.
>>> -ADD_NAMESPACES(alice1)
>>> -ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
>>> -         "172.16.1.1")
>>> -ovn-nbctl lsp-add alice alice1 \
>>> --- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
>>> -
>>> -# Logical port 'bar1' in switch 'bar'.
>>> -ADD_NAMESPACES(bar1)
>>> -ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
>>> -"192.168.2.1")
>>> -ovn-nbctl lsp-add bar bar1 \
>>> --- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
>>> -
>>> -# Config OVN load-balancer with a VIP.
>>> -uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
>>> -ovn-nbctl set logical_router R2 load_balancer=$uuid
>>> -
>>> -# Config OVN load-balancer with another VIP (this time with ports).
>>> -ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
>>> -
>>> -# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
>>> -ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
>>> -    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
>>> -
>>> -# Wait for ovn-controller to catch up.
>>> -ovn-nbctl --wait=hv sync
>>> -OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
>>> -grep 'nat(dst=192.168.2.2:12345)'])
>>> -
>>> -# Start webservers in 'foo1', 'bar1'.
>>> -OVS_START_L7([foo1], [sctp])
>>> -OVS_START_L7([bar1], [sctp])
>>> -
>>> -on_exit "ovs-ofctl -O OpenFlow13 dump-flows br-int"
>>> -
>>> -dnl Should work with the virtual IP address through NAT
>>> -for i in `seq 1 20`; do
>>> -    echo Request $i
>>> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.1 12345 > client$i.log])
>>> -done
>>> -
>>> -dnl Each server should have at least one connection.
>>> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
>>> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>>> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>>> -])
>>> -
>>> -dnl Test load-balancing that includes L4 ports in NAT.
>>> -for i in `seq 1 20`; do
>>> -    echo Request $i
>>> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
>>> -done
>>> -
>>> -dnl Each server should have at least one connection.
>>> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
>>> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>>> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>>> -])
>>> -
>>> -check_est_flows () {
>>> -    n=$(ovs-ofctl dump-flows br-int table=15 | grep "+est" \
>>> -        | grep "ct_mark=$1" | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p')
>>> -
>>> -    echo "n_packets=$n"
>>> -    test -n "$n" && test "$n" != "0"
>>> -}
>>> -
>>> -OVS_WAIT_UNTIL([check_est_flows 0x2], [check established flows])
>>> -
>>> -
>>> -ovn-nbctl set logical_router R2 options:lb_force_snat_ip="20.0.0.2"
>>> -
>>> -# Destroy the load balancer and create again. ovn-controller will
>>> -# clear the OF flows and re add again and clears the n_packets
>>> -# for these flows.
>>> -ovn-nbctl destroy load_balancer $uuid
>>> -uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
>>> -ovn-nbctl set logical_router R2 load_balancer=$uuid
>>> -
>>> -check ovs-appctl dpctl/flush-conntrack
>>> -
>>> -# Config OVN load-balancer with another VIP (this time with ports).
>>> -ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
>>> -
>>> -ovn-nbctl list load_balancer
>>> -ovn-sbctl dump-flows R2
>>> -OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=45 | grep 'nat(src=20.0.0.2)'])
>>> -
>>> -dnl Test load-balancing that includes L4 ports in NAT.
>>> -for i in `seq 1 20`; do
>>> -    echo Request $i
>>> -    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
>>> -done
>>> -
>>> -dnl Each server should have at least one connection.
>>> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
>>> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>>> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
>>> -sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
>>> -])
>>> -
>>> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) |
>>> -sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>>> -sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>>> -sctp,orig=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
>>> -sctp,orig=(src=172.16.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
>>> -])
>>> -
>>> -OVS_WAIT_UNTIL([check_est_flows 0xa], [check established flows])
>>> -
>>> -OVS_APP_EXIT_AND_WAIT([ovn-controller])
>>> -
>>> -as ovn-sb
>>> -OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>> -
>>> -as ovn-nb
>>> -OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>> -
>>> -as northd
>>> -OVS_APP_EXIT_AND_WAIT([ovn-northd])
>>> -
>>> -as
>>> -OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>>> -/connection dropped.*/d"])
>>> -AT_CLEANUP
>>> -
>>>   OVN_FOR_EACH_NORTHD([
>>>   AT_SETUP([load balancing affinity sessions - IPv4])
>>>   AT_KEYWORDS([ovnlb])
>>> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
>>> index c45452607..871ffb14d 100644
>>> --- a/tests/system-ovn.at
>>> +++ b/tests/system-ovn.at
>>> @@ -11819,3 +11819,214 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>>>   /connection dropped.*/d"])
>>>   AT_CLEANUP
>>>   ])
>>> +
>>> +AT_SETUP([load balancing in gateway router - SCTP])
>>> +AT_SKIP_IF([test $HAVE_SCTP = no])
>>> +AT_SKIP_IF([test $HAVE_NC = no])
>>> +AT_KEYWORDS([ovnlb sctp])
>>> +
>>> +# Make sure the SCTP kernel module is loaded.
>>> +LOAD_MODULE([sctp])
>>> +
>>> +CHECK_CONNTRACK()
>>> +CHECK_CONNTRACK_NAT()
>>> +ovn_start
>>> +OVS_TRAFFIC_VSWITCHD_START()
>>> +ADD_BR([br-int])
>>> +
>>> +# Set external-ids in br-int needed for ovn-controller.
>>> +ovs-vsctl \
>>> +        -- set Open_vSwitch . external-ids:system-id=hv1 \
>>> +        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
>>> +        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
>>> +        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
>>> +        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
>>> +
>>> +# Start the ovn-controller.
>>> +start_daemon ovn-controller
>>> +
>>> +# Logical network:
>>> +# Two LRs - R1 and R2 that are connected to each other via LS "join"
>>> +# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
>>> +# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
>>> +# to it.  R2 is a gateway router on which we add load-balancing rules.
>>> +#
>>> +#    foo -- R1 -- join - R2 -- alice
>>> +#           |
>>> +#    bar ----
>>> +
>>> +ovn-nbctl create Logical_Router name=R1
>>> +ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
>>> +
>>> +ovn-nbctl ls-add foo
>>> +ovn-nbctl ls-add bar
>>> +ovn-nbctl ls-add alice
>>> +ovn-nbctl ls-add join
>>> +
>>> +# Connect foo to R1
>>> +ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
>>> +ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
>>> +    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
>>> +
>>> +# Connect bar to R1
>>> +ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
>>> +ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
>>> +    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
>>> +
>>> +# Connect alice to R2
>>> +ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
>>> +ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
>>> +    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
>>> +
>>> +# Connect R1 to join
>>> +ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
>>> +ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
>>> +    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
>>> +
>>> +# Connect R2 to join
>>> +ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
>>> +ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
>>> +    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
>>> +
>>> +# Static routes.
>>> +ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
>>> +ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
>>> +
>>> +# Logical port 'foo1' in switch 'foo'.
>>> +ADD_NAMESPACES(foo1)
>>> +ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
>>> +         "192.168.1.1")
>>> +ovn-nbctl lsp-add foo foo1 \
>>> +-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
>>> +
>>> +# Logical port 'alice1' in switch 'alice'.
>>> +ADD_NAMESPACES(alice1)
>>> +ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
>>> +         "172.16.1.1")
>>> +ovn-nbctl lsp-add alice alice1 \
>>> +-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
>>> +
>>> +# Logical port 'bar1' in switch 'bar'.
>>> +ADD_NAMESPACES(bar1)
>>> +ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
>>> +"192.168.2.1")
>>> +ovn-nbctl lsp-add bar bar1 \
>>> +-- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
>>> +
>>> +# Config OVN load-balancer with a VIP.
>>> +uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
>>> +ovn-nbctl set logical_router R2 load_balancer=$uuid
>>> +
>>> +# Config OVN load-balancer with another VIP (this time with ports).
>>> +ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
>>> +
>>> +# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
>>> +ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
>>> +    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
>>> +
>>> +# Wait for ovn-controller to catch up.
>>> +ovn-nbctl --wait=hv sync
>>> +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
>>> +grep 'nat(dst=192.168.2.2:12345)'])
>>> +
>>> +# Start webservers in 'foo1', 'bar1'.
>>> +OVS_START_L7([foo1], [sctp])
>>> +OVS_START_L7([bar1], [sctp])
>>> +
>>> +on_exit "ovs-ofctl -O OpenFlow13 dump-flows br-int"
>>> +
>>> +dnl Should work with the virtual IP address through NAT
>>> +for i in `seq 1 20`; do
>>> +    echo Request $i
>>> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.1 12345 > client$i.log])
>>> +done
>>> +
>>> +dnl Each server should have at least one connection.
>>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
>>> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>>> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>>> +])
>>> +
>>> +dnl Test load-balancing that includes L4 ports in NAT.
>>> +for i in `seq 1 20`; do
>>> +    echo Request $i
>>> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
>>> +done
>>> +
>>> +dnl Each server should have at least one connection.
>>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
>>> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>>> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
>>> +])
>>> +
>>> +check_est_flows () {
>>> +    n=$(ovs-ofctl dump-flows br-int table=15 | grep "+est" \
>>> +        | grep "ct_mark=$1" | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p')
>>> +
>>> +    echo "n_packets=$n"
>>> +    test -n "$n" && test "$n" != "0"
>>> +}
>>> +
>>> +OVS_WAIT_UNTIL([check_est_flows 0x2], [check established flows])
>>> +
>>> +
>>> +ovn-nbctl set logical_router R2 options:lb_force_snat_ip="20.0.0.2"
>>> +
>>> +# Destroy the load balancer and create again. ovn-controller will
>>> +# clear the OF flows and re add again and clears the n_packets
>>> +# for these flows.
>>> +ovn-nbctl destroy load_balancer $uuid
>>> +uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
>>> +ovn-nbctl set logical_router R2 load_balancer=$uuid
>>> +
>>> +check ovs-appctl dpctl/flush-conntrack
>>> +
>>> +# Config OVN load-balancer with another VIP (this time with ports).
>>> +ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
>>> +
>>> +ovn-nbctl list load_balancer
>>> +ovn-sbctl dump-flows R2
>>> +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=45 | grep 'nat(src=20.0.0.2)'])
>>> +
>>> +dnl Test load-balancing that includes L4 ports in NAT.
>>> +for i in `seq 1 20`; do
>>> +    echo Request $i
>>> +    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
>>> +done
>>> +
>>> +dnl Each server should have at least one connection.
>>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
>>> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>>> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
>>> +sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
>>> +])
>>> +
>>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) |
>>> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>>> +sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
>>> +sctp,orig=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
>>> +sctp,orig=(src=172.16.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
>>> +])
>>> +
>>> +OVS_WAIT_UNTIL([check_est_flows 0xa], [check established flows])
>>> +
>>> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
>>> +
>>> +as ovn-sb
>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>> +
>>> +as ovn-nb
>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>> +
>>> +as northd
>>> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
>>> +
>>> +as
>>> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>>> +/connection dropped.*/d"])
>>> +AT_CLEANUP
>>>
>>> _______________________________________________
>>> dev mailing list
>>> dev@openvswitch.org
>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>>
> 
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
diff mbox series

Patch

diff --git a/tests/system-ovn-kmod.at b/tests/system-ovn-kmod.at
index 9eaf07147..f777376c6 100644
--- a/tests/system-ovn-kmod.at
+++ b/tests/system-ovn-kmod.at
@@ -1,220 +1,5 @@ 
 AT_BANNER([system-ovn-kmod])
 
-# SCTP and userspace conntrack do not mix. Therefore this
-# test only can be run with kernel datapath. Otherwise,
-# this is mostly a copy of existing load balancer tests
-# in system-ovn.at
-AT_SETUP([load balancing in gateway router - SCTP])
-AT_SKIP_IF([test $HAVE_SCTP = no])
-AT_SKIP_IF([test $HAVE_NC = no])
-AT_KEYWORDS([ovnlb sctp])
-
-# Make sure the SCTP kernel module is loaded.
-LOAD_MODULE([sctp])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# Two LRs - R1 and R2 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
-# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
-# to it.  R2 is a gateway router on which we add load-balancing rules.
-#
-#    foo -- R1 -- join - R2 -- alice
-#           |
-#    bar ----
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add join
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-# Static routes.
-ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
-ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
-
-# Logical port 'bar1' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
-"192.168.2.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
-
-# Config OVN load-balancer with a VIP.
-uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
-ovn-nbctl set logical_router R2 load_balancer=$uuid
-
-# Config OVN load-balancer with another VIP (this time with ports).
-ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
-
-# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
-ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
-    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
-
-# Wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
-grep 'nat(dst=192.168.2.2:12345)'])
-
-# Start webservers in 'foo1', 'bar1'.
-OVS_START_L7([foo1], [sctp])
-OVS_START_L7([bar1], [sctp])
-
-on_exit "ovs-ofctl -O OpenFlow13 dump-flows br-int"
-
-dnl Should work with the virtual IP address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.1 12345 > client$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
-sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
-sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
-sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
-])
-
-dnl Test load-balancing that includes L4 ports in NAT.
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
-sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
-sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
-sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
-])
-
-check_est_flows () {
-    n=$(ovs-ofctl dump-flows br-int table=15 | grep "+est" \
-        | grep "ct_mark=$1" | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p')
-
-    echo "n_packets=$n"
-    test -n "$n" && test "$n" != "0"
-}
-
-OVS_WAIT_UNTIL([check_est_flows 0x2], [check established flows])
-
-
-ovn-nbctl set logical_router R2 options:lb_force_snat_ip="20.0.0.2"
-
-# Destroy the load balancer and create again. ovn-controller will
-# clear the OF flows and re add again and clears the n_packets
-# for these flows.
-ovn-nbctl destroy load_balancer $uuid
-uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
-ovn-nbctl set logical_router R2 load_balancer=$uuid
-
-check ovs-appctl dpctl/flush-conntrack
-
-# Config OVN load-balancer with another VIP (this time with ports).
-ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
-
-ovn-nbctl list load_balancer
-ovn-sbctl dump-flows R2
-OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=45 | grep 'nat(src=20.0.0.2)'])
-
-dnl Test load-balancing that includes L4 ports in NAT.
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
-sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
-sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
-sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
-])
-
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
-sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
-sctp,orig=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
-sctp,orig=(src=172.16.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
-])
-
-OVS_WAIT_UNTIL([check_est_flows 0xa], [check established flows])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
 OVN_FOR_EACH_NORTHD([
 AT_SETUP([load balancing affinity sessions - IPv4])
 AT_KEYWORDS([ovnlb])
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index c45452607..871ffb14d 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -11819,3 +11819,214 @@  OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
 /connection dropped.*/d"])
 AT_CLEANUP
 ])
+
+AT_SETUP([load balancing in gateway router - SCTP])
+AT_SKIP_IF([test $HAVE_SCTP = no])
+AT_SKIP_IF([test $HAVE_NC = no])
+AT_KEYWORDS([ovnlb sctp])
+
+# Make sure the SCTP kernel module is loaded.
+LOAD_MODULE([sctp])
+
+CHECK_CONNTRACK()
+CHECK_CONNTRACK_NAT()
+ovn_start
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-int])
+
+# Set external-ids in br-int needed for ovn-controller.
+ovs-vsctl \
+        -- set Open_vSwitch . external-ids:system-id=hv1 \
+        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
+        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
+        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
+        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
+
+# Start the ovn-controller.
+start_daemon ovn-controller
+
+# Logical network:
+# Two LRs - R1 and R2 that are connected to each other via LS "join"
+# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
+# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
+# to it.  R2 is a gateway router on which we add load-balancing rules.
+#
+#    foo -- R1 -- join - R2 -- alice
+#           |
+#    bar ----
+
+ovn-nbctl create Logical_Router name=R1
+ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
+
+ovn-nbctl ls-add foo
+ovn-nbctl ls-add bar
+ovn-nbctl ls-add alice
+ovn-nbctl ls-add join
+
+# Connect foo to R1
+ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
+ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
+    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
+
+# Connect bar to R1
+ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
+ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
+    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
+
+# Connect alice to R2
+ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
+ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
+    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
+
+# Connect R1 to join
+ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
+ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
+    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
+
+# Connect R2 to join
+ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
+ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
+    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
+
+# Static routes.
+ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
+ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
+
+# Logical port 'foo1' in switch 'foo'.
+ADD_NAMESPACES(foo1)
+ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
+         "192.168.1.1")
+ovn-nbctl lsp-add foo foo1 \
+-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
+
+# Logical port 'alice1' in switch 'alice'.
+ADD_NAMESPACES(alice1)
+ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
+         "172.16.1.1")
+ovn-nbctl lsp-add alice alice1 \
+-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
+
+# Logical port 'bar1' in switch 'bar'.
+ADD_NAMESPACES(bar1)
+ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
+"192.168.2.1")
+ovn-nbctl lsp-add bar bar1 \
+-- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
+
+# Config OVN load-balancer with a VIP.
+uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
+ovn-nbctl set logical_router R2 load_balancer=$uuid
+
+# Config OVN load-balancer with another VIP (this time with ports).
+ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
+
+# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
+ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
+    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
+
+# Wait for ovn-controller to catch up.
+ovn-nbctl --wait=hv sync
+OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
+grep 'nat(dst=192.168.2.2:12345)'])
+
+# Start webservers in 'foo1', 'bar1'.
+OVS_START_L7([foo1], [sctp])
+OVS_START_L7([bar1], [sctp])
+
+on_exit "ovs-ofctl -O OpenFlow13 dump-flows br-int"
+
+dnl Should work with the virtual IP address through NAT
+for i in `seq 1 20`; do
+    echo Request $i
+    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.1 12345 > client$i.log])
+done
+
+dnl Each server should have at least one connection.
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
+sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
+sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
+sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
+sctp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
+])
+
+dnl Test load-balancing that includes L4 ports in NAT.
+for i in `seq 1 20`; do
+    echo Request $i
+    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
+done
+
+dnl Each server should have at least one connection.
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
+sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
+sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
+sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
+sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2
+])
+
+check_est_flows () {
+    n=$(ovs-ofctl dump-flows br-int table=15 | grep "+est" \
+        | grep "ct_mark=$1" | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p')
+
+    echo "n_packets=$n"
+    test -n "$n" && test "$n" != "0"
+}
+
+OVS_WAIT_UNTIL([check_est_flows 0x2], [check established flows])
+
+
+ovn-nbctl set logical_router R2 options:lb_force_snat_ip="20.0.0.2"
+
+# Destroy the load balancer and create again. ovn-controller will
+# clear the OF flows and re add again and clears the n_packets
+# for these flows.
+ovn-nbctl destroy load_balancer $uuid
+uuid=`ovn-nbctl  create load_balancer protocol=sctp vips:30.0.0.1="192.168.1.2,192.168.2.2"`
+ovn-nbctl set logical_router R2 load_balancer=$uuid
+
+check ovs-appctl dpctl/flush-conntrack
+
+# Config OVN load-balancer with another VIP (this time with ports).
+ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:12345,192.168.2.2:12345"'
+
+ovn-nbctl list load_balancer
+ovn-sbctl dump-flows R2
+OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=45 | grep 'nat(src=20.0.0.2)'])
+
+dnl Test load-balancing that includes L4 ports in NAT.
+for i in `seq 1 20`; do
+    echo Request $i
+    NS_CHECK_EXEC([alice1], [nc --sctp --recv-only 30.0.0.2 8000 > clients$i.log])
+done
+
+dnl Each server should have at least one connection.
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
+sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
+sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
+sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
+sctp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10
+])
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) |
+sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
+sed 's/,protoinfo=.*$//' | uniq], [0], [dnl
+sctp,orig=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
+sctp,orig=(src=172.16.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>
+])
+
+OVS_WAIT_UNTIL([check_est_flows 0xa], [check established flows])
+
+OVS_APP_EXIT_AND_WAIT([ovn-controller])
+
+as ovn-sb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as ovn-nb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as northd
+OVS_APP_EXIT_AND_WAIT([ovn-northd])
+
+as
+OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
+/connection dropped.*/d"])
+AT_CLEANUP