aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Tu <u9012063@gmail.com>2018-02-05 16:35:34 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-06 11:32:48 -0500
commit3df1928302950dfa728ab2eade28eea0da291567 (patch)
tree325f571ad901f437ba33ace9f820be396444c81b
parentd7cdee5ea8d28ae1b6922deb0c1badaa3aa0ef8c (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.h26
-rw-r--r--net/ipv4/ip_gre.c5
-rw-r--r--net/ipv6/ip6_gre.c6
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