Bug 24412

Summary: SCTP traffic over IPv6 IPsec tunnel fails to be encrypted
Product: Networking Reporter: Alan.Chester
Component: IPV6Assignee: Hideaki YOSHIFUJI (yoshfuji)
Status: RESOLVED CODE_FIX    
Severity: normal CC: adobriyan, Alan.Chester, alan, daniel, jkastner, joe.keller
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.18 (Also tested in 3.6.32) Subsystem:
Regression: No Bisected commit-id:

Description Alan.Chester 2010-12-06 13:37:30 UTC
When sending SCTP traffic over and IPv6 IPsec tunnel the SCTP packets are transmitted unencrypted.  It seems that these packets are being ignored by ipsec/kernel.

Recreation:
1. Set up and IPv6 IPsec tunnel using any configuration tools (This problem was seen with both Racoon and Racoon2.  Other people have seen this with OpenSwan)

2. Send SCTP traffic from Host A to Host B.

3. Using wireshark detect if the packets are encrypted or if the sctp packets are unencrypted.

Notes:
- When IPsec is configured to encrypt all upper layer protocols the sctp connection does not initialize.  After using wireshark to follow packets, this is because the SCTP packet leaves Box A unencrypted and Box B believes all upper layer protocols are to be encrypted so it drops this packet.  Causing the SCTP connection to fail to initialize.

- When IPsec is configured to encrypt just SCTP the SCTP packets are observed unencrypted.
Comment 1 Alan.Chester 2011-07-15 18:16:25 UTC
I was wondering if there has been any additional investigation/work done on this issue.  A few people have emailed me offline asking me if I have fixed this or know the status of the issue.  Is there anything else I can do or provide to help with this bug?
Comment 2 Alexey Dobriyan 2011-08-13 19:02:32 UTC
I can sort of reproduce this with simple setkey(8) file and socat invocations.
Comment 3 Alexey Dobriyan 2011-08-13 19:17:14 UTC
IPv4 works while IPv6 doesn't.
Comment 4 Alexey Dobriyan 2011-08-13 19:21:31 UTC
IPv4 tcpdump

socat sctp-listen:3333 -
echo plaintext | socat - sctp-connect:$IP:3333

and it works (first socat prints "plaintext" and exists)


22:14:20.809645 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 116)
    192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x1): ESP(spi=0x00000044,seq=0x1), length 72
22:14:20.813270 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 340)
    192.168.0.5 > 192.168.0.2: AH(spi=0x00000043,sumlen=16,seq=0x1): ESP(spi=0x00000045,seq=0x1), length 296
22:14:20.813834 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 308)
    192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x2): ESP(spi=0x00000044,seq=0x2), length 264
22:14:20.813920 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 84)
    192.168.0.5 > 192.168.0.2: AH(spi=0x00000043,sumlen=16,seq=0x2): ESP(spi=0x00000045,seq=0x2), length 40
22:14:20.814330 IP (tos 0x2,ECT(0), ttl 64, id 1, offset 0, flags [DF], proto AH (51), length 108)
    192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x3): ESP(spi=0x00000044,seq=0x3), length 64
22:14:20.814379 IP (tos 0x2,ECT(0), ttl 64, id 5721, offset 0, flags [DF], proto AH (51), length 92)
    192.168.0.5 > 192.168.0.2: AH(spi=0x00000043,sumlen=16,seq=0x3): ESP(spi=0x00000045,seq=0x3), length 48
22:14:20.814709 IP (tos 0x2,ECT(0), ttl 64, id 2, offset 0, flags [DF], proto AH (51), length 84)
    192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x4): ESP(spi=0x00000044,seq=0x4), length 40
22:14:20.814745 IP (tos 0x2,ECT(0), ttl 64, id 5722, offset 0, flags [DF], proto AH (51), length 84)
    192.168.0.5 > 192.168.0.2: AH(spi=0x00000043,sumlen=16,seq=0x4): ESP(spi=0x00000045,seq=0x4), length 40
22:14:20.815062 IP (tos 0x2,ECT(0), ttl 64, id 3, offset 0, flags [DF], proto AH (51), length 84)
    192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x5): ESP(spi=0x00000044,seq=0x5), length 40
Comment 5 Alexey Dobriyan 2011-08-13 19:35:26 UTC
IPv6 tcpdump

socat sctp6-listen:3333 -
[socat maybe doesn't have option to setup sin6_scope_id, so a simple program was written instead]

and it doesn't work

22:31:16.212810 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::92e6:baff:fe0d:5a54 > ff02::1:ff87:7fc: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::222:15ff:fe87:7fc
          source link-address option (1), length 8 (1): 90:e6:ba:0d:5a:54
            0x0000:  90e6 ba0d 5a54
22:31:16.212907 IP6 (hlim 255, next-header AH (51) payload length: 80) fe80::222:15ff:fe87:7fc > fe80::92e6:baff:fe0d:5a54: AH(spi=0x00000043,sumlen=16,seq=0x1): ESP(spi=0x00000045,seq=0x1), length 56
22:31:16.213299 IP6 (class 0x02, hlim 64, next-header AH (51) payload length: 120) fe80::92e6:baff:fe0d:5a54 > fe80::222:15ff:fe87:7fc: AH(spi=0x00000042,sumlen=16,seq=0x1): ESP(spi=0x00000044,seq=0x1), length 96
22:31:16.213423 IP6 (class 0x02, hlim 64, next-header SCTP (132) payload length: 364) fe80::222:15ff:fe87:7fc.3333 > fe80::92e6:baff:fe0d:5a54.36767: sctp
        1) [INIT ACK] [init tag: 1875304899] [rwnd: 62464] [OS: 10] [MIS: 10] [init TSN: 131147491]
