• Daniel Borkmann's avatar
    bpf: fix checksum for vlan push/pop helper · 8065694e
    Daniel Borkmann authored
    When having skbs on ingress with CHECKSUM_COMPLETE, tc BPF programs don't
    push rcsum of mac header back in and after BPF run back pull out again as
    opposed to some other subsystems (ovs, for example).
    
    For cases like q-in-q, meaning when a vlan tag for offloading is already
    present and we're about to push another one, then skb_vlan_push() pushes the
    inner one into the skb, increasing mac header and skb_postpush_rcsum()'ing
    the 4 bytes vlan header diff. Likewise, for the reverse operation in
    skb_vlan_pop() for the case where vlan header needs to be pulled out of the
    skb, we're decreasing the mac header and skb_postpull_rcsum()'ing the 4 bytes
    rcsum of the vlan header that was removed.
    
    However mangling the rcsum here will lead to hw csum failure for BPF case,
    since we're pulling or pushing data that was not part of the current rcsum.
    Changing tc BPF programs in general to push/pull rcsum around BPF_PROG_RUN()
    is also not really an option since current behaviour is ABI by now, but apart
    from that would also mean to do quite a bit of useless work in the sense that
    usually 12 bytes need to be rcsum pushed/pulled also when we don't need to
    touch this vlan related corner case. One way to fix it would be to push the
    necessary rcsum fixup down into vlan helpers that are (mostly) slow-path
    anyway.
    
    Fixes: 4e10df9a ("bpf: introduce bpf_skb_vlan_push/pop() helpers")
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    8065694e
filter.c 72.6 KB