@@ -35,12 +35,22 @@ struct geneve_opt {
35
35
u8 opt_data [8 ]; /* hard-coded to 8 byte */
36
36
};
37
37
38
+ struct erspan_md2 {
39
+ __be32 timestamp ;
40
+ __be16 sgt ;
41
+ __be16 flags ;
42
+ };
43
+
38
44
struct vxlan_metadata {
39
45
u32 gbp ;
40
46
};
41
47
42
48
struct erspan_metadata {
43
- __be32 index ;
49
+ union {
50
+ __be32 index ;
51
+ struct erspan_md2 md2 ;
52
+ } u ;
53
+ int version ;
44
54
};
45
55
46
56
SEC ("gre_set_tunnel" )
@@ -143,7 +153,18 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
143
153
return TC_ACT_SHOT ;
144
154
}
145
155
146
- md .index = htonl (123 );
156
+ __builtin_memset (& md , 0 , sizeof (md ));
157
+ #ifdef ERSPAN_V1
158
+ md .version = 1 ;
159
+ md .u .index = htonl (123 );
160
+ #else
161
+ u8 direction = 1 ;
162
+ u16 hwid = 7 ;
163
+
164
+ md .version = 2 ;
165
+ md .u .md2 .flags = htons ((direction << 3 ) | (hwid << 4 ));
166
+ #endif
167
+
147
168
ret = bpf_skb_set_tunnel_opt (skb , & md , sizeof (md ));
148
169
if (ret < 0 ) {
149
170
ERROR (ret );
@@ -156,7 +177,7 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
156
177
SEC ("erspan_get_tunnel" )
157
178
int _erspan_get_tunnel (struct __sk_buff * skb )
158
179
{
159
- char fmt [] = "key %d remote ip 0x%x erspan index 0x%x \n" ;
180
+ char fmt [] = "key %d remote ip 0x%x erspan version %d \n" ;
160
181
struct bpf_tunnel_key key ;
161
182
struct erspan_metadata md ;
162
183
u32 index ;
@@ -174,9 +195,22 @@ int _erspan_get_tunnel(struct __sk_buff *skb)
174
195
return TC_ACT_SHOT ;
175
196
}
176
197
177
- index = bpf_ntohl (md .index );
178
198
bpf_trace_printk (fmt , sizeof (fmt ),
179
- key .tunnel_id , key .remote_ipv4 , index );
199
+ key .tunnel_id , key .remote_ipv4 , md .version );
200
+
201
+ #ifdef ERSPAN_V1
202
+ char fmt2 [] = "\tindex %x\n" ;
203
+
204
+ index = bpf_ntohl (md .u .index );
205
+ bpf_trace_printk (fmt2 , sizeof (fmt2 ), index );
206
+ #else
207
+ char fmt2 [] = "\tdirection %d hwid %x timestamp %u\n" ;
208
+
209
+ 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 ));
213
+ #endif
180
214
181
215
return TC_ACT_OK ;
182
216
}
@@ -201,7 +235,19 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
201
235
return TC_ACT_SHOT ;
202
236
}
203
237
204
- md .index = htonl (123 );
238
+ __builtin_memset (& md , 0 , sizeof (md ));
239
+
240
+ #ifdef ERSPAN_V1
241
+ md .u .index = htonl (123 );
242
+ md .version = 1 ;
243
+ #else
244
+ u8 direction = 0 ;
245
+ u16 hwid = 17 ;
246
+
247
+ md .version = 2 ;
248
+ md .u .md2 .flags = htons ((direction << 3 ) | (hwid << 4 ));
249
+ #endif
250
+
205
251
ret = bpf_skb_set_tunnel_opt (skb , & md , sizeof (md ));
206
252
if (ret < 0 ) {
207
253
ERROR (ret );
@@ -214,7 +260,7 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
214
260
SEC ("ip4ip6erspan_get_tunnel" )
215
261
int _ip4ip6erspan_get_tunnel (struct __sk_buff * skb )
216
262
{
217
- char fmt [] = "key %d remote ip6 ::%x erspan index 0x%x \n" ;
263
+ char fmt [] = "ip6erspan get key %d remote ip6 ::%x erspan version %d \n" ;
218
264
struct bpf_tunnel_key key ;
219
265
struct erspan_metadata md ;
220
266
u32 index ;
@@ -232,9 +278,22 @@ int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
232
278
return TC_ACT_SHOT ;
233
279
}
234
280
235
- index = bpf_ntohl (md .index );
236
281
bpf_trace_printk (fmt , sizeof (fmt ),
237
- key .tunnel_id , key .remote_ipv6 [0 ], index );
282
+ key .tunnel_id , key .remote_ipv4 , md .version );
283
+
284
+ #ifdef ERSPAN_V1
285
+ char fmt2 [] = "\tindex %x\n" ;
286
+
287
+ index = bpf_ntohl (md .u .index );
288
+ bpf_trace_printk (fmt2 , sizeof (fmt2 ), index );
289
+ #else
290
+ char fmt2 [] = "\tdirection %d hwid %x timestamp %u\n" ;
291
+
292
+ 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 ));
296
+ #endif
238
297
239
298
return TC_ACT_OK ;
240
299
}
0 commit comments