I looked into this a little further: From what I've found in the source code GRE NAT has never been properly implemented. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/net/ipv4/netfilter/nf_nat_proto_gre.c?id=HEAD |switch (greh->flags & GRE_VERSION) { case GRE_VERSION_0: /* We do not currently NAT any GREv0 packets. * Try to behave like "nf_nat_proto_unknown" */ break; case GRE_VERSION_1: pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); pgreh->call_id = tuple->dst.u.gre.key; break; default: pr_debug("can't nat unknown GRE version\n"); return false; } How did this work before? Or am I looking at the wrong place? Regards, Matthias | Am 24.01.2018 um 20:54 schrieb Matthias Walther: > Hello, > > I used to nat GRE-tunnels into a kvm machine. That used to work > perfectly, till it stopped working in early January. > > I'm not really sure, what caused this malfunction. I tried different > kernel versions, 4.4.113, 4.10.0-35, 4.10.0-37, 4.14. All on ubuntu 16.04.3. > > Normal destination based nat rules, like ssh tcp 22 e. g., work > perfectly. That gre nat rule is in place: > > -A PREROUTING -i eth0 -p gre -j DNAT --to-destination 192.168.10.62 > > And the needed kernel modules are loaded: > > root# lsmod|grep gre > 61:nf_conntrack_proto_gre 16384 0 > 62:nf_nat_proto_gre 16384 0 > 63:nf_nat 24576 4 > nf_nat_proto_gre,nf_nat_ipv4,xt_nat,nf_nat_masquerade_ipv4 > 64:nf_conntrack 106496 6 > nf_conntrack_proto_gre,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ipv4 > > Still some packes are just not correctly natted. The configuration > should be correct, as it used to work like this. > > One or two tunnels usually work. For the others, the gre packages are > just not natted but dropped. First example, which shows the expected > behavior: > > root# tcpdump -ni any host 185.66.195.1 <http://185.66.195.1> and \( > host 176.9.38.150 or host 192.168.10.62 <http://192.168.10.62> \) and > proto 47 and ip[33]=0x01 and \( ip[36:4]==0x644007BA or > ip[40:4]==0x644007BA \) > tcpdump: verbose output suppressed, use -v or -vv for full protocol decode > listening on any, link-type LINUX_SLL (Linux cooked), capture size > 262144 bytes > 04:06:41.322914 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.1 > <http://185.66.195.1>: GREv0, length 88: IP 185.66.194.49 > <http://185.66.194.49> > 100.64.7.186: ICMP echo request, id 26639, seq > 1, length 64 > 04:06:41.322922 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.1 > <http://185.66.195.1>: GREv0, length 88: IP 185.66.194.49 > <http://185.66.194.49> > 100.64.7.186: ICMP echo request, id 26639, seq > 1, length 64 > 04:06:41.322928 IP 176.9.38.150 > 185.66.195.1 <http://185.66.195.1>: > GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> > > 100.64.7.186: ICMP echo request, id 26639, seq 1, length 64 > 04:06:41.341906 IP 185.66.195.1 <http://185.66.195.1> > 176.9.38.150: > GREv0, length 88: IP 100.64.7.186 > 185.66.194.49 > <http://185.66.194.49>: ICMP echo reply, id 26639, seq 1, length 64 > 04:06:41.341915 IP 185.66.195.1 <http://185.66.195.1> > 192.168.10.62 > <http://192.168.10.62>: GREv0, length 88: IP 100.64.7.186 > > 185.66.194.49 <http://185.66.194.49>: ICMP echo reply, id 26639, seq 1, > length 64 > 04:06:41.341918 IP 185.66.195.1 <http://185.66.195.1> > 192.168.10.62 > <http://192.168.10.62>: GREv0, length 88: IP 100.64.7.186 > > 185.66.194.49 <http://185.66.194.49>: ICMP echo reply, id 26639, seq 1, > length 64 > > This^^ works as it should. The packet goes through the bridge interface, > then the bridge though which all natted vms are connected, then it is > translated and then through the eth0 interface of the hypervisor. And > the reply packages follows in reverse direction. The nat works, the > address is translated. Not so in the second case: > > root@# tcpdump -ni any host 185.66.195.0 and \( host 176.9.38.150 or > host 192.168.10.62 <http://192.168.10.62> \) and proto 47 and > ip[33]=0x01 and \( ip[36:4]==0x644007B4 or ip[40:4]==0x644007B4 \) > tcpdump: verbose output suppressed, use -v or -vv for full protocol decode > listening on any, link-type LINUX_SLL (Linux cooked), capture size > 262144 bytes > 03:58:01.972551 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.0: > GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> > > 100.64.7.180: ICMP echo request, id 25043, seq 1, length 64 > 03:58:01.972554 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.0: > GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> > > 100.64.7.180: ICMP echo request, id 25043, seq 1, length 64 > 03:58:03.001013 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.0: > GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> > > 100.64.7.180: ICMP echo request, id 25043, seq 2, length 64 > 03:58:03.001021 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.0: > GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> > > 100.64.7.180: ICMP echo request, id 25043, seq 2, length 64 > > tcpdump catches the outgoing package. But instead of being translated, > it's dropped. > > Any ideas, how I could analyse this? All tested kernels showed the exact > same behavior. It's as if only one gre nat connection was possible. > > Regards, > Matthias > > -- > To unsubscribe from this list: send the line "unsubscribe lartc" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe lartc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html