bpf: fix misconfigured nat to 0.0.0.0 on !masquerade config
bpf: fix misconfigured nat to 0.0.0.0 on !masquerade config

Thomas reported:

  When I do Pod to Pod I see this on the interface of the VM:

  21:30:11.022617 IP 0.0.0.0.53336 > 10.240.0.22.8080: Flags [S], seq 2523807568, win 64240,
    options [mss 1460,sackOK,TS val 207396274 ecr 0,nop,wscale 7], length 0

  When I do Host to Pod I see this on the interface of the same VM:

  21:30:02.275063 IP 10.240.0.35.46236 > 10.240.0.22.8080: Flags [S], seq 1718112282, win 64240,
    options [mss 1460,sackOK,TS val 2667439682 ecr 0,nop,wscale 7], length 0

The NAT table indeed had a bunch of entries that would cause the 0.0.0.0 translation:

  [...]
  TCP OUT 10.240.0.16:60250 -> 10.0.222.20:443 XLATE_SRC 0.0.0.0:60250 Created=17376sec HostLocal=0
  TCP OUT 10.240.0.16:46342 -> 10.240.0.49:9153 XLATE_SRC 0.0.0.0:46342 Created=17376sec HostLocal=0
  [...]

From the config, it turns out that the following was set:

  [...]
  enable-bpf-masquerade: "true"
  masquerade: "false"
  [...]

And looking at the headers, ENABLE_MASQUERADE was enabled. This in fact meant that
in snat_v4_needed() we'd look up the endpoint based on the src IPv4 and given neither
ENABLE_IP_MASQ_AGENT nor ENCAP_IFINDEX was set, IPV4_MASQUERADE is set for the NAT
address. However, the latter will be 0.0.0.0 in this case since IPV4_MASQUERADE is
not defined from template side given it depends on ...

  if option.Config.EnableIPv4Masquerade && option.Config.EnableBPFMasquerade && bpfMasqIPv4Addrs != nil {
      if option.Config.EnableIPv4 {
         ipv4 := bpfMasqIPv4Addrs[ifName]
         opts["IPV4_MASQUERADE"] = byteorder.HostSliceToNetwork(ipv4, reflect.Uint32).(uint32)
      }
  }

... of which option.Config.EnableIPv4Masquerade is false. Yet ENABLE_MASQUERADE otoh
is defined in a more relaxed manner, that is option.Config.EnableBPFMasquerade &&
option.Config.EnableIPv4, both of which were true in this case. Fix it by requiring
option.Config.EnableIPv4Masquerade instead of option.Config.EnableIPv4 for the latter.

The commit got uncovered by a0ec2ad991c3 ("datapath: Decouple IPV4_MASQUERADE from
IPV4_NODEPORT"), but the original commit introducing the issue is 0962c0298491
("datapath: Enable BPF MASQ for veth mode in IPv4").

Fixes: 0962c0298491 ("datapath: Enable BPF MASQ for veth mode in IPv4")
Related: 5462cedd3e5d ("datapath: Do not set exclusion CIDR if IPv4 is disabled")
Related: a0ec2ad991c3 ("datapath: Decouple IPV4_MASQUERADE from IPV4_NODEPORT")
Reported-by: Thomas Graf <5f50a84c1fa3bcff146405017f36aec1a10a9e38@cilium.io>
Signed-off-by: Daniel Borkmann <3d0f3b9ddcacec30c4008c5e030e6c13a478cb4f@iogearbox.net>

cilium/cilium,tklauser/cilium,tgraf/cilium,cilium/cilium,michi-covalent/cilium,tgraf/cilium,tgraf/cilium,cilium/cilium,cilium/cilium,tklauser/cilium,michi-covalent/cilium,michi-covalent/cilium,michi-covalent/cilium,tklauser/cilium,tgraf/cilium,tklauser/cilium,tklauser/cilium,michi-covalent/cilium,tgraf/cilium,cilium/cilium,tgraf/cilium