Skip to content

Commit 67ae44e

Browse files
committed
Merge branch 'net-erspan-fixes'
William Tu says: ==================== net: erspan fixes The first patch fixes erspan metadata extraction issue from packet header due to commit d350a82 ("net: erspan: create erspan metadata uapi header"). The commit moves the erspan 'version' in 'struct erspan_metadata' in front of 'struct erspan_md2' for later extensibility, but breaks the existing metadata extraction code due to extra 4-byte size 'version'. The second patch fixes the case where tunnel device receives an erspan packet with different tunnel metadata (ex: version, index, hwid, direction), existing code overwrites the tunnel device's erspan configuration. The third patch fixes the bpf tests due to the above patches. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents d7cdee5 + 9c33ca4 commit 67ae44e

File tree

5 files changed

+39
-61
lines changed

5 files changed

+39
-61
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 & 10 deletions
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,21 +314,14 @@ 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;
321324
info->options_len = sizeof(*md);
322-
} else {
323-
tunnel->erspan_ver = ver;
324-
if (ver == 1) {
325-
tunnel->index = ntohl(pkt_md->u.index);
326-
} else {
327-
tunnel->dir = pkt_md->u.md2.dir;
328-
tunnel->hwid = get_hwid(&pkt_md->u.md2);
329-
}
330-
331325
}
332326

333327
skb_reset_mac_header(skb);

net/ipv6/ip6_gre.c

Lines changed: 4 additions & 11 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,24 +552,16 @@ 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

560562
ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
561563

562564
} else {
563-
tunnel->parms.erspan_ver = ver;
564-
565-
if (ver == 1) {
566-
tunnel->parms.index = ntohl(pkt_md->u.index);
567-
} else {
568-
tunnel->parms.dir = pkt_md->u.md2.dir;
569-
tunnel->parms.hwid = get_hwid(&pkt_md->u.md2);
570-
}
571-
572565
ip6_tnl_rcv(tunnel, skb, tpi, NULL, log_ecn_error);
573566
}
574567

samples/bpf/tcbpf2_kern.c

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <uapi/linux/tcp.h>
1616
#include <uapi/linux/filter.h>
1717
#include <uapi/linux/pkt_cls.h>
18+
#include <uapi/linux/erspan.h>
1819
#include <net/ipv6.h>
1920
#include "bpf_helpers.h"
2021
#include "bpf_endian.h"
@@ -35,24 +36,10 @@ struct geneve_opt {
3536
u8 opt_data[8]; /* hard-coded to 8 byte */
3637
};
3738

38-
struct erspan_md2 {
39-
__be32 timestamp;
40-
__be16 sgt;
41-
__be16 flags;
42-
};
43-
4439
struct vxlan_metadata {
4540
u32 gbp;
4641
};
4742

48-
struct erspan_metadata {
49-
union {
50-
__be32 index;
51-
struct erspan_md2 md2;
52-
} u;
53-
int version;
54-
};
55-
5643
SEC("gre_set_tunnel")
5744
int _gre_set_tunnel(struct __sk_buff *skb)
5845
{
@@ -156,13 +143,15 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
156143
__builtin_memset(&md, 0, sizeof(md));
157144
#ifdef ERSPAN_V1
158145
md.version = 1;
159-
md.u.index = htonl(123);
146+
md.u.index = bpf_htonl(123);
160147
#else
161148
u8 direction = 1;
162-
u16 hwid = 7;
149+
u8 hwid = 7;
163150

164151
md.version = 2;
165-
md.u.md2.flags = htons((direction << 3) | (hwid << 4));
152+
md.u.md2.dir = direction;
153+
md.u.md2.hwid = hwid & 0xf;
154+
md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
166155
#endif
167156

168157
ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
@@ -207,9 +196,9 @@ int _erspan_get_tunnel(struct __sk_buff *skb)
207196
char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
208197

209198
bpf_trace_printk(fmt2, sizeof(fmt2),
210-
(ntohs(md.u.md2.flags) >> 3) & 0x1,
211-
(ntohs(md.u.md2.flags) >> 4) & 0x3f,
212-
bpf_ntohl(md.u.md2.timestamp));
199+
md.u.md2.dir,
200+
(md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
201+
bpf_ntohl(md.u.md2.timestamp));
213202
#endif
214203

215204
return TC_ACT_OK;
@@ -242,10 +231,12 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
242231
md.version = 1;
243232
#else
244233
u8 direction = 0;
245-
u16 hwid = 17;
234+
u8 hwid = 17;
246235

247236
md.version = 2;
248-
md.u.md2.flags = htons((direction << 3) | (hwid << 4));
237+
md.u.md2.dir = direction;
238+
md.u.md2.hwid = hwid & 0xf;
239+
md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
249240
#endif
250241

251242
ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
@@ -290,9 +281,9 @@ int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
290281
char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
291282

292283
bpf_trace_printk(fmt2, sizeof(fmt2),
293-
(ntohs(md.u.md2.flags) >> 3) & 0x1,
294-
(ntohs(md.u.md2.flags) >> 4) & 0x3f,
295-
bpf_ntohl(md.u.md2.timestamp));
284+
md.u.md2.dir,
285+
(md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
286+
bpf_ntohl(md.u.md2.timestamp));
296287
#endif
297288

298289
return TC_ACT_OK;

samples/bpf/test_tunnel_bpf.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function add_erspan_tunnel {
6868
ip netns exec at_ns0 \
6969
ip link add dev $DEV_NS type $TYPE seq key 2 \
7070
local 172.16.1.100 remote 172.16.1.200 \
71-
erspan_ver 2 erspan_dir 1 erspan_hwid 3
71+
erspan_ver 2 erspan_dir egress erspan_hwid 3
7272
fi
7373
ip netns exec at_ns0 ip link set dev $DEV_NS up
7474
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
@@ -97,7 +97,7 @@ function add_ip6erspan_tunnel {
9797
ip netns exec at_ns0 \
9898
ip link add dev $DEV_NS type $TYPE seq key 2 \
9999
local ::11 remote ::22 \
100-
erspan_ver 2 erspan_dir 1 erspan_hwid 7
100+
erspan_ver 2 erspan_dir egress erspan_hwid 7
101101
fi
102102
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
103103
ip netns exec at_ns0 ip link set dev $DEV_NS up

0 commit comments

Comments
 (0)