1111#include "message_ipfix.h"
1212#include "modifier.h"
1313
14+ /* Default number of templates stored in mapper */
15+ #define MAPPER_MAX_TEMPLATES 20000
16+
1417ipx_modifier_t *
1518ipx_modifier_create (const struct ipx_modifier_field * fields ,
1619 size_t fields_size ,
@@ -257,34 +260,29 @@ modifier_ctx_find(ipx_modifier_t *mod, const struct ipx_msg_ctx *msg_ctx)
257260 * also includes reseting counter of last used template ID.
258261 *
259262 * \param[in] mod Modifier
260- * \param[out] tmgr_gc Template manager garbage structure
263+ * \param[out] tmgr_gc Generated template garbage
261264 * \return #IPX_OK on success, if current context is not set garbage is set to NULL
262- * \return #IPX_ERR_NOMEM on memory allocation error (garbage is unchanged )
265+ * \return #IPX_ERR_NOMEM on memory allocation error (garbage is NULL )
263266 */
264267static int
265- modifier_ctx_restart (ipx_modifier_t * mod , ipx_msg_garbage_t * * gb_msg )
268+ modifier_ctx_restart (ipx_modifier_t * mod , fds_tgarbage_t * * tmgr_gc )
266269{
267270 if (mod -> curr_ctx == NULL ) {
268- * gb_msg = NULL ;
271+ * tmgr_gc = NULL ;
269272 return IPX_OK ;
270273 }
271274
272275 int rc ;
273- fds_tgarbage_t * mgr_garbage ;
274276
275277 // Clear template manager and get garbage
276278 fds_tmgr_clear (mod -> curr_ctx -> mgr );
277- rc = fds_tmgr_garbage_get (mod -> curr_ctx -> mgr , & mgr_garbage );
279+ rc = fds_tmgr_garbage_get (mod -> curr_ctx -> mgr , tmgr_gc );
278280 if (rc ) {
279281 // Memory allocation error
282+ * tmgr_gc = NULL ;
280283 return rc ;
281284 }
282285
283- if (mgr_garbage != NULL ) {
284- ipx_msg_garbage_cb cb = (ipx_msg_garbage_cb ) & fds_tmgr_garbage_destroy ;
285- * gb_msg = ipx_msg_garbage_create (mgr_garbage , cb );
286- }
287-
288286 // Reset ID counter
289287 mod -> curr_ctx -> next_id = FDS_IPFIX_SET_MIN_DSET ;
290288
@@ -901,17 +899,22 @@ mgr_find_template(ipx_modifier_t *mod, struct fds_template *tmplt)
901899 *
902900 * \param[in] mod Modifier
903901 * \param[in] tmplt Template to store
904- * \param[out] garbage Potential garbage
905- * \return
902+ * \param[out] garbage Potential tmgr_gc from manager
903+ * \return #IPX_OK on success, #IPX_ERR_DENIED on any error and error message is printed
906904 */
907905static int
908- mgr_store_template (ipx_modifier_t * mod , struct fds_template * tmplt , ipx_msg_garbage_t * * garbage )
906+ mgr_store_template (ipx_modifier_t * mod , struct fds_template * tmplt , fds_tgarbage_t * * tmgr_gc )
909907{
910908 // Try to create new ID for template
911909 int rc = template_set_new_id (mod , tmplt );
912910 if (rc == IPX_ERR_LIMIT ) {
913911 // No more IDs available, restart context
914- modifier_ctx_restart (mod , garbage );
912+ if (modifier_ctx_restart (mod , tmgr_gc ) != IPX_OK ) {
913+ MODIFIER_ERROR (mod , "Failed to restart context (%s:%d)" , __FILE__ , __LINE__ );
914+ return IPX_ERR_DENIED ;
915+ }
916+ // Templates in mapper are invalid, clear them too
917+ ipx_mapper_clear (mod -> curr_ctx -> mapper );
915918 // Need to set new ID again
916919 rc = template_set_new_id (mod , tmplt );
917920 assert (rc == IPX_OK );
@@ -929,7 +932,7 @@ mgr_store_template(ipx_modifier_t *mod, struct fds_template *tmplt, ipx_msg_garb
929932 MODIFIER_ERROR (mod , "fds_tmgr_template_add unexpected error (%s:%d)" , __FILE__ , __LINE__ );
930933 break ;
931934 }
932- return rc ;
935+ return IPX_ERR_DENIED ;
933936 }
934937
935938 // Set definitions to new fields (preserve == true)
@@ -944,7 +947,7 @@ mgr_store_template(ipx_modifier_t *mod, struct fds_template *tmplt, ipx_msg_garb
944947 MODIFIER_ERROR (mod , "fds_template_ies_define unexpected error (%s:%d)" , __FILE__ , __LINE__ );
945948 break ;
946949 }
947- return rc ;
950+ return IPX_ERR_DENIED ;
948951 }
949952
950953 return IPX_OK ;
@@ -964,7 +967,32 @@ mapper_add_template(ipx_modifier_t *mod, const struct fds_template *tmplt, uint1
964967}
965968
966969/**
967- * \brief Store template
970+ * \brief Auxiliary structure for storing garbage from template_store function
971+ * Contains both possible grabages generated by template_store function.
972+ */
973+ struct aux_template_store_garbage {
974+ fds_tgarbage_t * mapper_garbage ; /**< Garbage from mapper */
975+ fds_tgarbage_t * context_garbage ; /**< Garbage from manager */
976+ };
977+
978+ /**
979+ * \brief Auxiliary function to destroy garbage from template_store function
980+ *
981+ * \param[in] gb Garbage to destroy
982+ */
983+ void
984+ aux_template_store_garbage_destroy (struct aux_template_store_garbage * gb )
985+ {
986+ if (gb -> mapper_garbage ) {
987+ fds_tmgr_garbage_destroy (gb -> mapper_garbage );
988+ }
989+ if (gb -> context_garbage ) {
990+ fds_tmgr_garbage_destroy (gb -> context_garbage );
991+ }
992+ }
993+
994+ /**
995+ * \brief Store template in modifier
968996 *
969997 * First, try to look for given template in template manager. If template is not
970998 * found, try to add it to manager. In both cases, add mapping to mapper.
@@ -981,9 +1009,23 @@ mapper_add_template(ipx_modifier_t *mod, const struct fds_template *tmplt, uint1
9811009static const struct fds_template *
9821010template_store (ipx_modifier_t * mod , struct fds_template * tmplt , uint16_t original_id , ipx_msg_garbage_t * * garbage )
9831011{
984- // First, try to look in manager for given template
985- struct fds_template * mgr_tmplt = mgr_find_template (mod , tmplt );
9861012 int rc ;
1013+ fds_tgarbage_t * mapper_garbage = NULL ;
1014+ fds_tgarbage_t * context_garbage = NULL ;
1015+
1016+ // First, check if template mapper is not full
1017+ if (ipx_mapper_get_tmplt_count (mod -> curr_ctx -> mapper ) >= MAPPER_MAX_TEMPLATES ) {
1018+ // Clear mapper and get garbage from template manager
1019+ ipx_mapper_clear (mod -> curr_ctx -> mapper );
1020+ rc = fds_tmgr_garbage_get (mod -> curr_ctx -> mgr , & mapper_garbage );
1021+ if (rc != IPX_OK ) {
1022+ MODIFIER_ERROR (mod , "Failed to get garbage from template manager (%s:%d)" , __FILE__ , __LINE__ );
1023+ return NULL ;
1024+ }
1025+ }
1026+
1027+ // Try to find template in template manager
1028+ struct fds_template * mgr_tmplt = mgr_find_template (mod , tmplt );
9871029
9881030 if (mgr_tmplt ) {
9891031 // Template exists in manager, add mapping
@@ -992,14 +1034,30 @@ template_store(ipx_modifier_t *mod, struct fds_template *tmplt, uint16_t origina
9921034 }
9931035
9941036 // Template not found in manager, try to add it
995- rc = mgr_store_template (mod , tmplt , garbage );
996- if (rc ) {
1037+ rc = mgr_store_template (mod , tmplt , & context_garbage );
1038+ if (rc != IPX_OK ) {
9971039 // Message has been generated
9981040 return NULL ;
9991041 }
10001042
10011043 // Add new mapping
10021044 mapper_add_template (mod , tmplt , original_id );
1045+
1046+ // If any garbage was generated, create garbage message from it
1047+ if (mapper_garbage || context_garbage ) {
1048+ struct aux_template_store_garbage * gb = malloc (sizeof (* gb ));
1049+ if (gb == NULL ) {
1050+ MODIFIER_ERROR (mod , "Memory allocation failed (%s:%d)" , __FILE__ , __LINE__ );
1051+ return NULL ;
1052+ }
1053+
1054+ gb -> mapper_garbage = mapper_garbage ;
1055+ gb -> context_garbage = context_garbage ;
1056+
1057+ ipx_msg_garbage_cb cb = (ipx_msg_garbage_cb ) & aux_template_store_garbage_destroy ;
1058+ * garbage = ipx_msg_garbage_create (gb , cb );
1059+ }
1060+
10031061 return tmplt ;
10041062}
10051063
@@ -1143,7 +1201,7 @@ ipx_modifier_modify(ipx_modifier_t *mod, const struct fds_drec *rec, ipx_msg_gar
11431201 if (fields_update (new_rec , mod , buffers , filter ) != IPX_OK ) {
11441202 MODIFIER_ERROR (mod , "Failed to update fields in record (%s:%d)" , __FILE__ , __LINE__ );
11451203 free (new_rec );
1146- // Do not free template, as it is stored in modifier
1204+ // DO NOT free modified template, as it is stored in modifier
11471205 return NULL ;
11481206 }
11491207
0 commit comments