On 7/5/26 2:12 AM, Numan Siddique wrote: > On Thu, Jul 2, 2026 at 11:27 AM Lorenzo Bianconi > <[email protected]> wrote: >> >>> From: Numan Siddique <[email protected]> >>> >>> 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 any ICMPv4 Destination >>> Unreachable error (type 3) 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. Every type-3 code quotes >>> the original datagram (RFC 792), so this is correct for all of them; >>> it covers Fragmentation Needed (code 4, for PMTUD) as well as the >>> host/port unreachable codes. 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. >>> >>> The rewrite flow round-trips the packet through ovn-controller, so it is >>> emitted with the logical router's icmp4-error CoPP meter (when one is >>> configured), rate-limiting the punt the same way OVN does for the other >>> controller-handled ICMPv4 errors. >>> >>> 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. >>> >>> Assisted-by: Claude Opus 4.7, Claude Code >>> Signed-off-by: Numan Siddique <[email protected]> >> >> Acked-by: Lorenzo Bianconi <[email protected]> > > Thank you Lorenzo. I applied the series to the main branch. > > Numan >
Hi Numan, I didn't check too closely but it seems that since this series was applied one of our multinode jobs is permafailing: https://github.com/ovn-org/ovn/actions/workflows/ovn-fake-multinode-tests.yml 8: ovn multinode stateless NAT - icmp4 PMTUD inner src un-NAT FAILED (multinode.at:1113) ... ./multinode.at:1102: podman exec ovn-chassis-1 ip netns exec sw0p1 ping -q -c 3 -i 0.3 -w 2 172.20.1.2 | grep "transmitted" | sed 's/time.*ms$/time 0ms/' ./multinode.at:1112: podman exec ovn-gw-1 ip netns exec ovn-ext0 ip link set dev ext1 mtu 1100 ./multinode.at:1113: podman exec ovn-chassis-1 ip netns exec sw0p1 ping -c 20 -i 0.5 -s 1300 -M do 172.20.1.2 2>&1 | grep -q "mtu = 1100" ./multinode.at:1113: exit code was 1, expected 0 8. multinode.at:1044: 8. ovn multinode stateless NAT - icmp4 PMTUD inner src un-NAT (multinode.at:1044): FAILED (multinode.at:1113) > git log > a19ad49d9a959cd717502beab7fcef46bba05e01..3be2e4cc255865cf9a42a18cc62a5b9ec4411f17 > --oneline 3be2e4cc25 northd: Extend stateless ICMP helper to more ICMPv4 error types. e44e18f46a northd: Emit inner-IP rewrite flow for stateless DNAT. ff59f392b4 pinctrl: Implement put_icmp4_inner_ip4_src action. 32b4409833 ovn-fields: Add icmp4.inner_ip4.src to rewrite ICMP inner source. Would you happen to have some time to look into it? Thanks, Dumitru _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
