Skip to content

Commit aa8fe7f

Browse files
committed
UniRec output: added support for UniRec arrays
1 parent 06f0fe5 commit aa8fe7f

File tree

3 files changed

+508
-30
lines changed

3 files changed

+508
-30
lines changed

extra_plugins/output/unirec/src/map.c

Lines changed: 85 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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!

extra_plugins/output/unirec/src/map.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ enum MAP_FLAGS {
6868

6969
/** IPFIX-to-UniRec mapping record */
7070
struct map_rec {
71-
struct {
71+
struct map_ipfix_s {
7272
/**
7373
* \brief Data source
7474
* \note If the field is not ::MAP_SRC_IPFIX, parameters en, id and def are NOT defined!
@@ -81,6 +81,7 @@ struct map_rec {
8181
uint16_t id;
8282
/** Definition of the IE (MUST not be NULL) */
8383
const struct fds_iemgr_elem *def;
84+
struct map_ipfix_s *next;
8485
} ipfix; /**< IPFIX specific parameters */
8586

8687
struct {

0 commit comments

Comments
 (0)