• Daniel Borkmann's avatar
    net: sctp: fix and consolidate SCTP checksumming code · e6d8b64b
    Daniel Borkmann authored
    This fixes an outstanding bug found through IPVS, where SCTP packets
    with skb->data_len > 0 (non-linearized) and empty frag_list, but data
    accumulated in frags[] member, are forwarded with incorrect checksum
    letting SCTP initial handshake fail on some systems. Linearizing each
    SCTP skb in IPVS to prevent that would not be a good solution as
    this leads to an additional and unnecessary performance penalty on
    the load-balancer itself for no good reason (as we actually only want
    to update the checksum, and can do that in a different/better way
    presented here).
    
    The actual problem is elsewhere, namely, that SCTP's checksumming
    in sctp_compute_cksum() does not take frags[] into account like
    skb_checksum() does. So while we are fixing this up, we better reuse
    the existing code that we have anyway in __skb_checksum() and use it
    for walking through the data doing checksumming. This will not only
    fix this issue, but also consolidates some SCTP code with core
    sk_buff code, bringing it closer together and removing respectively
    avoiding reimplementation of skb_checksum() for no good reason.
    
    As crc32c() can use hardware implementation within the crypto layer,
    we leave that intact (it wraps around / falls back to e.g. slice-by-8
    algorithm in __crc32c_le() otherwise); plus use the __crc32c_le_combine()
    combinator for crc32c blocks.
    
    Also, we remove all other SCTP checksumming code, so that we only
    have to use sctp_compute_cksum() from now on; for doing that, we need
    to transform SCTP checkumming in output path slightly, and can leave
    the rest intact.
    Signed-off-by: default avatarDaniel Borkmann <dborkman@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    e6d8b64b
checksum.h 2.37 KB