22:31:19.214962 IP6 (class 0x02, hlim 64, next-header AH (51) payload length: 120) fe80::92e6:baff:fe0d:5a54 > fe80::222:15ff:fe87:7fc: AH(spi=0x00000042,sumlen=16,seq=0x2): ESP(spi=0x00000044,seq=0x2), length 96
22:31:19.215029 IP6 (class 0x02, hlim 64, next-header SCTP (132) payload length: 364) fe80::222:15ff:fe87:7fc.3333 > fe80::92e6:baff:fe0d:5a54.36767: sctp
        1) [INIT ACK] [init tag: 747759530] [rwnd: 62464] [OS: 10] [MIS: 10] [init TSN: 310556273]
22:31:19.340499 IP (tos 0x0, ttl 64, id 5200, offset 0, flags [none], proto UDP (17), length 197)
    192.168.0.1.8099 > 239.255.0.1.9303: [udp sum ok] UDP, length 169
22:31:21.212624 IP6 (hlim 255, next-header AH (51) payload length: 80) fe80::222:15ff:fe87:7fc > fe80::92e6:baff:fe0d:5a54: AH(spi=0x00000043,sumlen=16,seq=0x2): ESP(spi=0x00000045,seq=0x2), length 56
22:31:21.213150 IP6 (hlim 255, next-header AH (51) payload length: 72) fe80::92e6:baff:fe0d:5a54 > fe80::222:15ff:fe87:7fc: AH(spi=0x00000042,sumlen=16,seq=0x3): ESP(spi=0x00000044,seq=0x3), length 48
22:31:25.235139 IP6 (class 0x02, hlim 64, next-header AH (51) payload length: 120) fe80::92e6:baff:fe0d:5a54 > fe80::222:15ff:fe87:7fc: AH(spi=0x00000042,sumlen=16,seq=0x4): ESP(spi=0x00000044,seq=0x4), length 96
22:31:25.235209 IP6 (class 0x02, hlim 64, next-header SCTP (132) payload length: 364) fe80::222:15ff:fe87:7fc.3333 > fe80::92e6:baff:fe0d:5a54.36767: sctp
        1) [INIT ACK] [init tag: 3018255165] [rwnd: 62464] [OS: 10] [MIS: 10] [init TSN: 464808795]
22:31:29.341912 IP (tos 0x0, ttl 64, id 5557, offset 0, flags [none], proto UDP (17), length 197)
    192.168.0.1.8100 > 239.255.0.1.9303: [udp sum ok] UDP, length 169
22:31:37.259513 IP6 (class 0x02, hlim 64, next-header AH (51) payload length: 120) fe80::92e6:baff:fe0d:5a54 > fe80::222:15ff:fe87:7fc: AH(spi=0x00000042,sumlen=16,seq=0x5): ESP(spi=0x00000044,seq=0x5), length 96
22:31:37.259583 IP6 (class 0x02, hlim 64, next-header SCTP (132) payload length: 364) fe80::222:15ff:fe87:7fc.3333 > fe80::92e6:baff:fe0d:5a54.36767: sctp
        1) [INIT ACK] [init tag: 1733515857] [rwnd: 62464] [OS: 10] [MIS: 10] [init TSN: 2931534808]
Comment 6 Alexey Dobriyan 2011-08-22 19:06:00 UTC
LINUX_MIB_XFRMINTMPLMISMATCH is incremented at __xfrm_policy_check():

for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
    k = xfrm_policy_ok(tpp[i], sp, k, family);
    if (k < 0) {
        if (k < -1)
            /* "-2 - errored_index" returned */
            xerr_idx = -(2+k);
        XFRM_INC_STATS(net, LINUX_MIB_XFRMINTMPLMISMATCH);
        goto reject;
    }
}
Comment 7 Alexey Dobriyan 2011-08-22 19:21:17 UTC
For some reason, skb->sp is NULL at sctp_v6_get_dst() which of course doesn't work:

__xfrm_policy_check: skb->sp ffff880222e62000
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 50
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 51
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: skb->sp ffff880222e62000
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 50
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 51
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: skb->sp ffff880222e62000
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 50
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 51
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: skb->sp ffff880222e62000
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 50
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 51
__xfrm_policy_check: ->mode 0
sctp_v6_get_dst: ENTER
sctp_v6_get_dst: dst ffff880222e64900, asoc ffff880211c48000, saddr           (null)
__xfrm_policy_check: skb->sp           (null)
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 50
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: ->id.daddr ::
__xfrm_policy_check: ->id.proto 51
__xfrm_policy_check: ->mode 0
__xfrm_policy_check: 001, k -1
Comment 9 Jiri Kastner 2013-10-16 09:04:54 UTC
(In reply to Alexey Dobriyan from comment #5)
> IPv6 tcpdump
> 
> socat sctp6-listen:3333 -
> [socat maybe doesn't have option to setup sin6_scope_id, so a simple program
> was written instead]

@alexey - can you, please, attach that simple program for ipv6?
Comment 10 Alexey Dobriyan 2015-02-20 07:34:08 UTC
RESOLVED FIXED in 3.12
commit 95ee62083cb6453e056562d91f597552021e6ae7
net: sctp: fix ipv6 ipsec encryption bug in sctp_v6_xmit