NICMx / Jool

SIIT and NAT64 for Linux
GNU General Public License v2.0
326 stars 66 forks source link

Wrong checksum on namespace'd translation #159

Closed ydahhrk closed 9 years ago

ydahhrk commented 9 years ago

Plagiarized from Andrew Yourtchenko's e-mail:

(I'm going to omit some miscellaneous terminal output for the sake of privacy. Not really sure if it's useful.)

I'm trying to test stateful NAT64 using namespaces. I create a veth link, and put one end into a namespace, and leave the second end in the "global" table, so as to allow Jool to "grab" the packets.

  ip netns add blue
  ip link add wire0 type veth peer name wire1
  ip link set wire0 netns blue
  ip -6 addr add dev wire1 2001:db8::1/64
  ifconfig wire1 up
  ip netns exec blue ip -6 addr add dev wire0 2001:db8::2/64
  ip netns exec blue ifconfig wire0 up
  ip netns exec blue ip -6 route add default via 2001:db8::1

Then in the namespace:

  # ip netns exec blue bash
  # ip -6 addr
  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
      inet6 ::1/128 scope host
         valid_lft forever preferred_lft forever
  5: wire0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qlen 1000
      inet6 2001:db8::2/64 scope global
         valid_lft forever preferred_lft forever
      inet6 fe80::1c13:28ff:fe7c:ef2a/64 scope link
         valid_lft forever preferred_lft forever
  # ip -6 route
  2001:db8::/64 dev wire0  proto kernel  metric 256
  fe80::/64 dev wire0  proto kernel  metric 256
  default via 2001:db8::1 dev wire0  metric 1024
  #
  # for i in wire0; do for f in tso ufo gso gro lro; do ethtool --offload $i $f off; done; done
  Cannot change large-receive-offload
  #

The global routing table looks like this:

  # ip -6 addr
  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
      inet6 ::1/128 scope host
         valid_lft forever preferred_lft forever
  2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
      [Valid IPv6 configuration here.]
  4: wire1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
      inet6 2001:db8::1/64 scope global
         valid_lft forever preferred_lft forever
      inet6 fe80::9029:43ff:fe81:ed29/64 scope link
         valid_lft forever preferred_lft forever
  # for i in eth0 wire1; do for f in tso ufo gso gro lro; do ethtool --offload $i $f off; done; done
  Cannot change udp-fragmentation-offload
  Cannot change large-receive-offload
  Cannot change large-receive-offload
  # modprobe jool pool6=64:ff9b::/96 pool4=[IPv4 address here]

Problem:

When I initiate curl from within the namespace:

  curl -v 'http://\[64:ff9b::188.40.136.148\]'
  * Rebuilt URL to: http://[64:ff9b::188.40.136.148]/
  * Hostname was NOT found in DNS cache
  *   Trying 64:ff9b::bc28:8894...

The translation takes place but apparently the TCP checksum is wrong:

  # tcpdump -ln -i eth0 -s 1518 -v -v -v tcp port 80
  tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 1518 bytes
  11:20:17.241692 IP (tos 0x0, ttl 63, id 7454, offset 0, flags [none], proto TCP (6), length 60)
      10.48.100.99.50589 > 188.40.136.148.80: Flags [S], cksum 0x0bb1 (incorrect -> 0x2fcd), seq 3241506314, win 28800, options [mss 1440,sackOK,TS val 522049 ecr 0,nop,wscale 7], length 0
  11:20:18.239831 IP (tos 0x0, ttl 63, id 5022, offset 0, flags [none], proto TCP (6), length 60)
      10.48.100.99.50589 > 188.40.136.148.80: Flags [S], cksum 0x0bb1 (incorrect -> 0x2ed3), seq 3241506314, win 28800, options [mss 1440,sackOK,TS val 522299 ecr 0,nop,wscale 7], length 0
  11:20:20.243854 IP (tos 0x0, ttl 63, id 42191, offset 0, flags [none], proto TCP (6), length 60)
      10.48.100.99.50589 > 188.40.136.148.80: Flags [S], cksum 0x0bb1 (incorrect -> 0x2cde), seq 3241506314, win 28800, options [mss 1440,sackOK,TS val 522800 ecr 0,nop,wscale 7], length 0

The ICMP pings work, however.

The machine is a KVM VM running the stock Ubuntu 14.04 Server:

Thanks!

ydahhrk commented 9 years ago

Progress: e726a8708da3612c33d0f82e44abedaeec0fd9cb