Skip to content

Commit 3df1928

Browse files
williamtudavem330
authored andcommitted
net: erspan: fix metadata extraction
Commit d350a82 ("net: erspan: create erspan metadata uapi header") moves the erspan 'version' in front of the 'struct erspan_md2' for later extensibility reason. This breaks the existing erspan metadata extraction code because the erspan_md2 then has a 4-byte offset to between the erspan_metadata and erspan_base_hdr. This patch fixes it. Fixes: 1a66a83 ("gre: add collect_md mode to ERSPAN tunnel") Fixes: ef7baf5 ("ip6_gre: add ip6 erspan collect_md mode") Fixes: 1d7e2ed ("net: erspan: refactor existing erspan code") Signed-off-by: William Tu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d7cdee5 commit 3df1928

File tree

3 files changed

+21
-16
lines changed

3 files changed

+21
-16
lines changed

include/net/erspan.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,13 @@ static inline void erspan_build_header(struct sk_buff *skb,
159159
struct ethhdr *eth = (struct ethhdr *)skb->data;
160160
enum erspan_encap_type enc_type;
161161
struct erspan_base_hdr *ershdr;
162-
struct erspan_metadata *ersmd;
163162
struct qtag_prefix {
164163
__be16 eth_type;
165164
__be16 tci;
166165
} *qp;
167166
u16 vlan_tci = 0;
168167
u8 tos;
168+
__be32 *idx;
169169

170170
tos = is_ipv4 ? ip_hdr(skb)->tos :
171171
(ipv6_hdr(skb)->priority << 4) +
@@ -195,8 +195,8 @@ static inline void erspan_build_header(struct sk_buff *skb,
195195
set_session_id(ershdr, id);
196196

197197
/* Build metadata */
198-
ersmd = (struct erspan_metadata *)(ershdr + 1);
199-
ersmd->u.index = htonl(index & INDEX_MASK);
198+
idx = (__be32 *)(ershdr + 1);
199+
*idx = htonl(index & INDEX_MASK);
200200
}
201201

202202
/* ERSPAN GRA: timestamp granularity
@@ -225,7 +225,7 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
225225
{
226226
struct ethhdr *eth = (struct ethhdr *)skb->data;
227227
struct erspan_base_hdr *ershdr;
228-
struct erspan_metadata *md;
228+
struct erspan_md2 *md2;
229229
struct qtag_prefix {
230230
__be16 eth_type;
231231
__be16 tci;
@@ -261,15 +261,15 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
261261
set_session_id(ershdr, id);
262262

263263
/* Build metadata */
264-
md = (struct erspan_metadata *)(ershdr + 1);
265-
md->u.md2.timestamp = erspan_get_timestamp();
266-
md->u.md2.sgt = htons(sgt);
267-
md->u.md2.p = 1;
268-
md->u.md2.ft = 0;
269-
md->u.md2.dir = direction;
270-
md->u.md2.gra = gra;
271-
md->u.md2.o = 0;
272-
set_hwid(&md->u.md2, hwid);
264+
md2 = (struct erspan_md2 *)(ershdr + 1);
265+
md2->timestamp = erspan_get_timestamp();
266+
md2->sgt = htons(sgt);
267+
md2->p = 1;
268+
md2->ft = 0;
269+
md2->dir = direction;
270+
md2->gra = gra;
271+
md2->o = 0;
272+
set_hwid(md2, hwid);
273273
}
274274

275275
#endif

net/ipv4/ip_gre.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
261261
struct ip_tunnel_net *itn;
262262
struct ip_tunnel *tunnel;
263263
const struct iphdr *iph;
264+
struct erspan_md2 *md2;
264265
int ver;
265266
int len;
266267

@@ -313,8 +314,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
313314
return PACKET_REJECT;
314315

315316
md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
316-
memcpy(md, pkt_md, sizeof(*md));
317317
md->version = ver;
318+
md2 = &md->u.md2;
319+
memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
320+
ERSPAN_V2_MDSIZE);
318321

319322
info = &tun_dst->u.tun_info;
320323
info->key.tun_flags |= TUNNEL_ERSPAN_OPT;

net/ipv6/ip6_gre.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
505505
struct erspan_base_hdr *ershdr;
506506
struct erspan_metadata *pkt_md;
507507
const struct ipv6hdr *ipv6h;
508+
struct erspan_md2 *md2;
508509
struct ip6_tnl *tunnel;
509510
u8 ver;
510511

@@ -551,9 +552,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
551552

552553
info = &tun_dst->u.tun_info;
553554
md = ip_tunnel_info_opts(info);
554-
555-
memcpy(md, pkt_md, sizeof(*md));
556555
md->version = ver;
556+
md2 = &md->u.md2;
557+
memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
558+
ERSPAN_V2_MDSIZE);
557559
info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
558560
info->options_len = sizeof(*md);
559561

0 commit comments

Comments
 (0)