@@ -193,6 +193,40 @@ ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
193
193
return 0 ;
194
194
}
195
195
196
+ /* Sizes of fixed known protocol headers without header options */
197
+ #define ICE_FLOW_PROT_HDR_SZ_MAC 14
198
+ #define ICE_FLOW_PROT_HDR_SZ_IPV4 20
199
+ #define ICE_FLOW_PROT_HDR_SZ_IPV6 40
200
+ #define ICE_FLOW_PROT_HDR_SZ_TCP 20
201
+ #define ICE_FLOW_PROT_HDR_SZ_UDP 8
202
+ #define ICE_FLOW_PROT_HDR_SZ_SCTP 12
203
+
204
+ /**
205
+ * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
206
+ * @params: information about the flow to be processed
207
+ * @seg: index of packet segment whose header size is to be determined
208
+ */
209
+ static u16 ice_flow_calc_seg_sz (struct ice_flow_prof_params * params , u8 seg )
210
+ {
211
+ u16 sz = ICE_FLOW_PROT_HDR_SZ_MAC ;
212
+
213
+ /* L3 headers */
214
+ if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_IPV4 )
215
+ sz += ICE_FLOW_PROT_HDR_SZ_IPV4 ;
216
+ else if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_IPV6 )
217
+ sz += ICE_FLOW_PROT_HDR_SZ_IPV6 ;
218
+
219
+ /* L4 headers */
220
+ if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_TCP )
221
+ sz += ICE_FLOW_PROT_HDR_SZ_TCP ;
222
+ else if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_UDP )
223
+ sz += ICE_FLOW_PROT_HDR_SZ_UDP ;
224
+ else if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_SCTP )
225
+ sz += ICE_FLOW_PROT_HDR_SZ_SCTP ;
226
+
227
+ return sz ;
228
+ }
229
+
196
230
/**
197
231
* ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
198
232
* @params: information about the flow to be processed
@@ -347,6 +381,81 @@ ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
347
381
return 0 ;
348
382
}
349
383
384
+ /**
385
+ * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
386
+ * @hw: pointer to the HW struct
387
+ * @params: information about the flow to be processed
388
+ * @seg: index of packet segment whose raw fields are to be be extracted
389
+ */
390
+ static enum ice_status
391
+ ice_flow_xtract_raws (struct ice_hw * hw , struct ice_flow_prof_params * params ,
392
+ u8 seg )
393
+ {
394
+ u16 fv_words ;
395
+ u16 hdrs_sz ;
396
+ u8 i ;
397
+
398
+ if (!params -> prof -> segs [seg ].raws_cnt )
399
+ return 0 ;
400
+
401
+ if (params -> prof -> segs [seg ].raws_cnt >
402
+ ARRAY_SIZE (params -> prof -> segs [seg ].raws ))
403
+ return ICE_ERR_MAX_LIMIT ;
404
+
405
+ /* Offsets within the segment headers are not supported */
406
+ hdrs_sz = ice_flow_calc_seg_sz (params , seg );
407
+ if (!hdrs_sz )
408
+ return ICE_ERR_PARAM ;
409
+
410
+ fv_words = hw -> blk [params -> blk ].es .fvw ;
411
+
412
+ for (i = 0 ; i < params -> prof -> segs [seg ].raws_cnt ; i ++ ) {
413
+ struct ice_flow_seg_fld_raw * raw ;
414
+ u16 off , cnt , j ;
415
+
416
+ raw = & params -> prof -> segs [seg ].raws [i ];
417
+
418
+ /* Storing extraction information */
419
+ raw -> info .xtrct .prot_id = ICE_PROT_MAC_OF_OR_S ;
420
+ raw -> info .xtrct .off = (raw -> off / ICE_FLOW_FV_EXTRACT_SZ ) *
421
+ ICE_FLOW_FV_EXTRACT_SZ ;
422
+ raw -> info .xtrct .disp = (raw -> off % ICE_FLOW_FV_EXTRACT_SZ ) *
423
+ BITS_PER_BYTE ;
424
+ raw -> info .xtrct .idx = params -> es_cnt ;
425
+
426
+ /* Determine the number of field vector entries this raw field
427
+ * consumes.
428
+ */
429
+ cnt = DIV_ROUND_UP (raw -> info .xtrct .disp +
430
+ (raw -> info .src .last * BITS_PER_BYTE ),
431
+ (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE ));
432
+ off = raw -> info .xtrct .off ;
433
+ for (j = 0 ; j < cnt ; j ++ ) {
434
+ u16 idx ;
435
+
436
+ /* Make sure the number of extraction sequence required
437
+ * does not exceed the block's capability
438
+ */
439
+ if (params -> es_cnt >= hw -> blk [params -> blk ].es .count ||
440
+ params -> es_cnt >= ICE_MAX_FV_WORDS )
441
+ return ICE_ERR_MAX_LIMIT ;
442
+
443
+ /* some blocks require a reversed field vector layout */
444
+ if (hw -> blk [params -> blk ].es .reverse )
445
+ idx = fv_words - params -> es_cnt - 1 ;
446
+ else
447
+ idx = params -> es_cnt ;
448
+
449
+ params -> es [idx ].prot_id = raw -> info .xtrct .prot_id ;
450
+ params -> es [idx ].off = off ;
451
+ params -> es_cnt ++ ;
452
+ off += ICE_FLOW_FV_EXTRACT_SZ ;
453
+ }
454
+ }
455
+
456
+ return 0 ;
457
+ }
458
+
350
459
/**
351
460
* ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
352
461
* @hw: pointer to the HW struct
@@ -373,6 +482,11 @@ ice_flow_create_xtrct_seq(struct ice_hw *hw,
373
482
if (status )
374
483
return status ;
375
484
}
485
+
486
+ /* Process raw matching bytes */
487
+ status = ice_flow_xtract_raws (hw , params , i );
488
+ if (status )
489
+ return status ;
376
490
}
377
491
378
492
return status ;
@@ -943,6 +1057,42 @@ ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
943
1057
ice_flow_set_fld_ext (seg , fld , t , val_loc , mask_loc , last_loc );
944
1058
}
945
1059
1060
+ /**
1061
+ * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1062
+ * @seg: packet segment the field being set belongs to
1063
+ * @off: offset of the raw field from the beginning of the segment in bytes
1064
+ * @len: length of the raw pattern to be matched
1065
+ * @val_loc: location of the value to match from entry's input buffer
1066
+ * @mask_loc: location of mask value from entry's input buffer
1067
+ *
1068
+ * This function specifies the offset of the raw field to be match from the
1069
+ * beginning of the specified packet segment, and the locations, in the form of
1070
+ * byte offsets from the start of the input buffer for a flow entry, from where
1071
+ * the value to match and the mask value to be extracted. These locations are
1072
+ * then stored in the flow profile. When adding flow entries to the associated
1073
+ * flow profile, these locations can be used to quickly extract the values to
1074
+ * create the content of a match entry. This function should only be used for
1075
+ * fixed-size data structures.
1076
+ */
1077
+ void
1078
+ ice_flow_add_fld_raw (struct ice_flow_seg_info * seg , u16 off , u8 len ,
1079
+ u16 val_loc , u16 mask_loc )
1080
+ {
1081
+ if (seg -> raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX ) {
1082
+ seg -> raws [seg -> raws_cnt ].off = off ;
1083
+ seg -> raws [seg -> raws_cnt ].info .type = ICE_FLOW_FLD_TYPE_SIZE ;
1084
+ seg -> raws [seg -> raws_cnt ].info .src .val = val_loc ;
1085
+ seg -> raws [seg -> raws_cnt ].info .src .mask = mask_loc ;
1086
+ /* The "last" field is used to store the length of the field */
1087
+ seg -> raws [seg -> raws_cnt ].info .src .last = len ;
1088
+ }
1089
+
1090
+ /* Overflows of "raws" will be handled as an error condition later in
1091
+ * the flow when this information is processed.
1092
+ */
1093
+ seg -> raws_cnt ++ ;
1094
+ }
1095
+
946
1096
#define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
947
1097
(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
948
1098
0 commit comments