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

Commit 3df19283 authored by William Tu's avatar William Tu Committed by David S. Miller
Browse files

net: erspan: fix metadata extraction



Commit d350a823 ("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: 1a66a836 ("gre: add collect_md mode to ERSPAN tunnel")
Fixes: ef7baf5e ("ip6_gre: add ip6 erspan collect_md mode")
Fixes: 1d7e2ed2 ("net: erspan: refactor existing erspan code")
Signed-off-by: default avatarWilliam Tu <u9012063@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d7cdee5e
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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);