On Wed, Apr 29, 2020 at 2:30 PM Numan Siddique <num...@ovn.org> wrote:
> > > On Fri, Apr 24, 2020 at 8:41 PM Mark Michelson <mmich...@redhat.com> > wrote: > >> This is essentially a copy of existing load balancer tests that use TCP, >> but with a few modifications for SCTP. >> >> Userspace conntrack and SCTP do not currently mix. Therefore, the test >> has been added to a new kernel-only system testsuite file. If userspace >> conntrack support for SCTP is added in the future, we can potentially >> move the SCTP test into the unified system-ovn.at file. >> >> Signed-off-by: Mark Michelson <mmich...@redhat.com> >> > > > Acked-by: Numan Siddique <num...@ovn.org> > Hi Mark, Looks like you missed this Ack. I applied this patch to master. Numan > > Thanks > Numan > > > > >> --- >> v1->v2: rebase >> --- >> tests/atlocal.in | 2 + >> tests/automake.mk | 3 +- >> tests/system-kmod-testsuite.at | 1 + >> tests/system-ovn-kmod.at | 217 +++++++++++++++++++++++++++++++++ >> tests/test-l7.py | 27 ++++ >> 5 files changed, 249 insertions(+), 1 deletion(-) >> create mode 100644 tests/system-ovn-kmod.at >> >> diff --git a/tests/atlocal.in b/tests/atlocal.in >> index 8f3ff03b9..26681f02d 100644 >> --- a/tests/atlocal.in >> +++ b/tests/atlocal.in >> @@ -150,6 +150,8 @@ find_l7_lib() >> find_l7_lib ftp >> # HAVE_TFTP >> find_l7_lib tftp >> +# HAVE_SCTP >> +find_l7_lib sctp >> >> # Look for a commnand in the system. If it is found, defines >> # HAVE_COMMAND="yes", otherwise HAVE_COMMAND="no". >> diff --git a/tests/automake.mk b/tests/automake.mk >> index 215fb432b..2b587af8b 100644 >> --- a/tests/automake.mk >> +++ b/tests/automake.mk >> @@ -45,7 +45,8 @@ SYSTEM_USERSPACE_TESTSUITE_AT = \ >> >> SYSTEM_TESTSUITE_AT = \ >> tests/system-common-macros.at \ >> - tests/system-ovn.at >> + tests/system-ovn.at \ >> + tests/system-ovn-kmod.at >> >> check_SCRIPTS += tests/atlocal >> >> diff --git a/tests/system-kmod-testsuite.at b/tests/ >> system-kmod-testsuite.at >> index 2ccd9f1ce..5ba35babb 100644 >> --- a/tests/system-kmod-testsuite.at >> +++ b/tests/system-kmod-testsuite.at >> @@ -24,3 +24,4 @@ m4_include([tests/system-common-macros.at]) >> m4_include([tests/system-kmod-macros.at]) >> >> m4_include([tests/system-ovn.at]) >> +m4_include([tests/system-ovn-kmod.at]) >> diff --git a/tests/system-ovn-kmod.at b/tests/system-ovn-kmod.at >> new file mode 100644 >> index 000000000..1c0ab194d >> --- /dev/null >> +++ b/tests/system-ovn-kmod.at >> @@ -0,0 +1,217 @@ >> +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([ovn -- load balancing in gateway router - SCTP]) >> +AT_SKIP_IF([test $HAVE_SCTP = no]) >> +AT_SKIP_IF([test $HAVE_NC = no]) >> +AT_KEYWORDS([ovnlb 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 -e 's/vtag_orig=[[0-9]]*/vtag_orig=<cleared>/' | >> +sed -e 's/vtag_reply=[[0-9]]*/vtag_reply=<cleared>/' | 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>,protoinfo=(state=<cleared>,vtag_orig=<cleared>,vtag_reply=<cleared>) >> >> +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>,protoinfo=(state=<cleared>,vtag_orig=<cleared>,vtag_reply=<cleared>) >> +]) >> + >> +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 -e 's/vtag_orig=[[0-9]]*/vtag_orig=<cleared>/' | >> +sed -e 's/vtag_reply=[[0-9]]*/vtag_reply=<cleared>/' | 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>,protoinfo=(state=<cleared>,vtag_orig=<cleared>,vtag_reply=<cleared>) >> >> +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>,protoinfo=(state=<cleared>,vtag_orig=<cleared>,vtag_reply=<cleared>) >> +]) >> + >> +check_est_flows () { >> + n=$(ovs-ofctl dump-flows br-int table=14 | grep \ >> +"priority=120,ct_state=+est+trk,sctp,metadata=0x2,nw_dst=30.0.0.2,tp_dst=8000" >> \ >> +| grep nat | sed -n 's/.*n_packets=\([[0-9]]\{1,\}\).*/\1/p') >> + >> + echo "n_packets=$n" >> + test "$n" != 0 >> +} >> + >> +OVS_WAIT_UNTIL([check_est_flows], [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 >> + >> +# 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=41 | \ >> +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 -e 's/vtag_orig=[[0-9]]*/vtag_orig=<cleared>/' | >> +sed -e 's/vtag_reply=[[0-9]]*/vtag_reply=<cleared>/' | 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>,protoinfo=(state=<cleared>,vtag_orig=<cleared>,vtag_reply=<cleared>) >> >> +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>,protoinfo=(state=<cleared>,vtag_orig=<cleared>,vtag_reply=<cleared>) >> +]) >> + >> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) | >> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' | >> +sed -e 's/vtag_orig=[[0-9]]*/vtag_orig=<cleared>/' | >> +sed -e 's/vtag_reply=[[0-9]]*/vtag_reply=<cleared>/' | 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>,protoinfo=(state=<cleared>,vtag_orig=<cleared>,vtag_reply=<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>,protoinfo=(state=<cleared>,vtag_orig=<cleared>,vtag_reply=<cleared>) >> +]) >> + >> +OVS_WAIT_UNTIL([check_est_flows], [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 >> diff --git a/tests/test-l7.py b/tests/test-l7.py >> index d7854a1df..701c63f0d 100755 >> --- a/tests/test-l7.py >> +++ b/tests/test-l7.py >> @@ -73,12 +73,39 @@ def get_tftpd(): >> return server >> >> >> +def get_sctp(): >> + try: >> + import socket >> + import sctp >> + except ImportError: >> + print("Failed to import for SCTP") >> + server = None >> + pass >> + else: >> + class OVSSCTPServer(object): >> + def __init__(self, listen, handler=None): >> + self.sock = sctp.sctpsocket_tcp(socket.AF_INET) >> + self.sock.bind(listen) >> + self.sock.listen() >> + >> + def serve_forever(self): >> + while True: >> + client, _ = self.sock.accept() >> + client.send(b"SCRAM\r\n") >> + client.close() >> + >> + server = [OVSSCTPServer, None, 12345] >> + >> + return server >> + >> + >> def main(): >> SERVERS = { >> 'http': [TCPServer, SimpleHTTPRequestHandler, 80], >> 'http6': [TCPServerV6, SimpleHTTPRequestHandler, 80], >> 'ftp': get_ftpd(), >> 'tftp': get_tftpd(), >> + 'sctp': get_sctp(), >> } >> >> protocols = [srv for srv in SERVERS if SERVERS[srv] is not None] >> -- >> 2.25.1 >> >> _______________________________________________ >> dev mailing list >> d...@openvswitch.org >> https://mail.openvswitch.org/mailman/listinfo/ovs-dev >> >> _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev