RE: Problem with dynamic row creation and free inside the table.

"Graeme Wilson" <[email protected]>
Newsgroups gmane.network.net-snmp.user
Message-ID <[email protected]>
Hi,
Not sure if you ever found a solution/workaround to this, but I had a
similar problem a while ago (with the free functions not getting called
correctly, or getting called too many times) - and posted a email or 2
on the list as well - I suspect there is a bug.
In the end I moved to using the MFD-iterator style code.
 
Regards
Graeme



________________________________

	From: [email protected]
[mailto:[email protected]] On Behalf Of
Sreenath S
	Sent: 10 August 2007 10:33
	To: [email protected]
	Subject: Problem with dynamic row creation and free inside the
table.
	
	
	Hi All,
	
	In my table implementation, I am creating a row inside the
	"xxx_get_first_data_point" function using "xxx_createEntry" 
	till it reaches the maximum allowed count, as the row creation 
	needs to be dynamic. But I don't know the correct way to free 
	these allocated rows.
	
	The function "xxx_free_loop_context_at_end" is not getting
called 
	even if it is given in the function pointer like this, 
	"iinfo->free_loop_context_at_end =
xxx_free_loop_context_at_end".
	But "xxx_free_data_context" will gets called if it is given in
	"iinfo->free_data_context = xxx_free_data_context_at_end".
	
	Even this "xxx_free_data_context_at_end" doesn't help, as it is 
	called on every time "xxx_get_next_data_point" returns NULL. 
	On a "snmpwalk" the "net-snmp handler" is called in a column 
	wise order, so traversal through same row happens multiple times
	for each column value and "xxx_get_next_data_point" returns NULL

	on each occasion. So I am getting only the first column values 
	for each row after "snmpwalk". This is because after the
traversal 
	for first column the entire row gets freed.
	
	If anybody knows the solution for this please reply back. Please

	find the source code and "snmpwalk" output below for the
reference.
	
	Best Regards,
	Sreenath 
	
	
	SOURCE CODE
	===========
	
	/*
	 * Note: this file originally auto-generated by mib2c using
	 *  : mib2c.iterate.conf,v 1.4 2004/10/14 19:48:52 slozovsk Exp
$
	 */
	
	#include <net-snmp/net-snmp-config.h>
	#include <net-snmp/net-snmp-includes.h>
	#include <net-snmp/agent/net-snmp-agent-includes.h>
	#include "dot1xPaePortTable.h"
	
	struct dot1xPaePortTable_entry *dot1xPaePortTable_head = NULL;
	static int rowCount = 0;
	
	/** Initializes the dot1xPaePortTable module */
	void
	init_dot1xPaePortTable(void)
	{
	    /*
	     * here we initialize all the tables we're planning on
supporting 
	     */
	    initialize_table_dot1xPaePortTable();
	}
	
	/** Initialize the dot1xPaePortTable table by defining its
contents and how it's
	 * structured */
	void
	initialize_table_dot1xPaePortTable(void)
	{
	    static oid      dot1xPaePortTable_oid[] =
	        { 1, 0, 8802, 1, 1, 1, 1, 1, 2 };
	    size_t          dot1xPaePortTable_oid_len =
	        OID_LENGTH(dot1xPaePortTable_oid);
	    netsnmp_handler_registration *reg;
	    netsnmp_iterator_info *iinfo;
	    netsnmp_table_registration_info *table_info;
	    
	    reg =
	        netsnmp_create_handler_registration("dot1xPaePortTable",
	
dot1xPaePortTable_handler,
	
dot1xPaePortTable_oid,
	
dot1xPaePortTable_oid_len,
	                                            HANDLER_CAN_RWRITE);
	
	    table_info =
SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
	    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,
/* index:
	                                     dot1xPaePortNumber */
	                                     0);
	    table_info->min_column = 2;
	    table_info->max_column = 5;
	
	    iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
	    iinfo->get_first_data_point =
dot1xPaePortTable_get_first_data_point;
	    iinfo->get_next_data_point =
dot1xPaePortTable_get_next_data_point;
	    iinfo->table_reginfo = table_info;
	   
	    iinfo->free_loop_context = NULL;
	    iinfo->free_data_context =
dot1xPaePortTable_free_loop_context_at_end;
	    iinfo->free_loop_context_at_end =
