NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/52346: Android VPN (IPSEC) setup fails with UDP checksum errors



>Number:         52346
>Category:       kern
>Synopsis:       Android VPN (IPSEC) setup fails with UDP checksum errors
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 28 09:45:00 +0000 2017
>Originator:     kardel%netbsd.org@localhost
>Release:        NetBSD 8.0_BETA
>Organization:
	
>Environment:
	
	
System: NetBSD Gateway 8.0_BETA NetBSD 8.0_BETA (GATEWAY) #0: Wed Jun 28 10:22:03 CEST 2017 kardel@xxx:/fs/raid2a/src/NetBSD/n8/src/obj.amd64/sys/arch/amd64/compile/GATEWAY i386
Architecture: i386
Machine: i386
>Description:
	Setup of IPSEC VPN from Android (4-7) smartphones does not work.
	raccoon negotiation works mostly, but once the SA is established
	the udp checksum error counter keeps increasing and the packets 
	get dropped.

	Using an old checksum fix patch from gnats gets the packets
	through, but the is just a stop gap measure.

	Failing setup (current state):
	2017-06-28T08:08:33.267782+00:00 Gateway racoon - - - INFO: respond new phase 1 negotiation: A.B.C.36[500]<=>D.E.F.66[54056] 
	2017-06-28T08:08:33.268144+00:00 Gateway racoon - - - INFO: begin Identity Protection mode. 
	2017-06-28T08:08:33.271946+00:00 Gateway racoon - - - INFO: received Vendor ID: RFC 3947 
	2017-06-28T08:08:33.272321+00:00 Gateway racoon - - - INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02 
	2017-06-28T08:08:33.272720+00:00 Gateway racoon - - - INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02  
	2017-06-28T08:08:33.273120+00:00 Gateway racoon - - - INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-00 
	2017-06-28T08:08:33.273529+00:00 Gateway racoon - - - INFO: received broken Microsoft ID: FRAGMENTATION 
	2017-06-28T08:08:33.273941+00:00 Gateway racoon - - - INFO: received Vendor ID: DPD 
	2017-06-28T08:08:33.274741+00:00 Gateway racoon - - - [D.E.F.66] INFO: Selected NAT-T version: RFC 3947 
	2017-06-28T08:08:33.380892+00:00 Gateway racoon - - - [A.B.C.36] INFO: Hashing A.B.C.36[500] with algo #2  
	2017-06-28T08:08:33.381704+00:00 Gateway racoon - - - INFO: NAT-D payload #0 verified 
	2017-06-28T08:08:33.382097+00:00 Gateway racoon - - - [D.E.F.66] INFO: Hashing D.E.F.66[54056] with algo #2  
	2017-06-28T08:08:33.382930+00:00 Gateway racoon - - - INFO: NAT-D payload #1 doesn't match 
	2017-06-28T08:08:33.383290+00:00 Gateway racoon - - - INFO: NAT detected: PEER 
	2017-06-28T08:08:33.437106+00:00 Gateway racoon - - - [D.E.F.66] INFO: Hashing D.E.F.66[54056] with algo #2  
	2017-06-28T08:08:33.437957+00:00 Gateway racoon - - - [A.B.C.36] INFO: Hashing A.B.C.36[500] with algo #2  
	2017-06-28T08:08:33.438746+00:00 Gateway racoon - - - INFO: Adding remote and local NAT-D payloads. 
	2017-06-28T08:08:33.531282+00:00 Gateway racoon - - - INFO: NAT-T: ports changed to: D.E.F.66[61800]<->A.B.C.36[4500] 
	2017-06-28T08:08:33.531715+00:00 Gateway racoon - - - INFO: KA found: A.B.C.36[4500]->D.E.F.66[61800] (in_use=2) 
	2017-06-28T08:08:33.671851+00:00 Gateway racoon - - - INFO: ISAKMP-SA established A.B.C.36[4500]-D.E.F.66[61800] spi:bde4da111d9ff002:6dc5cbf88793ded1 
	2017-06-28T08:08:33.710131+00:00 Gateway racoon - - - [D.E.F.66] INFO: received INITIAL-CONTACT 
	2017-06-28T08:08:33.711071+00:00 Gateway racoon - - - INFO: purging spi=138460684. 
	2017-06-28T08:08:33.711350+00:00 Gateway racoon - - - INFO: deleting a generated policy. 
	2017-06-28T08:08:33.713001+00:00 Gateway racoon - - - INFO: purging spi=37096200. 
	2017-06-28T08:08:34.716899+00:00 Gateway racoon - - - INFO: respond new phase 2 negotiation: A.B.C.36[4500]<=>D.E.F.66[61800] 
	2017-06-28T08:08:34.730630+00:00 Gateway racoon - - - INFO: Update the generated policy : 10.0.8.198/32[0] A.B.C.36/32[1701] proto=udp dir=in 
	2017-06-28T08:08:34.787365+00:00 Gateway racoon - - - INFO: Adjusting my encmode UDP-Transport->Transport 
	2017-06-28T08:08:34.787637+00:00 Gateway racoon - - - INFO: Adjusting peer's encmode UDP-Transport(4)->Transport(2) 
	2017-06-28T08:08:34.849171+00:00 Gateway racoon - - - INFO: IPsec-SA established: ESP/Transport A.B.C.36[4500]->D.E.F.66[61800] spi=202980303(0xc193bcf) 
	2017-06-28T08:08:34.850159+00:00 Gateway racoon - - - INFO: IPsec-SA established: ESP/Transport A.B.C.36[4500]->D.E.F.66[61800] spi=255416436(0xf395874) 
	[ communication ends here ]

	Successful setup with band-aid solution from fix section
	2017-06-28T08:50:15.422354+00:00 Gateway racoon - - - INFO: begin Identity Protection mode. 
	2017-06-28T08:50:15.425008+00:00 Gateway racoon - - - INFO: received Vendor ID: RFC 3947 
	2017-06-28T08:50:15.425336+00:00 Gateway racoon - - - INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02 
	2017-06-28T08:50:15.425656+00:00 Gateway racoon - - - INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02  
	2017-06-28T08:50:15.425975+00:00 Gateway racoon - - - INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-00 
	2017-06-28T08:50:15.426296+00:00 Gateway racoon - - - INFO: received broken Microsoft ID: FRAGMENTATION 
	2017-06-28T08:50:15.426615+00:00 Gateway racoon - - - INFO: received Vendor ID: DPD 
	2017-06-28T08:50:15.427190+00:00 Gateway racoon - - - [D.E.F.66] INFO: Selected NAT-T version: RFC 3947 
	2017-06-28T08:50:15.513449+00:00 Gateway racoon - - - [A.B.C.36] INFO: Hashing A.B.C.36[500] with algo #2  
	2017-06-28T08:50:15.514376+00:00 Gateway racoon - - - INFO: NAT-D payload #0 verified 
	2017-06-28T08:50:15.514882+00:00 Gateway racoon - - - [D.E.F.66] INFO: Hashing D.E.F.66[57612] with algo #2  
	2017-06-28T08:50:15.515778+00:00 Gateway racoon - - - INFO: NAT-D payload #1 doesn't match 
	2017-06-28T08:50:15.516253+00:00 Gateway racoon - - - INFO: NAT detected: PEER 
	2017-06-28T08:50:15.554179+00:00 Gateway racoon - - - [D.E.F.66] INFO: Hashing D.E.F.66[57612] with algo #2  
	2017-06-28T08:50:15.554821+00:00 Gateway racoon - - - [A.B.C.36] INFO: Hashing A.B.C.36[500] with algo #2  
	2017-06-28T08:50:15.555419+00:00 Gateway racoon - - - INFO: Adding remote and local NAT-D payloads. 
	2017-06-28T08:50:15.605758+00:00 Gateway racoon - - - INFO: NAT-T: ports changed to: D.E.F.66[58130]<->A.B.C.36[4500] 
	2017-06-28T08:50:15.605981+00:00 Gateway racoon - - - INFO: KA found: A.B.C.36[4500]->D.E.F.66[58130] (in_use=2) 
	2017-06-28T08:50:15.674438+00:00 Gateway racoon - - - INFO: ISAKMP-SA established A.B.C.36[4500]-D.E.F.66[58130] spi:5d2c0f59d34a4711:13cb2478a258e84a 
	2017-06-28T08:50:15.711301+00:00 Gateway racoon - - - [D.E.F.66] INFO: received INITIAL-CONTACT 
	2017-06-28T08:50:15.712442+00:00 Gateway racoon - - - INFO: purging spi=75014854. 
	2017-06-28T08:50:15.712658+00:00 Gateway racoon - - - INFO: deleting a generated policy. 
	2017-06-28T08:50:15.714399+00:00 Gateway racoon - - - INFO: purging spi=244968613. 
	2017-06-28T08:50:16.711657+00:00 Gateway racoon - - - INFO: respond new phase 2 negotiation: A.B.C.36[4500]<=>D.E.F.66[58130] 
	2017-06-28T08:50:16.743801+00:00 Gateway racoon - - - INFO: Update the generated policy : 10.0.8.198/32[0] A.B.C.36/32[1701] proto=udp dir=in 
	2017-06-28T08:50:16.804974+00:00 Gateway racoon - - - INFO: Adjusting my encmode UDP-Transport->Transport 
	2017-06-28T08:50:16.805207+00:00 Gateway racoon - - - INFO: Adjusting peer's encmode UDP-Transport(4)->Transport(2) 
	[ missing above ]
	2017-06-28T08:50:16.806462+00:00 Gateway /netbsd - - - key_set_natt_ports: type 2, sport = 58130, dport = 4500
	2017-06-28T08:50:16.806462+00:00 Gateway /netbsd - - - key_set_natt_ports: type 2, sport = 58130, dport = 4500
	2017-06-28T08:50:16.865769+00:00 Gateway /netbsd - - - key_handle_natt_info: type 2, sport = 58130, dport = 4500
	2017-06-28T08:50:16.867046+00:00 Gateway /netbsd - - - key_set_natt_ports: type 2, sport = 4500, dport = 58130
	2017-06-28T08:50:16.867365+00:00 Gateway /netbsd - - - key_handle_natt_info: type 2, sport = 4500, dport = 58130
	2017-06-28T08:50:16.873260+00:00 Gateway racoon - - - INFO: IPsec-SA established: ESP/Transport A.B.C.36[4500]->D.E.F.66[58130] spi=227017815(0xd880457) 
	2017-06-28T08:50:16.874219+00:00 Gateway racoon - - - INFO: IPsec-SA established: ESP/Transport A.B.C.36[4500]->D.E.F.66[58130] spi=47888302(0x2dab7ae) 
	[ communications works - l2tp setup starts ]
	2017-06-28T08:50:17.444637+00:00 Gateway xl2tpd 635 - - Connection established to D.E.F.66, 43576.  Local: 11927, Remote: 16196 (ref=0/0).  LNS session is 'default' 
	2017-06-28T08:50:17.534643+00:00 Gateway xl2tpd 635 - - set queue size for /dev/pts/0 to 32768 
	2017-06-28T08:50:17.542567+00:00 Gateway xl2tpd 635 - - Call established with D.E.F.66, Local: 32025, Remote: 17590, Serial: 1337645123 
	2017-06-28T08:50:17.597676+00:00 Gateway pppd 7793 - - pppd 2.4.7 started by root, uid 0
	2017-06-28T08:50:17.606893+00:00 Gateway pppd 7793 - - set_up_tty: Changed queue size of 8 from 1024 to 32768
	2017-06-28T08:50:17.610306+00:00 Gateway pppd 7793 - - tty_establish_ppp: Changed queue size of 8 from 1024 to 32768
	2017-06-28T08:50:17.613510+00:00 Gateway pppd 7793 - - Using interface ppp0
	2017-06-28T08:50:17.817129+00:00 Gateway pppd 7793 - - Connect: ppp0 <--> /dev/pts/0
	2017-06-28T08:50:20.499316+00:00 Gateway pppd 7793 - - Deflate (15) compression enabled
	2017-06-28T08:50:20.529084+00:00 Gateway pppd 7793 - - sifproxyarp: Cannot determine ethernet address for proxy ARP
	2017-06-28T08:50:20.529358+00:00 Gateway pppd 7793 - - local  IP address 10.200.103.1
	2017-06-28T08:50:20.529572+00:00 Gateway pppd 7793 - - remote IP address 10.200.103.192
	2017-06-28T08:50:20.530953+00:00 Gateway named 350 - - listening on IPv4 interface ppp0, 10.200.103.1#53
	2017-06-28T08:50:24.502080+00:00 Gateway ntpd 654 - - Listen normally on 13 ppp0 10.200.103.1:123

