udp: GRO L4 improvements
Subsystems (4)
Paolo Abeni
maintainerv2 cover udp: GRO L4 improvements
This series improves the UDP L4 - either 'forward' or 'frag_list' - co-existence with UDP tunnel GRO, allowing the first to take place correctly even for encapsulated UDP traffic.
The first for patches are mostly bugfixes, addressing some GRO edge-cases when both tunnels and L4 are present, enabled and in use.
The next 3 patches avoid unneeded segmentation when UDP GRO traffic traverses in the receive path UDP tunnels.
Finally, some self-tests are included, covering the relevant GRO scenarios.
Even if most patches are actually bugfixes, this series is targeting net-next, as overall it makes available a new feature.
v1 -> v2:
- restrict post segmentation csum fixup to the only the relevant pkts
- use individual 'accept_gso_type' fields instead of whole gso bitmask (Willem)
- use only ipv6 addesses from test range in self-tests (Willem)
- hopefully clarified most individual patches commit messages
Paolo Abeni (8):
udp: fixup csum for GSO receive slow path
udp: skip L4 aggregation for UDP tunnel packets
udp: properly complete L4 GRO over UDP tunnel packet
udp: never accept GSO_FRAGLIST packets
vxlan: allow L4 GRO passthrough
geneve: allow UDP L4 GRO passthrou
bareudp: allow UDP L4 GRO passthrou
selftests: net: add UDP GRO forwarding self-tests
drivers/net/bareudp.c | 1 + drivers/net/geneve.c | 1 + drivers/net/vxlan.c | 1 + include/linux/udp.h | 22 +- include/net/udp.h | 18 ++ net/ipv4/udp.c | 5 + net/ipv4/udp_offload.c | 27 ++- net/ipv6/udp.c | 1 + net/ipv6/udp_offload.c | 3 +- tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/net/udpgro_fwd.sh | 251 ++++++++++++++++++++++ 11 files changed, 318 insertions(+), 13 deletions(-) create mode 100755 tools/testing/selftests/net/udpgro_fwd.sh
Signature · 1 line
2.26.2
Paolo Abeni
maintainerPATCH v2 1/8 udp: fixup csum for GSO receive slow path
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)
they are segmented as part of the rx socket receive operation, and 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.
v1 -> v2:
- restrict the csum update to the packets strictly needing them
- hopefully clarify the commit message and code comments
--- include/net/udp.h | 18 ++++++++++++++++++ net/ipv4/udp.c | 2 ++ net/ipv6/udp.c | 1 + 3 files changed, 21 insertions(+)
include/net/udp.h +18 -0
@@ -515,6 +515,24 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk,return segs; } +static inline void udp_post_segment_fix_csum (struct sk_buff *skb) +{ +/* UDP-lite can't land here - no GRO */ +WARN_ON_ONCE (UDP_SKB_CB (skb)->partial_cov); + +/* UDP packets generated with UDP_SEGMENT and traversing: +* UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) -> UDP tunnel (rx) +* land here with CHECKSUM_NONE. Instead of adding another check +* in the tunnel fastpath, we can force valid csums here: +* packets are locally generated and the GRO engine already validated +* the csum. +* Additionally fixup the UDP CB +*/ +UDP_SKB_CB (skb)->cscov = skb->len; +if (skb->ip_summed ==CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid =1 ; +} +#ifdef CONFIG_BPF_SYSCALL struct sk_psock ;struct proto *udp_bpf_get_proto (struct sock *sk,struct sk_psock *psock);
net/ipv4/udp.c +2 -0
@@ -2178,6 +2178,8 @@ static int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) segs =udp_rcv_segment (sk, skb, true); skb_list_walk_safe(segs, skb, next) {__skb_pull (skb,skb_transport_offset (skb)); + +udp_post_segment_fix_csum (skb); ret =udp_queue_rcv_one_skb (sk, skb);if (ret >0 )ip_protocol_deliver_rcu (dev_net (skb->dev), skb, ret);
net/ipv6/udp.c +1 -0
@@ -749,6 +749,7 @@ static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) skb_list_walk_safe(segs, skb, next) {__skb_pull (skb,skb_transport_offset (skb)); +udp_post_segment_fix_csum (skb); ret =udpv6_queue_rcv_one_skb (sk, skb);if (ret >0 ) ip6_protocol_deliver_rcu(dev_net(skb->dev), skb, ret,
Signature · 1 line
2.26.2
Willem de Bruijn
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 9 lines · Paolo Abeni
When UDP packets generated locally by a socket with
UDP_SEGMENTtraverse the following path:UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) ->
UDP tunnel (rx) -> UDP socket (no UDP_GRO)they are segmented as part of the rx socket receive operation, and present a
CHECKSUM_NONEafter segmentation.
would be good to capture how this happens, as it was not immediately obvious.
Quoted 15 lines
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.
v1 -> v2:
- restrict the csum update to the packets strictly needing them
- hopefully clarify the commit message and code commentsSigned-off-by Paolo Abeni <[email protected]>
include/net/udp.h static inline struct sk_buff *udp_rcv_segment(struct sock *sk, · line 533
Quoted 2 lines
include/net/udp.h +2
-0+if (skb->ip_summed ==CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid =1 ;
Not entirely obvious is that UDP packets arriving on a device with rx checksum offload off, i.e., with CHECKSUM_NONE, are not matched by this test.
I assume that such packets are not coalesced by the GRO layer in the first place. But I can't immediately spot the reason for it..
Paolo Abeni
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 11 lines · Willem de Bruijn
Quoted 8 lines · Paolo Abeni
When UDP packets generated locally by a socket with
UDP_SEGMENTtraverse the following path:UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) ->
UDP tunnel (rx) -> UDP socket (no UDP_GRO)they are segmented as part of the rx socket receive operation, and present a
CHECKSUM_NONEafter segmentation.would be good to capture how this happens, as it was not immediately obvious.
The CHECKSUM_PARTIAL is propagated up to the UDP tunnel processing, where we have:
__iptunnel_pull_header() -> skb_pull_rcsum() ->
skb_postpull_rcsum() -> __skb_postpull_rcsum() and the latter do the conversion.
Quoted 16 lines
Quoted 13 lines
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.
v1 -> v2:
- restrict the csum update to the packets strictly needing them
- hopefully clarify the commit message and code commentsSigned-off-by Paolo Abeni <[email protected]>include/net/udp.h static inline struct sk_buff *udp_rcv_segment(struct sock *sk, · line 533
Quoted 2 lines
include/net/udp.h +2
-0+if (skb->ip_summed ==CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid =1 ;
Quoted 6 lines
Not entirely obvious is that UDP packets arriving on a device with rx checksum offload off, i.e., with
CHECKSUM_NONE, are not matched by this test.I assume that such packets are not coalesced by the GRO layer in the first place. But I can't immediately spot the reason for it..
Packets with CHECKSUM_NONE are actually aggregated by the GRO engine.
Their checksum is validated by:
udp4_gro_receive -> skb_gro_checksum_validate_zero_check()
-> __skb_gro_checksum_validate -> __skb_gro_checksum_validate_complete()
and skb->ip_summed is changed to CHECKSUM_UNNECESSARY by:
__skb_gro_checksum_validate -> skb_gro_incr_csum_unnecessary
-> __skb_incr_checksum_unnecessary()
and finally to CHECKSUM_PARTIAL by:
udp4_gro_complete() -> udp_gro_complete() -> udp_gro_complete_segment()
Do you prefer I resubmit with some more comments, either in the commit message or in the code?
Thanks
Paolo
side note: perf probe here is fooled by skb->ip_summed being a bitfield and does not dump the real value. I had to look at skb-
Quoted 1 line
__pkt_type_offset[0] instead.
Willem de Bruijn
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 12 lines · Paolo Abeni
Quoted 10 lines · Willem de Bruijn
Quoted 8 lines · Paolo Abeni
When UDP packets generated locally by a socket with
UDP_SEGMENTtraverse the following path:UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) ->
UDP tunnel (rx) -> UDP socket (no UDP_GRO)they are segmented as part of the rx socket receive operation, and present a
CHECKSUM_NONEafter segmentation.
Quoted 8 lines
Quoted 1 line
would be good to capture how this happens, as it was not immediately obvious.
The
CHECKSUM_PARTIALis propagated up to the UDP tunnel processing, where we have:__iptunnel_pull_header() -> skb_pull_rcsum() ->
skb_postpull_rcsum()->__skb_postpull_rcsum()and the latter do the conversion.
Please capture this in the commit message.
Quoted 33 lines
Quoted 16 lines
Quoted 13 lines
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.
v1 -> v2:
- restrict the csum update to the packets strictly needing them
- hopefully clarify the commit message and code commentsSigned-off-by Paolo Abeni <[email protected]>include/net/udp.h static inline struct sk_buff *udp_rcv_segment(struct sock *sk, · line 533
Quoted 2 lines
include/net/udp.h +2
-0+if (skb->ip_summed ==CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid =1 ;Quoted 6 lines
Not entirely obvious is that UDP packets arriving on a device with rx checksum offload off, i.e., with
CHECKSUM_NONE, are not matched by this test.I assume that such packets are not coalesced by the GRO layer in the first place. But I can't immediately spot the reason for it..
Packets with
CHECKSUM_NONEare actually aggregated by the GRO engine.Their checksum is validated by:
udp4_gro_receive->skb_gro_checksum_validate_zero_check()-> __skb_gro_checksum_validate -> __skb_gro_checksum_validate_complete()and
skb->ip_summedis changed toCHECKSUM_UNNECESSARYby:
__skb_gro_checksum_validate->skb_gro_incr_csum_unnecessary
Quoted 8 lines
-> __skb_incr_checksum_unnecessary()and finally to
CHECKSUM_PARTIALby:
udp4_gro_complete()->udp_gro_complete()->udp_gro_complete_segment()Do you prefer I resubmit with some more comments, either in the commit message or in the code?
That breaks the checksum-and-copy optimization when delivering to local sockets. I wonder if that is a regression.
Paolo Abeni
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 14 lines · Willem de Bruijn
Quoted 13 lines · Paolo Abeni
Quoted 11 lines · Willem de Bruijn
Quoted 8 lines · Paolo Abeni
When UDP packets generated locally by a socket with
UDP_SEGMENTtraverse the following path:UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) ->
UDP tunnel (rx) -> UDP socket (no UDP_GRO)they are segmented as part of the rx socket receive operation, and present a
CHECKSUM_NONEafter segmentation.would be good to capture how this happens, as it was not immediately obvious.
Quoted 8 lines
Quoted 6 lines
The
CHECKSUM_PARTIALis propagated up to the UDP tunnel processing, where we have:__iptunnel_pull_header() -> skb_pull_rcsum() ->
skb_postpull_rcsum()->__skb_postpull_rcsum()and the latter do the conversion.Please capture this in the commit message.
I will do.
Quoted 37 lines
Quoted 37 lines
Quoted 16 lines
Quoted 13 lines
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.
v1 -> v2:
- restrict the csum update to the packets strictly needing them
- hopefully clarify the commit message and code commentsSigned-off-by Paolo Abeni <[email protected]>include/net/udp.h static inline struct sk_buff *udp_rcv_segment(struct sock *sk, · line 533
Quoted 2 lines
include/net/udp.h +2
-0+if (skb->ip_summed ==CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid =1 ;Quoted 6 lines
Not entirely obvious is that UDP packets arriving on a device with rx checksum offload off, i.e., with
CHECKSUM_NONE, are not matched by this test.I assume that such packets are not coalesced by the GRO layer in the first place. But I can't immediately spot the reason for it..
Packets with
CHECKSUM_NONEare actually aggregated by the GRO engine.Their checksum is validated by:
udp4_gro_receive->skb_gro_checksum_validate_zero_check()-> __skb_gro_checksum_validate -> __skb_gro_checksum_validate_complete()and
skb->ip_summedis changed toCHECKSUM_UNNECESSARYby:
__skb_gro_checksum_validate->skb_gro_incr_csum_unnecessary-> __skb_incr_checksum_unnecessary()and finally to
CHECKSUM_PARTIALby:
Quoted 7 lines
Quoted 4 lines
udp4_gro_complete()->udp_gro_complete()->udp_gro_complete_segment()Do you prefer I resubmit with some more comments, either in the commit message or in the code?
That breaks the checksum-and-copy optimization when delivering to local sockets. I wonder if that is a regression.
The conversion to CHECKSUM_UNNECESSARY happens since commit 573e8fca255a27e3573b51f9b183d62641c47a3d.
Even the conversion to CHECKSUM_PARTIAL happens independently from this series, since commit 6f1c0ea133a6e4a193a7b285efe209664caeea43.
I don't see a regression here ?!?
Thanks!
Paolo
Willem de Bruijn
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 45 lines
Quoted 37 lines
Quoted 37 lines
Quoted 16 lines
Quoted 13 lines
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.
v1 -> v2:
- restrict the csum update to the packets strictly needing them
- hopefully clarify the commit message and code commentsSigned-off-by Paolo Abeni <[email protected]>include/net/udp.h static inline struct sk_buff *udp_rcv_segment(struct sock *sk, · line 533
Quoted 2 lines
include/net/udp.h +2
-0+if (skb->ip_summed ==CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid =1 ;Quoted 6 lines
Not entirely obvious is that UDP packets arriving on a device with rx checksum offload off, i.e., with
CHECKSUM_NONE, are not matched by this test.I assume that such packets are not coalesced by the GRO layer in the first place. But I can't immediately spot the reason for it..
Packets with
CHECKSUM_NONEare actually aggregated by the GRO engine.Their checksum is validated by:
udp4_gro_receive->skb_gro_checksum_validate_zero_check()-> __skb_gro_checksum_validate -> __skb_gro_checksum_validate_complete()and
skb->ip_summedis changed toCHECKSUM_UNNECESSARYby:
__skb_gro_checksum_validate->skb_gro_incr_csum_unnecessary-> __skb_incr_checksum_unnecessary()and finally to
CHECKSUM_PARTIALby:Quoted 7 lines
Quoted 4 lines
udp4_gro_complete()->udp_gro_complete()->udp_gro_complete_segment()Do you prefer I resubmit with some more comments, either in the commit message or in the code?
That breaks the checksum-and-copy optimization when delivering to local sockets. I wonder if that is a regression.
Quoted 7 lines
The conversion to
CHECKSUM_UNNECESSARYhappens since commit573e8fca255a27e3573b51f9b183d62641c47a3d.Even the conversion to
CHECKSUM_PARTIALhappens independently from this series, since commit6f1c0ea133a6e4a193a7b285efe209664caeea43.I don't see a regression here ?!?
I mean that UDP packets with local destination socket and no tunnels that arrive with CHECKSUM_NONE normally benefit from the checksum-and-copy optimization in recvmsg() when copying to user.
If those packets are now checksummed during GRO, that voids that optimization, and the packet payload is now touched twice.
Paolo Abeni
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 9 lines · Willem de Bruijn
Quoted 9 lines
Quoted 2 lines
That breaks the checksum-and-copy optimization when delivering to local sockets. I wonder if that is a regression.
The conversion to
CHECKSUM_UNNECESSARYhappens since commit573e8fca255a27e3573b51f9b183d62641c47a3d.Even the conversion to
CHECKSUM_PARTIALhappens independently from this series, since commit6f1c0ea133a6e4a193a7b285efe209664caeea43.
Quoted 8 lines
Quoted 1 line
I don't see a regression here ?!?
I mean that UDP packets with local destination socket and no tunnels that arrive with
CHECKSUM_NONEnormally benefit from the checksum-and-copy optimization inrecvmsg()when copying to user.If those packets are now checksummed during GRO, that voids that optimization, and the packet payload is now touched twice.
The 'now' part confuses me. Nothing in this patch or this series changes the processing of CHECKSUM_NONE UDP packets with no tunnel.
I do see checksum validation in the GRO engine for CHECKSUM_NONE UDP packet prior to this series.
I *think* the checksum-and-copy optimization is lost since 573e8fca255a27e3573b51f9b183d62641c47a3d.
Regards,
Paolo
Willem de Bruijn
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 17 lines · Paolo Abeni
Quoted 15 lines · Willem de Bruijn
Quoted 10 lines
Quoted 2 lines
That breaks the checksum-and-copy optimization when delivering to local sockets. I wonder if that is a regression.
The conversion to
CHECKSUM_UNNECESSARYhappens since commit573e8fca255a27e3573b51f9b183d62641c47a3d.Even the conversion to
CHECKSUM_PARTIALhappens independently from this series, since commit6f1c0ea133a6e4a193a7b285efe209664caeea43.I don't see a regression here ?!?
I mean that UDP packets with local destination socket and no tunnels that arrive with
CHECKSUM_NONEnormally benefit from the checksum-and-copy optimization inrecvmsg()when copying to user.
Quoted 5 lines
Quoted 2 lines
If those packets are now checksummed during GRO, that voids that optimization, and the packet payload is now touched twice.
The 'now' part confuses me. Nothing in this patch or this series changes the processing of
CHECKSUM_NONEUDP packets with no tunnel.
Agreed. I did not mean to imply that this patch changes that. I was responding to
Quoted 9 lines
Quoted 9 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (skb->ip_summed == CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid = 1;Not entirely obvious is that UDP packets arriving on a device with rx checksum offload off, i.e., with
CHECKSUM_NONE, are not matched by this test.I assume that such packets are not coalesced by the GRO layer in the first place. But I can't immediately spot the reason for it..
As you point out, such packets will already have had their checksum verified at this point, so this branch only matches tunneled packets. That point is just not immediately obvious from the code.
Quoted 5 lines
I do see checksum validation in the GRO engine for
CHECKSUM_NONEUDP packet prior to this series.I *think* the checksum-and-copy optimization is lost since
573e8fca255a27e3573b51f9b183d62641c47a3d.
Wouldn't this have been introduced with UDP_GRO?
Paolo Abeni
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 9 lines · Willem de Bruijn
Quoted 8 lines · Paolo Abeni
Quoted 7 lines · Willem de Bruijn
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (skb->ip_summed == CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid = 1;Not entirely obvious is that UDP packets arriving on a device with rx checksum offload off, i.e., with
CHECKSUM_NONE, are not matched by this test.
Quoted 6 lines
Quoted 2 lines
Quoted 2 lines
I assume that such packets are not coalesced by the GRO layer in the first place. But I can't immediately spot the reason for it..
As you point out, such packets will already have had their checksum verified at this point, so this branch only matches tunneled packets. That point is just not immediately obvious from the code.
I understand is a matter of comment clarity ?!?
I'll rewrite the related code comment - in udp_post_segment_fix_csum()
- as:
/* UDP packets generated with UDP_SEGMENT and traversing:
*
* UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) -> UDP tunnel (rx) *
* land here with CHECKSUM_NONE, because __iptunnel_pull_header() converts
* CHECKSUM_PARTIAL into NONE.
* SKB_GSO_UDP_L4 or SKB_GSO_FRAGLIST packets with no UDP tunnel will land
* here with valid checksum, as the GRO engine validates the UDP csum
* before the aggregation and nobody strips such info in between.
* Instead of adding another check in the tunnel fastpath, we can force
* a valid csum here.
* Additionally fixup the UDP CB.
*/
Would that be clear enough?
Quoted 7 lines
Quoted 5 lines
I do see checksum validation in the GRO engine for
CHECKSUM_NONEUDP packet prior to this series.I *think* the checksum-and-copy optimization is lost since
573e8fca255a27e3573b51f9b183d62641c47a3d.Wouldn't this have been introduced with
UDP_GRO?
Uhmm.... looks like the checksum-and-copy optimization has been lost and recovered a few times. I think the last one
with 9fd1ff5d2ac7181844735806b0a703c942365291, which move the csum validation before the static branch on udp_encap_needed_key.
Can we agree re-introducing the optimization is independent from this series?
Thanks!
Paolo
Willem de Bruijn
maintainerRe: [PATCH net-next v2 1/8] udp: fixup csum for GSO receive slow path
Quoted 37 lines · Paolo Abeni
Quoted 9 lines · Willem de Bruijn
Quoted 8 lines · Paolo Abeni
Quoted 7 lines · Willem de Bruijn
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (skb->ip_summed == CHECKSUM_NONE && !skb->csum_valid) + skb->csum_valid = 1;Not entirely obvious is that UDP packets arriving on a device with rx checksum offload off, i.e., with
CHECKSUM_NONE, are not matched by this test.Quoted 6 lines
Quoted 2 lines
Quoted 2 lines
I assume that such packets are not coalesced by the GRO layer in the first place. But I can't immediately spot the reason for it..
As you point out, such packets will already have had their checksum verified at this point, so this branch only matches tunneled packets. That point is just not immediately obvious from the code.
I understand is a matter of comment clarity ?!?
I'll rewrite the related code comment - in
udp_post_segment_fix_csum()
- as:/* UDP packets generated with
UDP_SEGMENTand traversing:
*
* UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) -> UDP tunnel (rx) *
* land here withCHECKSUM_NONE, because__iptunnel_pull_header()converts
*CHECKSUM_PARTIALinto NONE.
*SKB_GSO_UDP_L4orSKB_GSO_FRAGLISTpackets with no UDP tunnel will land
* here with valid checksum, as the GRO engine validates the UDP csum
* before the aggregation and nobody strips such info in between.
* Instead of adding another check in the tunnel fastpath, we can force
* a valid csum here.
* Additionally fixup the UDP CB.
*/
Quoted 1 line
Would that be clear enough?
Definitely. Thanks!
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
I do see checksum validation in the GRO engine for
CHECKSUM_NONEUDP packet prior to this series.I *think* the checksum-and-copy optimization is lost since
573e8fca255a27e3573b51f9b183d62641c47a3d.Wouldn't this have been introduced with
UDP_GRO?
Quoted 7 lines
Uhmm.... looks like the checksum-and-copy optimization has been lost and recovered a few times. I think the last one
with9fd1ff5d2ac7181844735806b0a703c942365291, which move the csum validation before the static branch onudp_encap_needed_key.Can we agree re-introducing the optimization is independent from this series?
Yep :)
Quoted 5 lines
Thanks!
Paolo
Paolo Abeni
maintainerPATCH v2 2/8 udp: skip L4 aggregation for UDP tunnel packets
In reply to Paolo AbeniIf 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, the latter is a very thin corner case and covering it would add quite a bit of complexity.
v1 -> v2:
- hopefully clarify the commit message
--- net/ipv4/udp_offload.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
net/ipv4/udp_offload.c +11 -8
@@ -515,21 +515,24 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,unsigned int off =skb_gro_offset (skb);int flush =1 ; +/* we can do L4 aggregation only if the packet can't land in a tunnel +* otherwise we could corrupt the inner stream +*/ NAPI_GRO_CB (skb)->is_flist =0 ; -if (skb->dev->features &NETIF_F_GRO_FRAGLIST ) -NAPI_GRO_CB (skb)->is_flist = sk ? !udp_sk (sk)->gro_enabled:1 ; +if (!sk || !udp_sk (sk)->gro_receive) { +if (skb->dev->features &NETIF_F_GRO_FRAGLIST ) +NAPI_GRO_CB (skb)->is_flist = sk ? !udp_sk (sk)->gro_enabled :1 ; -if ((!sk && (skb->dev->features &NETIF_F_GRO_UDP_FWD )) || - (sk &&udp_sk (sk)->gro_enabled) ||NAPI_GRO_CB (skb)->is_flist) { - pp =call_gro_receive (udp_gro_receive_segment, head, skb); +if ((!sk && (skb->dev->features &NETIF_F_GRO_UDP_FWD )) || + (sk &&udp_sk (sk)->gro_enabled) ||NAPI_GRO_CB (skb)->is_flist) + pp =call_gro_receive (udp_gro_receive_segment, head, skb);return pp; } -if (!sk ||NAPI_GRO_CB (skb)->encap_mark || +if (NAPI_GRO_CB (skb)->encap_mark || (uh->check && skb->ip_summed !=CHECKSUM_PARTIAL &&NAPI_GRO_CB (skb)->csum_cnt ==0 && - !NAPI_GRO_CB (skb)->csum_valid) || - !udp_sk (sk)->gro_receive) + !NAPI_GRO_CB (skb)->csum_valid)) goto out;/* mark that this skb passed once through the tunnel gro layer */
Signature · 1 line
2.26.2
Re: [PATCH net-next v2 2/8] udp: skip L4 aggregation for UDP tunnel packets
Quoted 24 lines · Paolo Abeni
If
NETIF_F_GRO_FRAGLISTorNETIF_F_GRO_UDP_FWDare enabled, and there are UDP tunnels available in the system,udp_gro_receive()could end-up doing L4 aggregation (eitherSKB_GSO_UDP_L4orSKB_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_L4andSKB_GSO_FRAGLISTcode path if the current packet could land in a UDP tunnel, and letudp_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, the latter is a very thin corner case and covering it would add quite a bit of complexity.
Quoted 6 lines
v1 -> v2:
- hopefully clarify the commit messageFixes 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")Fixes 36707061d6ba ("udp: allow forwarding of plain (non-fraglisted) UDP GRO packets")Signed-off-by Paolo Abeni <[email protected]>
Key is that udp tunnel GRO must take precedence over transport GRO, but the way the code is structured, the latter is tried first.
Paolo Abeni
maintainerPATCH v2 3/8 udp: properly complete L4 GRO over UDP tunnel packet
In reply to Paolo AbeniAfter 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
--- net/ipv4/udp_offload.c | 8 +++++++- net/ipv6/udp_offload.c | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-)
net/ipv4/udp_offload.c +7 -1
@@ -642,6 +642,11 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff,skb_shinfo (skb)->gso_type = uh->check ?SKB_GSO_UDP_TUNNEL_CSUM :SKB_GSO_UDP_TUNNEL ; +/* clear the encap mark, so that inner frag_list gro_complete +* can take place +*/ +NAPI_GRO_CB (skb)->encap_mark =0 ; +/* Set encapsulation before calling into inner gro_complete() * functions to make them set up the inner offsets. */
@@ -665,7 +670,8 @@ INDIRECT_CALLABLE_SCOPE int udp4_gro_complete(struct sk_buff *skb, int nhoff)const struct iphdr *iph =ip_hdr (skb);struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); -if (NAPI_GRO_CB (skb)->is_flist) { +/* do fraglist only if there is no outer UDP encap (or we already processed it) */ +if (NAPI_GRO_CB (skb)->is_flist && !NAPI_GRO_CB (skb)->encap_mark) { uh->len =htons (skb->len - nhoff);skb_shinfo (skb)->gso_type |= (SKB_GSO_FRAGLIST |SKB_GSO_UDP_L4 );
net/ipv6/udp_offload.c +2 -1
@@ -163,7 +163,8 @@ INDIRECT_CALLABLE_SCOPE int udp6_gro_complete(struct sk_buff *skb, int nhoff)const struct ipv6hdr *ipv6h =ipv6_hdr (skb);struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); -if (NAPI_GRO_CB (skb)->is_flist) { +/* do fraglist only if there is no outer UDP encap (or we already processed it) */ +if (NAPI_GRO_CB (skb)->is_flist && !NAPI_GRO_CB (skb)->encap_mark) { uh->len =htons (skb->len - nhoff);skb_shinfo (skb)->gso_type |= (SKB_GSO_FRAGLIST |SKB_GSO_UDP_L4 );
Signature · 1 line
2.26.2
Re: [PATCH net-next v2 3/8] udp: properly complete L4 GRO over UDP tunnel packet
Quoted 18 lines · Paolo Abeni
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_flistbranch immediately, even though that is only correct on the second call, asGSO_FRAGLISTis 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 inudp_gro_complete()so that we can enter the frag list path on the next round, for the inner header.
Quoted 4 lines
v1 -> v2:
- hopefully clarified the commit messageSigned-off-by Paolo Abeni <[email protected]>
Paolo Abeni
maintainerPATCH v2 4/8 udp: never accept GSO_FRAGLIST packets
In reply to Paolo AbeniCurrently 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)
--- include/linux/udp.h | 16 +++++++++++++--- net/ipv4/udp.c | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-)
include/linux/udp.h +13 -3
@@ -51,7 +51,9 @@ struct udp_sock {* different encapsulation layer set * this */ - gro_enabled:1 ;/* Can accept GRO packets */ + gro_enabled:1, /* Request GRO aggregation */ + accept_udp_l4:1, + accept_udp_fraglist:1;/* * Following member retains the information to create a UDP header * when the socket is uncorked.
@@ -131,8 +133,16 @@ static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk,static inline bool udp_unexpected_gso (struct sock *sk,struct sk_buff *skb) { -return !udp_sk (sk)->gro_enabled &&skb_is_gso (skb) && -skb_shinfo (skb)->gso_type &SKB_GSO_UDP_L4 ; +if (!skb_is_gso (skb)) +return false; + +if (skb_shinfo (skb)->gso_type &SKB_GSO_UDP_L4 && !udp_sk (sk)->accept_udp_l4) +return true; + +if (skb_shinfo (skb)->gso_type &SKB_GSO_FRAGLIST && !udp_sk (sk)->accept_udp_fraglist) +return true; + +return false; }#define udp_portaddr_for_each_entry (__sk, list) \
net/ipv4/udp.c +3 -0
@@ -2666,9 +2666,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,case UDP_GRO :lock_sock (sk); + +/* when enabling GRO, accept the related GSO packet type */ if (valbool)udp_tunnel_encap_enable (sk->sk_socket); up->gro_enabled = valbool; + up->accept_udp_l4 = valbool;release_sock (sk);break ;
Signature · 1 line
2.26.2
Willem de Bruijn
maintainerRe: [PATCH net-next v2 4/8] udp: never accept GSO_FRAGLIST packets
Quoted 9 lines · Paolo Abeni
Currently the UDP protocol delivers
GSO_FRAGLISTpackets 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_L4orGSO_FRAGLISTpackets. Additionally updatesudp_unexpected_gso()accordingly.
Quoted 8 lines
UDP sockets enabling
UDP_GROstil keepaccept_udp_fraglistzeroed.v1 -> v2:
- use 2 bits instead of a whole GSO bitmask (Willem)Fixes 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")Signed-off-by Paolo Abeni <[email protected]>
This looks good to me in principle, thanks for the revision.
I hadn't fully appreciated that gro_enabled implies accept_udp_l4, but not necessarily vice versa.
It is equivalent to (accept_udp_l4 && !up->gro_receive), right?
Could the extra bit be avoided with
"
+ /* Prefer fraglist GRO unless target is a socket with UDP_GRO,
+ * which requires all but last segments to be of same gso_size,
passed in cmsg */
if (skb->dev->features & NETIF_F_GRO_FRAGLIST)
- NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled: 1;
+ NAPI_GRO_CB(skb)->is_flist = sk ?
(!udp_sk(sk)->gro_enabled || udp_sk(sk)->accept_udp_fraglist) : 1;
+ /* Apply transport layer GRO if forwarding is enabled or the
flow lands at a local socket */
if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) ||
(sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) ||
NAPI_GRO_CB(skb)->is_flist) {
pp = call_gro_receive(udp_gro_receive_segment, head, skb);
return pp;
}+ /* Continue with tunnel GRO */
"
.. not that the extra bit matters a lot. And these two conditions with gro_enabled are not very obvious.
Just a thought.
Paolo Abeni
maintainerRe: [PATCH net-next v2 4/8] udp: never accept GSO_FRAGLIST packets
Quoted 18 lines · Willem de Bruijn
Quoted 8 lines · Paolo Abeni
Currently the UDP protocol delivers
GSO_FRAGLISTpackets 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_L4orGSO_FRAGLISTpackets. Additionally updatesudp_unexpected_gso()accordingly.Quoted 8 lines
UDP sockets enabling
UDP_GROstil keepaccept_udp_fraglistzeroed.v1 -> v2:
- use 2 bits instead of a whole GSO bitmask (Willem)Fixes 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")Signed-off-by Paolo Abeni <[email protected]>
Quoted 6 lines
This looks good to me in principle, thanks for the revision.
I hadn't fully appreciated that
gro_enabledimpliesaccept_udp_l4, but not necessarily vice versa.It is equivalent to (
accept_udp_l4&& !up->gro_receive), right?
In this series, yes.
Quoted 10 lines
Could the extra bit be avoided with
"
(quoted diff) +2
-0+ /* Prefer fraglist GRO unless target is a socket with UDP_GRO, + * which requires all but last segments to be of same gso_size,passed in cmsg */
if (skb->dev->features & NETIF_F_GRO_FRAGLIST)(quoted diff) +1
-1- NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled: 1; + NAPI_GRO_CB(skb)->is_flist = sk ?(!udp_sk(sk)->gro_enabled || udp_sk(sk)->accept_udp_fraglist) : 1;
This is not ovious at all to me.
Quoted 9 lines
+ /* Apply transport layer GRO if forwarding is enabled or the
flow lands at a local socket */if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) || (sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) || NAPI_GRO_CB(skb)->is_flist) { pp = call_gro_receive(udp_gro_receive_segment, head, skb); return pp; }
Quoted 7 lines
+ /* Continue with tunnel GRO */
".. not that the extra bit matters a lot. And these two conditions with
gro_enabledare not very obvious.Just a thought.
Overall looks more complex to me. I would keep the extra bit, unless you have strong opinion.
Side note: I was wondering about a follow-up to simplify the condition:
if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) ||
(sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) || NAPI_GRO_CB(skb)->is_flist) {Since UDP sockets could process (segmenting as needed) unexpected GSO packets, we could always do 'NETIF_F_GRO_UDP_FWD', when enabled on the device level. The above becomes:
if (skb->dev->features & NETIF_F_GRO_UDP_FWD) ||
(sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) ||
NAPI_GRO_CB(skb)->is_flist) {which is hopefully more clear (and simpler). As said, non for this series anyhow.
Thanks,
Paolo
Willem de Bruijn
maintainerRe: [PATCH net-next v2 4/8] udp: never accept GSO_FRAGLIST packets
Quoted 54 lines · Paolo Abeni
Quoted 18 lines · Willem de Bruijn
Quoted 8 lines · Paolo Abeni
Currently the UDP protocol delivers
GSO_FRAGLISTpackets 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_L4orGSO_FRAGLISTpackets. Additionally updatesudp_unexpected_gso()accordingly.Quoted 8 lines
UDP sockets enabling
UDP_GROstil keepaccept_udp_fraglistzeroed.v1 -> v2:
- use 2 bits instead of a whole GSO bitmask (Willem)Fixes 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")Signed-off-by Paolo Abeni <[email protected]>Quoted 6 lines
This looks good to me in principle, thanks for the revision.
I hadn't fully appreciated that
gro_enabledimpliesaccept_udp_l4, but not necessarily vice versa.It is equivalent to (
accept_udp_l4&& !up->gro_receive), right?In this series, yes.
Quoted 10 lines
Could the extra bit be avoided with
"
(quoted diff) +2
-0+ /* Prefer fraglist GRO unless target is a socket with UDP_GRO, + * which requires all but last segments to be of same gso_size,passed in cmsg */
if (skb->dev->features & NETIF_F_GRO_FRAGLIST)(quoted diff) +1
-1- NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled: 1; + NAPI_GRO_CB(skb)->is_flist = sk ?(!udp_sk(sk)->gro_enabled || udp_sk(sk)->accept_udp_fraglist) : 1;
This is not ovious at all to me.
Quoted 12 lines
+ /* Apply transport layer GRO if forwarding is enabled or the
flow lands at a local socket */if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) || (sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) || NAPI_GRO_CB(skb)->is_flist) { pp = call_gro_receive(udp_gro_receive_segment, head, skb); return pp; }+ /* Continue with tunnel GRO */
"
Quoted 7 lines
Quoted 4 lines
.. not that the extra bit matters a lot. And these two conditions with
gro_enabledare not very obvious.Just a thought.
Overall looks more complex to me. I would keep the extra bit, unless you have strong opinion.
Sounds good.
Quoted 9 lines
Side note: I was wondering about a follow-up to simplify the condition:
if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) || (sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) || NAPI_GRO_CB(skb)->is_flist) {Since UDP sockets could process (segmenting as needed) unexpected GSO packets, we could always do '
NETIF_F_GRO_UDP_FWD', when enabled on the device level. The above becomes:
Quoted 6 lines
if (skb->dev->features & NETIF_F_GRO_UDP_FWD) || (sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) || NAPI_GRO_CB(skb)->is_flist) {which is hopefully more clear (and simpler). As said, non for this series anyhow.
UDP sockets can segment, but it is expensive. In this case I think the simplification is not worth the possible regression.
Paolo Abeni
maintainerRe: [PATCH net-next v2 4/8] udp: never accept GSO_FRAGLIST packets
Quoted 77 lines · Willem de Bruijn
Quoted 53 lines · Paolo Abeni
Quoted 18 lines · Willem de Bruijn
Quoted 8 lines · Paolo Abeni
Currently the UDP protocol delivers
GSO_FRAGLISTpackets 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_L4orGSO_FRAGLISTpackets. Additionally updatesudp_unexpected_gso()accordingly.Quoted 8 lines
UDP sockets enabling
UDP_GROstil keepaccept_udp_fraglistzeroed.v1 -> v2:
- use 2 bits instead of a whole GSO bitmask (Willem)Fixes 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")Signed-off-by Paolo Abeni <[email protected]>Quoted 6 lines
This looks good to me in principle, thanks for the revision.
I hadn't fully appreciated that
gro_enabledimpliesaccept_udp_l4, but not necessarily vice versa.It is equivalent to (
accept_udp_l4&& !up->gro_receive), right?In this series, yes.
Quoted 10 lines
Could the extra bit be avoided with
"
(quoted diff) +2
-0+ /* Prefer fraglist GRO unless target is a socket with UDP_GRO, + * which requires all but last segments to be of same gso_size,passed in cmsg */
if (skb->dev->features & NETIF_F_GRO_FRAGLIST)(quoted diff) +1
-1- NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled: 1; + NAPI_GRO_CB(skb)->is_flist = sk ?(!udp_sk(sk)->gro_enabled || udp_sk(sk)->accept_udp_fraglist) : 1;
This is not ovious at all to me.
Quoted 12 lines
+ /* Apply transport layer GRO if forwarding is enabled or the
flow lands at a local socket */if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) || (sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) || NAPI_GRO_CB(skb)->is_flist) { pp = call_gro_receive(udp_gro_receive_segment, head, skb); return pp; }+ /* Continue with tunnel GRO */
"Quoted 7 lines
Quoted 4 lines
.. not that the extra bit matters a lot. And these two conditions with
gro_enabledare not very obvious.Just a thought.
Overall looks more complex to me. I would keep the extra bit, unless you have strong opinion.
Sounds good.
Quoted 13 lines
Side note: I was wondering about a follow-up to simplify the condition:
if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) || (sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) || NAPI_GRO_CB(skb)->is_flist) {Since UDP sockets could process (segmenting as needed) unexpected GSO packets, we could always do '
NETIF_F_GRO_UDP_FWD', when enabled on the device level. The above becomes:if (skb->dev->features & NETIF_F_GRO_UDP_FWD) || (sk && udp_sk(sk)->gro_enabled && !up->encap_rcv) || NAPI_GRO_CB(skb)->is_flist) {
Quoted 5 lines
Quoted 2 lines
which is hopefully more clear (and simpler). As said, non for this series anyhow.
UDP sockets can segment, but it is expensive. In this case I think the simplification is not worth the possible regression.
No strong opinion here, I will not do the thing mentioned above.
Thanks!
Paolo
Paolo Abeni
maintainerPATCH v2 5/8 vxlan: allow L4 GRO passthrough
In reply to Paolo AbeniWhen 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
--- drivers/net/vxlan.c | 1 + include/linux/udp.h | 6 ++++++ 2 files changed, 7 insertions(+)
drivers/net/vxlan.c +1 -0
@@ -3484,6 +3484,7 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,if (err <0 )return ERR_PTR (err); +udp_allow_gso (sock->sk);return sock; }
include/linux/udp.h +6 -0
@@ -145,6 +145,12 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb)return false; } +static inline void udp_allow_gso (struct sock *sk) +{ +udp_sk (sk)->accept_udp_l4 =1 ; +udp_sk (sk)->accept_udp_fraglist =1 ; +} +#define udp_portaddr_for_each_entry (__sk, list) \ hlist_for_each_entry(__sk, list, __sk_common.skc_portaddr_node)
Signature · 1 line
2.26.2
Paolo Abeni
maintainerPATCH v2 6/8 geneve: allow UDP L4 GRO passthrou
In reply to Paolo AbeniSimilar to the previous commit, let even geneve
passthrou the L4 GRO packets
--- drivers/net/geneve.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/geneve.c +1 -0
@@ -461,6 +461,7 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6,if (err <0 )return ERR_PTR (err); +udp_allow_gso (sock->sk);return sock; }
Signature · 1 line
2.26.2
Paolo Abeni
maintainerPATCH v2 7/8 bareudp: allow UDP L4 GRO passthrou
In reply to Paolo AbeniSimilar to the previous commit, let even geneve
passthrou the L4 GRO packets
--- drivers/net/bareudp.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/bareudp.c +1 -0
@@ -218,6 +218,7 @@ static struct socket *bareudp_create_sock(struct net *net, __be16 port)if (err <0 )return ERR_PTR (err); +udp_allow_gso (sock->sk);return sock; }
Signature · 1 line
2.26.2
Paolo Abeni
maintainerPATCH v2 8/8 selftests: net: add UDP GRO forwarding self-tests
In reply to Paolo AbeniCreate a bunch of virtual topologies and verify that NETIF_F_GRO_FRAGLIST or NETIF_F_GRO_UDP_FWD-enabled devices aggregate the ingress packets as expected. Additionally check that the aggregate packets are segmented correctly when landing on a socket
Also test SKB_GSO_FRAGLIST and SKB_GSO_UDP_L4 aggregation on top of UDP tunnel (vxlan)
v1 -> v2:
- hopefully clarify the commit message
- moved the overlay network ipv6 range into the 'documentation' reserved range (Willem)
--- tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/net/udpgro_fwd.sh | 251 ++++++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100755 tools/testing/selftests/net/udpgro_fwd.sh
tools/testing/selftests/net/Makefile +1 -0
@@ -23,6 +23,7 @@ TEST_PROGS += drop_monitor_tests.sh TEST_PROGS += vrf_route_leaking.sh TEST_PROGS += bareudp.sh TEST_PROGS += unicast_extensions.sh +TEST_PROGS += udpgro_fwd.sh TEST_PROGS_EXTENDED := in_netns.sh TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
tools/testing/selftests/net/udpgro_fwd.sh new file +251 -0
251 lines not on this page · raw message
Signature · 1 line
2.26.2