[ovs-dev] [PATCH v3 2/2 ovn] OVN: Use ip4.src and ip4.dst actions for NAT rules
Ankur Sharma
ankur.sharma at nutanix.com
Tue Oct 29 21:59:05 UTC 2019
For dnat_and_snat rules which are meant to be stateless
instead of using ct_snat/dnat OVN actions, we will use
ip4.src/ip4.dst.
This actions will do 1:1 mapping to inner ip to external ip,
while recalculating the checksums.
Signed-off-by: Ankur Sharma <ankur.sharma at nutanix.com>
---
northd/ovn-northd.8.xml | 34 ++++--
northd/ovn-northd.c | 86 +++++++++++--
tests/ovn-northd.at | 57 +++++++++
tests/ovn.at | 311 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 472 insertions(+), 16 deletions(-)
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index d3e0e5e..87a6909 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -1807,7 +1807,9 @@ icmp6 {
to change the source IP address of a packet from <var>A</var> to
<var>B</var>, a priority-90 flow matches <code>ip &&
ip4.dst == <var>B</var></code> with an action
- <code>ct_snat; </code>.
+ <code>ct_snat; </code>. If the NAT rule is of type dnat_and_snat
+ and has <code>stateless=true</code> in the options, then the action
+ would be <code>ip4.dst=(<var>B</var>)</code>.
</p>
<p>
@@ -1827,7 +1829,10 @@ icmp6 {
<var>B</var>, a priority-100 flow matches <code>ip &&
ip4.dst == <var>B</var> && inport == <var>GW</var></code>,
where <var>GW</var> is the logical router gateway port, with an
- action <code>ct_snat;</code>.
+ action <code>ct_snat;</code>. If the NAT rule is of type
+ dnat_and_snat and has <code>stateless=true</code> in the
+ options, then the action would be <code>ip4.dst=
+ (<var>B</var>)</code>.
</p>
<p>
@@ -1947,7 +1952,10 @@ icmp6 {
Gateway router is configured to force SNAT any DNATed packet,
the above action will be replaced by
<code>flags.force_snat_for_dnat = 1; flags.loopback = 1;
- ct_dnat(<var>B</var>);</code>.
+ ct_dnat(<var>B</var>);</code>. If the NAT rule is of type
+ dnat_and_snat and has <code>stateless=true</code> in the
+ options, then the action would be <code>ip4.dst=
+ (<var>B</var>)</code>.
</li>
<li>
@@ -1979,7 +1987,10 @@ icmp6 {
<var>B</var>, a priority-100 flow matches <code>ip &&
ip4.dst == <var>B</var> && inport == <var>GW</var></code>,
where <var>GW</var> is the logical router gateway port, with an
- action <code>ct_dnat(<var>B</var>);</code>.
+ action <code>ct_dnat(<var>B</var>);</code>. If the NAT rule is of
+ type dnat_and_snat and has <code>stateless=true</code> in the
+ options, then the action would be <code>ip4.dst=
+ (<var>B</var>)</code>.
</p>
<p>
@@ -2653,7 +2664,10 @@ nd_ns {
matches <code>ip && ip4.src == <var>B</var>
&& outport == <var>GW</var></code>, where <var>GW</var>
is the logical router gateway port, with an action
- <code>ct_dnat;</code>.
+ <code>ct_dnat;</code>. If the NAT rule is of type
+ dnat_and_snat and has <code>stateless=true</code> in the
+ options, then the action would be <code>ip4.src=
+ (<var>B</var>)</code>.
</p>
<p>
@@ -2711,7 +2725,10 @@ nd_ns {
<code>ip && ip4.src == <var>A</var></code> with an action
<code>ct_snat(<var>B</var>);</code>. The priority of the flow
is calculated based on the mask of <var>A</var>, with matches
- having larger masks getting higher priorities.
+ having larger masks getting higher priorities. If the NAT rule is
+ of type dnat_and_snat and has <code>stateless=true</code> in the
+ options, then the action would be <code>ip4.src=
+ (<var>B</var>)</code>.
</p>
<p>
A priority-0 logical flow with match <code>1</code> has actions
@@ -2734,7 +2751,10 @@ nd_ns {
logical router gateway port, with an action
<code>ct_snat(<var>B</var>);</code>. The priority of the flow
is calculated based on the mask of <var>A</var>, with matches
- having larger masks getting higher priorities.
+ having larger masks getting higher priorities. If the NAT rule
+ is of type dnat_and_snat and has <code>stateless=true</code>
+ in the options, then the action would be <code>ip4.src=
+ (<var>B</var>)</code>.
</p>
<p>
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 194e4bf..4431659 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -6500,6 +6500,18 @@ copy_ra_to_sb(struct ovn_port *op, const char *address_mode)
smap_destroy(&options);
}
+static inline bool
+lrouter_nat_is_stateless(const struct nbrec_nat *nat)
+{
+ const char *stateless = smap_get(&nat->options, "stateless");
+
+ if (stateless && !strcmp(stateless, "true")) {
+ return true;
+ }
+
+ return false;
+}
+
static void
build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
struct hmap *lflows, struct shash *meter_groups)
@@ -7261,6 +7273,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
nat = od->nbr->nat[i];
ovs_be32 ip, mask;
+ bool stateless = lrouter_nat_is_stateless(nat);
char *error = ip_parse_masked(nat->external_ip, &ip, &mask);
if (error || mask != OVS_BE32_MAX) {
@@ -7326,15 +7339,26 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
if (!od->l3dgw_port) {
/* Gateway router. */
ds_clear(&match);
+ ds_clear(&actions);
ds_put_format(&match, "ip && ip4.dst == %s",
nat->external_ip);
+
+ if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
+ ds_put_format(&actions, "ip4.dst=%s; next;",
+ nat->logical_ip);
+ } else {
+ ds_put_cstr(&actions, "ct_snat;");
+ }
+
ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 90,
- ds_cstr(&match), "ct_snat;");
+ ds_cstr(&match), ds_cstr(&actions));
} else {
/* Distributed router. */
/* Traffic received on l3dgw_port is subject to NAT. */
ds_clear(&match);
+ ds_clear(&actions);
+
ds_put_format(&match, "ip && ip4.dst == %s"
" && inport == %s",
nat->external_ip,
@@ -7345,8 +7369,16 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, " && is_chassis_resident(%s)",
od->l3redirect_port->json_key);
}
+
+ if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
+ ds_put_format(&actions, "ip4.dst=%s; next;",
+ nat->logical_ip);
+ } else {
+ ds_put_cstr(&actions, "ct_snat;");
+ }
+
ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 100,
- ds_cstr(&match), "ct_snat;");
+ ds_cstr(&match), ds_cstr(&actions));
/* Traffic received on other router ports must be
* redirected to the central instance of the l3dgw_port
@@ -7381,8 +7413,16 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&actions,
"flags.force_snat_for_dnat = 1; ");
}
- ds_put_format(&actions, "flags.loopback = 1; ct_dnat(%s);",
- nat->logical_ip);
+
+ if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
+ ds_put_format(&actions, "flags.loopback = 1; "
+ "ip4.dst=%s; next;",
+ nat->logical_ip);
+ } else {
+ ds_put_format(&actions, "flags.loopback = 1; "
+ "ct_dnat(%s);", nat->logical_ip);
+ }
+
ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 100,
ds_cstr(&match), ds_cstr(&actions));
} else {
@@ -7401,8 +7441,15 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
od->l3redirect_port->json_key);
}
ds_clear(&actions);
- ds_put_format(&actions, "ct_dnat(%s);",
- nat->logical_ip);
+
+ if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
+ ds_put_format(&actions, "ip4.dst=%s; next;",
+ nat->logical_ip);
+ } else {
+ ds_put_format(&actions, "ct_dnat(%s);",
+ nat->logical_ip);
+ }
+
ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 100,
ds_cstr(&match), ds_cstr(&actions));
@@ -7444,7 +7491,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&actions, "eth.src = "ETH_ADDR_FMT"; ",
ETH_ADDR_ARGS(mac));
}
- ds_put_format(&actions, "ct_dnat;");
+
+ if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
+ ds_put_format(&actions, "ip4.src=%s; next;",
+ nat->external_ip);
+ } else {
+ ds_put_format(&actions, "ct_dnat;");
+ }
+
ovn_lflow_add(lflows, od, S_ROUTER_OUT_UNDNAT, 100,
ds_cstr(&match), ds_cstr(&actions));
}
@@ -7460,7 +7514,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, "ip && ip4.src == %s",
nat->logical_ip);
ds_clear(&actions);
- ds_put_format(&actions, "ct_snat(%s);", nat->external_ip);
+
+ if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
+ ds_put_format(&actions, "ip4.src=%s; next;",
+ nat->external_ip);
+ } else {
+ ds_put_format(&actions, "ct_snat(%s);",
+ nat->external_ip);
+ }
/* The priority here is calculated such that the
* nat->logical_ip with the longest mask gets a higher
@@ -7489,7 +7550,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&actions, "eth.src = "ETH_ADDR_FMT"; ",
ETH_ADDR_ARGS(mac));
}
- ds_put_format(&actions, "ct_snat(%s);", nat->external_ip);
+
+ if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
+ ds_put_format(&actions, "ip4.src=%s; next;",
+ nat->external_ip);
+ } else {
+ ds_put_format(&actions, "ct_snat(%s);",
+ nat->external_ip);
+ }
/* The priority here is calculated such that the
* nat->logical_ip with the longest mask gets a higher
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 42033d5..60b3d11 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -966,3 +966,60 @@ OVS_WAIT_UNTIL([ovn-sbctl get Port_Binding ${uuid} options:redirect-type], [0],
])
AT_CLEANUP
+
+AT_SETUP([ovn -- check stateless dnat_and_snat rule])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+ovn_start
+
+ovn-sbctl chassis-add gw1 geneve 127.0.0.1
+
+ovn-nbctl lr-add R1
+ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
+
+ovn-nbctl ls-add S1
+ovn-nbctl lsp-add S1 S1-R1
+ovn-nbctl lsp-set-type S1-R1 router
+ovn-nbctl lsp-set-addresses S1-R1 router
+ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1
+
+ovn-nbctl lrp-set-gateway-chassis R1-S1 gw1
+
+uuid=`ovn-sbctl --columns=_uuid --bare find Port_Binding logical_port=cr-R1-S1`
+echo "CR-LRP UUID is: " $uuid
+
+ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.1 50.0.0.11
+
+OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
+wc -l`])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [2
+])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [2
+])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.dst=| wc -l], [0], [0
+])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.src=| wc -l], [0], [0
+])
+
+ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1
+
+ovn-nbctl --stateless lr-nat-add R1 dnat_and_snat 172.16.1.1 50.0.0.11
+OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
+wc -l`])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [0
+])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [0
+])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.dst=| wc -l], [0], [2
+])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.src=| wc -l], [0], [2
+])
+
+AT_CLEANUP
diff --git a/tests/ovn.at b/tests/ovn.at
index 9f06059..0922bf6 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -16359,3 +16359,314 @@ grep 101 | wc -l`])
OVN_CLEANUP([hv1])
AT_CLEANUP
+
+AT_SETUP([ovn -- Stateless Floating IP])
+ovn_start
+
+# In this test cases we create 3 switches, all connected to same
+# physical network (through br-phys on each HV). LS1 and LS2 have
+# 1 VIF each. Each HV has 1 VIF port. The first digit
+# of VIF port name indicates the hypervisor it is bound to, e.g.
+# lp23 means VIF 3 on hv2.
+#
+# All the switches are connected to a logical router "router".
+#
+# There is an external logical switch, ls-north.
+# This test validates the stateless floating ip implementation.
+#
+# Each switch's VLAN tag and their logical switch ports are:
+# - ls1:
+# - tagged with VLAN 101
+# - ports: lp11
+# - ls2:
+# - tagged with VLAN 201
+# - ports: lp22
+# - ls-north:
+# - tagged with VLAN 1000
+# Note: a localnet port is created for each switch to connect to
+# physical network.
+
+for i in 1 2; do
+ ls_name=ls$i
+ ovn-nbctl ls-add $ls_name
+ ln_port_name=ln$i
+ if test $i -eq 1; then
+ ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
+ elif test $i -eq 2; then
+ ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
+ fi
+ ovn-nbctl lsp-set-addresses $ln_port_name unknown
+ ovn-nbctl lsp-set-type $ln_port_name localnet
+ ovn-nbctl lsp-set-options $ln_port_name network_name=phys
+done
+
+# lsp_to_ls LSP
+#
+# Prints the name of the logical switch that contains LSP.
+lsp_to_ls () {
+ case $1 in dnl (
+ lp?[[11]]) echo ls1 ;; dnl (
+ lp?[[12]]) echo ls2 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+}
+
+vif_to_hv () {
+ case $1 in dnl (
+ vif[[1]]?) echo hv1 ;; dnl (
+ vif[[2]]?) echo hv2 ;; dnl (
+ vif?[[north]]?) echo hv4 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+}
+
+ip_to_hex() {
+ printf "%02x%02x%02x%02x" "$@"
+}
+
+net_add n1
+for i in 1 2; do
+ sim_add hv$i
+ as hv$i
+ ovs-vsctl add-br br-phys
+ ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+ ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
+ ovn_attach n1 br-phys 192.168.0.$i
+
+ ovs-vsctl add-port br-int vif$i$i -- \
+ set Interface vif$i$i external-ids:iface-id=lp$i$i \
+ options:tx_pcap=hv$i/vif$i$i-tx.pcap \
+ options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
+ ofport-request=$i$i
+
+ lsp_name=lp$i$i
+ ls_name=$(lsp_to_ls $lsp_name)
+
+ ovn-nbctl lsp-add $ls_name $lsp_name
+ ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
+ ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
+
+ OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
+
+done
+
+ovn-nbctl ls-add ls-underlay
+ovn-nbctl lsp-add ls-underlay ln3 "" 1000
+ovn-nbctl lsp-set-addresses ln3 unknown
+ovn-nbctl lsp-set-type ln3 localnet
+ovn-nbctl lsp-set-options ln3 network_name=phys
+
+ovn-nbctl ls-add ls-north
+ovn-nbctl lsp-add ls-north ln4 "" 1000
+ovn-nbctl lsp-set-addresses ln4 unknown
+ovn-nbctl lsp-set-type ln4 localnet
+ovn-nbctl lsp-set-options ln4 network_name=phys
+
+# Add a VM on ls-north
+ovn-nbctl lsp-add ls-north lp-north
+ovn-nbctl lsp-set-addresses lp-north "f0:f0:00:00:00:11 172.31.0.10"
+ovn-nbctl lsp-set-port-security lp-north f0:f0:00:00:00:11
+
+# Add 3rd hypervisor
+sim_add hv3
+as hv3 ovs-vsctl add-br br-phys
+as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+as hv3 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:33"
+as hv3 ovn_attach n1 br-phys 192.168.0.3
+
+# Add 4th hypervisor
+sim_add hv4
+as hv4 ovs-vsctl add-br br-phys
+as hv4 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+as hv4 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:44"
+as hv4 ovn_attach n1 br-phys 192.168.0.4
+
+as hv4 ovs-vsctl add-port br-int vif-north -- \
+ set Interface vif-north external-ids:iface-id=lp-north \
+ options:tx_pcap=hv4/vif-north-tx.pcap \
+ options:rxq_pcap=hv4/vif-north-rx.pcap \
+ ofport-request=44
+
+ovn-nbctl lr-add router
+ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
+ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
+ovn-nbctl lrp-add router router-to-underlay 00:00:01:01:02:07 172.31.0.1/24
+
+ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router \
+ options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
+ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router \
+ options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
+ovn-nbctl lsp-add ls-underlay underlay-to-router -- set Logical_Switch_Port \
+ underlay-to-router type=router \
+ options:router-port=router-to-underlay \
+ -- lsp-set-addresses underlay-to-router router
+
+ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3
+ovn-nbctl --stateless lr-nat-add router dnat_and_snat 172.31.0.100 192.168.1.1
+ovn-nbctl lrp-set-redirect-type router-to-underlay bridged
+
+ovn-nbctl --wait=sb sync
+
+
+OVN_POPULATE_ARP
+
+# lsp_to_ls LSP
+#
+# Prints the name of the logical switch that contains LSP.
+lsp_to_ls () {
+ case $1 in dnl (
+ lp?[[11]]) echo ls1 ;; dnl (
+ lp?[[12]]) echo ls2 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+}
+
+vif_to_ls () {
+ case $1 in dnl (
+ vif?[[11]]) echo ls1 ;; dnl (
+ vif?[[12]]) echo ls2 ;; dnl (
+ vif-north) echo ls-north ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+}
+
+hv_to_num () {
+ case $1 in dnl (
+ hv1) echo 1 ;; dnl (
+ hv2) echo 2 ;; dnl (
+ hv3) echo 3 ;; dnl (
+ hv4) echo 4 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+}
+
+vif_to_num () {
+ case $1 in dnl (
+ vif22) echo 22 ;; dnl (
+ vif21) echo 21 ;; dnl (
+ vif11) echo 11 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+}
+
+vif_to_hv () {
+ case $1 in dnl (
+ vif[[1]]?) echo hv1 ;; dnl (
+ vif[[2]]?) echo hv2 ;; dnl (
+ vif-north) echo hv4 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+}
+
+vif_to_lrp () {
+ echo router-to-`vif_to_ls $1`
+}
+
+ip_to_hex() {
+ printf "%02x%02x%02x%02x" "$@"
+}
+
+
+test_ip() {
+ # This packet has bad checksums but logical L3 routing doesn't check.
+ local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 outport=$6
+ local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
+ shift; shift; shift; shift; shift
+ hv=`vif_to_hv $inport`
+ as $hv ovs-appctl netdev-dummy/receive $inport $packet
+ in_ls=`vif_to_ls $inport`
+ for outport; do
+ out_ls=`vif_to_ls $outport`
+ if test $in_ls = $out_ls; then
+ # Ports on the same logical switch receive exactly the same packet.
+ echo $packet
+ else
+ # Routing decrements TTL and updates source and dest MAC
+ # (and checksum).
+ out_lrp=`vif_to_lrp $outport`
+ # For North-South, packet will come via gateway chassis, i.e hv3
+ if test $inport = vif-north; then
+ echo f0000000001100000101020308004500001c000000003f110100${src_ip}${dst_ip}0035111100080000 >> $outport.expected
+ fi
+ if test $outport = vif-north; then
+ echo f0f00000001100000101020708004500001c000000003e111726ac1f0064${dst_ip}0035111100080000 >> $outport.expected
+ fi
+ fi >> $outport.expected
+ done
+}
+
+# Dump a bunch of info helpful for debugging if there's a failure.
+
+echo "------ OVN dump ------"
+ovn-nbctl show
+ovn-nbctl lr-nat-list router
+ovn-sbctl show
+ovn-sbctl list port_binding
+ovn-sbctl list mac_binding
+ovn-sbctl dump-flows
+
+echo "------ hv1 dump ------"
+as hv1 ovs-vsctl show
+as hv1 ovs-vsctl list Open_Vswitch
+
+echo "------ hv2 dump ------"
+as hv2 ovs-vsctl show
+as hv2 ovs-vsctl list Open_Vswitch
+
+echo "------ hv3 dump ------"
+as hv3 ovs-vsctl show
+as hv3 ovs-vsctl list Open_Vswitch
+
+echo "------ hv4 dump ------"
+as hv4 ovs-vsctl show
+as hv4 ovs-vsctl list Open_Vswitch
+
+echo "Send traffic South to Nouth"
+sip=`ip_to_hex 192 168 1 1`
+dip=`ip_to_hex 172 31 0 10`
+test_ip vif11 f00000000011 000001010203 $sip $dip vif-north
+
+# Confirm that South to North traffic works fine.
+OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv4/vif-north-tx.pcap], [vif-north.expected])
+
+# Confirm that NATing happened without connection tracker
+
+AT_CHECK([ovn-sbctl dump-flows router | grep ct_snat | wc -l], [0], [0
+])
+
+AT_CHECK([ovn-sbctl dump-flows router | grep ct_dnat | wc -l], [0], [0
+])
+
+AT_CHECK([ovn-sbctl dump-flows router | grep ip4.dst=| wc -l], [0], [2
+])
+
+AT_CHECK([ovn-sbctl dump-flows router | grep ip4.src=| wc -l], [0], [2
+])
+
+echo "----------- Post Traffic hv1 dump -----------"
+as hv1 ovs-ofctl dump-flows br-int
+as hv1 ovs-ofctl show br-phys
+as hv1 ovs-appctl fdb/show br-phys
+as hv1 ovs-dpctl dump-flows
+
+echo "----------- Post Traffic hv2 dump -----------"
+as hv2 ovs-ofctl dump-flows br-int
+as hv2 ovs-ofctl show br-phys
+as hv2 ovs-appctl fdb/show br-phys
+
+echo "----------- Post Traffic hv3 dump -----------"
+as hv3 ovs-ofctl dump-flows br-int
+as hv3 ovs-ofctl show br-phys
+as hv3 ovs-appctl dpctl/dump-conntrack
+as hv3 ovs-appctl fdb/show br-phys
+as hv3 ovs-dpctl dump-flows
+as hv3 ovs-ofctl dump-flows br-int
+
+echo "----------- Post Traffic hv4 dump -----------"
+as hv4 ovs-ofctl dump-flows br-int
+as hv4 ovs-ofctl show br-phys
+as hv4 ovs-appctl fdb/show br-phys
+
+OVN_CLEANUP([hv1],[hv2],[hv3],[hv4])
+
+AT_CLEANUP
--
1.8.3.1
More information about the dev
mailing list