iptables NETMAP not reliably adjusting source address of multicast UDP packets
Solution 1:
Maintainer of SMCRoute here. This should definitely work. We use this exact approach, albeit with actual HW and not network namespaces, for various customers at work.
There is a very similar problem reported in the SMCRoute issue tracker, only difference from you is they don't use 1:1 NAT with netmap (yet).
I've whipped up a test case for this in preparation for the next release (v2.5). I run all tests locally and in GitHub Actions (Azure cloud) using:
cd test/
unshare -mrun ./multi.sh
The test has two separate routers (R1, and R2) in dedicated network namespaces, with a shared LAN segment between them (192.168.0.0/24). Behind each router is a private LAN (10.0.0.0/24), which is the same for both routers. An extra (dummy) interface eth1 is used to route multicast from to the shared LAN (eth0). The NETMAP rule uses the PREROUTING and POSTROUTING chain. Translating the R1 private LAN to 192.168.10.0/24 and the R2 private LAN to 192.168.20.0/24. As you can see below, the multicast routes installed in the kernel use the 1:1 mapped (global) addresses.
>> Starting emitters ...
R1[2811708]: New multicast data from 192.168.10.1 to group 225.1.2.3 on VIF 1
R1[2811708]: Add 192.168.10.1 -> 225.1.2.3 from VIF 1
R2[2811709]: New multicast data from 192.168.10.1 to group 225.1.2.3 on VIF 0
R2[2811709]: Add 192.168.10.1 -> 225.1.2.3 from VIF 0
R2[2811709]: New multicast data from 192.168.20.1 to group 225.1.2.3 on VIF 1
R2[2811709]: Add 192.168.20.1 -> 225.1.2.3 from VIF 1
R1[2811708]: New multicast data from 192.168.20.1 to group 225.1.2.3 on VIF 0
R1[2811708]: Add 192.168.20.1 -> 225.1.2.3 from VIF 0
>> R1 multicast routes and 1:1 NAT ...
(192.168.10.1,225.1.2.3) Iif: eth1 Oifs: eth0 State: resolved
(192.168.20.1,225.1.2.3) Iif: eth0 Oifs: eth1 State: resolved
Chain PREROUTING (policy ACCEPT 5 packets, 244 bytes)
pkts bytes target prot opt in out source destination
0 0 NETMAP all -- any any anywhere 192.168.10.0/24 to:10.0.0.0/24
Chain INPUT (policy ACCEPT 1 packets, 84 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 4 packets, 248 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 2 packets, 124 bytes)
pkts bytes target prot opt in out source destination
2 124 NETMAP all -- any any 10.0.0.0/24 anywhere to:192.168.10.0/24
>> R2 multicast routes and 1:1 NAT ...
(192.168.10.1,225.1.2.3) Iif: eth0 Oifs: eth1 State: resolved
(192.168.20.1,225.1.2.3) Iif: eth1 Oifs: eth0 State: resolved
Chain PREROUTING (policy ACCEPT 4 packets, 204 bytes)
pkts bytes target prot opt in out source destination
1 84 NETMAP all -- any any anywhere 192.168.20.0/24 to:10.0.0.0/24
Chain INPUT (policy ACCEPT 2 packets, 168 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 3 packets, 164 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 1 packets, 40 bytes)
pkts bytes target prot opt in out source destination
2 124 NETMAP all -- any any 10.0.0.0/24 anywhere to:192.168.20.0/24
>> Analyzing ...
1 0.000000000 0.000000000 192.168.10.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe769, seq=1/256, ttl=2
2 1.000105261 1.000105261 192.168.10.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe769, seq=2/512, ttl=2
3 1.000957268 0.000852007 192.168.20.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe76b, seq=1/256, ttl=2
4 2.024216212 1.023258944 192.168.10.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe769, seq=3/768, ttl=2
5 2.024216229 0.000000017 192.168.20.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe76b, seq=2/512, ttl=2
6 3.048426868 1.024210639 192.168.10.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe769, seq=4/1024, ttl=2
7 3.048426842 -0.000000026 192.168.20.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe76b, seq=3/768, ttl=2
8 4.072270331 1.023843489 192.168.10.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe769, seq=5/1280, ttl=2
9 4.072270458 0.000000127 192.168.20.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe76b, seq=4/1024, ttl=2
10 5.096430449 1.024159991 192.168.20.1 → 225.1.2.3 ICMP 98 Echo (ping) request id=0xe76b, seq=5/1280, ttl=2
=> 10 for group ff04::114, expected >= 8
It's maybe a bit hard to read, you may have to consult the test case for details. Anyway, I get consistent results in the translation, which btw is the responsibility of Linux not SMCRoute, so you may have a kernel bug or something. May personal workstation has Linux Mint with kernel 5.11.0 and the backend servers for GitHub Actions run Ubuntu 20.04 LTS, kernel 5.8.0, both quite patched distro kernels, but maybe a baseline to start from?