forked from mirrors/linux
		
	openvswitch: update checksum in {push,pop}_mpls
In the case of CHECKSUM_COMPLETE the skb checksum should be updated in
{push,pop}_mpls() as they the type in the ethernet header.
As suggested by Pravin Shelar.
Cc: Pravin Shelar <pshelar@nicira.com>
Fixes: 25cd9ba0ab ("openvswitch: Add basic MPLS support to kernel")
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Acked-by: Pravin B Shelar <pshelar@ovn.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									40eb90e9cc
								
							
						
					
					
						commit
						bc7cc5999f
					
				
					 1 changed files with 15 additions and 5 deletions
				
			
		|  | @ -137,11 +137,23 @@ static bool is_flow_key_valid(const struct sw_flow_key *key) | |||
| 	return !!key->eth.type; | ||||
| } | ||||
| 
 | ||||
| static void update_ethertype(struct sk_buff *skb, struct ethhdr *hdr, | ||||
| 			     __be16 ethertype) | ||||
| { | ||||
| 	if (skb->ip_summed == CHECKSUM_COMPLETE) { | ||||
| 		__be16 diff[] = { ~(hdr->h_proto), ethertype }; | ||||
| 
 | ||||
| 		skb->csum = ~csum_partial((char *)diff, sizeof(diff), | ||||
| 					~skb->csum); | ||||
| 	} | ||||
| 
 | ||||
| 	hdr->h_proto = ethertype; | ||||
| } | ||||
| 
 | ||||
| static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, | ||||
| 		     const struct ovs_action_push_mpls *mpls) | ||||
| { | ||||
| 	__be32 *new_mpls_lse; | ||||
| 	struct ethhdr *hdr; | ||||
| 
 | ||||
| 	/* Networking stack do not allow simultaneous Tunnel and MPLS GSO. */ | ||||
| 	if (skb->encapsulation) | ||||
|  | @ -160,9 +172,7 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, | |||
| 
 | ||||
| 	skb_postpush_rcsum(skb, new_mpls_lse, MPLS_HLEN); | ||||
| 
 | ||||
| 	hdr = eth_hdr(skb); | ||||
| 	hdr->h_proto = mpls->mpls_ethertype; | ||||
| 
 | ||||
| 	update_ethertype(skb, eth_hdr(skb), mpls->mpls_ethertype); | ||||
| 	if (!skb->inner_protocol) | ||||
| 		skb_set_inner_protocol(skb, skb->protocol); | ||||
| 	skb->protocol = mpls->mpls_ethertype; | ||||
|  | @ -193,7 +203,7 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key, | |||
| 	 * field correctly in the presence of VLAN tags. | ||||
| 	 */ | ||||
| 	hdr = (struct ethhdr *)(skb_mpls_header(skb) - ETH_HLEN); | ||||
| 	hdr->h_proto = ethertype; | ||||
| 	update_ethertype(skb, hdr, ethertype); | ||||
| 	if (eth_p_mpls(skb->protocol)) | ||||
| 		skb->protocol = ethertype; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Simon Horman
						Simon Horman