netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 1/1] net: openvswitch: fix csum updates for MPLS actions
@ 2019-06-27 13:37 John Hurley
  2019-06-30  0:33 ` Pravin Shelar
  2019-07-01  1:45 ` David Miller
  0 siblings, 2 replies; 3+ messages in thread
From: John Hurley @ 2019-06-27 13:37 UTC (permalink / raw)
  To: netdev
  Cc: davem, pshelar, simon.horman, jakub.kicinski, oss-drivers, John Hurley

Skbs may have their checksum value populated by HW. If this is a checksum
calculated over the entire packet then the CHECKSUM_COMPLETE field is
marked. Changes to the data pointer on the skb throughout the network
stack still try to maintain this complete csum value if it is required
through functions such as skb_postpush_rcsum.

The MPLS actions in Open vSwitch modify a CHECKSUM_COMPLETE value when
changes are made to packet data without a push or a pull. This occurs when
the ethertype of the MAC header is changed or when MPLS lse fields are
modified.

The modification is carried out using the csum_partial function to get the
csum of a buffer and add it into the larger checksum. The buffer is an
inversion of the data to be removed followed by the new data. Because the
csum is calculated over 16 bits and these values align with 16 bits, the
effect is the removal of the old value from the CHECKSUM_COMPLETE and
addition of the new value.

However, the csum fed into the function and the outcome of the
calculation are also inverted. This would only make sense if it was the
new value rather than the old that was inverted in the input buffer.

Fix the issue by removing the bit inverts in the csum_partial calculation.

The bug was verified and the fix tested by comparing the folded value of
the updated CHECKSUM_COMPLETE value with the folded value of a full
software checksum calculation (reset skb->csum to 0 and run
skb_checksum_complete(skb)). Prior to the fix the outcomes differed but
after they produce the same result.

