[ovs-dev] [PATCH ovn v2] system-ovn.at: Create IPv6 load balancing tests

Mark Michelson mmichels at redhat.com
Wed Nov 6 18:46:31 UTC 2019


I pushed this to master. Thanks!

On 11/5/19 8:26 PM, Russell Bryant wrote:
> Duplicate all of the IPv4 load balancing test cases for IPv6.
> All of these are passing without any changes needed in OVN code, but
> this will help ensure that we do not have any IPv6 load balancing
> regressions in the future.
> 
> Signed-off-by: Russell Bryant <russell at ovn.org>
> ---
>   tests/system-ovn.at | 876 ++++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 799 insertions(+), 77 deletions(-)
> 
> v1 -> v2:
>   - Use [[ and ]] instead of quadigraphs to enhance readability,
>     as suggested by Ben Pfaff
> 
> 
> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> index b3f90aae2..5885df58e 100644
> --- a/tests/system-ovn.at
> +++ b/tests/system-ovn.at
> @@ -1158,6 +1158,153 @@ tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(s
>   ])
>   
>   
> +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"])
> +AT_CLEANUP
> +
> +AT_SETUP([ovn -- load-balancing - IPv6])
> +AT_KEYWORDS([ovnlb])
> +
> +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:
> +# 2 logical switches "foo" (fd01::/64) and "bar" (fd02::/64)
> +# connected to a router R1.
> +# foo has foo1 to act as a client.
> +# bar has bar1, bar2, bar3 to act as servers.
> +#
> +# Loadbalancer VIPs in fd03::/64 network.
> +
> +ovn-nbctl create Logical_Router name=R1
> +ovn-nbctl ls-add foo
> +ovn-nbctl ls-add bar
> +
> +# Connect foo to R1
> +ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 fd01::1/64
> +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 fd02::1/64
> +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\"
> +
> +# Create logical port 'foo1' in switch 'foo'.
> +ADD_NAMESPACES(foo1)
> +ADD_VETH(foo1, foo1, br-int, "fd01::2/64", "f0:00:00:01:02:03", \
> +         "fd01::1")
> +ovn-nbctl lsp-add foo foo1 \
> +-- lsp-set-addresses foo1 "f0:00:00:01:02:03 fd01::2"
> +
> +# Create logical ports 'bar1', 'bar2', 'bar3' in switch 'bar'.
> +ADD_NAMESPACES(bar1)
> +ADD_VETH(bar1, bar1, br-int, "fd02::2/64", "f0:00:0f:01:02:03", \
> +         "fd02::1")
> +ovn-nbctl lsp-add bar bar1 \
> +-- lsp-set-addresses bar1 "f0:00:0f:01:02:03 fd02::2"
> +
> +ADD_NAMESPACES(bar2)
> +ADD_VETH(bar2, bar2, br-int, "fd02::3/64", "f0:00:0f:01:02:04", \
> +         "fd02::1")
> +ovn-nbctl lsp-add bar bar2 \
> +-- lsp-set-addresses bar2 "f0:00:0f:01:02:04 fd02::3"
> +
> +ADD_NAMESPACES(bar3)
> +ADD_VETH(bar3, bar3, br-int, "fd02::4/64", "f0:00:0f:01:02:05", \
> +         "fd02::1")
> +ovn-nbctl lsp-add bar bar3 \
> +-- lsp-set-addresses bar3 "f0:00:0f:01:02:05 fd02::4"
> +
> +# Config OVN load-balancer with a VIP.
> +uuid=`ovn-nbctl  create load_balancer vips:\"fd03::1\"=\"fd02::2,fd02::3,fd02::4\"`
> +ovn-nbctl set logical_switch foo load_balancer=$uuid
> +
> +# Create another load-balancer with another VIP.
> +uuid=`ovn-nbctl create load_balancer vips:\"fd03::3\"=\"fd02::2,fd02::3,fd02::4\"`
> +ovn-nbctl add logical_switch foo load_balancer $uuid
> +
> +# Config OVN load-balancer with another VIP (this time with ports).
> +ovn-nbctl set load_balancer $uuid vips:'"[[fd03::2]]:8000"'='"@<:@fd02::2@:>@:80,@<:@fd02::3@:>@:80,@<:@fd02::4@:>@:80"'
> +
> +# 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=\[[fd02::4\]]:80)'])
> +
> +# Start webservers in 'bar1', 'bar2' and 'bar3'.
> +OVS_START_L7([bar1], [http6])
> +OVS_START_L7([bar2], [http6])
> +OVS_START_L7([bar3], [http6])
> +
> +dnl Should work with the virtual IP fd03::1 address through NAT
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([foo1], [wget http://[[fd03::1]] -t 5 -T 1 --retry-connrefused -v -o wget$i.log || (ovs-ofctl -O OpenFlow13 dump-flows br-int && false)])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd03::1) | grep -v fe80 | \
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> +tcp,orig=(src=fd01::2,dst=fd03::1,sport=<cleared>,dport=<cleared>),reply=(src=fd02::2,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::1,sport=<cleared>,dport=<cleared>),reply=(src=fd02::3,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::1,sport=<cleared>,dport=<cleared>),reply=(src=fd02::4,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +])
> +
> +dnl Should work with the virtual IP fd03::3 address through NAT
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([foo1], [wget http://[[fd03::3]] -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd03::3) | grep -v fe80 | \
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> +tcp,orig=(src=fd01::2,dst=fd03::3,sport=<cleared>,dport=<cleared>),reply=(src=fd02::2,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::3,sport=<cleared>,dport=<cleared>),reply=(src=fd02::3,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::3,sport=<cleared>,dport=<cleared>),reply=(src=fd02::4,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +])
> +
> +dnl Test load-balancing that includes L4 ports in NAT.
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([foo1], [wget http://[[fd03::2]]:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd03::2) | grep -v fe80 | \
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> +tcp,orig=(src=fd01::2,dst=fd03::2,sport=<cleared>,dport=<cleared>),reply=(src=fd02::2,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::2,sport=<cleared>,dport=<cleared>),reply=(src=fd02::3,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::2,sport=<cleared>,dport=<cleared>),reply=(src=fd02::4,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +])
> +
> +
>   OVS_APP_EXIT_AND_WAIT([ovn-controller])
>   
>   as ovn-sb
> @@ -1253,18 +1400,431 @@ tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(s
>   dnl Test load-balancing that includes L4 ports in NAT.
>   for i in `seq 1 20`; do
>       echo Request $i
> -    NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +    NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$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>/'], [0], [dnl
> +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.5,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +])
> +
> +
> +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"])
> +AT_CLEANUP
> +
> +AT_SETUP([ovn -- load-balancing - same subnet. - IPv6])
> +AT_KEYWORDS([ovnlb])
> +
> +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:
> +# 1 logical switch "foo" (fd01::/64) connected to router R1.
> +# foo has foo1, foo2, foo3, foo4 as logical ports.
> +#
> +# Loadbalancer VIPs in fd03::/64 network. Router is needed for default
> +# gateway. We will test load-balancing with foo1 as a client and foo2, foo3 and
> +# foo4 as servers.
> +
> +ovn-nbctl create Logical_Router name=R1
> +ovn-nbctl ls-add foo
> +
> +# Connect foo to R1
> +ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 fd01::1/64
> +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\"
> +
> +# Create logical port 'foo1', 'foo2', 'foo3' and 'foo4' in switch 'foo'.
> +ADD_NAMESPACES(foo1, foo2, foo3, foo4)
> +for i in `seq 1 4`; do
> +    j=`expr $i + 1`
> +    ADD_VETH(foo$i, foo$i, br-int, "fd01::$j/64", "f0:00:00:01:02:0$j", \
> +             "fd01::1")
> +    ovn-nbctl lsp-add foo foo$i \
> +        -- lsp-set-addresses foo$i "f0:00:00:01:02:0$j fd01::$j"
> +done
> +
> +# Config OVN load-balancer with a VIP.
> +uuid=`ovn-nbctl  create load_balancer vips:\"fd03::1\"=\"fd01::3,fd01::4,fd01::5\"`
> +ovn-nbctl set logical_switch foo load_balancer=$uuid
> +
> +# Config OVN load-balancer with another VIP (this time with ports).
> +ovn-nbctl set load_balancer $uuid vips:'"[[fd03::2]]:8000"'='"@<:@fd01::3@:>@:80,@<:@fd01::4@:>@:80,@<:@fd01::5@:>@:80"'
> +
> +ovn-nbctl list load_balancer
> +
> +# 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=\[[fd01::5\]]:80)'])
> +
> +# Start webservers in 'foo2', 'foo3' and 'foo4'.
> +OVS_START_L7([foo2], [http6])
> +OVS_START_L7([foo3], [http6])
> +OVS_START_L7([foo4], [http6])
> +
> +dnl Should work with the virtual IP address through NAT
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([foo1], [wget http://[[fd03::1]] -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd03::1) | grep -v fe80 | \
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> +tcp,orig=(src=fd01::2,dst=fd03::1,sport=<cleared>,dport=<cleared>),reply=(src=fd01::3,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::1,sport=<cleared>,dport=<cleared>),reply=(src=fd01::4,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::1,sport=<cleared>,dport=<cleared>),reply=(src=fd01::5,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +])
> +
> +dnl Test load-balancing that includes L4 ports in NAT.
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([foo1], [wget http://[[fd03::2]]:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd03::2) | grep -v fe80 | \
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> +tcp,orig=(src=fd01::2,dst=fd03::2,sport=<cleared>,dport=<cleared>),reply=(src=fd01::3,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::2,sport=<cleared>,dport=<cleared>),reply=(src=fd01::4,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd01::2,dst=fd03::2,sport=<cleared>,dport=<cleared>),reply=(src=fd01::5,dst=fd01::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +])
> +
> +
> +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"])
> +AT_CLEANUP
> +
> +AT_SETUP([ovn -- load balancing in gateway router])
> +AT_KEYWORDS([ovnlb])
> +
> +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 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:80,192.168.2.2:80"'
> +
> +# 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:80)'])
> +
> +# Start webservers in 'foo1', 'bar1'.
> +OVS_START_L7([foo1], [http])
> +OVS_START_L7([bar1], [http])
> +
> +dnl Should work with the virtual IP address through NAT
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([alice1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$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>/'], [0], [dnl
> +tcp,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>)
> +tcp,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>)
> +])
> +
> +dnl Test load-balancing that includes L4 ports in NAT.
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([alice1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$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>/'], [0], [dnl
> +tcp,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>)
> +tcp,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>)
> +])
> +
> +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
> +
> +AT_SETUP([ovn -- load balancing in gateway router - IPv6])
> +AT_KEYWORDS([ovnlb])
> +
> +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 fd20::/64 network. R1 has switchess foo (fd11::/64) and
> +# bar (fd12::/64) connected to it. R2 has alice (fd72::/64) 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 fd11::1/64
> +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 fd12::1/64
> +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 fd72::1/64
> +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 fd20::1/64
> +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 fd20::2/64
> +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 fd72::/64 fd20::2
> +ovn-nbctl lr-route-add R2 fd11::/64 fd20::1
> +ovn-nbctl lr-route-add R2 fd12::/64 fd20::1
> +
> +# Logical port 'foo1' in switch 'foo'.
> +ADD_NAMESPACES(foo1)
> +ADD_VETH(foo1, foo1, br-int, "fd11::2/64", "f0:00:00:01:02:03", \
> +         "fd11::1")
> +ovn-nbctl lsp-add foo foo1 \
> +-- lsp-set-addresses foo1 "f0:00:00:01:02:03 fd11::2"
> +
> +# Logical port 'alice1' in switch 'alice'.
> +ADD_NAMESPACES(alice1)
> +ADD_VETH(alice1, alice1, br-int, "fd72::2/64", "f0:00:00:01:02:04", \
> +         "fd72::1")
> +ovn-nbctl lsp-add alice alice1 \
> +-- lsp-set-addresses alice1 "f0:00:00:01:02:04 fd72::2"
> +
> +# Logical port 'bar1' in switch 'bar'.
> +ADD_NAMESPACES(bar1)
> +ADD_VETH(bar1, bar1, br-int, "fd12::2/64", "f0:00:00:01:02:05", \
> +"fd12::1")
> +ovn-nbctl lsp-add bar bar1 \
> +-- lsp-set-addresses bar1 "f0:00:00:01:02:05 fd12::2"
> +
> +# Config OVN load-balancer with a VIP.
> +uuid=`ovn-nbctl  create load_balancer vips:\"fd30::1\"=\"fd11::2,fd12::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:'"[[fd30::2]]:8000"'='"@<:@fd11::2@:>@:80,@<:@fd12::2@:>@:80"'
> +
> +ovn-nbctl list load_balancer
> +
> +# 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=\"fd12::2\" \
> +    external_ip=\"fd30::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=\[[fd12::2\]]:80)'])
> +
> +# Start webservers in 'foo1', 'bar1'.
> +OVS_START_L7([foo1], [http6])
> +OVS_START_L7([bar1], [http6])
> +
> +dnl Should work with the virtual IP address through NAT
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([alice1], [wget http://[[fd30::1]] -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd30::1) | grep -v fe80 |
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> +tcp,orig=(src=fd72::2,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd11::2,dst=fd72::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd72::2,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd12::2,dst=fd72::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<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], [wget http://[[fd30::2]]:8000 -t 5 -T 1 --retry-connrefused -v -o wget$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) | \
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd30::2) | grep -v fe80 |
>   sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> -tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> -tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> -tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.5,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd72::2,dst=fd30::2,sport=<cleared>,dport=<cleared>),reply=(src=fd11::2,dst=fd72::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd72::2,dst=fd30::2,sport=<cleared>,dport=<cleared>),reply=(src=fd12::2,dst=fd72::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
>   ])
>   
> -
>   OVS_APP_EXIT_AND_WAIT([ovn-controller])
>   
>   as ovn-sb
> @@ -1277,10 +1837,11 @@ as northd
>   OVS_APP_EXIT_AND_WAIT([ovn-northd])
>   
>   as
> -OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
> +/connection dropped.*/d"])
>   AT_CLEANUP
>   
> -AT_SETUP([ovn -- load balancing in gateway router])
> +AT_SETUP([ovn -- multiple gateway routers, load-balancing])
>   AT_KEYWORDS([ovnlb])
>   
>   CHECK_CONNTRACK()
> @@ -1301,21 +1862,27 @@ ovs-vsctl \
>   start_daemon ovn-controller
>   
>   # Logical network:
> -# Two LRs - R1 and R2 that are connected to each other via LS "join"
> +# Three LRs - R1, R2 and R3 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.
> +# to it.  R3 has bob (172.16.1.0/24) connected to it. Note how both alice and
> +# bob have the same subnet behind it.  We are trying to simulate external
> +# network via those 2 switches. In real world the switch ports of these
> +# switches will have addresses set as "unknown" to make them learning switches.
> +# Or those switches will be "localnet" ones.
>   #
>   #    foo -- R1 -- join - R2 -- alice
> -#           |
> -#    bar ----
> +#           |          |
> +#    bar ----          - R3 --- bob
>   
>   ovn-nbctl create Logical_Router name=R1
>   ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
> +ovn-nbctl create Logical_Router name=R3 options:chassis=hv1
>   
>   ovn-nbctl ls-add foo
>   ovn-nbctl ls-add bar
>   ovn-nbctl ls-add alice
> +ovn-nbctl ls-add bob
>   ovn-nbctl ls-add join
>   
>   # Connect foo to R1
> @@ -1333,6 +1900,11 @@ 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 bob to R3
> +ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
> +ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
> +    type=router options:router-port=bob addresses=\"00:00:03: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 \
> @@ -1343,9 +1915,23 @@ 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"'
>   
> +# Connect R3 to join
> +ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
> +ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
> +    type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
> +
> +# Install static routes with source ip address as the policy for routing.
> +# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
> +ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
> +ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
> +
>   # 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
> +ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
> +
> +# For gateway routers R2 and R3, set a force SNAT rule.
> +ovn-nbctl set logical_router R2 options:lb_force_snat_ip=20.0.0.2
> +ovn-nbctl set logical_router R3 options:lb_force_snat_ip=20.0.0.3
>   
>   # Logical port 'foo1' in switch 'foo'.
>   ADD_NAMESPACES(foo1)
> @@ -1356,10 +1942,10 @@ ovn-nbctl lsp-add foo foo1 \
>   
>   # 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", \
> +ADD_VETH(alice1, alice1, br-int, "172.16.1.3/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"
> +-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.3"
>   
>   # Logical port 'bar1' in switch 'bar'.
>   ADD_NAMESPACES(bar1)
> @@ -1368,22 +1954,22 @@ ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
>   ovn-nbctl lsp-add bar bar1 \
>   -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
>   
> +# Logical port 'bob1' in switch 'bob'.
> +ADD_NAMESPACES(bob1)
> +ADD_VETH(bob1, bob1, br-int, "172.16.1.4/24", "f0:00:00:01:02:06", \
> +         "172.16.1.2")
> +ovn-nbctl lsp-add bob bob1 \
> +-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
> +
>   # Config OVN load-balancer with a VIP.
>   uuid=`ovn-nbctl  create load_balancer 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:80,192.168.2.2:80"'
> -
> -# 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
> -
> +ovn-nbctl set logical_router R3 load_balancer=$uuid
>   
>   # 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:80)'])
> +grep 'nat(dst=192.168.2.2)'])
>   
>   # Start webservers in 'foo1', 'bar1'.
>   OVS_START_L7([foo1], [http])
> @@ -1398,23 +1984,16 @@ 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>/'], [0], [dnl
> -tcp,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>)
> -tcp,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>)
> +tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<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], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$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) |
> +dnl Force SNAT should have worked.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0) |
>   sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> -tcp,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>)
> -tcp,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>)
> +tcp,orig=(src=172.16.1.3,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>)
> +tcp,orig=(src=172.16.1.3,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>)
>   ])
> -
>   OVS_APP_EXIT_AND_WAIT([ovn-controller])
>   
>   as ovn-sb
> @@ -1431,7 +2010,7 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>   /connection dropped.*/d"])
>   AT_CLEANUP
>   
> -AT_SETUP([ovn -- multiple gateway routers, load-balancing])
> +AT_SETUP([ovn -- multiple gateway routers, load-balancing - IPv6])
>   AT_KEYWORDS([ovnlb])
>   
>   CHECK_CONNTRACK()
> @@ -1453,9 +2032,9 @@ start_daemon ovn-controller
>   
>   # Logical network:
>   # Three LRs - R1, R2 and R3 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.  R3 has bob (172.16.1.0/24) connected to it. Note how both alice and
> +# in fd20::/64 network. R1 has switchess foo (fd11::/64) and
> +# bar (fd12::/64) connected to it. R2 has alice (fd72::/64) connected
> +# to it.  R3 has bob (fd72::/64) connected to it. Note how both alice and
>   # bob have the same subnet behind it.  We are trying to simulate external
>   # network via those 2 switches. In real world the switch ports of these
>   # switches will have addresses set as "unknown" to make them learning switches.
> @@ -1476,113 +2055,115 @@ ovn-nbctl ls-add bob
>   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 lrp-add R1 foo 00:00:01:01:02:03 fd11::1/64
>   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 lrp-add R1 bar 00:00:01:01:02:04 fd12::1/64
>   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 lrp-add R2 alice 00:00:02:01:02:03 fd72::1/64
>   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 bob to R3
> -ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
> +ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 fd72::2/64
>   ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
>       type=router options:router-port=bob addresses=\"00:00:03: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 lrp-add R1 R1_join 00:00:04:01:02:03 fd20::1/64
>   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 lrp-add R2 R2_join 00:00:04:01:02:04 fd20::2/64
>   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"'
>   
>   # Connect R3 to join
> -ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
> +ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 fd20::3/64
>   ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
>       type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
>   
>   # Install static routes with source ip address as the policy for routing.
>   # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
> -ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
> -ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
> +ovn-nbctl --policy="src-ip" lr-route-add R1 fd11::/64 fd20::2
> +ovn-nbctl --policy="src-ip" lr-route-add R1 fd12::/64 fd20::3
>   
>   # Static routes.
> -ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
> -ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
> +ovn-nbctl lr-route-add R2 fd11::/64 fd20::1
> +ovn-nbctl lr-route-add R2 fd12::/64 fd20::1
> +ovn-nbctl lr-route-add R3 fd11::/64 fd20::1
> +ovn-nbctl lr-route-add R3 fd12::/64 fd20::1
>   
>   # For gateway routers R2 and R3, set a force SNAT rule.
> -ovn-nbctl set logical_router R2 options:lb_force_snat_ip=20.0.0.2
> -ovn-nbctl set logical_router R3 options:lb_force_snat_ip=20.0.0.3
> +ovn-nbctl set logical_router R2 options:lb_force_snat_ip=fd20::2
> +ovn-nbctl set logical_router R3 options:lb_force_snat_ip=fd20::3
>   
>   # 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")
> +ADD_VETH(foo1, foo1, br-int, "fd11::2/64", "f0:00:00:01:02:03", \
> +         "fd11::1")
>   ovn-nbctl lsp-add foo foo1 \
> --- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
> +-- lsp-set-addresses foo1 "f0:00:00:01:02:03 fd11::2"
>   
>   # Logical port 'alice1' in switch 'alice'.
>   ADD_NAMESPACES(alice1)
> -ADD_VETH(alice1, alice1, br-int, "172.16.1.3/24", "f0:00:00:01:02:04", \
> -         "172.16.1.1")
> +ADD_VETH(alice1, alice1, br-int, "fd72::3/64", "f0:00:00:01:02:04", \
> +         "fd72::1")
>   ovn-nbctl lsp-add alice alice1 \
> --- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.3"
> +-- lsp-set-addresses alice1 "f0:00:00:01:02:04 fd72::3"
>   
>   # 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")
> +ADD_VETH(bar1, bar1, br-int, "fd12::2/64", "f0:00:00:01:02:05", \
> +"fd12::1")
>   ovn-nbctl lsp-add bar bar1 \
> --- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
> +-- lsp-set-addresses bar1 "f0:00:00:01:02:05 fd12::2"
>   
>   # Logical port 'bob1' in switch 'bob'.
>   ADD_NAMESPACES(bob1)
> -ADD_VETH(bob1, bob1, br-int, "172.16.1.4/24", "f0:00:00:01:02:06", \
> -         "172.16.1.2")
> +ADD_VETH(bob1, bob1, br-int, "fd72::4/64", "f0:00:00:01:02:06", \
> +         "fd72::2")
>   ovn-nbctl lsp-add bob bob1 \
> --- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
> +-- lsp-set-addresses bob1 "f0:00:00:01:02:06 fd72::4"
>   
>   # Config OVN load-balancer with a VIP.
> -uuid=`ovn-nbctl  create load_balancer vips:30.0.0.1="192.168.1.2,192.168.2.2"`
> +uuid=`ovn-nbctl create load_balancer vips:\"fd30::1\"=\"fd11::2,fd12::2\"`
>   ovn-nbctl set logical_router R2 load_balancer=$uuid
>   ovn-nbctl set logical_router R3 load_balancer=$uuid
>   
>   # 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)'])
> +grep 'nat(dst=fd12::2)'])
>   
>   # Start webservers in 'foo1', 'bar1'.
> -OVS_START_L7([foo1], [http])
> -OVS_START_L7([bar1], [http])
> +OVS_START_L7([foo1], [http6])
> +OVS_START_L7([bar1], [http6])
>   
>   dnl Should work with the virtual IP address through NAT
>   for i in `seq 1 20`; do
>       echo Request $i
> -    NS_CHECK_EXEC([alice1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +    NS_CHECK_EXEC([alice1], [wget http://[[fd30::1]] -t 5 -T 1 --retry-connrefused -v -o wget$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) |
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd30::1) | grep -v fe80 |
>   sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> -tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> -tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd11::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd12::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
>   ])
>   
>   dnl Force SNAT should have worked.
> -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0) |
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd20::2) | grep -v fe80 |
>   sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> -tcp,orig=(src=172.16.1.3,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>)
> -tcp,orig=(src=172.16.1.3,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>)
> +tcp,orig=(src=fd72::3,dst=fd11::2,sport=<cleared>,dport=<cleared>),reply=(src=fd11::2,dst=fd20::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd72::3,dst=fd12::2,sport=<cleared>,dport=<cleared>),reply=(src=fd12::2,dst=fd20::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
>   ])
>   OVS_APP_EXIT_AND_WAIT([ovn-controller])
>   
> @@ -1741,6 +2322,147 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
>   /connection dropped.*/d"])
>   AT_CLEANUP
>   
> +AT_SETUP([ovn -- load balancing in router with gateway router port - IPv6])
> +AT_KEYWORDS([ovnlb])
> +
> +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:
> +# One LR R1 with switches foo (fd01::/64), bar (fd02::/64),
> +# and alice (fd72::/64) connected to it.  The port between R1 and
> +# alice is the router gateway port where the R1 LB rules are applied.
> +#
> +#    foo -- R1 -- bar
> +#           |
> +#    alice ----
> +
> +ovn-nbctl lr-add R1
> +
> +ovn-nbctl ls-add foo
> +ovn-nbctl ls-add bar
> +ovn-nbctl ls-add alice
> +
> +ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 fd01::1/64
> +ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 fd02::1/64
> +ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 fd72::1/64 \
> +    -- set Logical_Router_Port alice options:redirect-chassis=hv1
> +
> +# Connect foo to R1
> +ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
> +    type=router options:router-port=foo \
> +    -- lsp-set-addresses rp-foo router
> +
> +# Connect bar to R1
> +ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
> +    type=router options:router-port=bar \
> +    -- lsp-set-addresses rp-bar router
> +
> +# Connect alice to R1
> +ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
> +    type=router options:router-port=alice \
> +    -- lsp-set-addresses rp-alice router
> +
> +# Logical port 'foo1' in switch 'foo'.
> +ADD_NAMESPACES(foo1)
> +ADD_VETH(foo1, foo1, br-int, "fd01::2/64", "f0:00:00:01:02:03", \
> +         "fd01::1")
> +ovn-nbctl lsp-add foo foo1 \
> +-- lsp-set-addresses foo1 "f0:00:00:01:02:03 fd01::2"
> +
> +# Logical port 'foo2' in switch 'foo'.
> +ADD_NAMESPACES(foo2)
> +ADD_VETH(foo2, foo2, br-int, "fd01::3/64", "f0:00:00:01:02:06", \
> +         "fd01::1")
> +ovn-nbctl lsp-add foo foo2 \
> +-- lsp-set-addresses foo2 "f0:00:00:01:02:06 fd01::3"
> +
> +# Logical port 'bar1' in switch 'bar'.
> +ADD_NAMESPACES(bar1)
> +ADD_VETH(bar1, bar1, br-int, "fd02::2/64", "f0:00:00:01:02:04", \
> +         "fd02::1")
> +ovn-nbctl lsp-add bar bar1 \
> +-- lsp-set-addresses bar1 "f0:00:00:01:02:04 fd02::2"
> +
> +# Logical port 'alice1' in switch 'alice'.
> +ADD_NAMESPACES(alice1)
> +ADD_VETH(alice1, alice1, br-int, "fd72::2/64", "f0:00:00:01:02:05", \
> +         "fd72::1")
> +ovn-nbctl lsp-add alice alice1 \
> +-- lsp-set-addresses alice1 "f0:00:00:01:02:05 fd72::2"
> +
> +# Config OVN load-balancer with a VIP.
> +uuid=`ovn-nbctl  create load_balancer vips:\"fd72::10\"=\"fd01::2,fd02::2\"`
> +ovn-nbctl set logical_router R1 load_balancer=$uuid
> +
> +# Config OVN load-balancer with another VIP (this time with ports).
> +ovn-nbctl set load_balancer $uuid vips:'"[[fd72::11]]:8000"'='"@<:@fd01::2@:>@:80,@<:@fd02::2@:>@:80"'
> +
> +# 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=\[[fd02::2\]]:80)'])
> +
> +# Start webservers in 'foo1', 'bar1'.
> +OVS_START_L7([foo1], [http6])
> +OVS_START_L7([bar1], [http6])
> +
> +dnl Should work with the virtual IP address through NAT
> +for i in `seq 1 20`; do
> +    echo Request $i
> +    NS_CHECK_EXEC([alice1], [wget http://[[fd72::10]] -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd72::10) | grep -v fe80 |
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> +tcp,orig=(src=fd72::2,dst=fd72::10,sport=<cleared>,dport=<cleared>),reply=(src=fd01::2,dst=fd72::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd72::2,dst=fd72::10,sport=<cleared>,dport=<cleared>),reply=(src=fd02::2,dst=fd72::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<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], [wget http://[[fd72::11]]:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
> +done
> +
> +dnl Each server should have at least one connection.
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd72::11) | grep -v fe80 |
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> +tcp,orig=(src=fd72::2,dst=fd72::11,sport=<cleared>,dport=<cleared>),reply=(src=fd01::2,dst=fd72::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +tcp,orig=(src=fd72::2,dst=fd72::11,sport=<cleared>,dport=<cleared>),reply=(src=fd02::2,dst=fd72::2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
> +])
> +
> +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
> +
>   AT_SETUP([ovn -- DNAT and SNAT on distributed router - N/S])
>   AT_KEYWORDS([ovnnat])
>   
> 



More information about the dev mailing list