[ovs-dev] [PATCH] datapath: Fix checksum calculation when modifying ICMPv6 packets.

Pravin Shelar pshelar at nicira.com
Fri Aug 29 19:38:59 UTC 2014


On Fri, Aug 15, 2014 at 11:18 AM, Jesse Gross <jesse at nicira.com> wrote:
> 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.
>
> Reported-by: Neal Shrader <icosahedral at gmail.com>
> Signed-off-by: Jesse Gross <jesse at nicira.com>

Looks good.
Acked-by: Pravin B Shelar <pshelar at nicira.com>
> ---
>  datapath/actions.c | 8 ++++++--
>  lib/packets.c      | 5 +++++
>  2 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/datapath/actions.c b/datapath/actions.c
> index b16e0b2..713a45d 100644
> --- a/datapath/actions.c
> +++ b/datapath/actions.c
> @@ -383,11 +383,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);
>
> @@ -398,6 +398,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);
>         }
>  }
>
> diff --git a/lib/packets.c b/lib/packets.c
> index 6244c3f..ace7d8e 100644
> --- a/lib/packets.c
> +++ b/lib/packets.c
> @@ -20,6 +20,7 @@
>  #include <sys/socket.h>
>  #include <netinet/in.h>
>  #include <netinet/ip6.h>
> +#include <netinet/icmp6.h>
>  #include <stdlib.h>
>  #include "byte-order.h"
>  #include "csum.h"
> @@ -714,6 +715,10 @@ packet_update_csum128(struct ofpbuf *packet, uint8_t proto,
>                  uh->udp_csum = htons(0xffff);
>              }
>          }
> +    } else if (proto == IPPROTO_ICMPV6 && l4_size >= sizeof(struct icmp6_hdr)) {
> +        struct icmp6_hdr *icmp = ofpbuf_l4(packet);
> +
> +        icmp->icmp6_cksum = recalc_csum128(icmp->icmp6_cksum, addr, new_addr);
>      }
>  }
>
> --
> 1.9.1
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev



More information about the dev mailing list