@@ -9,10 +9,11 @@ N_LOG_INIT(EthFlowDef);
9
9
10
10
__attribute__((nonnull )) static inline void
11
11
AppendItem (EthFlowDef * flow , size_t * i , enum rte_flow_item_type typ , const void * spec ,
12
- const void * mask , __rte_unused size_t size ) {
12
+ const void * mask , size_t size ) {
13
13
flow -> pattern [* i ].type = typ ;
14
14
flow -> pattern [* i ].spec = spec ;
15
15
flow -> pattern [* i ].mask = mask ;
16
+ flow -> patternSpecLen [* i ] = size ;
16
17
++ (* i );
17
18
NDNDPDK_ASSERT (* i < RTE_DIM (flow -> pattern ));
18
19
}
@@ -45,23 +46,25 @@ PrepareVxlan(const EthLocator* loc, struct rte_vxlan_hdr* vxlanSpec,
45
46
PutEtherHdr ((uint8_t * )innerEthSpec , loc -> innerRemote , loc -> innerLocal , 0 , EtherTypeNDN );
46
47
}
47
48
48
- __attribute__((nonnull )) static inline void
49
- GeneratePattern (EthFlowDef * flow , size_t specLen [], const EthLocator * loc , EthLocatorClass c ,
50
- EthFlowFlags flowFlags ) {
49
+ __attribute__((nonnull )) static inline EthFlowDefResult
50
+ GeneratePattern (EthFlowDef * flow , const EthLocator * loc , EthLocatorClass c , int variant ) {
51
51
size_t i = 0 ;
52
52
#define APPEND (typ , field ) \
53
53
AppendItem(flow, &i, RTE_FLOW_ITEM_TYPE_##typ, &flow->field##Spec, &flow->field##Mask, \
54
- (specLen[i] = sizeof(flow->field##Spec) ))
54
+ sizeof(flow->field##Spec))
55
55
56
56
if (c .passthru ) {
57
- if (flowFlags & EthFlowFlagsPassthruArp ) {
58
- MASK (flow -> ethMask .hdr .ether_type );
59
- flow -> ethSpec .hdr .ether_type = rte_cpu_to_be_16 (RTE_ETHER_TYPE_ARP );
60
- APPEND (ETH , eth );
61
- } else {
62
- flow -> attr .priority = 1 ;
57
+ switch (variant ) {
58
+ case 0 :
59
+ flow -> attr .priority = 1 ;
60
+ return EthFlowDefResultValid ;
61
+ case 1 :
62
+ MASK (flow -> ethMask .hdr .ether_type );
63
+ flow -> ethSpec .hdr .ether_type = rte_cpu_to_be_16 (RTE_ETHER_TYPE_ARP );
64
+ APPEND (ETH , eth );
65
+ return EthFlowDefResultValid ;
63
66
}
64
- return ;
67
+ return 0 ;
65
68
}
66
69
67
70
MASK (flow -> ethMask .hdr .dst_addr );
@@ -83,7 +86,7 @@ GeneratePattern(EthFlowDef* flow, size_t specLen[], const EthLocator* loc, EthLo
83
86
// don't mask EtherType for IPv4/IPv6 - rejected by i40e driver
84
87
MASK (flow -> ethMask .hdr .ether_type );
85
88
MASK (flow -> vlanMask .hdr .eth_proto );
86
- return ;
89
+ return variant == 0 ? EthFlowDefResultValid : 0 ;
87
90
}
88
91
// i40e and several other drivers reject ETH+IP combination, so clear ETH spec
89
92
flow -> pattern [0 ].spec = NULL ;
@@ -109,40 +112,43 @@ GeneratePattern(EthFlowDef* flow, size_t specLen[], const EthLocator* loc, EthLo
109
112
110
113
switch (c .tunnel ) {
111
114
case 'V' : {
112
- if (flowFlags & EthFlowFlagsVxRaw ) {
113
- struct {
114
- struct rte_vxlan_hdr vxlan ;
115
- struct rte_ether_hdr eth ;
116
- } __rte_aligned (2 ) spec = {0 }, mask = {0 };
117
- PrepareVxlan (loc , & spec .vxlan , & mask .vxlan , & spec .eth , & mask .eth );
118
- static_assert (sizeof (spec ) == 4 + 16 + 2 , "" );
119
- PrepareRawItem (flow , 4 , 16 , RTE_PTR_ADD (& spec , 4 ), RTE_PTR_ADD (& mask , 4 ));
120
- APPEND (RAW , raw );
121
- } else {
122
- PrepareVxlan (loc , & flow -> vxlanSpec .hdr , & flow -> vxlanMask .hdr , & flow -> innerEthSpec .hdr ,
123
- & flow -> innerEthMask .hdr );
124
- APPEND (VXLAN , vxlan );
125
- APPEND (ETH , innerEth );
115
+ switch (variant ) {
116
+ case 0 :
117
+ PrepareVxlan (loc , & flow -> vxlanSpec .hdr , & flow -> vxlanMask .hdr , & flow -> innerEthSpec .hdr ,
118
+ & flow -> innerEthMask .hdr );
119
+ APPEND (VXLAN , vxlan );
120
+ APPEND (ETH , innerEth );
121
+ return EthFlowDefResultValid ;
122
+ case 1 : {
123
+ struct {
124
+ struct rte_vxlan_hdr vxlan ;
125
+ struct rte_ether_hdr eth ;
126
+ } __rte_aligned (2 ) spec = {0 }, mask = {0 };
127
+ PrepareVxlan (loc , & spec .vxlan , & mask .vxlan , & spec .eth , & mask .eth );
128
+ static_assert (sizeof (spec ) == 4 + 16 + 2 , "" );
129
+ PrepareRawItem (flow , 4 , 16 , RTE_PTR_ADD (& spec , 4 ), RTE_PTR_ADD (& mask , 4 ));
130
+ APPEND (RAW , raw );
131
+ return EthFlowDefResultValid ;
132
+ }
133
+ default :
134
+ return 0 ;
126
135
}
127
- break ;
128
136
}
129
137
case 'G' : {
130
138
EthGtpHdr spec = {0 }, mask = {0 };
131
139
PutGtpHdr ((uint8_t * )& spec , true, loc -> ulTEID , loc -> ulQFI );
132
140
133
- switch (flowFlags & EthFlowFlagsGtpMask ) {
134
- case EthFlowFlagsGtpGtpu : {
141
+ switch (variant ) {
142
+ case 0 :
135
143
APPEND (GTPU , gtp );
136
144
goto FILL_GTP_ITEM ;
137
- }
138
- case EthFlowFlagsGtpGtp : {
145
+ case 1 :
139
146
APPEND (GTP , gtp );
140
147
FILL_GTP_ITEM :
141
148
flow -> gtpSpec .hdr = spec .hdr ;
142
149
MASK (flow -> gtpMask .hdr .teid );
143
- break ;
144
- }
145
- case EthFlowFlagsGtpRaw : {
150
+ return EthFlowDefResultValid ;
151
+ case 2 :
146
152
// In i40e driver, RAW item can have up to I40E_FDIR_MAX_FLEX_LEN=16 uint16 words, of
147
153
// which up to I40E_FDIR_BITMASK_NUM_WORD=2 words may have a "bit mask" i.e. mask other
148
154
// than 0000 and FFFF, see i40e_flow_store_flex_mask(). We use bit masks on the first and
@@ -155,11 +161,13 @@ GeneratePattern(EthFlowDef* flow, size_t specLen[], const EthLocator* loc, EthLo
155
161
static_assert (sizeof (spec ) == 16 );
156
162
PrepareRawItem (flow , 0 , 16 , & spec , & mask );
157
163
APPEND (RAW , raw );
158
- break ;
159
- }
164
+ return EthFlowDefResultValid ;
165
+ default :
166
+ return 0 ;
160
167
}
161
- break ;
162
168
}
169
+ default :
170
+ return variant == 0 ? EthFlowDefResultValid : 0 ;
163
171
}
164
172
165
173
#undef APPEND
@@ -173,9 +181,9 @@ MaskSpecOctets(uint8_t* spec, const uint8_t* mask, size_t len) {
173
181
}
174
182
175
183
__attribute__((nonnull )) static inline void
176
- CleanPattern (EthFlowDef * flow , size_t specLen [] ) {
184
+ CleanPattern (EthFlowDef * flow ) {
177
185
for (int i = 0 ;; ++ i ) {
178
- size_t itemLen = specLen [i ];
186
+ size_t itemLen = flow -> patternSpecLen [i ];
179
187
struct rte_flow_item * item = & flow -> pattern [i ];
180
188
switch (item -> type ) {
181
189
case RTE_FLOW_ITEM_TYPE_END :
@@ -207,11 +215,9 @@ AppendAction(EthFlowDef* flow, size_t* i, enum rte_flow_action_type typ, const v
207
215
NDNDPDK_ASSERT (* i < RTE_DIM (flow -> pattern ));
208
216
}
209
217
210
- __attribute__((nonnull )) static inline EthFlowFlags
211
- GenerateActions (EthFlowDef * flow , EthLocatorClass c , EthFlowFlags flowFlags , uint32_t mark ,
218
+ __attribute__((nonnull )) static inline EthFlowDefResult
219
+ GenerateActions (EthFlowDef * flow , EthLocatorClass c , int variant , uint32_t mark ,
212
220
const uint16_t queues [], int nQueues ) {
213
- EthFlowFlags addFlowFlags = 0 ;
214
-
215
221
size_t i = 0 ;
216
222
#define APPEND (typ , field ) AppendAction(flow, &i, RTE_FLOW_ACTION_TYPE_##typ, &flow->field##Act)
217
223
@@ -228,19 +234,44 @@ GenerateActions(EthFlowDef* flow, EthLocatorClass c, EthFlowFlags flowFlags, uin
228
234
APPEND (RSS , rss );
229
235
}
230
236
231
- if (!(((flowFlags & EthFlowFlagsRssUnmarked ) && nQueues > 1 ) ||
232
- ((flowFlags & EthFlowFlagsEtherUnmarked ) && !c .udp ))) {
233
- flow -> markAct .id = mark ;
234
- APPEND (MARK , mark );
235
- addFlowFlags |= EthFlowFlagsMarked ;
237
+ if (variant == 1 ) {
238
+ return 0 ;
236
239
}
237
240
241
+ flow -> markAct .id = mark ;
242
+ APPEND (MARK , mark );
243
+ return EthFlowDefResultMarked ;
238
244
#undef APPEND
239
- return addFlowFlags ;
240
245
}
241
246
242
- __attribute__((nonnull )) static inline void
243
- PrintDef (const EthFlowDef * flow , size_t specLen []) {
247
+ EthFlowDefResult
248
+ EthFlowDef_Prepare (EthFlowDef * flow , const EthLocator * loc , int variant , uint32_t mark ,
249
+ const uint16_t queues [], int nQueues ) {
250
+ NDNDPDK_ASSERT (variant < EthFlowDef_MaxVariant );
251
+ EthLocatorClass c = EthLocator_Classify (loc );
252
+ * flow = (const EthFlowDef ){
253
+ .attr .ingress = 1 ,
254
+ };
255
+
256
+ EthFlowDefResult res = GeneratePattern (flow , loc , c , variant / 2 );
257
+ if (!(res & EthFlowDefResultValid )) {
258
+ return 0 ;
259
+ }
260
+
261
+ CleanPattern (flow );
262
+ res |= GenerateActions (flow , c , variant % 2 , mark , queues , nQueues );
263
+ return res ;
264
+ }
265
+
266
+ __attribute__((nonnull )) void
267
+ EthFlowDef_DebugPrint (const EthFlowDef * flow , const char * msg ) {
268
+ if (!N_LOG_ENABLED (DEBUG )) {
269
+ return ;
270
+ }
271
+
272
+ N_LOGD ("%s" , msg );
273
+ N_LOGD ("^ attr group=%" PRIu32 " priority=%" PRIu32 , flow -> attr .group , flow -> attr .priority );
274
+
244
275
for (int i = 0 ;; ++ i ) {
245
276
const struct rte_flow_item * item = & flow -> pattern [i ];
246
277
enum {
@@ -250,9 +281,9 @@ PrintDef(const EthFlowDef* flow, size_t specLen[]) {
250
281
char b16Spec [b16BufSize ] = {'-' , 0 };
251
282
char b16Mask [b16BufSize ] = {'-' , 0 };
252
283
if (item -> spec != NULL && item -> mask != NULL ) {
253
- NDNDPDK_ASSERT (specLen [i ] <= 64 );
254
- Base16_Encode (b16Spec , sizeof (b16Spec ), item -> spec , specLen [i ]);
255
- Base16_Encode (b16Mask , sizeof (b16Mask ), item -> mask , specLen [i ]);
284
+ NDNDPDK_ASSERT (flow -> patternSpecLen [i ] <= 64 );
285
+ Base16_Encode (b16Spec , sizeof (b16Spec ), item -> spec , flow -> patternSpecLen [i ]);
286
+ Base16_Encode (b16Mask , sizeof (b16Mask ), item -> mask , flow -> patternSpecLen [i ]);
256
287
}
257
288
const char * typeName = NULL ;
258
289
if (rte_flow_conv (RTE_FLOW_CONV_OP_ITEM_NAME_PTR , & typeName , sizeof (& typeName ),
@@ -293,25 +324,6 @@ PrintDef(const EthFlowDef* flow, size_t specLen[]) {
293
324
}
294
325
}
295
326
296
- void
297
- EthFlowDef_Prepare (EthFlowDef * flow , const EthLocator * loc , EthFlowFlags * flowFlags , uint32_t mark ,
298
- const uint16_t queues [], int nQueues ) {
299
- EthLocatorClass c = EthLocator_Classify (loc );
300
- * flow = (const EthFlowDef ){0 };
301
- flow -> attr .ingress = 1 ;
302
-
303
- size_t specLen [RTE_DIM (flow -> pattern )];
304
- GeneratePattern (flow , specLen , loc , c , * flowFlags );
305
- CleanPattern (flow , specLen );
306
- * flowFlags |= GenerateActions (flow , c , * flowFlags , mark , queues , nQueues );
307
-
308
- if (N_LOG_ENABLED (DEBUG )) {
309
- N_LOGD ("Prepare loc=%p flow-flags=%08" PRIx32 , loc , * flowFlags );
310
- N_LOGD ("^ attr group=%" PRIu32 " priority=%" PRIu32 , flow -> attr .group , flow -> attr .priority );
311
- PrintDef (flow , specLen );
312
- }
313
- }
314
-
315
327
void
316
328
EthFlowDef_UpdateError (const EthFlowDef * flow , struct rte_flow_error * error ) {
317
329
ptrdiff_t offset = RTE_PTR_DIFF (error -> cause , flow );
0 commit comments