net: erspan: fix metadata extraction
Commitd350a82302
("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:1a66a836da
("gre: add collect_md mode to ERSPAN tunnel") Fixes:ef7baf5e08
("ip6_gre: add ip6 erspan collect_md mode") Fixes:1d7e2ed22f
("net: erspan: refactor existing erspan code") Signed-off-by: William Tu <u9012063@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d7cdee5ea8
commit
3df1928302
@ -159,13 +159,13 @@ static inline void erspan_build_header(struct sk_buff *skb,
|
||||
struct ethhdr *eth = (struct ethhdr *)skb->data;
|
||||
enum erspan_encap_type enc_type;
|
||||
struct erspan_base_hdr *ershdr;
|
||||
struct erspan_metadata *ersmd;
|
||||
struct qtag_prefix {
|
||||
__be16 eth_type;
|
||||
__be16 tci;
|
||||
} *qp;
|
||||
u16 vlan_tci = 0;
|
||||
u8 tos;
|
||||
__be32 *idx;
|
||||
|
||||
tos = is_ipv4 ? ip_hdr(skb)->tos :
|
||||
(ipv6_hdr(skb)->priority << 4) +
|
||||
@ -195,8 +195,8 @@ static inline void erspan_build_header(struct sk_buff *skb,
|
||||
set_session_id(ershdr, id);
|
||||
|
||||
/* Build metadata */
|
||||
ersmd = (struct erspan_metadata *)(ershdr + 1);
|
||||
ersmd->u.index = htonl(index & INDEX_MASK);
|
||||
idx = (__be32 *)(ershdr + 1);
|
||||
*idx = htonl(index & INDEX_MASK);
|
||||
}
|
||||
|
||||
/* ERSPAN GRA: timestamp granularity
|
||||
@ -225,7 +225,7 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
|
||||
{
|
||||
struct ethhdr *eth = (struct ethhdr *)skb->data;
|
||||
struct erspan_base_hdr *ershdr;
|
||||
struct erspan_metadata *md;
|
||||
struct erspan_md2 *md2;
|
||||
struct qtag_prefix {
|
||||
__be16 eth_type;
|
||||
__be16 tci;
|
||||
@ -261,15 +261,15 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
|
||||
set_session_id(ershdr, id);
|
||||
|
||||
/* Build metadata */
|
||||
md = (struct erspan_metadata *)(ershdr + 1);
|
||||
md->u.md2.timestamp = erspan_get_timestamp();
|
||||
md->u.md2.sgt = htons(sgt);
|
||||
md->u.md2.p = 1;
|
||||
md->u.md2.ft = 0;
|
||||
md->u.md2.dir = direction;
|
||||
md->u.md2.gra = gra;
|
||||
md->u.md2.o = 0;
|
||||
set_hwid(&md->u.md2, hwid);
|
||||
md2 = (struct erspan_md2 *)(ershdr + 1);
|
||||
md2->timestamp = erspan_get_timestamp();
|
||||
md2->sgt = htons(sgt);
|
||||
md2->p = 1;
|
||||
md2->ft = 0;
|
||||
md2->dir = direction;
|
||||
md2->gra = gra;
|
||||
md2->o = 0;
|
||||
set_hwid(md2, hwid);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -261,6 +261,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
|
||||
struct ip_tunnel_net *itn;
|
||||
struct ip_tunnel *tunnel;
|
||||
const struct iphdr *iph;
|
||||
struct erspan_md2 *md2;
|
||||
int ver;
|
||||
int len;
|
||||
|
||||
@ -313,8 +314,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
|
||||
return PACKET_REJECT;
|
||||
|
||||
md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
|
||||
memcpy(md, pkt_md, sizeof(*md));
|
||||
md->version = ver;
|
||||
md2 = &md->u.md2;
|
||||
memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
|
||||
ERSPAN_V2_MDSIZE);
|
||||
|
||||
info = &tun_dst->u.tun_info;
|
||||
info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
|
||||
|
@ -505,6 +505,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
|
||||
struct erspan_base_hdr *ershdr;
|
||||
struct erspan_metadata *pkt_md;
|
||||
const struct ipv6hdr *ipv6h;
|
||||
struct erspan_md2 *md2;
|
||||
struct ip6_tnl *tunnel;
|
||||
u8 ver;
|
||||
|
||||
@ -551,9 +552,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
|
||||
|
||||
info = &tun_dst->u.tun_info;
|
||||
md = ip_tunnel_info_opts(info);
|
||||
|
||||
memcpy(md, pkt_md, sizeof(*md));
|
||||
md->version = ver;
|
||||
md2 = &md->u.md2;
|
||||
memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
|
||||
ERSPAN_V2_MDSIZE);
|
||||
info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
|
||||
info->options_len = sizeof(*md);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user