@@ -69,6 +69,7 @@ struct ipxfil_lookup_table {
6969
7070struct ipxfil_lookup_state {
7171 size_t source_idx ;
72+ uint16_t find_flags ; // 0, FDS_DREC_BIFLOW_FWD or FDS_DREC_BIFLOW_REV
7273};
7374
7475struct fds_ipfix_filter {
@@ -81,6 +82,27 @@ struct fds_ipfix_filter {
8182 struct ipxfil_lookup_state lookup_state ;
8283};
8384
85+ /**
86+ * Same as fds_drec_find, but with flags (see fds_drec_iter_init documentation).
87+ */
88+ static int
89+ fds_drec_find_with_flags (struct fds_drec * drec , uint32_t pen , uint16_t id , uint16_t flags , struct fds_drec_field * field )
90+ {
91+ if (flags == 0 ) {
92+ return fds_drec_find (drec , pen , id , field );
93+
94+ } else {
95+ struct fds_drec_iter iter ;
96+ fds_drec_iter_init (& iter , drec , flags );
97+
98+ int ret = fds_drec_iter_find (& iter , pen , id );
99+ if (ret != FDS_EOC ) {
100+ * field = iter .field ;
101+ }
102+ return ret ;
103+ }
104+ }
105+
84106/**
85107 * Calculate index of a lookup item in a lookup table
86108 */
@@ -293,13 +315,13 @@ set_default_value(fds_filter_value_u *out_value)
293315 * Try to read the desired field from a record into a filter value
294316 */
295317static int
296- read_record_field (struct fds_drec * record , const struct fds_iemgr_elem * field_def ,
318+ read_record_field (struct fds_drec * record , const struct fds_iemgr_elem * field_def , uint16_t find_flags ,
297319 fds_filter_value_u * out_value )
298320{
299321 struct fds_drec_field field ;
300322
301323 // The wanted field does not exist in the record
302- if (fds_drec_find (record , field_def -> scope -> pen , field_def -> id , & field ) == FDS_EOC ) {
324+ if (fds_drec_find_with_flags (record , field_def -> scope -> pen , field_def -> id , find_flags , & field ) == FDS_EOC ) {
303325 return FDS_ERR_NOTFOUND ;
304326 }
305327
@@ -390,13 +412,13 @@ read_record_field(struct fds_drec *record, const struct fds_iemgr_elem *field_de
390412 * Read the first source that is found in the record
391413 */
392414static bool
393- read_first_of (struct fds_drec * record , const struct fds_iemgr_alias * alias , size_t * source_idx ,
415+ read_first_of (struct fds_drec * record , const struct fds_iemgr_alias * alias , size_t * source_idx , uint16_t find_flags ,
394416 fds_filter_value_u * out_value )
395417{
396418 while (* source_idx < alias -> sources_cnt ) {
397419 const struct fds_iemgr_elem * field_def = alias -> sources [* source_idx ];
398420 (* source_idx )++ ;
399- if (read_record_field (record , field_def , out_value ) == FDS_OK ) {
421+ if (read_record_field (record , field_def , find_flags , out_value ) == FDS_OK ) {
400422 return true;
401423 }
402424 }
@@ -427,7 +449,7 @@ data_callback(void *user_ctx, bool reset_ctx, int id, void *data, fds_filter_val
427449 case FDS_ALIAS_FIRST_OF :
428450 if (reset_ctx ) {
429451 ipxfil -> lookup_state .source_idx = 0 ;
430- return read_first_of (rec , item -> alias , & ipxfil -> lookup_state .source_idx , out_value )
452+ return read_first_of (rec , item -> alias , & ipxfil -> lookup_state .source_idx , ipxfil -> lookup_state . find_flags , out_value )
431453 ? FDS_OK : FDS_ERR_NOTFOUND ;
432454 }
433455 set_default_value (out_value );
@@ -437,15 +459,15 @@ data_callback(void *user_ctx, bool reset_ctx, int id, void *data, fds_filter_val
437459 if (reset_ctx ) {
438460 ipxfil -> lookup_state .source_idx = 0 ;
439461 }
440- return read_first_of (rec , item -> alias , & ipxfil -> lookup_state .source_idx , out_value )
462+ return read_first_of (rec , item -> alias , & ipxfil -> lookup_state .source_idx , ipxfil -> lookup_state . find_flags , out_value )
441463 ? FDS_OK_MORE : FDS_ERR_NOTFOUND ;
442464 default :
443465 assert (0 );
444466 }
445467 break ;
446468
447469 case IPXFIL_FIELD_LOOKUP : {
448- int rc = read_record_field (rec , item -> elem , out_value );
470+ int rc = read_record_field (rec , item -> elem , ipxfil -> lookup_state . find_flags , out_value );
449471 if (rc != FDS_OK ) {
450472 set_default_value (out_value );
451473 }
@@ -491,9 +513,30 @@ bool
491513fds_ipfix_filter_eval (struct fds_ipfix_filter * ipxfil , struct fds_drec * record )
492514{
493515 ipxfil -> lookup_state .source_idx = 0 ;
516+ ipxfil -> lookup_state .find_flags = 0 ;
494517 return fds_filter_eval (ipxfil -> filter , record );
495518}
496519
520+ enum fds_ipfix_filter_match
521+ fds_ipfix_filter_eval_biflow (struct fds_ipfix_filter * ipxfil , struct fds_drec * record )
522+ {
523+ int result = 0 ;
524+
525+ ipxfil -> lookup_state .source_idx = 0 ;
526+ ipxfil -> lookup_state .find_flags = FDS_DREC_BIFLOW_FWD ;
527+ if (fds_filter_eval (ipxfil -> filter , record )) {
528+ result |= FDS_IPFIX_FILTER_MATCH_FWD ;
529+ }
530+
531+ ipxfil -> lookup_state .source_idx = 0 ;
532+ ipxfil -> lookup_state .find_flags = FDS_DREC_BIFLOW_REV ;
533+ if (fds_filter_eval (ipxfil -> filter , record )) {
534+ result |= FDS_IPFIX_FILTER_MATCH_REV ;
535+ }
536+
537+ return result ;
538+ }
539+
497540void
498541fds_ipfix_filter_destroy (struct fds_ipfix_filter * ipxfil )
499542{
0 commit comments