On Mon, Jun 15, 2026 at 4:08 AM shy liu <[email protected]> wrote:
> In-Reply-To: <[email protected]> > > Hi Numan, > > Great patch! This nicely fixes the PMTUD issue. > > Since the inner-IP rewrite infrastructure is now in place, can we also > support Traceroute (ICMPv4 Type 11)? It suffers from the exact same > conntrack ct.inv drop due to the un-NATed inner payload. > > Do you think we should include Type 11 in this series, or leave it for > a follow-up? > Thanks for the comment. I think it makes sense to include it in this series. I'll take a look and handle it in v2. Thanks Numan > Best regards, > Xie Liu > > > Stateless DNAT in OVN rewrites only the outer IPv4 destination via a > > flow-based 'ip4.dst = <logical_ip>' action. This is fine for normal > > reply traffic, but it leaves the inner payload of an inbound ICMPv4 > > error untouched. When such an error reaches the downstream logical > > switch pipeline, conntrack tries to correlate the embedded original > > packet with the tracked outgoing flow. Because that embedded packet > > is the VM's outbound datagram after stateless SNAT, its inner source > > still carries the external (post-NAT) IP, the lookup fails, and the > > packet is marked ct.inv, causing the LS ACL stage to drop it. The VM > > never sees the ICMP error, kernel PMTU discovery (RFC 1191) breaks, > > and TCP/UDP traffic to destinations beyond a smaller-MTU link > > black-holes. > > > > Emit an additional, higher-priority logical flow for each stateless > > NAT entry that matches the external IP plus ICMPv4 type 3 code 4 > > (Fragmentation Needed) and uses the new 'icmp4.inner_ip4.src' action > > to un-NAT the embedded inner source back to the logical IP, in > > addition to rewriting the outer destination. After this rewrite, > > conntrack in the LS zone can correlate the error with the tracked > > outgoing flow, the LS ACL stage allows it, and the VM receives a > > well-formed ICMP error whose inner source is its own private address > > - so the kernel's PMTU update path installs a correct route > > exception. > > > > This behavior is gated by a per-NAT option, > > options:stateless_icmp_helper, on the NB_Global NAT entry. It > > defaults to true, so the inner-IP rewrite flow is emitted for every > > stateless NAT entry out of the box and PMTUD works without any extra > > configuration. Operators who do not want the additional flow (for > > example to avoid the pinctrl round-trip for these ICMP errors) can > > opt out by setting options:stateless_icmp_helper=false on the > > individual NAT entry. > > > > The new flow uses priority + 1 so that: > > - The exempted-ext-ips bypass flow (priority + 2, emits 'next;') > > still wins for traffic explicitly excluded from NAT. > > - Non-ICMP traffic falls through to the existing stateless DNAT > > flow at the original priority. > > > > Only IPv4 is wired up; IPv6 stateless NAT is not currently supported > > in OVN, so no equivalent action is needed for icmp6 Packet Too Big. > > > > The pinctrl-side implementation of icmp4.inner_ip4.src is in the > > previous patch. > > > > Note that this is required when CMS doesn't use the gateway_mtu > > option and an external PE router generates the ICMPv4 error > > message. > > > > Signed-off-by: Numan Siddique <[email protected]> > > Assisted-by: Claude Opus 4.7, Claude Code > > Signed-off-by: Numan Siddique <[email protected]> > > --- > > Documentation/ref/ovn-logical-flows.7.rst | 29 ++++++ > > NEWS | 7 ++ > > northd/northd.c | 33 +++++++ > > ovn-nb.xml | 35 +++++++ > > tests/multinode.at | 73 ++++++++++++++ > > tests/ovn-northd.at | 18 +++- > > tests/ovn.at | 113 +++++++++++++++++++++- > > 7 files changed, 305 insertions(+), 3 deletions(-) > > > > diff --git a/Documentation/ref/ovn-logical-flows.7.rst > b/Documentation/ref/ovn-logical-flows.7.rst > > index ce4dd53559..45cc2c0d65 100644 > > --- a/Documentation/ref/ovn-logical-flows.7.rst > > +++ b/Documentation/ref/ovn-logical-flows.7.rst > > @@ -2775,6 +2775,22 @@ flows do not get programmed for load balancers > with IPv6 *VIPs*. > > rule is of type dnat_and_snat and has ``stateless=true`` in the > options, then > > the action would be ``ip4/6.dst=(B)``. > > > > + For an IPv4 stateless ``dnat_and_snat`` rule that has > > + ``options:stateless_icmp_helper`` set to ``true`` (the default), an > > + additional flow at priority *P + 1* is added that matches ``ip && > ip4.dst > > + == A && icmp4 && icmp4.type == 3 && icmp4.code == 4`` with the action > > + ``ip4.dst = B; icmp4.inner_ip4.src = B; next;``, where *P* is the > priority of > > + the flow above. This rewrites the outer destination and un-NATs the > source > > + embedded in the inbound ICMPv4 ``Fragmentation Needed`` error payload > (from > > + the external IP *A* back to the logical IP *B*), so that conntrack in > the > > + downstream logical switch can correlate the error with the tracked > outgoing > > + flow and Path MTU discovery (RFC 1191) works end-to-end across > stateless > > + NAT. See ``options:stateless_icmp_helper`` in the ``NAT`` table of the > > + ``OVN_Northbound`` database (``ovn-nb`` (5)). The priority is *P + 1* > so that > > + the ``exempted_ext_ips`` bypass flow (at *P + 2*) still wins for > traffic > > + excluded from NAT, and non-ICMP traffic falls through to the regular > > + stateless DNAT flow. > > + > > If the NAT rule has ``allowed_ext_ips`` configured, then there is an > > additional match ``ip4.src == allowed_ext_ips``. Similarly, for IPV6, > match > > would be ``ip6.src == allowed_ext_ips``. > > @@ -2815,6 +2831,19 @@ the egress pipeline. > > the IPv6 case. If the NAT rule is of type dnat_and_snat and has > > ``stateless=true`` in the options, then the action would be > ``ip4/6.dst=(B)``. > > > > + For an IPv4 stateless ``dnat_and_snat`` rule that has > > + ``options:stateless_icmp_helper`` set to ``true`` (the default), an > > + additional priority-101 flow is added that matches ``ip && ip4.dst == > B && > > + inport == GW && icmp4 && icmp4.type == 3 && icmp4.code == 4`` with > the action > > + ``ip4.dst = B; icmp4.inner_ip4.src = B; next;``. This rewrites the > outer > > + destination and un-NATs the source embedded in the inbound ICMPv4 > > + ``Fragmentation Needed`` error payload (back to the logical IP *B*), > so that > > + conntrack in the downstream logical switch can correlate the error > with the > > + tracked outgoing flow and Path MTU discovery (RFC 1191) works > end-to-end > > + across stateless NAT. See > > + ``options:stateless_icmp_helper`` in the ``NAT`` table of the > > + ``OVN_Northbound`` database (``ovn-nb`` (5)). > > + > > If the NAT rule cannot be handled in a distributed manner, then the > > priority-100 flow above is only programmed on the gateway chassis. > > > > diff --git a/NEWS b/NEWS > > index 748ae30eb2..216728998f 100644 > > --- a/NEWS > > +++ b/NEWS > > @@ -33,6 +33,13 @@ Post v26.03.0 > > The DHCP and unbound-router ARP/ND drop lflows for external > > ports were updated to key on the external LSP's inport > > accordingly. > > + - Added a new "icmp4.inner_ip4.src" action that rewrites the source > > + IPv4 address embedded in an ICMPv4 error's inner packet. > ovn-northd > > + uses it for stateless "dnat_and_snat" rules, controlled by the new > > + "options:stateless_icmp_helper" NAT option (default true), so that > > + inbound ICMPv4 "fragmentation needed" errors generated by an > external > > + router are un-NATed correctly and Path MTU discovery works through > > + stateless NAT. > > > > OVN v26.03.0 - xxx xx xxxx > > -------------------------- > > diff --git a/northd/northd.c b/northd/northd.c > > index 0dbf174269..369322c2ac 100644 > > --- a/northd/northd.c > > +++ b/northd/northd.c > > @@ -17654,6 +17654,39 @@ build_lrouter_in_dnat_flow(struct lflow_table > *lflows, > > > > ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, priority, > ds_cstr(match), > > ds_cstr(actions), lflow_ref, > WITH_HINT(&nat->header_)); > > + > > + /* For stateless DNAT, the action above only rewrites the outer IPv4 > > + * destination. An inbound ICMPv4 error (RFC 792 / RFC 1191) > carries > > + * the original (post-NAT) packet inside its payload, whose source > is > > + * the external (post-SNAT) IP. The conntrack-based ACL check in > the > > + * downstream logical switch zone uses that inner tuple to match the > > + * reverse direction of the tracked outgoing flow; without un-NATing > > + * the inner ip4.src back to the logical IP, that lookup fails and > the > > + * error is dropped as ct.inv. > > + * > > + * Emit a higher-priority flow that matches the same external IP > plus > > + * ICMPv4 type 3 code 4 (Fragmentation Needed and DF set) and > rewrites > > + * the outer ip4.dst and the embedded inner ip4.src to the logical > IP, > > + * so PMTUD works end-to-end through stateless NAT. */ > > + if (stateless && !is_v6 && > > + smap_get_bool(&nat_entry->nb->options, "stateless_icmp_helper", > > + true)) { > > + size_t match_len = match->length; > > + > > + ds_put_cstr(match, > > + " && icmp4 && icmp4.type == 3 && icmp4.code == 4"); > > + > > + ds_clear(actions); > > + ds_put_format(actions, > > + "ip4.dst=%s; icmp4.inner_ip4.src = %s; next;", > > + nat->logical_ip, nat->logical_ip); > > + > > + ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, priority + 1, > > + ds_cstr(match), ds_cstr(actions), lflow_ref, > > + WITH_HINT(&nat->header_)); > > + > > + ds_truncate(match, match_len); > > + } > > } > > > > static void > > diff --git a/ovn-nb.xml b/ovn-nb.xml > > index 15fb1d7e86..769bf05e4f 100644 > > --- a/ovn-nb.xml > > +++ b/ovn-nb.xml > > @@ -5457,6 +5457,41 @@ or > > tracking state or not. > > </column> > > > > + <column name="options" key="stateless_icmp_helper" > > + type='{"type": "boolean"}'> > > + <p> > > + Applies only to stateless <code>dnat_and_snat</code> rules (that > > + is, NATs with <ref column="options" key="stateless"/> set to > > + <code>true</code>) on IPv4 addresses. Defaults to > > + <code>true</code>. > > + </p> > > + > > + <p> > > + A stateless DNAT rule rewrites only the outer IPv4 destination > of > > + inbound packets. For an inbound ICMPv4 error (for example a > > + <code>Fragmentation Needed</code> message generated for Path MTU > > + discovery, RFC 1191), the original packet embedded in the ICMP > > + payload still carries the external, post-NAT IP as its source. > > + When the error reaches the downstream logical switch, conntrack > > + cannot correlate the embedded tuple with the tracked outgoing > > + flow, the packet is marked <code>ct.inv</code> and dropped by > the > > + ACL stage, and PMTU discovery breaks. > > + </p> > > + > > + <p> > > + When this option is <code>true</code>, <code>ovn-northd</code> > > + emits an additional, higher-priority logical flow in the router > > + ingress DNAT stage that matches ICMPv4 type 3 code 4 errors > > + destined to the external IP. It rewrites the outer IPv4 > > + destination to the logical IP and, using the > > + <code>icmp4.inner_ip4.src</code> action, un-NATs the embedded > > + inner IPv4 source from the external IP back to the logical IP, > so > > + that conntrack can correlate the error and PMTU discovery works > > + end-to-end. Set it to <code>false</code> to suppress this flow > for > > + an individual NAT entry. > > + </p> > > + </column> > > + > > <column name="options" key="add_route"> > > If set to <code>true</code>, then neighbor routers will have > logical > > flows added that will allow for routing to the NAT address. It > also will > > diff --git a/tests/multinode.at b/tests/multinode.at > > index 069f2a677d..37ef523f95 100644 > > --- a/tests/multinode.at > > +++ b/tests/multinode.at > > @@ -1041,6 +1041,79 @@ run_ns_traffic > > AT_CLEANUP > > ]) > > > > +AT_SETUP([ovn multinode stateless NAT - icmp4 PMTUD inner src un-NAT]) > > + > > +# Check that ovn-fake-multinode setup is up and running > > +check_fake_multinode_setup > > + > > +# Delete the multinode NB and OVS resources before starting the test. > > +cleanup_multinode_resources > > + > > +m_as ovn-chassis-1 ip link del sw0p1-p > > + > > +# Reset geneve tunnels > > +for c in ovn-chassis-1 ovn-gw-1 > > +do > > + m_as $c ovs-vsctl set open . external-ids:ovn-encap-type=geneve > > +done > > + > > +OVS_WAIT_UNTIL([m_as ovn-chassis-1 ip link show | grep -q genev_sys]) > > +OVS_WAIT_UNTIL([m_as ovn-gw-1 ip link show | grep -q genev_sys]) > > + > > +# Internal switch with one VM (10.0.0.3) on ovn-chassis-1. > > +check multinode_nbctl ls-add sw0 > > +check multinode_nbctl lsp-add sw0 sw0-port1 > > +check multinode_nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:03 > 10.0.0.3" > > + > > +m_as ovn-chassis-1 /data/create_fake_vm.sh sw0-port1 sw0p1 > 50:54:00:00:00:03 1342 10.0.0.3 24 10.0.0.1 > > + > > +# Gateway router pinned to ovn-gw-1. > > +check multinode_nbctl lr-add lr0 -- set Logical_Router lr0 > options:chassis=ovn-gw-1 > > +check multinode_nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 > > +check multinode_nbctl lsp-add-router-port sw0 sw0-lr0 lr0-sw0 > > + > > +# External / provider network. > > +check multinode_nbctl ls-add public > > +check multinode_nbctl lsp-add-localnet-port public ln-public public > > +check multinode_nbctl lrp-add lr0 lr0-public 00:11:22:00:ff:01 > 172.20.0.100/24 > > +check multinode_nbctl lsp-add-router-port public public-lr0 lr0-public > > +check multinode_nbctl lr-route-add lr0 0.0.0.0/0 172.20.0.1 > > + > > +# Stateless dnat_and_snat for the VM. options:stateless_icmp_helper > defaults > > +# to true, so ovn-northd emits the extra DNAT flow that, for an inbound > ICMPv4 > > +# "fragmentation needed" error destined to 172.20.0.110, un-NATs the > inner > > +# source from 172.20.0.110 back to 10.0.0.3 (icmp4.inner_ip4.src). > Unlike > > +# stateful NAT (where conntrack fixes the embedded header > automatically), > > +# stateless NAT relies entirely on this flow for PMTUD to work. > > +check multinode_nbctl --stateless lr-nat-add lr0 dnat_and_snat > 172.20.0.110 10.0.0.3 > > + > > +m_as ovn-gw-1 ovs-vsctl set open . > external-ids:ovn-bridge-mappings=public:br-ex > > +m_as ovn-chassis-1 ovs-vsctl set open . > external-ids:ovn-bridge-mappings=public:br-ex > > + > > +m_wait_for_ports_up > > + > > +# ovn-ext0 routes between the OVN public net (172.20.0.0/24) and a > downstream > > +# net (172.20.1.0/24); ovn-ext2 (172.20.1.2) is the far host behind it. > > +m_add_internal_port ovn-gw-1 ovn-ext0 br-ex ext0 172.20.0.1/24 > > +m_add_internal_port ovn-gw-1 ovn-ext0 br-ex ext1 172.20.1.1/24 > > +m_add_internal_port ovn-gw-1 ovn-ext2 br-ex ext2 172.20.1.2/24 > 172.20.1.1 > > + > > +# Baseline: the VM reaches the far host through stateless NAT. > > +M_NS_CHECK_EXEC([ovn-chassis-1], [sw0p1], [ping -q -c 3 -i 0.3 -w 2 > 172.20.1.2 | FORMAT_PING], \ > > +[0], [dnl > > +3 packets transmitted, 3 received, 0% packet loss, time 0ms > > +]) > > + > > +# Shrink the downstream link MTU so ovn-ext0 emits ICMPv4 "fragmentation > > +# needed" (type 3, code 4) towards 172.20.0.110 (the VM's stateless SNAT > > +# address) for oversized DF traffic. The error's inner packet carries > > +# 172.20.0.110 as its source; the VM only honors the PMTU signal if OVN > > +# un-NATs that inner source back to 10.0.0.3. > > +M_NS_CHECK_EXEC([ovn-gw-1], [ovn-ext0], [ip link set dev ext1 mtu 1100]) > > +M_NS_CHECK_EXEC([ovn-chassis-1], [sw0p1], [ping -c 20 -i 0.5 -s 1300 -M > do 172.20.1.2 2>&1 | grep -q "mtu = 1100"]) > > + > > +AT_CLEANUP > > + > > PMTUD_SWITCH_TESTS(["geneve"]) > > PMTUD_SWITCH_TESTS(["vxlan"]) > > > > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > > index f87b14c9a1..9b875f5adc 100644 > > --- a/tests/ovn-northd.at > > +++ b/tests/ovn-northd.at > > @@ -1087,13 +1087,29 @@ check ovn-nbctl lr-nat-del R1 dnat_and_snat > 172.16.1.1 > > echo > > echo "IPv4: stateless" > > check ovn-nbctl --wait=sb --stateless lr-nat-add R1 dnat_and_snat > 172.16.1.1 50.0.0.11 > > +dnl Two ip4.dst= flows: the regular stateless DNAT flow plus the default > > +dnl stateless_icmp_helper flow that also rewrites the inner ICMPv4 src. > > +check_flow_match_sets 2 0 0 2 1 0 0 > > +dnl stateless_icmp_helper defaults to true, so the inner-IP rewrite flow > > +dnl is present. > > +check_flow_matches "icmp4.inner_ip4.src" 1 > > +check ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 > > + > > +echo > > +echo "IPv4: stateless, stateless_icmp_helper=false" > > +check ovn-nbctl --wait=sb --stateless lr-nat-add R1 dnat_and_snat > 172.16.1.1 50.0.0.11 > > +check ovn-nbctl --wait=sb set NAT . options:stateless_icmp_helper=false > > +dnl With the helper disabled, only the regular stateless DNAT flow > remains > > +dnl and the inner-IP rewrite flow is gone. > > check_flow_match_sets 2 0 0 1 1 0 0 > > +check_flow_matches "icmp4.inner_ip4.src" 0 > > check ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 > > > > echo > > echo "IPv4: stateless with match" > > check ovn-nbctl --wait=sb --match="udp" --stateless lr-nat-add R1 > dnat_and_snat 172.16.1.1 50.0.0.11 > > -check_flow_match_sets 2 0 0 1 1 0 0 > > +dnl As above, the stateless_icmp_helper flow adds a second ip4.dst= > flow. > > +check_flow_match_sets 2 0 0 2 1 0 0 > > check ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 > > > > echo > > diff --git a/tests/ovn.at b/tests/ovn.at > > index 68061a623d..dddbebb0e4 100644 > > --- a/tests/ovn.at > > +++ b/tests/ovn.at > > @@ -22705,6 +22705,113 @@ OVN_CLEANUP([hv1]) > > AT_CLEANUP > > ]) > > > > +AT_SETUP([stateless NAT - icmp4.inner_ip4.src rewrite]) > > +AT_KEYWORDS([stateless-nat icmp4-inner-ip4-src]) > > +AT_SKIP_IF([test $HAVE_SCAPY = no]) > > +ovn_start > > + > > +# Topology: > > +# "external" host (ext1, on the public LS) --- lr0 (gw router) --- > vm1 (on sw0) > > +# > > +# lr0 has a stateless dnat_and_snat rule that maps the external IP > > +# 172.168.0.110 to the logical IP 10.0.0.3 (vm1). With > > +# options:stateless_icmp_helper defaulting to true, ovn-northd emits a > > +# higher-priority DNAT flow that matches inbound ICMPv4 "Fragmentation > > +# Needed" errors (type 3, code 4) destined to the external IP and > applies > > +# the action "ip4.dst = 10.0.0.3; icmp4.inner_ip4.src = 10.0.0.3;". > > +# > > +# An inbound ICMP error quotes the VM's original outbound (post-SNAT) > > +# datagram, so its inner source is the external IP 172.168.0.110. This > test > > +# injects such an error from the external side and verifies that > > +# ovn-controller (pinctrl) DNATs the outer destination to 10.0.0.3 and > > +# un-NATs the inner (embedded) IPv4 source back to 10.0.0.3 - while > leaving > > +# the inner destination untouched - before delivering the packet to vm1. > > + > > +vm1_mac=50:54:00:00:00:01 > > +vm1_ip=10.0.0.3 > > +rtr_int_mac=00:00:00:00:ff:01 > > +rtr_ext_mac=00:00:20:20:12:13 > > +ext1_mac=00:00:00:00:00:99 > > +ext1_ip=172.168.0.50 > > +nat_ext_ip=172.168.0.110 > > + > > +# Internal switch with vm1. > > +check ovn-nbctl ls-add sw0 > > +check ovn-nbctl lsp-add sw0 sw0-vm1 > > +check ovn-nbctl lsp-set-addresses sw0-vm1 "$vm1_mac $vm1_ip" > > + > > +# Router (gateway router pinned to hv1). > > +check ovn-nbctl lr-add lr0 > > +check ovn-nbctl lrp-add lr0 lr0-sw0 $rtr_int_mac 10.0.0.1/24 > > +check ovn-nbctl lsp-add-router-port sw0 sw0-lr0 lr0-sw0 > > + > > +# Public switch with the external host. > > +check ovn-nbctl ls-add public > > +check ovn-nbctl lrp-add lr0 lr0-public $rtr_ext_mac 172.168.0.100/24 > > +check ovn-nbctl lsp-add-router-port public public-lr0 lr0-public > > +check ovn-nbctl lsp-add public ext1 > > +check ovn-nbctl lsp-set-addresses ext1 "$ext1_mac $ext1_ip" > > + > > +check ovn-nbctl set logical_router lr0 options:chassis=hv1 > > + > > +# Stateless dnat_and_snat: external 172.168.0.110 <-> logical 10.0.0.3. > > +check ovn-nbctl --wait=sb --stateless lr-nat-add lr0 dnat_and_snat \ > > + $nat_ext_ip $vm1_ip > > + > > +net_add n1 > > +sim_add hv1 > > +as hv1 > > +ovs-vsctl add-br br-phys > > +ovn_attach n1 br-phys 192.168.0.1 > > +ovs-vsctl -- add-port br-int hv1-vif1 -- \ > > + set interface hv1-vif1 external-ids:iface-id=sw0-vm1 \ > > + options:tx_pcap=hv1/vif1-tx.pcap \ > > + options:rxq_pcap=hv1/vif1-rx.pcap \ > > + ofport-request=1 > > +ovs-vsctl -- add-port br-int hv1-vif2 -- \ > > + set interface hv1-vif2 external-ids:iface-id=ext1 \ > > + options:tx_pcap=hv1/vif2-tx.pcap \ > > + options:rxq_pcap=hv1/vif2-rx.pcap \ > > + ofport-request=2 > > + > > +wait_for_ports_up > > +check ovn-nbctl --wait=hv sync > > + > > +# The inner packet is the original (post-SNAT) datagram quoted in the > ICMP > > +# error. Use a raw 8-byte blob for the embedded L4 header so that no > inner > > +# L4 checksum (which the action does not recompute) is involved. > > +inner_l4="0102030405060708" > > + > > +# ICMP fragmentation-needed error from ext1 to the NAT external IP. The > > +# embedded original packet is the VM's outbound datagram after stateless > > +# SNAT, so its inner source is the external IP and its inner > destination is > > +# some far host (50.0.0.100). > > +packet=$(fmt_pkt "Ether(dst='$rtr_ext_mac', src='$ext1_mac')/ \ > > + IP(src='$ext1_ip', dst='$nat_ext_ip', ttl=64)/ \ > > + ICMP(type=3, code=4, nexthopmtu=1400)/ \ > > + IP(src='$nat_ext_ip', dst='50.0.0.100', ttl=63, > proto=17)/ \ > > + bytes.fromhex('$inner_l4')") > > + > > +# Expected packet delivered to vm1: the router has DNATed the outer > > +# destination to 10.0.0.3, decremented the outer TTL, rewritten the L2 > > +# addresses, and (via pinctrl) un-NATed the inner IPv4 source to > 10.0.0.3. > > +# The inner destination (50.0.0.100) is left unchanged. > > +expected=$(fmt_pkt "Ether(dst='$vm1_mac', src='$rtr_int_mac')/ \ > > + IP(src='$ext1_ip', dst='$vm1_ip', ttl=63)/ \ > > + ICMP(type=3, code=4, nexthopmtu=1400)/ \ > > + IP(src='$vm1_ip', dst='50.0.0.100', ttl=63, > proto=17)/ \ > > + bytes.fromhex('$inner_l4')") > > +echo $expected > vif1.expected > > + > > +as hv1 reset_pcap_file hv1-vif1 hv1/vif1 > > + > > +check as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet > > + > > +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected]) > > + > > +OVN_CLEANUP([hv1]) > > +AT_CLEANUP > > + > > OVN_FOR_EACH_NORTHD([ > > AT_SETUP([IP packet buffering]) > > AT_KEYWORDS([ip-buffering]) > > @@ -26932,14 +27039,16 @@ 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 > > +# Confirm that NATing happened without connection tracker. > > +# Two ip4.dst= flows are expected: the regular stateless DNAT flow plus > the > > +# default stateless_icmp_helper flow (which also carries > icmp4.inner_ip4.src). > > ovn-sbctl dump-flows router > sbflows > > AT_CAPTURE_FILE([sbflows]) > > AT_CHECK([for regex in ct_snat ct_dnat ip4.dst= ip4.src=; do > > grep -c "$regex" sbflows; > > done], [0], [0 > > 0 > > -1 > > +2 > > 1 > > ]) > > > > -- > > 2.54.0 > > > > > > > > ------------------------------ > > > > Subject: Digest Footer > > > > _______________________________________________ > > dev mailing list > > [email protected] > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > > > > > ------------------------------ > > > > End of dev Digest, Vol 203, Issue 172 > > ************************************* > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
