static void ip_multipath_l3_keys(const struct sk_buff *skb,
				 struct flow_keys *hash_keys)
{
	const struct iphdr *outer_iph = ip_hdr(skb);
	const struct iphdr *key_iph = outer_iph;
	const struct iphdr *inner_iph;
	const struct icmphdr *icmph;
	struct iphdr _inner_iph;
	struct icmphdr _icmph;

	if (likely(outer_iph->protocol != IPPROTO_ICMP))
		goto out;

	if (unlikely((outer_iph->frag_off & htons(IP_OFFSET)) != 0))
		goto out;

	icmph = skb_header_pointer(skb, outer_iph->ihl * 4, sizeof(_icmph),
				   &_icmph);
	if (!icmph)
		goto out;

	if (!icmp_is_err(icmph->type))
		goto out;

	inner_iph = skb_header_pointer(skb,
				       outer_iph->ihl * 4 + sizeof(_icmph),
				       sizeof(_inner_iph), &_inner_iph);
	if (!inner_iph)
		goto out;

	key_iph = inner_iph;
out:
	hash_keys->addrs.v4addrs.src = key_iph->saddr;
	hash_keys->addrs.v4addrs.dst = key_iph->daddr;
}
static void ip_multipath_l3_keys(const struct sk_buff *skb,
				 struct flow_keys *hash_keys)
{
	const struct iphdr *outer_iph = ip_hdr(skb);
	const struct iphdr *key_iph = outer_iph;
	const struct iphdr *inner_iph;
	const struct icmphdr *icmph;
	struct iphdr _inner_iph;
	struct icmphdr _icmph;

	if (likely(outer_iph->protocol != IPPROTO_ICMP))
		goto out;

	if (unlikely((outer_iph->frag_off & htons(IP_OFFSET)) != 0))
		goto out;

	icmph = skb_header_pointer(skb, outer_iph->ihl * 4, sizeof(_icmph),
				   &_icmph);
	if (!icmph)
		goto out;

	if (!icmp_is_err(icmph->type))
		goto out;

	inner_iph = skb_header_pointer(skb,
				       outer_iph->ihl * 4 + sizeof(_icmph),
				       sizeof(_inner_iph), &_inner_iph);
	if (!inner_iph)
		goto out;

	key_iph = inner_iph;
out:
	hash_keys->addrs.v4addrs.src = key_iph->saddr;
	hash_keys->addrs.v4addrs.dst = key_iph->daddr;
}