summaryrefslogtreecommitdiff
path: root/net/openvswitch/actions.c
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2014-11-11 14:32:20 -0800
committerPravin B Shelar <pshelar@nicira.com>2014-11-14 15:13:26 -0800
commit856447d0209c2214d806b30bd3b0d873db5998bd (patch)
tree21aa98052bc2859980686929eec464680d3a3627 /net/openvswitch/actions.c
parentab64f16ff2e83371927c57a0380fd3c0fee5c1c1 (diff)
downloadlwn-856447d0209c2214d806b30bd3b0d873db5998bd.tar.gz
lwn-856447d0209c2214d806b30bd3b0d873db5998bd.zip
openvswitch: Fix checksum calculation when modifying ICMPv6 packets.
The checksum of ICMPv6 packets uses the IP pseudoheader as part of the calculation, unlike ICMP in IPv4. This was not implemented, which means that modifying the IP addresses of an ICMPv6 packet would cause the checksum to no longer be correct as the psuedoheader did not match. Introduced by commit 3fdbd1ce11e5 ("openvswitch: add ipv6 'set' action"). Reported-by: Neal Shrader <icosahedral@gmail.com> Signed-off-by: Jesse Gross <jesse@nicira.com> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Diffstat (limited to 'net/openvswitch/actions.c')
-rw-r--r--net/openvswitch/actions.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 00e447a17f64..8c4229b11c34 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -246,11 +246,11 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
{
int transport_len = skb->len - skb_transport_offset(skb);
- if (l4_proto == IPPROTO_TCP) {
+ if (l4_proto == NEXTHDR_TCP) {
if (likely(transport_len >= sizeof(struct tcphdr)))
inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb,
addr, new_addr, 1);
- } else if (l4_proto == IPPROTO_UDP) {
+ } else if (l4_proto == NEXTHDR_UDP) {
if (likely(transport_len >= sizeof(struct udphdr))) {
struct udphdr *uh = udp_hdr(skb);
@@ -261,6 +261,10 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
uh->check = CSUM_MANGLED_0;
}
}
+ } else if (l4_proto == NEXTHDR_ICMP) {
+ if (likely(transport_len >= sizeof(struct icmp6hdr)))
+ inet_proto_csum_replace16(&icmp6_hdr(skb)->icmp6_cksum,
+ skb, addr, new_addr, 1);
}
}