On Tue, Jul 7, 2026 at 6:23 AM Dumitru Ceara <[email protected]> wrote: > > 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?
Hi Dumitru, Oops. I'll take a look. Thanks Numan > > Thanks, > Dumitru > > > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
