Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb73ee40 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by David S. Miller
Browse files

net: ip_gre: use erspan key field for tunnel lookup



Use ERSPAN key header field as tunnel key in gre_parse_header routine
since ERSPAN protocol sets the key field of the external GRE header to
0 resulting in a tunnel lookup fail in ip6gre_err.
In addition remove key field parsing and pskb_may_pull check in
erspan_rcv and ip6erspan_rcv

Fixes: 5a963eb6 ("ip6_gre: Add ERSPAN native tunnel support")
Signed-off-by: default avatarLorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 56cb4e50
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/spinlock.h>
#include <net/protocol.h>
#include <net/gre.h>
#include <net/erspan.h>

#include <net/icmp.h>
#include <net/route.h>
@@ -119,6 +120,22 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
			hdr_len += 4;
	}
	tpi->hdr_len = hdr_len;

	/* ERSPAN ver 1 and 2 protocol sets GRE key field
	 * to 0 and sets the configured key in the
	 * inner erspan header field
	 */
	if (greh->protocol == htons(ETH_P_ERSPAN) ||
	    greh->protocol == htons(ETH_P_ERSPAN2)) {
		struct erspan_base_hdr *ershdr;

		if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr)))
			return -EINVAL;

		ershdr = (struct erspan_base_hdr *)options;
		tpi->key = cpu_to_be32(get_session_id(ershdr));
	}

	return hdr_len;
}
EXPORT_SYMBOL(gre_parse_header);
+0 −9
Original line number Diff line number Diff line
@@ -268,20 +268,11 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
	int len;

	itn = net_generic(net, erspan_net_id);
	len = gre_hdr_len + sizeof(*ershdr);

	/* Check based hdr len */
	if (unlikely(!pskb_may_pull(skb, len)))
		return PACKET_REJECT;

	iph = ip_hdr(skb);
	ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
	ver = ershdr->ver;

	/* The original GRE header does not have key field,
	 * Use ERSPAN 10-bit session ID as key.
	 */
	tpi->key = cpu_to_be32(get_session_id(ershdr));
	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
				  tpi->flags | TUNNEL_KEY,
				  iph->saddr, iph->daddr, tpi->key);
+0 −4
Original line number Diff line number Diff line
@@ -534,13 +534,9 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
	struct ip6_tnl *tunnel;
	u8 ver;

	if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr))))
		return PACKET_REJECT;

	ipv6h = ipv6_hdr(skb);
	ershdr = (struct erspan_base_hdr *)skb->data;
	ver = ershdr->ver;
	tpi->key = cpu_to_be32(get_session_id(ershdr));

	tunnel = ip6gre_tunnel_lookup(skb->dev,
				      &ipv6h->saddr, &ipv6h->daddr, tpi->key,