1. 31 Mar, 2021 7 commits
    • Paolo Abeni's avatar
      bareudp: allow UDP L4 GRO passthrou · b03ef676
      Paolo Abeni authored
      Similar to the previous commit, let even geneve
      passthrou the L4 GRO packets
      Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      b03ef676
    • Paolo Abeni's avatar
      geneve: allow UDP L4 GRO passthrou · 61630c4f
      Paolo Abeni authored
      Similar to the previous commit, let even geneve
      passthrou the L4 GRO packets
      Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      61630c4f
    • Paolo Abeni's avatar
      vxlan: allow L4 GRO passthrough · d18931a9
      Paolo Abeni authored
      When passing up an UDP GSO packet with L4 aggregation, there is
      no need to segment it at the vxlan level. We can propagate the
      packet untouched and let it be segmented later, if needed.
      
      Introduce an helper to allow let the UDP socket to accept any
      L4 aggregation and use it in the vxlan driver.
      
      v1 -> v2:
       - updated to use the newly introduced UDP socket 'accept*' fields
      Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
      Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      d18931a9
    • Paolo Abeni's avatar
      udp: never accept GSO_FRAGLIST packets · 78352f73
      Paolo Abeni authored
      Currently the UDP protocol delivers GSO_FRAGLIST packets to
      the sockets without the expected segmentation.
      
      This change addresses the issue introducing and maintaining
      a couple of new fields to explicitly accept SKB_GSO_UDP_L4
      or GSO_FRAGLIST packets. Additionally updates  udp_unexpected_gso()
      accordingly.
      
      UDP sockets enabling UDP_GRO stil keep accept_udp_fraglist
      zeroed.
      
      v1 -> v2:
       - use 2 bits instead of a whole GSO bitmask (Willem)
      
      Fixes: 9fd1ff5d ("udp: Support UDP fraglist GRO/GSO.")
      Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
      Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      78352f73
    • Paolo Abeni's avatar
      udp: properly complete L4 GRO over UDP tunnel packet · e0e3070a
      Paolo Abeni authored
      After the previous patch, the stack can do L4 UDP aggregation
      on top of a UDP tunnel.
      
      In such scenario, udp{4,6}_gro_complete will be called twice. This function
      will enter its is_flist branch immediately, even though that is only
      correct on the second call, as GSO_FRAGLIST is only relevant for the
      inner packet.
      
      Instead, we need to try first UDP tunnel-based aggregation, if the GRO
      packet requires that.
      
      This patch changes udp{4,6}_gro_complete to skip the frag list processing
      when while encap_mark == 1, identifying processing of the outer tunnel
      header.
      Additionally, clears the field in udp_gro_complete() so that we can enter
      the frag list path on the next round, for the inner header.
      
      v1 -> v2:
       - hopefully clarified the commit message
      Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
      Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      e0e3070a
    • Paolo Abeni's avatar
      udp: skip L4 aggregation for UDP tunnel packets · 18f25dc3
      Paolo Abeni authored
      If NETIF_F_GRO_FRAGLIST or NETIF_F_GRO_UDP_FWD are enabled, and there
      are UDP tunnels available in the system, udp_gro_receive() could end-up
      doing L4 aggregation (either SKB_GSO_UDP_L4 or SKB_GSO_FRAGLIST) at
      the outer UDP tunnel level for packets effectively carrying and UDP
      tunnel header.
      
      That could cause inner protocol corruption. If e.g. the relevant
      packets carry a vxlan header, different vxlan ids will be ignored/
      aggregated to the same GSO packet. Inner headers will be ignored, too,
      so that e.g. TCP over vxlan push packets will be held in the GRO
      engine till the next flush, etc.
      
      Just skip the SKB_GSO_UDP_L4 and SKB_GSO_FRAGLIST code path if the
      current packet could land in a UDP tunnel, and let udp_gro_receive()
      do GRO via udp_sk(sk)->gro_receive.
      
      The check implemented in this patch is broader than what is strictly
      needed, as the existing UDP tunnel could be e.g. configured on top of
      a different device: we could end-up skipping GRO at-all for some packets.
      
      Anyhow, that is a very thin corner case and covering it will add quite
      a bit of complexity.
      
      v1 -> v2:
       - hopefully clarify the commit message
      
      Fixes: 9fd1ff5d ("udp: Support UDP fraglist GRO/GSO.")
      Fixes: 36707061 ("udp: allow forwarding of plain (non-fraglisted) UDP GRO packets")
      Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
      Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      18f25dc3
    • Paolo Abeni's avatar
      udp: fixup csum for GSO receive slow path · 000ac44d
      Paolo Abeni authored
      When UDP packets generated locally by a socket with UDP_SEGMENT
      traverse the following path:
      
      UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) ->
      	UDP tunnel (rx) -> UDP socket (no UDP_GRO)
      
      ip_summed will be set to CHECKSUM_PARTIAL at creation time and
      such checksum mode will be preserved in the above path up to the
      UDP tunnel receive code where we have:
      
       __iptunnel_pull_header() -> skb_pull_rcsum() ->
      skb_postpull_rcsum() -> __skb_postpull_rcsum()
      
      The latter will convert the skb to CHECKSUM_NONE.
      
      The UDP GSO packet will be later segmented as part of the rx socket
      receive operation, and will present a CHECKSUM_NONE after segmentation.
      
      Additionally the segmented packets UDP CB still refers to the original
      GSO packet len. Overall that causes unexpected/wrong csum validation
      errors later in the UDP receive path.
      
      We could possibly address the issue with some additional checks and
      csum mangling in the UDP tunnel code. Since the issue affects only
      this UDP receive slow path, let's set a suitable csum status there.
      
      Note that SKB_GSO_UDP_L4 or SKB_GSO_FRAGLIST packets lacking an UDP
      encapsulation present a valid checksum when landing to udp_queue_rcv_skb(),
      as the UDP checksum has been validated by the GRO engine.
      
      v2 -> v3:
       - even more verbose commit message and comments
      
      v1 -> v2:
       - restrict the csum update to the packets strictly needing them
       - hopefully clarify the commit message and code comments
      Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
      Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      000ac44d
  2. 30 Mar, 2021 33 commits