Skip to content

Commit cb73ee4

Browse files
LorenzoBianconidavem330
authored andcommitted
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: 5a963eb ("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>
1 parent 56cb4e5 commit cb73ee4

File tree

3 files changed

+17
-13
lines changed

3 files changed

+17
-13
lines changed

net/ipv4/gre_demux.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/spinlock.h>
2626
#include <net/protocol.h>
2727
#include <net/gre.h>
28+
#include <net/erspan.h>
2829

2930
#include <net/icmp.h>
3031
#include <net/route.h>
@@ -119,6 +120,22 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
119120
hdr_len += 4;
120121
}
121122
tpi->hdr_len = hdr_len;
123+
124+
/* ERSPAN ver 1 and 2 protocol sets GRE key field
125+
* to 0 and sets the configured key in the
126+
* inner erspan header field
127+
*/
128+
if (greh->protocol == htons(ETH_P_ERSPAN) ||
129+
greh->protocol == htons(ETH_P_ERSPAN2)) {
130+
struct erspan_base_hdr *ershdr;
131+
132+
if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr)))
133+
return -EINVAL;
134+
135+
ershdr = (struct erspan_base_hdr *)options;
136+
tpi->key = cpu_to_be32(get_session_id(ershdr));
137+
}
138+
122139
return hdr_len;
123140
}
124141
EXPORT_SYMBOL(gre_parse_header);

net/ipv4/ip_gre.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -268,20 +268,11 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
268268
int len;
269269

270270
itn = net_generic(net, erspan_net_id);
271-
len = gre_hdr_len + sizeof(*ershdr);
272-
273-
/* Check based hdr len */
274-
if (unlikely(!pskb_may_pull(skb, len)))
275-
return PACKET_REJECT;
276271

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

281-
/* The original GRE header does not have key field,
282-
* Use ERSPAN 10-bit session ID as key.
283-
*/
284-
tpi->key = cpu_to_be32(get_session_id(ershdr));
285276
tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
286277
tpi->flags | TUNNEL_KEY,
287278
iph->saddr, iph->daddr, tpi->key);

net/ipv6/ip6_gre.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,13 +534,9 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
534534
struct ip6_tnl *tunnel;
535535
u8 ver;
536536

537-
if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr))))
538-
return PACKET_REJECT;
539-
540537
ipv6h = ipv6_hdr(skb);
541538
ershdr = (struct erspan_base_hdr *)skb->data;
542539
ver = ershdr->ver;
543-
tpi->key = cpu_to_be32(get_session_id(ershdr));
544540

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

0 commit comments

Comments
 (0)