@@ -101,6 +101,13 @@ map_clear(map_t *map)
101101{
102102 for (size_t i = 0 ; i < map -> rec_size ; ++ i ) {
103103 struct map_rec * rec = map -> rec_array [i ];
104+ struct map_ipfix_s * ipfix = rec -> ipfix .next ;
105+ while (ipfix ) {
106+ struct map_ipfix_s * tmp = ipfix -> next ;
107+ free (ipfix );
108+ ipfix = tmp ;
109+ }
110+
104111 free (rec -> unirec .name );
105112 free (rec -> unirec .type_str );
106113 free (rec );
@@ -280,15 +287,48 @@ map_load_line_ie_defs(map_t *map, char *ur_name, int ur_type, char *ur_type_str,
280287 }
281288
282289 // Parse IPFIX specifier
283- const struct fds_iemgr_elem * elem_def = map_elem_get_ipfix (map -> iemgr , subtoken );
290+ const struct fds_iemgr_elem * elem_def = NULL ;
291+ char * subsave_ptr_list = NULL ;
292+ struct map_ipfix_s * ipfix = & rec .ipfix ;
293+ rec .ipfix .next = NULL ;
294+ for (char * list = subtoken ; ;list = NULL ) {
295+ char * list_token = strtok_r (list , "/" , & subsave_ptr_list );
296+ if (!list_token ) {
297+ break ;
298+ }
299+
300+ elem_def = map_elem_get_ipfix (map -> iemgr , list_token );
301+ if (elem_def != NULL ) {
302+ if (list == NULL ) {
303+ ipfix -> next = malloc (sizeof (struct map_ipfix_s ));
304+ if (!ipfix -> next ) {
305+ rc = IPX_ERR_NOMEM ;
306+ elem_def = NULL ;
307+ break ;
308+ }
309+ ipfix = ipfix -> next ;
310+ }
311+ // Store the "IPFIX element" record
312+ ipfix -> source = MAP_SRC_IPFIX ;
313+ ipfix -> def = elem_def ;
314+ ipfix -> id = elem_def -> id ;
315+ ipfix -> en = elem_def -> scope -> pen ;
316+ ipfix -> next = NULL ;
317+
318+ continue ;
319+ }
320+ break ;
321+ }
284322 if (elem_def != NULL ) {
285- // Store the "IPFIX element" record
286- rec .ipfix .source = MAP_SRC_IPFIX ;
287- rec .ipfix .def = elem_def ;
288- rec .ipfix .id = elem_def -> id ;
289- rec .ipfix .en = elem_def -> scope -> pen ;
290- rc = map_rec_add (map , & rec );
291- continue ;
323+ rc = map_rec_add (map , & rec );
324+ continue ;
325+ }
326+
327+ ipfix = rec .ipfix .next ;
328+ while (ipfix ) {
329+ struct map_ipfix_s * tmp = ipfix -> next ;
330+ free (ipfix );
331+ ipfix = tmp ;
292332 }
293333
294334 enum MAP_SRC fn_id = map_elem_get_internal (subtoken );
@@ -298,6 +338,7 @@ map_load_line_ie_defs(map_t *map, char *ur_name, int ur_type, char *ur_type_str,
298338 rec .ipfix .def = NULL ;
299339 rec .ipfix .id = 0 ;
300340 rec .ipfix .en = 0 ;
341+ rec .ipfix .next = NULL ;
301342 rc = map_rec_add (map , & rec );
302343 continue ;
303344 }
@@ -431,6 +472,24 @@ map_sort_fn(const void *p1, const void *p2)
431472 return (rec1 -> ipfix .id < rec2 -> ipfix .id ) ? (-1 ) : 1 ;
432473 }
433474
475+ // TODO: better and more readable code
476+ // TODO: check all elements in linked list
477+ if (rec1 -> ipfix .next != NULL && rec2 -> ipfix .next != NULL ) {
478+ // Primary sort by PEN
479+ if (rec1 -> ipfix .next -> en != rec2 -> ipfix .next -> en ) {
480+ return (rec1 -> ipfix .next -> en < rec2 -> ipfix .next -> en ) ? (-1 ) : 1 ;
481+ }
482+
483+ // Secondary sort by ID
484+ if (rec1 -> ipfix .next -> id != rec2 -> ipfix .next -> id ) {
485+ return (rec1 -> ipfix .next -> id < rec2 -> ipfix .next -> id ) ? (-1 ) : 1 ;
486+ }
487+ } else if (rec1 -> ipfix .next != NULL ) {
488+ return -1 ;
489+ } else if (rec2 -> ipfix .next != NULL ) {
490+ return 1 ;
491+ }
492+
434493 return 0 ;
435494}
436495
@@ -507,9 +566,24 @@ map_load(map_t *map, const char *file)
507566 continue ;
508567 }
509568
510- if (rec_prev -> ipfix .en != rec_now -> ipfix .en || rec_prev -> ipfix .id != rec_now -> ipfix .id ) {
511- rec_prev = rec_now ;
512- continue ;
569+ bool collision = false;
570+ const struct map_ipfix_s * ipfix_prev = & rec_prev -> ipfix ;
571+ const struct map_ipfix_s * ipfix_now = & rec_now -> ipfix ;
572+ while (1 ) {
573+ if (ipfix_prev -> en != ipfix_now -> en || ipfix_prev -> id != ipfix_now -> id || !ipfix_prev || !ipfix_now ) {
574+ rec_prev = rec_now ;
575+ break ;
576+ }
577+
578+ ipfix_prev = ipfix_prev -> next ;
579+ ipfix_now = ipfix_now -> next ;
580+ if (!ipfix_prev && !ipfix_now ) {
581+ collision = true;
582+ break ;
583+ }
584+ }
585+ if (!collision ) {
586+ continue ;
513587 }
514588
515589 // Collision detected!
0 commit comments