46
46
* GRE proto ERSPAN type II = 0x88BE, type III = 0x22EB
47
47
*/
48
48
49
+ #include <uapi/linux/erspan.h>
50
+
49
51
#define ERSPAN_VERSION 0x1 /* ERSPAN type II */
50
52
#define VER_MASK 0xf000
51
53
#define VLAN_MASK 0x0fff
65
67
#define GRA_MASK 0x0006
66
68
#define O_MASK 0x0001
67
69
68
- /* ERSPAN version 2 metadata header */
69
- struct erspan_md2 {
70
- __be32 timestamp ;
71
- __be16 sgt ; /* security group tag */
72
- __be16 flags ;
73
- #define P_OFFSET 15
74
- #define FT_OFFSET 10
75
- #define HWID_OFFSET 4
76
- #define DIR_OFFSET 3
77
- #define GRA_OFFSET 1
78
- };
70
+ #define HWID_OFFSET 4
71
+ #define DIR_OFFSET 3
79
72
80
73
enum erspan_encap_type {
81
74
ERSPAN_ENCAP_NOVLAN = 0x0 , /* originally without VLAN tag */
@@ -86,24 +79,64 @@ enum erspan_encap_type {
86
79
87
80
#define ERSPAN_V1_MDSIZE 4
88
81
#define ERSPAN_V2_MDSIZE 8
89
- struct erspan_metadata {
90
- union {
91
- __be32 index ; /* Version 1 (type II)*/
92
- struct erspan_md2 md2 ; /* Version 2 (type III) */
93
- } u ;
94
- int version ;
95
- };
96
82
97
83
struct erspan_base_hdr {
98
- __be16 ver_vlan ;
99
- #define VER_OFFSET 12
100
- __be16 session_id ;
101
- #define COS_OFFSET 13
102
- #define EN_OFFSET 11
103
- #define BSO_OFFSET EN_OFFSET
104
- #define T_OFFSET 10
84
+ #if defined(__LITTLE_ENDIAN_BITFIELD )
85
+ __u8 vlan_upper :4 ,
86
+ ver :4 ;
87
+ __u8 vlan :8 ;
88
+ __u8 session_id_upper :2 ,
89
+ t :1 ,
90
+ en :2 ,
91
+ cos :3 ;
92
+ __u8 session_id :8 ;
93
+ #elif defined(__BIG_ENDIAN_BITFIELD )
94
+ __u8 ver : 4 ,
95
+ vlan_upper :4 ;
96
+ __u8 vlan :8 ;
97
+ __u8 cos :3 ,
98
+ en :2 ,
99
+ t :1 ,
100
+ session_id_upper :2 ;
101
+ __u8 session_id :8 ;
102
+ #else
103
+ #error "Please fix <asm/byteorder.h>"
104
+ #endif
105
105
};
106
106
107
+ static inline void set_session_id (struct erspan_base_hdr * ershdr , u16 id )
108
+ {
109
+ ershdr -> session_id = id & 0xff ;
110
+ ershdr -> session_id_upper = (id >> 8 ) & 0x3 ;
111
+ }
112
+
113
+ static inline u16 get_session_id (const struct erspan_base_hdr * ershdr )
114
+ {
115
+ return (ershdr -> session_id_upper << 8 ) + ershdr -> session_id ;
116
+ }
117
+
118
+ static inline void set_vlan (struct erspan_base_hdr * ershdr , u16 vlan )
119
+ {
120
+ ershdr -> vlan = vlan & 0xff ;
121
+ ershdr -> vlan_upper = (vlan >> 8 ) & 0xf ;
122
+ }
123
+
124
+ static inline u16 get_vlan (const struct erspan_base_hdr * ershdr )
125
+ {
126
+ return (ershdr -> vlan_upper << 8 ) + ershdr -> vlan ;
127
+ }
128
+
129
+ static inline void set_hwid (struct erspan_md2 * md2 , u8 hwid )
130
+ {
131
+ md2 -> hwid = hwid & 0xf ;
132
+ md2 -> hwid_upper = (hwid >> 4 ) & 0x3 ;
133
+ }
134
+
135
+ static inline u8 get_hwid (const struct erspan_md2 * md2 )
136
+ {
137
+ return (md2 -> hwid_upper << 4 ) + md2 -> hwid ;
138
+ }
139
+
107
140
static inline int erspan_hdr_len (int version )
108
141
{
109
142
return sizeof (struct erspan_base_hdr ) +
@@ -120,7 +153,7 @@ static inline u8 tos_to_cos(u8 tos)
120
153
}
121
154
122
155
static inline void erspan_build_header (struct sk_buff * skb ,
123
- __be32 id , u32 index ,
156
+ u32 id , u32 index ,
124
157
bool truncate , bool is_ipv4 )
125
158
{
126
159
struct ethhdr * eth = (struct ethhdr * )skb -> data ;
@@ -154,12 +187,12 @@ static inline void erspan_build_header(struct sk_buff *skb,
154
187
memset (ershdr , 0 , sizeof (* ershdr ) + ERSPAN_V1_MDSIZE );
155
188
156
189
/* Build base header */
157
- ershdr -> ver_vlan = htons (( vlan_tci & VLAN_MASK ) |
158
- ( ERSPAN_VERSION << VER_OFFSET ) );
159
- ershdr -> session_id = htons (( u16 )( ntohl ( id ) & ID_MASK ) |
160
- (( tos_to_cos ( tos ) << COS_OFFSET ) & COS_MASK ) |
161
- ( enc_type << EN_OFFSET & EN_MASK ) |
162
- (( truncate << T_OFFSET ) & T_MASK ) );
190
+ ershdr -> ver = ERSPAN_VERSION ;
191
+ ershdr -> cos = tos_to_cos ( tos );
192
+ ershdr -> en = enc_type ;
193
+ ershdr -> t = truncate ;
194
+ set_vlan ( ershdr , vlan_tci );
195
+ set_session_id ( ershdr , id );
163
196
164
197
/* Build metadata */
165
198
ersmd = (struct erspan_metadata * )(ershdr + 1 );
@@ -187,7 +220,7 @@ static inline __be32 erspan_get_timestamp(void)
187
220
}
188
221
189
222
static inline void erspan_build_header_v2 (struct sk_buff * skb ,
190
- __be32 id , u8 direction , u16 hwid ,
223
+ u32 id , u8 direction , u16 hwid ,
191
224
bool truncate , bool is_ipv4 )
192
225
{
193
226
struct ethhdr * eth = (struct ethhdr * )skb -> data ;
@@ -198,7 +231,6 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
198
231
__be16 tci ;
199
232
} * qp ;
200
233
u16 vlan_tci = 0 ;
201
- u16 session_id ;
202
234
u8 gra = 0 ; /* 100 usec */
203
235
u8 bso = 0 ; /* Bad/Short/Oversized */
204
236
u8 sgt = 0 ;
@@ -221,22 +253,23 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
221
253
memset (ershdr , 0 , sizeof (* ershdr ) + ERSPAN_V2_MDSIZE );
222
254
223
255
/* Build base header */
224
- ershdr -> ver_vlan = htons ((vlan_tci & VLAN_MASK ) |
225
- (ERSPAN_VERSION2 << VER_OFFSET ));
226
- session_id = (u16 )(ntohl (id ) & ID_MASK ) |
227
- ((tos_to_cos (tos ) << COS_OFFSET ) & COS_MASK ) |
228
- (bso << BSO_OFFSET & BSO_MASK ) |
229
- ((truncate << T_OFFSET ) & T_MASK );
230
- ershdr -> session_id = htons (session_id );
256
+ ershdr -> ver = ERSPAN_VERSION2 ;
257
+ ershdr -> cos = tos_to_cos (tos );
258
+ ershdr -> en = bso ;
259
+ ershdr -> t = truncate ;
260
+ set_vlan (ershdr , vlan_tci );
261
+ set_session_id (ershdr , id );
231
262
232
263
/* Build metadata */
233
264
md = (struct erspan_metadata * )(ershdr + 1 );
234
265
md -> u .md2 .timestamp = erspan_get_timestamp ();
235
266
md -> u .md2 .sgt = htons (sgt );
236
- md -> u .md2 .flags = htons (((1 << P_OFFSET ) & P_MASK ) |
237
- ((hwid << HWID_OFFSET ) & HWID_MASK ) |
238
- ((direction << DIR_OFFSET ) & DIR_MASK ) |
239
- ((gra << GRA_OFFSET ) & GRA_MASK ));
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 );
240
273
}
241
274
242
275
#endif
0 commit comments