>How-To-Repeat:
	Try to setup L2TP/IPSec RSA VPN from and Android phone. Communication will get stuck on UDP checksum errors
	after IPSEC decryption (see netstat -s).

>Fix:
	This fix was found long ago either in the mailing lists or gnats. Maybe a proper solution
	(differential UDP checksum fix) can be found.

Index: ipsec_input.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/ipsec_input.c,v
retrieving revision 1.43
diff -u -r1.43 ipsec_input.c
--- ipsec_input.c       19 May 2017 04:34:09 -0000      1.43
+++ ipsec_input.c       28 Jun 2017 09:27:35 -0000
@@ -68,6 +68,8 @@
 #include <netinet/ip_var.h>
 #include <netinet/in_var.h>
 #include <netinet/in_proto.h>
+#include <netinet/udp.h>
+#include <netinet/tcp.h>

 #include <netinet/ip6.h>
 #ifdef INET6
@@ -114,6 +116,63 @@
 } while (/*CONSTCOND*/0)

 /*
+ * fixup TCP/UDP checksum
+ *
+ * XXX: if we have NAT-OA payload from IKE server,
+ *      we must do the differential update of checksum.
+ *
+ * XXX: NAT-OAi/NAT-OAr drived from IKE initiator/responder.
+ *      how to know the IKE side from kernel?
+ */
+static struct mbuf *
+ipsec4_fixup_checksum(struct mbuf *m)
+{
+       struct ip *ip;
+       struct tcphdr *th;
+       struct udphdr *uh;
+       int poff, off;
+       int plen;
+
+       if (m->m_len < sizeof(*ip))
+               m = m_pullup(m, sizeof(*ip));
+       ip = mtod(m, struct ip *); 
+       poff = ip->ip_hl << 2;
+       plen = ntohs(ip->ip_len) - poff;
+
+       switch (ip->ip_p) {
+       case IPPROTO_TCP:
+               IP6_EXTHDR_GET(th, struct tcphdr *, m, poff, sizeof(*th));
+               if (th == NULL)
+                       return NULL;
+               off = th->th_off << 2;
+               if (off < sizeof(*th) || off > plen) {
+                       m_freem(m);
+                       return NULL;
+               }
+               th->th_sum = 0;
+               th->th_sum = in4_cksum(m, IPPROTO_TCP, poff, plen);
+               break;
+       case IPPROTO_UDP:
+               IP6_EXTHDR_GET(uh, struct udphdr *, m, poff, sizeof(*uh));
+               if (uh == NULL)
+                       return NULL;
+               off = sizeof(*uh); 
+               if (off > plen) {  
+                       m_freem(m);
+                       return NULL;
+               }
+               uh->uh_sum = 0;
+               uh->uh_sum = in4_cksum(m, IPPROTO_UDP, poff, plen);
+               break;
+       default:
+               /* no checksum */  
+               return m;
+       }
+
+       return m;
+}
+
+/*
  * ipsec_common_input gets called when an IPsec-protected packet
  * is received by IPv4 or IPv6.  It's job is to find the right SA
  # and call the appropriate transform.  The transform callback
@@ -319,6 +378,22 @@
        ip->ip_len = htons(m->m_pkthdr.len);
        prot = ip->ip_p;

+        /* Update TCP/UDP checksum */
+        m = ipsec4_fixup_checksum(m);
+        if (m == NULL) {
+               char buf[IPSEC_ADDRSTRLEN];
+                DPRINTF(("ipsec4_common_input_cb: processing failed "
+                    "for SA %s/%08lx\n",
+                    ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
+                    (u_long) ntohl(sav->spi)));
+                IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
+                    IPCOMP_STAT_HDROPS);
+                error = ENOBUFS;  
+                goto bad;
+        }
+
+
+
        /* IP-in-IP encapsulation */
        if (prot == IPPROTO_IPIP) {
                struct ip ipn;

>Unformatted:
 	
 	


Home | Main Index | Thread Index | Old Index