forked from Minki/linux
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: 5a963eb61b
("ip6_gre: Add ERSPAN native tunnel support")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
56cb4e5034
commit
cb73ee40b1
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user