diff options
author | William Tu <u9012063@gmail.com> | 2018-02-05 16:35:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-06 11:32:48 -0500 |
commit | 3df1928302950dfa728ab2eade28eea0da291567 (patch) | |
tree | 325f571ad901f437ba33ace9f820be396444c81b | |
parent | d7cdee5ea8d28ae1b6922deb0c1badaa3aa0ef8c (diff) |
net: erspan: fix metadata extraction
Commit d350a823020e ("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: 1a66a836da63 ("gre: add collect_md mode to ERSPAN tunnel")
Fixes: ef7baf5e083c ("ip6_gre: add ip6 erspan collect_md mode")
Fixes: 1d7e2ed22f8d ("net: erspan: refactor existing erspan code")
Signed-off-by: William Tu <u9012063@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/erspan.h | 26 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 5 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 6 |
3 files changed, 21 insertions, 16 deletions
diff --git a/include/net/erspan.h b/include/net/erspan.h index 5daa4866412b..d044aa60cc76 100644 --- a/include/net/erspan.h +++ b/include/net/erspan.h | |||
@@ -159,13 +159,13 @@ static inline void erspan_build_header(struct sk_buff *skb, | |||
159 | struct ethhdr *eth = (struct ethhdr *)skb->data; | 159 | struct ethhdr *eth = (struct ethhdr *)skb->data; |
160 | enum erspan_encap_type enc_type; | 160 | enum erspan_encap_type enc_type; |
161 | struct erspan_base_hdr *ershdr; | 161 | struct erspan_base_hdr *ershdr; |
162 | struct erspan_metadata *ersmd; | ||
163 | struct qtag_prefix { | 162 | struct qtag_prefix { |
164 | __be16 eth_type; | 163 | __be16 eth_type; |
165 | __be16 tci; | 164 | __be16 tci; |
166 | } *qp; | 165 | } *qp; |
167 | u16 vlan_tci = 0; | 166 | u16 vlan_tci = 0; |
168 | u8 tos; | 167 | u8 tos; |
168 | __be32 *idx; | ||
169 | 169 | ||
170 | tos = is_ipv4 ? ip_hdr(skb)->tos : | 170 | tos = is_ipv4 ? ip_hdr(skb)->tos : |
171 | (ipv6_hdr(skb)->priority << 4) + | 171 | (ipv6_hdr(skb)->priority << 4) + |
@@ -195,8 +195,8 @@ static inline void erspan_build_header(struct sk_buff *skb, | |||
195 | set_session_id(ershdr, id); | 195 | set_session_id(ershdr, id); |
196 | 196 | ||
197 | /* Build metadata */ | 197 | /* Build metadata */ |
198 | ersmd = (struct erspan_metadata *)(ershdr + 1); | 198 | idx = (__be32 *)(ershdr + 1); |
199 | ersmd->u.index = htonl(index & INDEX_MASK); | 199 | *idx = htonl(index & INDEX_MASK); |
200 | } | 200 | } |
201 | 201 | ||
202 | /* ERSPAN GRA: timestamp granularity | 202 | /* ERSPAN GRA: timestamp granularity |
@@ -225,7 +225,7 @@ static inline void erspan_build_header_v2(struct sk_buff *skb, | |||
225 | { | 225 | { |
226 | struct ethhdr *eth = (struct ethhdr *)skb->data; | 226 | struct ethhdr *eth = (struct ethhdr *)skb->data; |
227 | struct erspan_base_hdr *ershdr; | 227 | struct erspan_base_hdr *ershdr; |
228 | struct erspan_metadata *md; | 228 | struct erspan_md2 *md2; |
229 | struct qtag_prefix { | 229 | struct qtag_prefix { |
230 | __be16 eth_type; | 230 | __be16 eth_type; |
231 | __be16 tci; | 231 | __be16 tci; |
@@ -261,15 +261,15 @@ static inline void erspan_build_header_v2(struct sk_buff *skb, | |||
261 | set_session_id(ershdr, id); | 261 | set_session_id(ershdr, id); |
262 | 262 | ||
263 | /* Build metadata */ | 263 | /* Build metadata */ |
264 | md = (struct erspan_metadata *)(ershdr + 1); | 264 | md2 = (struct erspan_md2 *)(ershdr + 1); |
265 | md->u.md2.timestamp = erspan_get_timestamp(); | 265 | md2->timestamp = erspan_get_timestamp(); |
266 | md->u.md2.sgt = htons(sgt); | 266 | md2->sgt = htons(sgt); |
267 | md->u.md2.p = 1; | 267 | md2->p = 1; |
268 | md->u.md2.ft = 0; | 268 | md2->ft = 0; |
269 | md->u.md2.dir = direction; | 269 | md2->dir = direction; |
270 | md->u.md2.gra = gra; | 270 | md2->gra = gra; |
271 | md->u.md2.o = 0; | 271 | md2->o = 0; |
272 | set_hwid(&md->u.md2, hwid); | 272 | set_hwid(md2, hwid); |
273 | } | 273 | } |
274 | 274 | ||
275 | #endif | 275 | #endif |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 6ec670fbbbdd..9b50eddd1882 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -261,6 +261,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
261 | struct ip_tunnel_net *itn; | 261 | struct ip_tunnel_net *itn; |
262 | struct ip_tunnel *tunnel; | 262 | struct ip_tunnel *tunnel; |
263 | const struct iphdr *iph; | 263 | const struct iphdr *iph; |
264 | struct erspan_md2 *md2; | ||
264 | int ver; | 265 | int ver; |
265 | int len; | 266 | int len; |
266 | 267 | ||
@@ -313,8 +314,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
313 | return PACKET_REJECT; | 314 | return PACKET_REJECT; |
314 | 315 | ||
315 | md = ip_tunnel_info_opts(&tun_dst->u.tun_info); | 316 | md = ip_tunnel_info_opts(&tun_dst->u.tun_info); |
316 | memcpy(md, pkt_md, sizeof(*md)); | ||
317 | md->version = ver; | 317 | md->version = ver; |
318 | md2 = &md->u.md2; | ||
319 | memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE : | ||
320 | ERSPAN_V2_MDSIZE); | ||
318 | 321 | ||
319 | info = &tun_dst->u.tun_info; | 322 | info = &tun_dst->u.tun_info; |
320 | info->key.tun_flags |= TUNNEL_ERSPAN_OPT; | 323 | info->key.tun_flags |= TUNNEL_ERSPAN_OPT; |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 05f070e123e4..50913dbd0612 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -505,6 +505,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len, | |||
505 | struct erspan_base_hdr *ershdr; | 505 | struct erspan_base_hdr *ershdr; |
506 | struct erspan_metadata *pkt_md; | 506 | struct erspan_metadata *pkt_md; |
507 | const struct ipv6hdr *ipv6h; | 507 | const struct ipv6hdr *ipv6h; |
508 | struct erspan_md2 *md2; | ||
508 | struct ip6_tnl *tunnel; | 509 | struct ip6_tnl *tunnel; |
509 | u8 ver; | 510 | u8 ver; |
510 | 511 | ||
@@ -551,9 +552,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len, | |||
551 | 552 | ||
552 | info = &tun_dst->u.tun_info; | 553 | info = &tun_dst->u.tun_info; |
553 | md = ip_tunnel_info_opts(info); | 554 | md = ip_tunnel_info_opts(info); |
554 | |||
555 | memcpy(md, pkt_md, sizeof(*md)); | ||
556 | md->version = ver; | 555 | md->version = ver; |
556 | md2 = &md->u.md2; | ||
557 | memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE : | ||
558 | ERSPAN_V2_MDSIZE); | ||
557 | info->key.tun_flags |= TUNNEL_ERSPAN_OPT; | 559 | info->key.tun_flags |= TUNNEL_ERSPAN_OPT; |
558 | info->options_len = sizeof(*md); | 560 | info->options_len = sizeof(*md); |
559 | 561 | ||