dot1xPaePortTable_free_loop_context_at_end;
	
	    netsnmp_register_table_iterator(reg, iinfo);
	    
	    /*
	     * Initialise the contents of the table here 
	     */
	}
	
	
	/*
	 * create a new row in the (unsorted) table 
	 */
	struct dot1xPaePortTable_entry *
	dot1xPaePortTable_createEntry(long dot1xPaePortNumber)
	{
	    struct dot1xPaePortTable_entry *entry = NULL;
	    
	    entry = SNMP_MALLOC_TYPEDEF(struct dot1xPaePortTable_entry);
	    if (!entry)
	        return NULL;
	
	    entry->dot1xPaePortNumber = dot1xPaePortNumber;
	    entry->valid = 1;
	    entry->next = dot1xPaePortTable_head;
	    dot1xPaePortTable_head = entry;
	    
	    return entry;
	}
	
	/*
	 * remove a row from the table 
	 */
	void
	dot1xPaePortTable_removeEntry(struct dot1xPaePortTable_entry
*entry)
	{
	    struct dot1xPaePortTable_entry *ptr, *prev;
	    
	    if (!entry)
	        return;                 /* Nothing to remove */
	
	    for (ptr = dot1xPaePortTable_head, prev = NULL;
	         ptr != NULL; prev = ptr, ptr = ptr->next) {
	        if (ptr == entry)
	            break;
	    }
	    if (!ptr)
	        return;                 /* Can't find it */
	
	    if (prev == NULL)
	        dot1xPaePortTable_head = ptr->next;
	    else
	        prev->next = ptr->next;
	
	    SNMP_FREE(entry);           /* XXX - release any other
internal resources */
	}
	
	void
	dot1xPaePortTable_free_loop_context_at_end(void
*my_loop_context,
	
netsnmp_iterator_info *iinfo)
	{
	    struct dot1xPaePortTable_entry *ptr;
	 
	    ptr = (struct dot1xPaePortTable_entry *) my_loop_context;
	    
	    dot1xPaePortTable_removeEntry(ptr);
	}
	
	/*
	 * Example iterator hook routines - using 'get_next' to do most
of the work 
	 */
	netsnmp_variable_list *
	dot1xPaePortTable_get_first_data_point(void **my_loop_context,
	                                                           void
**my_data_context,
	
netsnmp_variable_list *
	
put_index_data,
	
netsnmp_iterator_info *mydata)
	{
	    netsnmp_variable_list * ret_val = NULL;
	
	   if (rowCount < MAX_ROW_COUNT)
	        dot1xPaePortTable_createEntry(++rowCount);
	    
	    *my_loop_context = dot1xPaePortTable_head;
	    ret_val =
dot1xPaePortTable_get_next_data_point(my_loop_context,
	
my_data_context,
	
put_index_data, mydata);
	    return ret_val;
	}
	
	netsnmp_variable_list *
	dot1xPaePortTable_get_next_data_point(void **my_loop_context,
	                                      void **my_data_context,
	                                      netsnmp_variable_list *
	                                      put_index_data,
	                                      netsnmp_iterator_info
*mydata)
	{
	    struct dot1xPaePortTable_entry *entry =
	        (struct dot1xPaePortTable_entry *) *my_loop_context;
	    netsnmp_variable_list *idx = put_index_data;
	    
	    if (NULL != entry) {
	        snmp_set_var_value(idx, (u_char
*)&(entry->dot1xPaePortNumber),
	                           sizeof(entry->dot1xPaePortNumber));
	
	        idx = idx->next_variable;
	        *my_data_context = (void *) entry;
	        *my_loop_context = (void *) entry->next;
	        return put_index_data;
	    } else {
	        return NULL;
	    }
	}
	
	
	/** handles requests for the dot1xPaePortTable table */
	int
	dot1xPaePortTable_handler(netsnmp_mib_handler *handler,
	                          netsnmp_handler_registration *reginfo,
	                          netsnmp_agent_request_info *reqinfo,
	                          netsnmp_request_info *requests)
	{
	    netsnmp_request_info *request;
	    netsnmp_table_request_info *table_info;
	    struct dot1xPaePortTable_entry *table_entry;
	    
	    switch (reqinfo->mode) {
	        /*
	         * Read-support (also covers GetNext requests)
	         */
	    case MODE_GET:
	        for (request = requests; request; request =
request->next) {
	            if (request->processed != 0) {
	                continue;
	            }
	
	            table_entry = (struct dot1xPaePortTable_entry *)
	                netsnmp_extract_iterator_context(request);
	            if (table_entry == NULL) {
	                continue;
	            }
	
	            table_info = netsnmp_extract_table_info(request);
	            if (table_info == NULL) {
	                continue;
	            }
	
	            switch (table_info->colnum) {
	            case COLUMN_DOT1XPAEPORTPROTOCOLVERSION:
	                table_entry->dot1xPaePortProtocolVersion = 1;
	                
	                snmp_set_var_typed_value(request->requestvb,
ASN_UNSIGNED,
	                                         (u_char
*)&(table_entry->
	
dot1xPaePortProtocolVersion),
	                                         sizeof(table_entry->
	
dot1xPaePortProtocolVersion));
	                break;
	            case COLUMN_DOT1XPAEPORTCAPABILITIES:
	                table_entry->dot1xPaePortCapabilities = 2; 
	               
	                snmp_set_var_typed_value(request->requestvb,
ASN_BIT_STR,
	                                         (u_char
*)&(table_entry->
	
dot1xPaePortCapabilities),
	                                         sizeof(table_entry->
	
dot1xPaePortCapabilities));
	                break;
	            case COLUMN_DOT1XPAEPORTINITIALIZE:
	                table_entry->dot1xPaePortInitialize = 3;
	                
	                snmp_set_var_typed_value(request->requestvb,
ASN_INTEGER,
	                                         (u_char
*)&(table_entry->
	
dot1xPaePortInitialize),
	                                         sizeof(table_entry->
	
dot1xPaePortInitialize));
	                break;
	            case COLUMN_DOT1XPAEPORTREAUTHENTICATE:
	                table_entry->dot1xPaePortReauthenticate = 4;
	               
	                snmp_set_var_typed_value(request->requestvb,
ASN_INTEGER,
	                                         (u_char
*)&(table_entry->
	
dot1xPaePortReauthenticate),
	                                         sizeof(table_entry->
	
dot1xPaePortReauthenticate));
	                break;
	            }
	        }
	        break;
	
	        /*
	         * Write-support
	         */
	    case MODE_SET_RESERVE1:
	        #if 0
	        for (request = requests; request; request =
request->next) {
	            table_entry = (struct dot1xPaePortTable_entry *)
	                netsnmp_extract_iterator_context(request);
	            table_info = netsnmp_extract_table_info(request);
	
	            switch (table_info->colnum) {
	            case COLUMN_DOT1XPAEPORTINITIALIZE:
	                if (request->requestvb->type != ASN_INTEGER) {
	                    netsnmp_set_request_error(reqinfo, request,
	
SNMP_ERR_WRONGTYPE);
	                    return SNMP_ERR_WRONGTYPE;
	                }
	                /*
	                 * Also may need to check size/value 
	                 */
	                break;
	            case COLUMN_DOT1XPAEPORTREAUTHENTICATE:
	                if (request->requestvb->type != ASN_INTEGER) {
	                    netsnmp_set_request_error(reqinfo, request,
	
SNMP_ERR_WRONGTYPE);
	                    return SNMP_ERR_WRONGTYPE;
	                }
	                /*
	                 * Also may need to check size/value 
	                 */
	                break;
	            default:
	                netsnmp_set_request_error(reqinfo, request,
	                                          SNMP_ERR_NOTWRITABLE);
	                return SNMP_ERR_NOTWRITABLE;
	            }
	        }
	        #endif
	        break;
	
	    case MODE_SET_RESERVE2:
	        break;
	
	    case MODE_SET_FREE:
	        break;
	
	    case MODE_SET_ACTION:
	        #if 0
	        for (request = requests; request; request =
request->next) {
	            table_entry = (struct dot1xPaePortTable_entry *)
	                netsnmp_extract_iterator_context(request);
	            table_info = netsnmp_extract_table_info(request);
	
	            switch (table_info->colnum) {
	            case COLUMN_DOT1XPAEPORTINITIALIZE:
	                /*
	                 * Need to save old
'table_entry->dot1xPaePortInitialize' value.
	                 * May need to use 'memcpy' 
	                 */
	                table_entry->old_dot1xPaePortInitialize =
	                    table_entry->dot1xPaePortInitialize;
	                table_entry->dot1xPaePortInitialize =
	                    request->requestvb->val.integer;
	                break;
	            case COLUMN_DOT1XPAEPORTREAUTHENTICATE:
	                /*
	                 * Need to save old
'table_entry->dot1xPaePortReauthenticate'
	                 * value.
	                 * May need to use 'memcpy' 
	                 */
	                table_entry->old_dot1xPaePortReauthenticate =
	                    table_entry->dot1xPaePortReauthenticate;
	                table_entry->dot1xPaePortReauthenticate =
	                    request->requestvb->val.integer;
	                break;
	            }
	        }
	        #endif
	        break;
	
	    case MODE_SET_UNDO:
	        #if 0
	        for (request = requests; request; request =
request->next) {
	            table_entry = (struct dot1xPaePortTable_entry *)
	                netsnmp_extract_iterator_context(request);
	            table_info = netsnmp_extract_table_info(request);
	
	            switch (table_info->colnum) {
	            case COLUMN_DOT1XPAEPORTINITIALIZE:
	                /*
	                 * Need to restore old
'table_entry->dot1xPaePortInitialize'
	                 * value.
	                 * May need to use 'memcpy' 
	                 */
	                table_entry->dot1xPaePortInitialize =
	                    table_entry->old_dot1xPaePortInitialize;
	                break;
	            case COLUMN_DOT1XPAEPORTREAUTHENTICATE:
	                /*
	                 * Need to restore old
'table_entry->dot1xPaePortReauthenticate'
	                 * value.
	                 * May need to use 'memcpy' 
	                 */
	                table_entry->dot1xPaePortReauthenticate =
	                    table_entry->old_dot1xPaePortReauthenticate;
	                break;
	            }
	        }
	        #endif   
	        break;
	
	    case MODE_SET_COMMIT:
	        break;
	    }
	    
	    return SNMP_ERR_NOERROR;
	}
	
	
	"snmpwalk" OUTPUT
	=================
	iso.0.8802.1.1.1.1.1.2.1.2.1 = Gauge32: 11
	iso.0.8802.1.1.1.1.1.2.1.2.2 = Gauge32: 21
	iso.0.8802.1.1.1.1.1.2.1.2.3 = Gauge32: 31

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.