Fixes: 25cd9ba0abc0 ("openvswitch: Add basic MPLS support to kernel")
Fixes: bc7cc5999fd3 ("openvswitch: update checksum in {push,pop}_mpls")
Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
 net/openvswitch/actions.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 151518d..bd13146 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -166,8 +166,7 @@ static void update_ethertype(struct sk_buff *skb, struct ethhdr *hdr,
 	if (skb->ip_summed == CHECKSUM_COMPLETE) {
 		__be16 diff[] = { ~(hdr->h_proto), ethertype };
 
-		skb->csum = ~csum_partial((char *)diff, sizeof(diff),
-					~skb->csum);
+		skb->csum = csum_partial((char *)diff, sizeof(diff), skb->csum);
 	}
 
 	hdr->h_proto = ethertype;
@@ -259,8 +258,7 @@ static int set_mpls(struct sk_buff *skb, struct sw_flow_key *flow_key,
 	if (skb->ip_summed == CHECKSUM_COMPLETE) {
 		__be32 diff[] = { ~(stack->label_stack_entry), lse };
 
-		skb->csum = ~csum_partial((char *)diff, sizeof(diff),
-					  ~skb->csum);
+		skb->csum = csum_partial((char *)diff, sizeof(diff), skb->csum);
 	}
 
 	stack->label_stack_entry = lse;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH net 1/1] net: openvswitch: fix csum updates for MPLS actions
  2019-06-27 13:37 [PATCH net 1/1] net: openvswitch: fix csum updates for MPLS actions John Hurley
@ 2019-06-30  0:33 ` Pravin Shelar
  2019-07-01  1:45 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: Pravin Shelar @ 2019-06-30  0:33 UTC (permalink / raw)
  To: John Hurley
  Cc: Linux Kernel Network Developers, David S. Miller, Simon Horman,
	Jakub Kicinski, oss-drivers

On Thu, Jun 27, 2019 at 6:37 AM John Hurley <john.hurley@netronome.com> wrote:
>
> Skbs may have their checksum value populated by HW. If this is a checksum
> calculated over the entire packet then the CHECKSUM_COMPLETE field is
> marked. Changes to the data pointer on the skb throughout the network
> stack still try to maintain this complete csum value if it is required
> through functions such as skb_postpush_rcsum.
>
> The MPLS actions in Open vSwitch modify a CHECKSUM_COMPLETE value when
> changes are made to packet data without a push or a pull. This occurs when
> the ethertype of the MAC header is changed or when MPLS lse fields are
> modified.
>
> The modification is carried out using the csum_partial function to get the
> csum of a buffer and add it into the larger checksum. The buffer is an
> inversion of the data to be removed followed by the new data. Because the
> csum is calculated over 16 bits and these values align with 16 bits, the
> effect is the removal of the old value from the CHECKSUM_COMPLETE and
> addition of the new value.
>
> However, the csum fed into the function and the outcome of the
> calculation are also inverted. This would only make sense if it was the
> new value rather than the old that was inverted in the input buffer.
>
> Fix the issue by removing the bit inverts in the csum_partial calculation.
>
> The bug was verified and the fix tested by comparing the folded value of
> the updated CHECKSUM_COMPLETE value with the folded value of a full
> software checksum calculation (reset skb->csum to 0 and run
> skb_checksum_complete(skb)). Prior to the fix the outcomes differed but
> after they produce the same result.
>
> Fixes: 25cd9ba0abc0 ("openvswitch: Add basic MPLS support to kernel")
> Fixes: bc7cc5999fd3 ("openvswitch: update checksum in {push,pop}_mpls")
> Signed-off-by: John Hurley <john.hurley@netronome.com>
> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> Reviewed-by: Simon Horman <simon.horman@netronome.com>
> ---

Thanks for fixing it.
Acked-by: Pravin B Shelar <pshelar@ovn.org>

>  net/openvswitch/actions.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> index 151518d..bd13146 100644
> --- a/net/openvswitch/actions.c
> +++ b/net/openvswitch/actions.c
> @@ -166,8 +166,7 @@ static void update_ethertype(struct sk_buff *skb, struct ethhdr *hdr,
>         if (skb->ip_summed == CHECKSUM_COMPLETE) {
>                 __be16 diff[] = { ~(hdr->h_proto), ethertype };
>
> -               skb->csum = ~csum_partial((char *)diff, sizeof(diff),
> -                                       ~skb->csum);
> +               skb->csum = csum_partial((char *)diff, sizeof(diff), skb->csum);
>         }
>
>         hdr->h_proto = ethertype;
> @@ -259,8 +258,7 @@ static int set_mpls(struct sk_buff *skb, struct sw_flow_key *flow_key,
>         if (skb->ip_summed == CHECKSUM_COMPLETE) {
>                 __be32 diff[] = { ~(stack->label_stack_entry), lse };
>
> -               skb->csum = ~csum_partial((char *)diff, sizeof(diff),
> -                                         ~skb->csum);
> +               skb->csum = csum_partial((char *)diff, sizeof(diff), skb->csum);
>         }
>
>         stack->label_stack_entry = lse;
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net 1/1] net: openvswitch: fix csum updates for MPLS actions
  2019-06-27 13:37 [PATCH net 1/1] net: openvswitch: fix csum updates for MPLS actions John Hurley
  2019-06-30  0:33 ` Pravin Shelar
@ 2019-07-01  1:45 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2019-07-01  1:45 UTC (permalink / raw)
  To: john.hurley; +Cc: netdev, pshelar, simon.horman, jakub.kicinski, oss-drivers

From: John Hurley <john.hurley@netronome.com>
Date: Thu, 27 Jun 2019 14:37:30 +0100

> Skbs may have their checksum value populated by HW. If this is a checksum
> calculated over the entire packet then the CHECKSUM_COMPLETE field is
> marked. Changes to the data pointer on the skb throughout the network
> stack still try to maintain this complete csum value if it is required
> through functions such as skb_postpush_rcsum.
> 
> The MPLS actions in Open vSwitch modify a CHECKSUM_COMPLETE value when
> changes are made to packet data without a push or a pull. This occurs when
> the ethertype of the MAC header is changed or when MPLS lse fields are
> modified.
> 
> The modification is carried out using the csum_partial function to get the
> csum of a buffer and add it into the larger checksum. The buffer is an
> inversion of the data to be removed followed by the new data. Because the
> csum is calculated over 16 bits and these values align with 16 bits, the
> effect is the removal of the old value from the CHECKSUM_COMPLETE and
> addition of the new value.
> 
> However, the csum fed into the function and the outcome of the
> calculation are also inverted. This would only make sense if it was the
> new value rather than the old that was inverted in the input buffer.
> 
> Fix the issue by removing the bit inverts in the csum_partial calculation.
> 
> The bug was verified and the fix tested by comparing the folded value of
> the updated CHECKSUM_COMPLETE value with the folded value of a full
> software checksum calculation (reset skb->csum to 0 and run
> skb_checksum_complete(skb)). Prior to the fix the outcomes differed but
> after they produce the same result.
> 
> Fixes: 25cd9ba0abc0 ("openvswitch: Add basic MPLS support to kernel")
> Fixes: bc7cc5999fd3 ("openvswitch: update checksum in {push,pop}_mpls")
> Signed-off-by: John Hurley <john.hurley@netronome.com>
> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> Reviewed-by: Simon Horman <simon.horman@netronome.com>

Applied and queued up for -stable, thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-07-01  1:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-27 13:37 [PATCH net 1/1] net: openvswitch: fix csum updates for MPLS actions John Hurley
2019-06-30  0:33 ` Pravin Shelar
2019-07-01  1:45 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).