summaryrefslogtreecommitdiff
path: root/cleopatre/application/spidnetsnmp/agent/mibgroup
diff options
context:
space:
mode:
authorTom Yang2012-06-04 17:15:05 +0530
committerJun Xiang2012-06-05 19:04:12 +0800
commitaa67b3ca9d310b50963be313fc58ff40ea840f9b (patch)
tree6d599c466a13deec0046cd6583f8f34d96d65473 /cleopatre/application/spidnetsnmp/agent/mibgroup
parentde707040140e3247201b9e396d59b850f5f5764d (diff)
cleo/app/snmp[eoc]: implement eocVLANTable, refs #3141
- modify eocMulticastVLANFlag value to disable(0), enable(1)
Diffstat (limited to 'cleopatre/application/spidnetsnmp/agent/mibgroup')
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable.h10
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.c5
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.h48
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.c425
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.h3
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_get.c28
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_set.c611
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.c243
-rw-r--r--cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.h3
9 files changed, 1176 insertions, 200 deletions
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable.h b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable.h
index e06f369e12..6d0944209b 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable.h
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable.h
@@ -1,5 +1,5 @@
-//config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable)
-//config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_get)
-//config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface)
-//config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_set)
-//config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access)
+config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable)
+config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_get)
+config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface)
+config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_set)
+config_require(mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access)
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.c b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.c
index ed4f01e3a8..0286387074 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.c
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.c
@@ -150,6 +150,11 @@ void eocVLANTable_rowreq_ctx_cleanup(eocVLANTable_rowreq_ctx *rowreq_ctx)
/*
* TODO:211:o: |-> Perform extra eocVLANTable rowreq cleanup.
*/
+ if (NULL != rowreq_ctx->data)
+ {
+ eocVLANTable_release_data (rowreq_ctx->data);
+ rowreq_ctx->data = NULL;
+ }
} /* eocVLANTable_rowreq_ctx_cleanup */
/**
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.h b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.h
index c33d5a7b65..7523498f24 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.h
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable.h
@@ -18,14 +18,6 @@ extern "C" {
*/
#include <net-snmp/library/asn1.h>
-/* other required module components */
- /* *INDENT-OFF* */
-config_add_mib(NSCRTV-EPONEOC-MOD-EOC-MIB)
-config_require(NSCRTV-EPONEOC-MOD-EOC-MIB/eocVLANTable/eocVLANTable_interface)
-config_require(NSCRTV-EPONEOC-MOD-EOC-MIB/eocVLANTable/eocVLANTable_data_access)
-config_require(NSCRTV-EPONEOC-MOD-EOC-MIB/eocVLANTable/eocVLANTable_data_get)
-config_require(NSCRTV-EPONEOC-MOD-EOC-MIB/eocVLANTable/eocVLANTable_data_set)
- /* *INDENT-ON* */
/* OID and column number definitions for eocVLANTable */
#include "eocVLANTable_oids.h"
@@ -33,6 +25,8 @@ config_require(NSCRTV-EPONEOC-MOD-EOC-MIB/eocVLANTable/eocVLANTable_data_set)
/* enum definions */
#include "eocVLANTable_enums.h"
+/* include common header */
+#include "EoCCommon.h"
/* *********************************************************************
* function declarations
*/
@@ -77,21 +71,27 @@ typedef netsnmp_data_list eocVLANTable_registration;
*/
typedef struct eocVLANTable_data_s {
- /*
- * eocVLANName(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H
- */
- char eocVLANName[64];
-size_t eocVLANName_len; /* # of char elements, not bytes */
+ /* fields added to use for container iteration */
+ netsnmp_index oid_index; /* MUST BE FIRST!! for container use */
+ oid st_index; /* arbitrary index */
- /*
- * eocMulticastVLANFlag(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
- */
- u_long eocMulticastVLANFlag;
+ /* field added for index written in service configuration file */
+ long eocVLANIndex;
+ /*
+ * eocVLANName(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/h
+ */
+ char eocVLANName[64];
+ size_t eocVLANName_len; /* # of char elements, not bytes */
- /*
- * eocVLANRowStatus(4)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
- */
- u_long eocVLANRowStatus;
+ /*
+ * eocMulticastVLANFlag(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
+ */
+ u_long eocMulticastVLANFlag;
+
+ /*
+ * eocVLANRowStatus(4)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
+ */
+ u_long eocVLANRowStatus;
} eocVLANTable_data;
@@ -139,8 +139,8 @@ typedef struct eocVLANTable_rowreq_ctx_s {
eocVLANTable_mib_index tbl_idx;
- eocVLANTable_data data;
- unsigned int column_exists_flags; /* flags for existence */
+ eocVLANTable_data * data;
+ unsigned int column_exists_flags; /* flags for existence */
eocVLANTable_undo_data * undo;
unsigned int column_set_flags; /* flags for set columns */
@@ -155,6 +155,7 @@ typedef struct eocVLANTable_rowreq_ctx_s {
* TODO:131:o: | |-> Add useful data to eocVLANTable rowreq context.
*/
+ u_char undo_ref_count;
/*
* storage for future expansion
*/
@@ -185,6 +186,7 @@ typedef struct eocVLANTable_ref_rowreq_ctx_s {
extern oid eocVLANTable_oid[];
extern int eocVLANTable_oid_size;
+extern int adding_vlan;
#include "eocVLANTable_interface.h"
#include "eocVLANTable_data_access.h"
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.c b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.c
index a859fe191c..4e5176e5c5 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.c
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.c
@@ -15,6 +15,7 @@
#include "eocVLANTable_data_access.h"
+int adding_vlan;
/** @ingroup interface
* @addtogroup data_access data_access: Routines to access data
*
@@ -122,6 +123,8 @@ eocVLANTable_container_init(netsnmp_container **container_ptr_ptr,
* cache->enabled to 0.
*/
cache->timeout = EOCVLANTABLE_CACHE_TIMEOUT; /* seconds */
+ /* initialize row adding indication */
+ adding_vlan = 0;
} /* eocVLANTable_container_init */
/**
@@ -152,6 +155,251 @@ eocVLANTable_container_shutdown(netsnmp_container *container_ptr)
} /* eocVLANTable_container_shutdown */
+void
+_vlan_update_entry (eocVLANTable_data * lhs, eocVLANTable_data * rhs)
+{
+ if (lhs->eocVLANName_len != rhs->eocVLANName_len)
+ {
+ lhs->eocVLANName_len = rhs->eocVLANName_len;
+ memcpy (lhs->eocVLANName, rhs->eocVLANName, rhs->eocVLANName_len);
+ }
+ else if (memcmp (lhs->eocVLANName, rhs->eocVLANName,
+ rhs->eocVLANName_len) != 0)
+ {
+ memcpy (lhs->eocVLANName, rhs->eocVLANName, rhs->eocVLANName_len);
+ }
+
+ if (lhs->eocMulticastVLANFlag != rhs->eocMulticastVLANFlag)
+ {
+ lhs->eocMulticastVLANFlag = rhs->eocMulticastVLANFlag;
+ }
+}
+
+int
+_vlan_container_load (netsnmp_container * container)
+{
+ eocVLANTable_data *entry;
+ int rc = MFD_SUCCESS;
+
+ int i, j;
+ int tmp;
+ int vlan_count;
+
+ int vlan_amount_limit;
+ char buf[LIBSPID_KEY_MAX_LEN];
+
+ memset (buf, 0x0, LIBSPID_KEY_MAX_LEN);
+
+ if (LIBSPID_SUCCESS != libspid_config_read_item (
+ LIBSPID_SYSTEM_CONF_PATH,
+ LIBSPID_SYSTEM_CONF_LABEL_VLAN_MAX_SUPPORTED_VLANS,
+ buf,
+ LIBSPID_KEY_MAX_LEN))
+
+ {
+ snmp_log (LOG_ERR, "error reading max number of supported VLANs\n");
+ return MFD_ERROR;
+ }
+
+ vlan_amount_limit = strtol (buf, NULL, 10);
+
+ if ((vlan_amount_limit < 0)
+ || (vlan_amount_limit > LIBSPID_VLAN_TABLE_NUM_MAX))
+ {
+ snmp_log (LOG_ERR, "max number of supported VLANs out of range\n");
+ return MFD_ERROR;
+ }
+
+ /* VLAN entries read from config file */
+ libspid_eoc_vlan_table_entry_t vlan_table_entries[vlan_amount_limit];
+
+ /* initial row status is set to active by default */
+ int init_row_status = ROWSTATUS_ACTIVE;
+
+ DEBUGMSGTL (("eocVLANTable:access",
+ "_eoccnu_vlan_container_load called \n"));
+
+ if (NULL == container)
+ {
+ snmp_log (LOG_ERR, "no container specified/found for _eoccnu"
+ "_vlan_container_load\n");
+ return MFD_ERROR;
+ }
+ if (LIBSPID_SUCCESS != libspid_eoc_vlan_table_check ())
+ {
+ snmp_log (LOG_ERR, "errors detected in vlan table configuration file\n");
+ init_row_status = ROWSTATUS_NOTINSERVICE;
+ }
+
+ memset (vlan_table_entries, 0x0, sizeof (vlan_table_entries));
+
+ /* get current contents of service config file */
+ if (LIBSPID_SUCCESS !=
+ libspid_eoc_vlan_table_get_list (vlan_table_entries, &vlan_count))
+ {
+ snmp_log (LOG_ERR, "service config file not read correctly\n");
+ return MFD_ERROR;
+ }
+
+ if (0 == vlan_count)
+ {
+ rc = MFD_END_OF_DATA;
+ }
+
+
+ for (i = 0; i < vlan_count; i++)
+ {
+
+ /* call interface function for allocating service table data */
+ if (NULL == (entry = eocVLANTable_allocate_data ()))
+ {
+ snmp_log (LOG_ERR, "service entry allocation error\n");
+ return MFD_ERROR;
+ }
+
+
+ /* set row status to initial value */
+ entry->eocVLANRowStatus = init_row_status;
+
+ /* parse VLAN index from VLAN entry */
+ if (vlan_table_entries[i].vlan_id < 1 ||
+ vlan_table_entries[i].vlan_id > LIBSPID_SERVICE_MAX_MATCH_VID)
+ entry->eocVLANIndex = INVALID_EOCVLANINDEX;
+ else
+ entry->eocVLANIndex = vlan_table_entries[i].vlan_id;
+
+ /* parse VLAN name from VLAN entry */
+ if ((NULL == vlan_table_entries[i].vlan_name)
+ || (!strcmp (vlan_table_entries[i].vlan_name, "")))
+ {
+ snmp_log (LOG_ERR, "empty vlan name field\n");
+ entry->eocVLANName[0] = '\0';
+ }
+ else
+ {
+ strncpy (entry->eocVLANName, vlan_table_entries[i].vlan_name, LIBSPID_VLAN_NAME_STR_MAX_LEN);
+ entry->eocVLANName_len = strlen (entry->eocVLANName);
+ }
+
+ /* parse multicast value from VLAN entry */
+ if (0 == vlan_table_entries[i].vlan_multicast)
+ entry->eocMulticastVLANFlag = EOCMULTICASTVLANFLAG_DISABLE;
+ else if (1 == vlan_table_entries[i].vlan_multicast)
+ entry->eocMulticastVLANFlag = EOCMULTICASTVLANFLAG_ENABLE;
+ else
+ entry->eocMulticastVLANFlag = INVALID_EOCVLANMULTICASTFLAG;
+
+ /* set entry index for container comparison */
+ entry->st_index = i + 1;
+
+ /*
+ * add entry to container
+ */
+ CONTAINER_INSERT (container, entry);
+ }
+ return rc;
+}
+
+/**
+ * check entry for update
+ */
+
+static void
+_vlan_check_entry_for_updates (eocVLANTable_rowreq_ctx * rowreq_ctx,
+ void **magic)
+{
+ netsnmp_container *vlan_container = magic[0];
+ netsnmp_container *to_delete = (netsnmp_container *) magic[1];
+
+ DEBUGMSGTL (("eocVLANTable:access", "checking entry for updates\n"));
+
+ netsnmp_assert (NULL != vlan_container);
+ netsnmp_assert (NULL != rowreq_ctx);
+ netsnmp_assert (NULL != rowreq_ctx->data);
+ /*
+ * check for matching entries to be deleted
+ */
+ eocVLANTable_data *vlan_entry = CONTAINER_FIND (vlan_container,
+ rowreq_ctx->data);
+ if (NULL == vlan_entry)
+ {
+
+ if (NULL == to_delete)
+ {
+ magic[1] = to_delete = netsnmp_container_find ("lifo");
+ if (NULL == to_delete)
+ snmp_log (LOG_ERR, "couldn't create delete container\n");
+ }
+ if (NULL != to_delete)
+ CONTAINER_INSERT (to_delete, rowreq_ctx);
+ }
+ else
+ {
+ /* check for updates for editable columns from VLAN table */
+ _vlan_update_entry (rowreq_ctx->data, vlan_entry);
+
+ /*
+ * remove entry from temporary VLAN container
+ */
+ CONTAINER_REMOVE (vlan_container, vlan_entry);
+ free (vlan_entry);
+ }
+}
+
+/**
+ * add new entry
+ */
+static void
+_vlan_add_new_entry (eocVLANTable_data * vlan_entry,
+ netsnmp_container * container)
+{
+ eocVLANTable_rowreq_ctx *rowreq_ctx;
+ size_t count = 0;
+
+ DEBUGMSGTL (("eocVLANTable:access", "creating new entry\n"));
+
+ netsnmp_assert (NULL != vlan_entry);
+ netsnmp_assert (NULL != container);
+
+ /*
+ * allocate an row context and set the index(es)
+ */
+ rowreq_ctx = eocVLANTable_allocate_rowreq_ctx (vlan_entry, NULL);
+
+ if ((NULL != rowreq_ctx) && (MFD_SUCCESS ==
+ eocVLANTable_indexes_set (rowreq_ctx,
+ vlan_entry->
+ eocVLANIndex)))
+ {
+ if (CONTAINER_INSERT (container, rowreq_ctx) < 0)
+ {
+ snmp_log (LOG_ERR, "eocVLANTable container insert failed for"
+ " new entry\n");
+ eocVLANTable_release_rowreq_ctx (rowreq_ctx);
+ return;
+ }
+ ++count;
+ }
+ else
+ {
+ if (NULL != rowreq_ctx)
+ {
+ snmp_log (LOG_ERR, "error setting index while loading "
+ "eocVLANTable cache.\n");
+ eocVLANTable_release_rowreq_ctx (rowreq_ctx);
+ }
+ else
+ {
+ snmp_log (LOG_ERR, "memory allocation failed while loading "
+ "eocVLANTable cache.\n");
+ free (vlan_entry);
+ }
+
+ return;
+ }
+ rowreq_ctx->data->eocVLANRowStatus = vlan_entry->eocVLANRowStatus;
+}
+
/**
* load initial data
*
@@ -188,102 +436,87 @@ eocVLANTable_container_shutdown(netsnmp_container *container_ptr)
int
eocVLANTable_container_load(netsnmp_container *container)
{
- eocVLANTable_rowreq_ctx *rowreq_ctx;
- size_t count = 0;
-
- /*
- * temporary storage for index values
- */
- /*
- * eocVLANIndex(1)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h
- */
- long eocVLANIndex;
-
-
- DEBUGMSGTL(("verbose:eocVLANTable:eocVLANTable_container_load","called\n"));
-
+ int rc = MFD_SUCCESS;
+ netsnmp_container *vlan_container;
+ void *tmp_ptr[2];
/*
* TODO:351:M: |-> Load/update data in the eocVLANTable container.
* loop over your eocVLANTable data, allocate a rowreq context,
* set the index(es) [and data, optionally] and insert into
* the container.
*/
- while( 1 ) {
- /*
- * check for end of data; bail out if there is no more data
- */
- if( 1 )
- break;
+ /* create temporary container for fresh service data */
+ vlan_container = netsnmp_container_find ("vlan_temp:table_container");
- /*
- * TODO:352:M: | |-> set indexes in new eocVLANTable rowreq context.
- * data context will be set from the param (unless NULL,
- * in which case a new data context will be allocated)
- */
- rowreq_ctx = eocVLANTable_allocate_rowreq_ctx(NULL);
- if (NULL == rowreq_ctx) {
- snmp_log(LOG_ERR, "memory allocation failed\n");
- return MFD_RESOURCE_UNAVAILABLE;
- }
- if(MFD_SUCCESS != eocVLANTable_indexes_set(rowreq_ctx
- , eocVLANIndex
- )) {
- snmp_log(LOG_ERR,"error setting index while loading "
- "eocVLANTable data.\n");
- eocVLANTable_release_rowreq_ctx(rowreq_ctx);
- continue;
- }
- /*
- * TODO:352:r: | |-> populate eocVLANTable data context.
- * Populate data context here. (optionally, delay until row prep)
- */
- /*
- * TRANSIENT or semi-TRANSIENT data:
- * copy data or save any info needed to do it in row_prep.
- */
- /*
- * setup/save data for eocVLANName
- * eocVLANName(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H
- */
- /** no mapping */
- /*
- * make sure there is enough space for eocVLANName data
- */
- if ((NULL == rowreq_ctx->data.eocVLANName) ||
- (rowreq_ctx->data.eocVLANName_len <
- (eocVLANName_len* sizeof(eocVLANName[0])))) {
- snmp_log(LOG_ERR,"not enough space for value\n");
+ if (NULL == vlan_container)
+ {
+ snmp_log (LOG_ERR, "vlan temp container not found\n");
+ return MFD_ERROR;
+ }
+
+ /* load fresh service data into temp container */
+ rc = _vlan_container_load (vlan_container);
+ if (MFD_ERROR == rc)
+ {
+ snmp_log (LOG_ERR, "vlan container load error\n");
return MFD_ERROR;
}
- rowreq_ctx->data.eocVLANName_len = eocVLANName_len* sizeof(eocVLANName[0]);
- memcpy( rowreq_ctx->data.eocVLANName, eocVLANName, eocVLANName_len* sizeof(eocVLANName[0]) );
+ tmp_ptr[0] = vlan_container;
+ tmp_ptr[1] = NULL;
+
+ /* check if eocVLANTable container needs updates */
+ /* (this is not called if table container is empty) */
+ CONTAINER_FOR_EACH (container, (netsnmp_container_obj_func *)
+ _vlan_check_entry_for_updates, tmp_ptr);
/*
- * setup/save data for eocMulticastVLANFlag
- * eocMulticastVLANFlag(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
+ * add new entries to eocVLANTable container
*/
- /** no mapping */
- rowreq_ctx->data.eocMulticastVLANFlag = eocMulticastVLANFlag;
+ CONTAINER_FOR_EACH (vlan_container,
+ (netsnmp_container_obj_func *) _vlan_add_new_entry,
+ container);
/*
- * setup/save data for eocVLANRowStatus
- * eocVLANRowStatus(4)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
+ * free temporary container. we've either claimed each entry, or released it,
+ * so we don't need to call CONTAINER_CLEAR to clear the container.
*/
- /** no mapping */
- rowreq_ctx->data.eocVLANRowStatus = eocVLANRowStatus;
+ CONTAINER_FREE (vlan_container);
+ /*
+ * remove deleted items from eocVLANTable container
+ */
+ if (NULL != tmp_ptr[1])
+ {
+ netsnmp_container *tmp_container = (netsnmp_container *) tmp_ptr[1];
+ eocVLANTable_rowreq_ctx *tmp_ctx;
/*
- * insert into table container
+ * this works because the tmp_container is a linked list,
+ * which can be used like a stack...
*/
- CONTAINER_INSERT(container, rowreq_ctx);
- ++count;
+ while (CONTAINER_SIZE (tmp_container))
+ {
+ /*
+ * get from delete list
+ */
+ tmp_ctx = CONTAINER_FIRST (tmp_container);
+
+ /*
+ * release context, delete from table container
+ */
+ CONTAINER_REMOVE (container, tmp_ctx);
+ eocVLANTable_release_rowreq_ctx (tmp_ctx);
+
+ /*
+ * pop off delete list
+ */
+ CONTAINER_REMOVE (tmp_container, NULL);
+ }
}
- DEBUGMSGT(("verbose:eocVLANTable:eocVLANTable_container_load",
- "inserted %d records\n", count));
-
+ DEBUGMSGT (("verbose:eocVLANTable:eocVLANTable_container_load",
+ "inserted %d records\n", CONTAINER_SIZE (container)));
return MFD_SUCCESS;
} /* eocVLANTable_container_load */
@@ -390,11 +623,38 @@ eocVLANIndex_check_index( eocVLANTable_rowreq_ctx *rowreq_ctx )
netsnmp_assert(NULL != rowreq_ctx);
+ char buf[LIBSPID_KEY_MAX_LEN];
+ memset (buf, 0x0, LIBSPID_KEY_MAX_LEN);
+
+ if (LIBSPID_SUCCESS != libspid_config_read_item (
+ LIBSPID_SYSTEM_CONF_PATH,
+ LIBSPID_SYSTEM_CONF_LABEL_VLAN_MAX_SUPPORTED_VLANS,
+ buf,
+ LIBSPID_KEY_MAX_LEN))
+ {
+ snmp_log (LOG_ERR, "error reading max number of supported VLANs\n");
+ return MFD_ERROR;
+ }
+
+ int vlan_amount_limit = strtol (buf, NULL, 10);
+
+ if ((vlan_amount_limit < 0)
+ || (vlan_amount_limit > LIBSPID_VLAN_TABLE_NUM_MAX))
+ {
+ snmp_log (LOG_ERR, "max number of supported VLANs out of range\n");
+ return MFD_ERROR;
+ }
/*
* TODO:426:M: |-> Check eocVLANTable index eocVLANIndex.
* check that index value in the table context is legal.
* (rowreq_ctx->tbl_index.eocVLANIndex)
*/
+ /* checking additional index restrictions - indexes must not
+ * exceed value of VLAN amount limitation */
+ if (rowreq_ctx->tbl_idx.eocVLANIndex > vlan_amount_limit)
+ {
+ return SNMP_ERR_WRONGVALUE;
+ }
return MFD_SUCCESS; /* eocVLANIndex index ok */
} /* eocVLANIndex_check_index */
@@ -443,9 +703,10 @@ eocVLANTable_validate_index( eocVLANTable_registration * eocVLANTable_reg,
/*
* TODO:430:M: |-> Validate potential eocVLANTable index.
*/
- if(1) {
- snmp_log(LOG_WARNING,"invalid index for a new row in the "
- "eocVLANTable table.\n");
+ if (0)
+ {
+ snmp_log (LOG_WARNING, "invalid index for a new row in the "
+ "eocVLANTable table.\n");
/*
* determine failure type.
*
@@ -454,13 +715,19 @@ eocVLANTable_validate_index( eocVLANTable_registration * eocVLANTable_reg,
* (even though it could be created under other circumstances),
* return MFD_NOT_NOW.
*/
- if(0) {
+ if (0)
+ {
return MFD_CANNOT_CREATE_EVER;
}
- else {
+ else
+ {
return MFD_CANNOT_CREATE_NOW;
}
}
+ else
+ {
+ rowreq_ctx->data->eocVLANIndex = rowreq_ctx->tbl_idx.eocVLANIndex;
+ }
return rc;
} /* eocVLANTable_validate_index */
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.h b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.h
index 285c834827..85b19bd6c6 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.h
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_access.h
@@ -11,6 +11,9 @@
extern "C" {
#endif
+#define INVALID_EOCVLANINDEX (-2)
+#define INVALID_EOCVLANMULTICASTFLAG (-1)
+
/* *********************************************************************
* function declarations
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_get.c b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_get.c
index ed54872c17..efe19df8ce 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_get.c
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_get.c
@@ -171,20 +171,28 @@ eocVLANName_get( eocVLANTable_rowreq_ctx *rowreq_ctx, char **eocVLANName_val_ptr
/*
* make sure there is enough space for eocVLANName data
*/
- if ((NULL == (* eocVLANName_val_ptr_ptr )) ||
- ((* eocVLANName_val_ptr_len_ptr ) <
- (rowreq_ctx->data.eocVLANName_len* sizeof(rowreq_ctx->data.eocVLANName[0])))) {
+ if ((NULL == (*eocVLANName_val_ptr_ptr)) ||
+ ((*eocVLANName_val_ptr_len_ptr) <
+ (rowreq_ctx->data->eocVLANName_len *
+ sizeof (rowreq_ctx->data->eocVLANName[0]))))
+ {
/*
* allocate space for eocVLANName data
*/
- (* eocVLANName_val_ptr_ptr ) = malloc(rowreq_ctx->data.eocVLANName_len* sizeof(rowreq_ctx->data.eocVLANName[0]));
- if(NULL == (* eocVLANName_val_ptr_ptr )) {
- snmp_log(LOG_ERR,"could not allocate memory\n");
+ (*eocVLANName_val_ptr_ptr) =
+ malloc (rowreq_ctx->data->eocVLANName_len *
+ sizeof (rowreq_ctx->data->eocVLANName[0]));
+ if (NULL == (*eocVLANName_val_ptr_ptr))
+ {
+ snmp_log (LOG_ERR, "could not allocate memory\n");
return MFD_ERROR;
}
}
- (* eocVLANName_val_ptr_len_ptr ) = rowreq_ctx->data.eocVLANName_len* sizeof(rowreq_ctx->data.eocVLANName[0]);
- memcpy( (* eocVLANName_val_ptr_ptr ), rowreq_ctx->data.eocVLANName, rowreq_ctx->data.eocVLANName_len* sizeof(rowreq_ctx->data.eocVLANName[0]) );
+ (*eocVLANName_val_ptr_len_ptr) = rowreq_ctx->data->eocVLANName_len *
+ sizeof (rowreq_ctx->data->eocVLANName[0]);
+ memcpy ((*eocVLANName_val_ptr_ptr), rowreq_ctx->data->eocVLANName,
+ rowreq_ctx->data->eocVLANName_len *
+ sizeof (rowreq_ctx->data->eocVLANName[0]));
return MFD_SUCCESS;
} /* eocVLANName_get */
@@ -236,7 +244,7 @@ eocMulticastVLANFlag_get( eocVLANTable_rowreq_ctx *rowreq_ctx, u_long * eocMulti
* TODO:231:o: |-> Extract the current value of the eocMulticastVLANFlag data.
* copy (* eocMulticastVLANFlag_val_ptr ) from rowreq_ctx->data
*/
- (* eocMulticastVLANFlag_val_ptr ) = rowreq_ctx->data.eocMulticastVLANFlag;
+ (*eocMulticastVLANFlag_val_ptr) = rowreq_ctx->data->eocMulticastVLANFlag;
return MFD_SUCCESS;
} /* eocMulticastVLANFlag_get */
@@ -279,7 +287,7 @@ eocVLANRowStatus_get( eocVLANTable_rowreq_ctx *rowreq_ctx, u_long * eocVLANRowSt
/** we should have a non-NULL pointer */
netsnmp_assert( NULL != eocVLANRowStatus_val_ptr );
- (* eocVLANRowStatus_val_ptr ) = rowreq_ctx->data.eocVLANRowStatus;
+ (* eocVLANRowStatus_val_ptr ) = rowreq_ctx->data->eocVLANRowStatus;
return MFD_SUCCESS;
} /* eocVLANRowStatus_get */
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_set.c b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_set.c
index a2da41d6ac..a0a8e9f819 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_set.c
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_data_set.c
@@ -144,6 +144,8 @@ eocVLANTable_undo_setup( eocVLANTable_rowreq_ctx *rowreq_ctx)
* set up eocVLANTable undo information, in preparation for a set.
* Undo storage is in (* eocVLANRowStatus_val_ptr )*
*/
+ /* copy data context to undo context */
+ memcpy (rowreq_ctx->undo, rowreq_ctx->data, sizeof (eocVLANTable_data));
return rc;
} /* eocVLANTable_undo_setup */
@@ -244,12 +246,19 @@ int
eocVLANTable_commit( eocVLANTable_rowreq_ctx *rowreq_ctx)
{
int rc = MFD_SUCCESS;
- int save_flags;
+ int save_flags;
+ int ret, i, tmp;
- DEBUGMSGTL(("verbose:eocVLANTable:eocVLANTable_commit","called\n"));
+ /* declarations for calls to libspid */
+ char key_buffer[LIBSPID_KEY_MAX_LEN];
+ char *placeholder = "0";
+ libspid_eoc_vlan_table_entry_t vlan_entry;
+ DEBUGMSGTL (("verbose:eocVLANTable:eocVLANTable_commit", "called\n"));
/** we should have a non-NULL pointer */
- netsnmp_assert( NULL != rowreq_ctx );
+ netsnmp_assert (NULL != rowreq_ctx);
+ if (0 == rowreq_ctx->data->eocVLANIndex)
+ return MFD_ERROR;
/*
* save flags, then clear until we actually do something
@@ -264,57 +273,206 @@ eocVLANTable_commit( eocVLANTable_rowreq_ctx *rowreq_ctx)
* 3) set the column's flag in column_set_flags if it needs undo
* processing in case of a failure.
*/
- if (save_flags & COLUMN_EOCVLANNAME_FLAG) {
- save_flags &= ~COLUMN_EOCVLANNAME_FLAG; /* clear eocVLANName */
- /*
- * TODO:482:o: |-> commit column eocVLANName.
- */
- rc = -1;
- if(-1 == rc) {
- snmp_log(LOG_ERR,"eocVLANTable column eocVLANName commit failed\n");
- }
- else {
- /*
- * set flag, in case we need to undo eocVLANName
- */
- rowreq_ctx->column_set_flags |= COLUMN_EOCVLANNAME_FLAG;
- }
+
+ /*
+ * did anything change?
+ */
+ if (0 == save_flags)
+ {
+ DEBUGMSGTL (("eocVLANTable:eocVLANTable_commit", "no change\n"));
+ return MFD_SUCCESS;
}
- if (save_flags & COLUMN_EOCMULTICASTVLANFLAG_FLAG) {
- save_flags &= ~COLUMN_EOCMULTICASTVLANFLAG_FLAG; /* clear eocMulticastVLANFlag */
- /*
- * TODO:482:o: |-> commit column eocMulticastVLANFlag.
- */
- rc = -1;
- if(-1 == rc) {
- snmp_log(LOG_ERR,"eocVLANTable column eocMulticastVLANFlag commit failed\n");
- }
- else {
- /*
- * set flag, in case we need to undo eocMulticastVLANFlag
- */
- rowreq_ctx->column_set_flags |= COLUMN_EOCMULTICASTVLANFLAG_FLAG;
- }
+ if (save_flags & COLUMN_EOCVLANNAME_FLAG)
+ {
+ save_flags &= ~COLUMN_EOCVLANNAME_FLAG; /* clear eocVLANName */
+ /*
+ * TODO:482:o: |-> commit column eocVLANName.
+ */
+ rowreq_ctx->column_set_flags |= COLUMN_EOCVLANNAME_FLAG;
}
- if (save_flags & COLUMN_EOCVLANROWSTATUS_FLAG) {
- save_flags &= ~COLUMN_EOCVLANROWSTATUS_FLAG; /* clear eocVLANRowStatus */
- /*
- * TODO:482:o: |-> commit column eocVLANRowStatus.
- */
- rc = -1;
- if(-1 == rc) {
- snmp_log(LOG_ERR,"eocVLANTable column eocVLANRowStatus commit failed\n");
- }
- else {
- /*
- * set flag, in case we need to undo eocVLANRowStatus
- */
- rowreq_ctx->column_set_flags |= COLUMN_EOCVLANROWSTATUS_FLAG;
- }
+
+ if (save_flags & COLUMN_EOCMULTICASTVLANFLAG_FLAG)
+ {
+ save_flags &= ~COLUMN_EOCMULTICASTVLANFLAG_FLAG; /* clear eocMulticastVLANFlag */
+ /*
+ * TODO:482:o: |-> commit column eocMulticastVLANFlag.
+ */
+ rowreq_ctx->column_set_flags |= COLUMN_EOCMULTICASTVLANFLAG_FLAG;
}
+ if (save_flags & COLUMN_EOCVLANROWSTATUS_FLAG)
+ {
+ save_flags &= ~COLUMN_EOCVLANROWSTATUS_FLAG; /* clear eocVLANRowStatus */
+ /*
+ * TODO:482:o: |-> commit column eocVLANRowStatus.
+ */
+ rowreq_ctx->column_set_flags |= COLUMN_EOCVLANROWSTATUS_FLAG;
+ }
+ /* handle row addition or deletion (similarly as in ipAddressTable) */
+ /*
+ * pass everything to data access
+ * let data access know what columns are set
+ */
+
+ if (rowreq_ctx->column_set_flags & COLUMN_EOCVLANROWSTATUS_FLAG)
+ {
+ if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)
+ {
+ DEBUGMSGTL (("verbose:eocVLANTable:eocVLANTable_commit",
+ "new row created!\n"));
+ }
+ else if (ROWSTATUS_DESTROY == rowreq_ctx->data->eocVLANRowStatus)
+ {
+ /* check if deleting unvalidated row */
+ /* a row can be unvalidated either before being added to
+ * configuration file, or to mark invalid line in
+ * configuration file */
+ if ((rowreq_ctx->undo->eocVLANRowStatus & ROWSTATUS_NOTINSERVICE))
+ {
+ DEBUGMSGTL (("verbose:eocVLANTable:eocVLANTable_commit",
+ "deleting unvalidated row!\n"));
+ /* convert index to string to serve as key for possible
+ * removing of invalid line */
+ sprintf (key_buffer, "%ld", rowreq_ctx->data->eocVLANIndex);
+ /* remove line with given index from VLAN configuration
+ * file, if existing */
+ if (LIBSPID_SUCCESS !=
+ libspid_eoc_vlan_table_remove (key_buffer))
+ {
+ snmp_log (LOG_ERR, "unvalidated row not in "
+ "configuration file\n");
+ }
+ return MFD_SUCCESS;
+ }
+
+ /* convert index to string to serve as key for removing line */
+ sprintf (key_buffer, "%ld", rowreq_ctx->data->eocVLANIndex);
+
+ /* remove line with given index from VLAN configuration file */
+ if (LIBSPID_SUCCESS != libspid_eoc_vlan_table_remove (key_buffer))
+ {
+ snmp_log (LOG_ERR, "libspid_eoc_vlan_table_remove error\n");
+ return MFD_ERROR;
+ }
+
+ }
+ else if (ROWSTATUS_ACTIVE == rowreq_ctx->data->eocVLANRowStatus)
+ {
+ /* this case covers modifying row status to active - ie.
+ * validating the row */
+ /* row can be either newly added from the agent,
+ * or having row status notInService to mark invalid line
+ * in configuration file */
+ DEBUGMSGTL (("verbose:eocVLANTable:eocVLANTable_commit",
+ "validating row\n"));
+
+ /* convert index to string to serve as key for row */
+ sprintf (key_buffer, "%ld", rowreq_ctx->data->eocVLANIndex);
+
+ /* copy VLAN index to VLAN entry */
+ vlan_entry.vlan_id = rowreq_ctx->data->eocVLANIndex;
+
+ /* copy VLAN name to VLAN entry */
+ strncpy (vlan_entry.vlan_name, rowreq_ctx->data->eocVLANName,
+ rowreq_ctx->data->eocVLANName_len);
+ /* add terminal 0 to VLAN name */
+ vlan_entry.vlan_name[rowreq_ctx->data->eocVLANName_len] = '\0';
+
+ if (EOCMULTICASTVLANFLAG_ENABLE ==
+ rowreq_ctx->data->eocMulticastVLANFlag)
+ vlan_entry.vlan_multicast = 1;
+ else
+ vlan_entry.vlan_multicast = 0;
+
+ /* check VLAN conf file before attempting to modify */
+ if (LIBSPID_SUCCESS != libspid_eoc_vlan_table_check ()){
+ snmp_log(LOG_ERR, "errors detected in VLAN conf file\n");
+ return MFD_ERROR;
+ }
+
+ /* write completed line to VLAN file */
+ ret = libspid_eoc_vlan_table_set (key_buffer, &vlan_entry);
+ if (LIBSPID_SUCCESS != ret)
+ {
+ snmp_log (LOG_ERR, "libspid_eoc_vlan_table_set error\n");
+ return MFD_ERROR;
+ }
+ /* if commit has successfully passed,
+ * clear VLAN adding indication */
+ adding_vlan = 0;
+ }
+ }
+ else
+ {
+ /* this case covers modifying columns without modifying row status */
+ if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)
+ && (ROWSTATUS_ACTIVE == rowreq_ctx->data->eocVLANRowStatus))
+ {
+ DEBUGMSGTL (("eocVLANTable_commit", "trying to change data for "
+ "VLAN table index: %ld \n",
+ rowreq_ctx->data->eocVLANIndex));
+ /* convert index to string to serve as key for line in
+ * configuration file */
+ sprintf (key_buffer, "%ld", rowreq_ctx->data->eocVLANIndex);
+
+ /* read existing line from configuration file */
+ ret = libspid_eoc_vlan_table_get (key_buffer, &vlan_entry);
+ if (LIBSPID_SUCCESS != ret)
+ {
+ snmp_log (LOG_ERR, "libspid_eoc_vlan_table_get error\n");
+ return MFD_ERROR;
+ }
+
+ if (rowreq_ctx->column_set_flags & COLUMN_EOCVLANNAME_FLAG)
+ {
+ DEBUGMSGTL (("eocVLANTable_commit", "VLAN name read from "
+ "rowreq context: %s\n",
+ rowreq_ctx->data->eocVLANName));
+ /* copy VLAN name to VLAN entry */
+ strncpy (vlan_entry.vlan_name, rowreq_ctx->data->eocVLANName,
+ rowreq_ctx->data->eocVLANName_len);
+ /* add terminal 0 to VLAN name */
+ vlan_entry.vlan_name[rowreq_ctx->data->eocVLANName_len] =
+ '\0';
+ }
+
+ if (rowreq_ctx->column_set_flags
+ & COLUMN_EOCMULTICASTVLANFLAG_FLAG)
+ {
+ DEBUGMSGTL (("eocVLANTable_commit", "vlan multicast flag "
+ "read from rowreq context: %ld\n",
+ rowreq_ctx->data->eocMulticastVLANFlag));
+ /* copy VLAN multicast to VLAN entry */
+
+ if (EOCMULTICASTVLANFLAG_ENABLE ==
+ rowreq_ctx->data->eocMulticastVLANFlag)
+ vlan_entry.vlan_multicast = 1;
+ else
+ vlan_entry.vlan_multicast = 0;
+ }
+
+ /* check VLAN conf file before attempting to modify */
+ if (LIBSPID_SUCCESS != libspid_eoc_vlan_table_check ()){
+ snmp_log(LOG_ERR, "errors detected in VLAN conf file\n");
+ return MFD_ERROR;
+ }
+ /* write modified line to configuration file */
+ ret = libspid_eoc_vlan_table_set (key_buffer, &vlan_entry);
+ if (LIBSPID_SUCCESS != ret)
+ {
+ snmp_log (LOG_ERR, "libspid_eoc_vlan_table_set error\n");
+ return MFD_ERROR;
+ }
+ else
+ {
+ DEBUGMSGTL (("eocVLANTable_commit",
+ "line succesfully written to conf file!\n"));
+ }
+
+ }
+ }
/*
* if we successfully commited this row, set the dirty flag.
*/
@@ -349,12 +507,21 @@ int
eocVLANTable_undo_commit( eocVLANTable_rowreq_ctx *rowreq_ctx)
{
int rc = MFD_SUCCESS;
+ /* declarations for calls to libspid */
+ char key_buffer[LIBSPID_KEY_MAX_LEN];
+ int ret;
+ int i;
+ int tmp;
+
+ libspid_eoc_vlan_table_entry_t vlan_entry;
DEBUGMSGTL(("verbose:eocVLANTable:eocVLANTable_undo_commit","called\n"));
/** we should have a non-NULL pointer */
netsnmp_assert( NULL != rowreq_ctx );
+ /* initialize VLAN entry */
+ memset (&vlan_entry, 0, sizeof (vlan_entry));
/*
* TODO:485:M: |-> Undo eocVLANTable commit.
* check the column's flag in rowreq_ctx->column_set_flags to see
@@ -363,7 +530,159 @@ eocVLANTable_undo_commit( eocVLANTable_rowreq_ctx *rowreq_ctx)
* eg: if (rowreq_ctx->column_set_flags & COLUMN__FLAG) {}
*/
-
+ if (rowreq_ctx->column_set_flags & COLUMN_EOCVLANROWSTATUS_FLAG)
+ {
+ if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)
+ {
+ /* when row is created and not validated, there is nothing to do */
+ if ((rowreq_ctx->undo->eocVLANRowStatus & ROWSTATUS_NOTINSERVICE))
+ {
+ DEBUGMSGTL (("verbose:eocVLANTable:eocVLANTable_commit",
+ "removing unvalidated row!\n"));
+ return MFD_SUCCESS;
+ }
+ }
+ else if (ROWSTATUS_DESTROY == rowreq_ctx->data->eocVLANRowStatus)
+ {
+ /* if a row was deleted, restore it */
+ /* if restoring unvalidated row, there is nothing to do */
+ if ((rowreq_ctx->undo->eocVLANRowStatus & ROWSTATUS_NOTINSERVICE))
+ {
+ DEBUGMSGTL (("verbose:eocVLANTable:eocVLANTable_commit",
+ "restoring unvalidated row!\n"));
+ return MFD_SUCCESS;
+ }
+ DEBUGMSGTL (("eocVLANTable_undo_commit",
+ "VLAN table index to undo: %ld \n",
+ rowreq_ctx->undo->eocVLANIndex));
+
+ /* convert index to string to serve as key for restoring line */
+ sprintf (key_buffer, "%ld", rowreq_ctx->undo->eocVLANIndex);
+
+ /* copy VLAN index to VLAN entry */
+ vlan_entry.vlan_id = rowreq_ctx->data->eocVLANIndex;
+
+ /* copy VLAN name to VLAN entry */
+ strncpy (vlan_entry.vlan_name, rowreq_ctx->undo->eocVLANName,
+ rowreq_ctx->undo->eocVLANName_len);
+
+ if (EOCMULTICASTVLANFLAG_ENABLE ==
+ rowreq_ctx->undo->eocMulticastVLANFlag)
+ vlan_entry.vlan_multicast = 1;
+ else
+ vlan_entry.vlan_multicast = 0;
+
+ /* clear flag for deletion */
+ rowreq_ctx->rowreq_flags &= ~MFD_ROW_DELETED;
+
+ /* check VLAN conf file before attempting to modify */
+ if (LIBSPID_SUCCESS != libspid_eoc_vlan_table_check ()){
+ snmp_log(LOG_ERR, "errors detected in VLAN conf file\n");
+ return MFD_ERROR;
+ }
+
+ /* write completed line to VLAN file */
+ ret = libspid_eoc_vlan_table_set (key_buffer, &vlan_entry);
+ if (LIBSPID_SUCCESS != ret)
+ {
+ snmp_log (LOG_ERR, "libspid_eoc_vlan_table_set error\n");
+ return MFD_ERROR;
+ }
+ }
+ else if (ROWSTATUS_ACTIVE == rowreq_ctx->data->eocVLANRowStatus)
+ {
+ DEBUGMSGTL (("verbose:eocVLANTable:eocVLANTable_undo_commit",
+ "removing newly validated row!\n"));
+ /* if a row was validated (its status set to active) revert
+ * its status to notInService */
+ rowreq_ctx->data->eocVLANRowStatus =
+ rowreq_ctx->undo->eocVLANRowStatus;
+ /* also remove row data from config file */
+ /* convert index to string to serve as key for removing line */
+ sprintf (key_buffer, "%ld", rowreq_ctx->undo->eocVLANIndex);
+
+ /* if a new row was added, remove line with given index from
+ * VLAN configuration file */
+ if (1 == adding_vlan)
+ {
+ if (LIBSPID_SUCCESS !=
+ libspid_eoc_vlan_table_remove (key_buffer))
+ {
+ snmp_log (LOG_ERR, "libspid_eoc_vlan_table_remove error\n");
+ return MFD_ERROR;
+ }
+
+ /* if undo has successfully passed, clear VLAN adding
+ * indication */
+ adding_vlan = 0;
+ }
+ }
+ }
+ else
+ {
+ /* this case covers restoring modified columns
+ * (without row status modified) */
+ if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)
+ && (ROWSTATUS_ACTIVE == rowreq_ctx->undo->eocVLANRowStatus))
+ {
+ DEBUGMSGTL (("eocVLANTable_undo_commit", "undoing data for "
+ "index: %ld \n", rowreq_ctx->data->eocVLANIndex));
+
+ /* convert index to string to serve as key for line in configuration file */
+ sprintf (key_buffer, "%ld", rowreq_ctx->data->eocVLANIndex);
+
+ /* read existing line from configuration file */
+ ret = libspid_eoc_vlan_table_get (key_buffer, &vlan_entry);
+ if (LIBSPID_SUCCESS != ret)
+ {
+ snmp_log (LOG_ERR, "libspid_eoc_vlan_table_get error\n");
+ return MFD_ERROR;
+ }
+
+ if (rowreq_ctx->column_set_flags & COLUMN_EOCVLANNAME_FLAG)
+ {
+ DEBUGMSGTL (("eocVLANTable_undo_commit", "VLAN name to "
+ "be restored: %s\n",
+ rowreq_ctx->undo->eocVLANName));
+ /* copy VLAN name to VLAN entry */
+ strncpy (vlan_entry.vlan_name, rowreq_ctx->undo->eocVLANName,
+ rowreq_ctx->undo->eocVLANName_len);
+ }
+
+ if (rowreq_ctx->column_set_flags
+ & COLUMN_EOCMULTICASTVLANFLAG_FLAG)
+ {
+ DEBUGMSGTL (("eocVLANTable_undo_commit",
+ "VLAN multicast to be restored: %ld\n",
+ rowreq_ctx->undo->eocMulticastVLANFlag));
+ /* copy VLAN multicast to VLAN entry */
+ if (EOCMULTICASTVLANFLAG_ENABLE ==
+ rowreq_ctx->undo->eocMulticastVLANFlag)
+ vlan_entry.vlan_multicast = 1;
+ else
+ vlan_entry.vlan_multicast = 0;
+ }
+
+ /* check VLAN conf file before attempting to modify */
+ if (LIBSPID_SUCCESS != libspid_eoc_vlan_table_check ()){
+ snmp_log(LOG_ERR, "errors detected in VLAN conf file\n");
+ return MFD_ERROR;
+ }
+
+ /* write modified line to configuration file */
+ ret = libspid_eoc_vlan_table_set (key_buffer, &vlan_entry);
+ if (LIBSPID_SUCCESS != ret)
+ {
+ snmp_log (LOG_ERR, "libspid_eoc_vlan_table_set error\n");
+ return MFD_ERROR;
+ }
+ else
+ {
+ DEBUGMSGTL (("eocVLANTable_undo_commit",
+ "line succesfully written to conf file!\n"));
+ }
+ }
+ }
/*
* if we successfully un-commited this row, clear the dirty flag.
*/
@@ -491,9 +810,10 @@ eocVLANName_undo_setup( eocVLANTable_rowreq_ctx *rowreq_ctx)
* copy eocVLANName and eocVLANName_len data
* set rowreq_ctx->undo->eocVLANName from rowreq_ctx->data.eocVLANName
*/
- memcpy( rowreq_ctx->undo->eocVLANName, rowreq_ctx->data.eocVLANName,
- (rowreq_ctx->data.eocVLANName_len * sizeof(rowreq_ctx->undo->eocVLANName[0])));
- rowreq_ctx->undo->eocVLANName_len = rowreq_ctx->data.eocVLANName_len;
+ memcpy (rowreq_ctx->undo->eocVLANName, rowreq_ctx->data->eocVLANName,
+ (rowreq_ctx->data->eocVLANName_len *
+ sizeof (rowreq_ctx->undo->eocVLANName[0])));
+ rowreq_ctx->undo->eocVLANName_len = rowreq_ctx->data->eocVLANName_len;
return MFD_SUCCESS;
@@ -524,9 +844,13 @@ eocVLANName_set( eocVLANTable_rowreq_ctx *rowreq_ctx, char *eocVLANName_val_ptr,
* TODO:461:M: |-> Set eocVLANName value.
* set eocVLANName value in rowreq_ctx->data
*/
- memcpy( rowreq_ctx->data.eocVLANName, eocVLANName_val_ptr, eocVLANName_val_ptr_len );
+ memcpy (rowreq_ctx->data->eocVLANName, eocVLANName_val_ptr,
+ eocVLANName_val_ptr_len);
/** convert bytes to number of char */
- rowreq_ctx->data.eocVLANName_len = eocVLANName_val_ptr_len / sizeof(eocVLANName_val_ptr[0]);
+ rowreq_ctx->data->eocVLANName_len =
+ eocVLANName_val_ptr_len / sizeof (eocVLANName_val_ptr[0]);
+
+ rowreq_ctx->column_exists_flags |= COLUMN_EOCVLANNAME_FLAG;
return MFD_SUCCESS;
} /* eocVLANName_set */
@@ -550,11 +874,12 @@ eocVLANName_undo( eocVLANTable_rowreq_ctx *rowreq_ctx)
*/
/*
* copy eocVLANName and eocVLANName_len data
- * set rowreq_ctx->data.eocVLANName from rowreq_ctx->undo->eocVLANName
+ * set rowreq_ctx->data->eocVLANName from rowreq_ctx->undo->eocVLANName
*/
- memcpy( rowreq_ctx->data.eocVLANName, rowreq_ctx->undo->eocVLANName,
- (rowreq_ctx->undo->eocVLANName_len * sizeof(rowreq_ctx->data.eocVLANName[0])));
- rowreq_ctx->data.eocVLANName_len = rowreq_ctx->undo->eocVLANName_len;
+ memcpy (rowreq_ctx->data->eocVLANName, rowreq_ctx->undo->eocVLANName,
+ (rowreq_ctx->undo->eocVLANName_len *
+ sizeof (rowreq_ctx->data->eocVLANName[0])));
+ rowreq_ctx->data->eocVLANName_len = rowreq_ctx->undo->eocVLANName_len;
return MFD_SUCCESS;
@@ -663,9 +988,10 @@ eocMulticastVLANFlag_undo_setup( eocVLANTable_rowreq_ctx *rowreq_ctx)
*/
/*
* copy eocMulticastVLANFlag data
- * set rowreq_ctx->undo->eocMulticastVLANFlag from rowreq_ctx->data.eocMulticastVLANFlag
+ * set rowreq_ctx->undo->eocMulticastVLANFlag from rowreq_ctx->data->eocMulticastVLANFlag
*/
- rowreq_ctx->undo->eocMulticastVLANFlag = rowreq_ctx->data.eocMulticastVLANFlag;
+ rowreq_ctx->undo->eocMulticastVLANFlag =
+ rowreq_ctx->data->eocMulticastVLANFlag;
return MFD_SUCCESS;
@@ -693,7 +1019,9 @@ eocMulticastVLANFlag_set( eocVLANTable_rowreq_ctx *rowreq_ctx, u_long eocMultica
* TODO:461:M: |-> Set eocMulticastVLANFlag value.
* set eocMulticastVLANFlag value in rowreq_ctx->data
*/
- rowreq_ctx->data.eocMulticastVLANFlag = eocMulticastVLANFlag_val;
+ rowreq_ctx->data->eocMulticastVLANFlag = eocMulticastVLANFlag_val;
+
+ rowreq_ctx->column_exists_flags |= COLUMN_EOCMULTICASTVLANFLAG_FLAG;
return MFD_SUCCESS;
} /* eocMulticastVLANFlag_set */
@@ -719,7 +1047,8 @@ eocMulticastVLANFlag_undo( eocVLANTable_rowreq_ctx *rowreq_ctx)
* copy eocMulticastVLANFlag data
* set rowreq_ctx->data.eocMulticastVLANFlag from rowreq_ctx->undo->eocMulticastVLANFlag
*/
- rowreq_ctx->data.eocMulticastVLANFlag = rowreq_ctx->undo->eocMulticastVLANFlag;
+ rowreq_ctx->data->eocMulticastVLANFlag =
+ rowreq_ctx->undo->eocMulticastVLANFlag;
return MFD_SUCCESS;
@@ -792,6 +1121,11 @@ eocVLANRowStatus_check_value( eocVLANTable_rowreq_ctx *rowreq_ctx, u_long eocVLA
/*
* TODO:441:o: |-> Check for valid eocVLANRowStatus value.
*/
+ if (ROWSTATUS_CREATEANDGO == eocVLANRowStatus_val)
+ {
+ DEBUGMSGTL (("eocVLANTable", "createAndGo not supported\n"));
+ return MFD_NOT_VALID_EVER;
+ }
return MFD_SUCCESS; /* eocVLANRowStatus value not illegal */
} /* eocVLANRowStatus_check_value */
@@ -830,7 +1164,7 @@ eocVLANRowStatus_undo_setup( eocVLANTable_rowreq_ctx *rowreq_ctx)
* copy eocVLANRowStatus data
* set rowreq_ctx->undo->eocVLANRowStatus from rowreq_ctx->data.eocVLANRowStatus
*/
- rowreq_ctx->undo->eocVLANRowStatus = rowreq_ctx->data.eocVLANRowStatus;
+ rowreq_ctx->undo->eocVLANRowStatus = rowreq_ctx->data->eocVLANRowStatus;
return MFD_SUCCESS;
@@ -858,7 +1192,7 @@ eocVLANRowStatus_set( eocVLANTable_rowreq_ctx *rowreq_ctx, u_long eocVLANRowStat
* TODO:461:M: |-> Set eocVLANRowStatus value.
* set eocVLANRowStatus value in rowreq_ctx->data
*/
- rowreq_ctx->data.eocVLANRowStatus = eocVLANRowStatus_val;
+ rowreq_ctx->data->eocVLANRowStatus = eocVLANRowStatus_val;
return MFD_SUCCESS;
} /* eocVLANRowStatus_set */
@@ -884,10 +1218,157 @@ eocVLANRowStatus_undo( eocVLANTable_rowreq_ctx *rowreq_ctx)
* copy eocVLANRowStatus data
* set rowreq_ctx->data.eocVLANRowStatus from rowreq_ctx->undo->eocVLANRowStatus
*/
- rowreq_ctx->data.eocVLANRowStatus = rowreq_ctx->undo->eocVLANRowStatus;
+ rowreq_ctx->data->eocVLANRowStatus = rowreq_ctx->undo->eocVLANRowStatus;
return MFD_SUCCESS;
} /* eocVLANRowStatus_undo */
+/**
+ * check dependencies
+ *
+ * This is useful for for tables which have dependencies between columns
+ * (or rows, or tables). For example, two columns allocating a percentage
+ * of something add up 100%.
+ *
+ * Should you need different behavior depending on which columns were
+ * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
+ * set. The definitions for the COLUMN_*_FLAG bits can be found in
+ * eocVLANTable_oids.h.
+ * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
+ *
+ * @retval MFD_SUCCESS all the changes to the row are legal
+ * @retval MFD_ERROR one or more changes are not legal
+ *
+ * (see README-table-eocVLANTable if you don't have dependencies)
+ */
+int
+eocVLANTable_check_dependencies (eocVLANTable_rowreq_ctx * rowreq_ctx)
+{
+ int rc = MFD_SUCCESS;
+
+ DEBUGMSGTL (("internal:eocVLANTable:eocVLANTable_check_dependencies",
+ "called\n"));
+
+ netsnmp_assert (NULL != rowreq_ctx);
+
+ /*
+ * TODO:470:o: Check eocVLANTable row dependencies.
+ * check that all new value are legal and consistent with each other
+ */
+ /*
+ * check RowStatus dependencies
+ */
+ if (rowreq_ctx->column_set_flags & COLUMN_EOCVLANROWSTATUS_FLAG)
+ {
+ /*
+ * check for valid RowStatus transition (old, new)
+ * (Note: move transition check to
+ * to catch errors earlier)
+ */
+ rc = check_rowstatus_transition (rowreq_ctx->undo->eocVLANRowStatus,
+ rowreq_ctx->data->eocVLANRowStatus);
+
+ if (MFD_SUCCESS != rc)
+ {
+ DEBUGMSGTL (("eocVLANTable", "row status transition from %d to "
+ "%d\n", rowreq_ctx->undo->eocVLANRowStatus,
+ rowreq_ctx->data->eocVLANRowStatus));
+ return rc;
+ }
+ /*
+ * row creation requirements
+ */
+ if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)
+ {
+ /* this case permits creating row with rowstatus 'destroy' -
+ * row is created and immediately deleted */
+ if (ROWSTATUS_DESTROY == rowreq_ctx->data->eocVLANRowStatus)
+ {
+ rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
+ }
+ else if (ROWSTATUS_CREATEANDWAIT ==
+ rowreq_ctx->data->eocVLANRowStatus)
+ {
+ /* set row adding indication */
+ adding_vlan = 1;
+ rowreq_ctx->data->eocVLANRowStatus = ROWSTATUS_NOTINSERVICE;
+ }
+ } /* row creation */
+ else
+ {
+ /*
+ * row change requirements
+ */
+ /*
+ * don't allow a destroy if any other value was changed, since
+ * that might call data access routines with bad info.
+ *
+ * you may or may not require the row be notInService before it
+ * can be destroyed.
+ */
+ if (ROWSTATUS_DESTROY == rowreq_ctx->data->eocVLANRowStatus)
+ {
+ if (rowreq_ctx->column_set_flags &
+ ~COLUMN_EOCVLANROWSTATUS_FLAG)
+ {
+ DEBUGMSGTL (("eocVLANTable", "destroy must be only "
+ "varbind for row\n"));
+ return MFD_NOT_VALID_NOW;
+ }
+ rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
+
+ } /* row destroy */
+ else if (ROWSTATUS_NOTINSERVICE ==
+ rowreq_ctx->data->eocVLANRowStatus)
+ {
+ /* do not permit invalidating once validated row */
+ if (rowreq_ctx->undo->eocVLANRowStatus & ROWSTATUS_ACTIVE)
+ {
+ DEBUGMSGTL (("eocVLANTable",
+ "Row status can't be changed "
+ "from Active to Not In Service!\n"));
+ return MFD_NOT_VALID_EVER;
+ }
+ }
+ else if (ROWSTATUS_ACTIVE == rowreq_ctx->data->eocVLANRowStatus)
+ {
+ /* before setting row to active, check that all columns are filled */
+ if ((rowreq_ctx->column_exists_flags &
+ EOCVLANTABLE_REQUIRED_COLS) !=
+ EOCVLANTABLE_REQUIRED_COLS)
+ {
+ DEBUGMSGTL (("eocVLANTable", "required columns from "
+ "modEoCCNU table missing (0x%0x != 0x%0x)\n",
+ rowreq_ctx->column_exists_flags,
+ EOCVLANTABLE_REQUIRED_COLS));
+ return MFD_NOT_VALID_NOW;
+ }
+ rowreq_ctx->data->eocVLANRowStatus = ROWSTATUS_ACTIVE;
+ }
+ } /* row change */
+ }
+ else
+ {
+ /*
+ * must have row status to create a row
+ */
+ if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)
+ {
+ DEBUGMSGTL (("eocVLANTable",
+ "must use RowStatus to create rows\n"));
+ return MFD_CANNOT_CREATE_NOW;
+ }
+ else if (ROWSTATUS_ACTIVE == rowreq_ctx->data->eocVLANRowStatus)
+ {
+
+ }
+ } /* row status not set */
+
+ if (MFD_SUCCESS != rc)
+ return rc;
+
+ return rc;
+} /* eocVLANTable_check_dependencies */
+
/** @} */
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.c b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.c
index fae511b9d0..bb1e04de18 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.c
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.c
@@ -133,6 +133,7 @@ static Netsnmp_Node_Handler _mfd_eocVLANTable_undo_values;
static Netsnmp_Node_Handler _mfd_eocVLANTable_commit;
static Netsnmp_Node_Handler _mfd_eocVLANTable_undo_commit;
static Netsnmp_Node_Handler _mfd_eocVLANTable_irreversible_commit;
+static Netsnmp_Node_Handler _mfd_eocVLANTable_check_dependencies;
NETSNMP_STATIC_INLINE int _eocVLANTable_undo_column( eocVLANTable_rowreq_ctx *rowreq_ctx,
netsnmp_variable_list *var, int column );
@@ -147,6 +148,29 @@ eocVLANTable_data *eocVLANTable_allocate_data(void);
* (Define its contents and how it's structured)
*/
void
+vlan_container_init (void)
+{
+ static int done = 0;
+
+ if (done)
+ return;
+
+ DEBUGMSGTL (("internal:eocVLANTable:vlan_container_init", "called\n"));
+
+ done = 1;
+
+ /*
+ * set up the container
+ */
+ _eocVLANTable_container_init (&eocVLANTable_if_ctx);
+}
+
+/**
+ * @internal
+ * Initialize the table eocVLANTable
+ * (Define its contents and how it's structured)
+ */
+void
_eocVLANTable_initialize_interface(eocVLANTable_registration * reg_ptr, u_long flags)
{
netsnmp_baby_steps_access_methods *access_multiplexer =
@@ -158,6 +182,9 @@ _eocVLANTable_initialize_interface(eocVLANTable_registration * reg_ptr, u_long
DEBUGMSGTL(("internal:eocVLANTable:_eocVLANTable_initialize_interface","called\n"));
+ (void) vlan_container_init ();
+ if (NULL == eocVLANTable_if_ctx.container)
+ return; /* msg already logged */
/*************************************************
*
@@ -223,6 +250,12 @@ _eocVLANTable_initialize_interface(eocVLANTable_registration * reg_ptr, u_long
access_multiplexer->undo_commit = _mfd_eocVLANTable_undo_commit;
access_multiplexer->irreversible_commit = _mfd_eocVLANTable_irreversible_commit;
+ /*
+ * REQUIRED for tables with dependencies
+ */
+ access_multiplexer->consistency_checks =
+ _mfd_eocVLANTable_check_dependencies;
+
/*************************************************
*
* Create a registration, save our reg data, register table.
@@ -454,6 +487,12 @@ eocVLANTable_allocate_data(void)
snmp_log(LOG_ERR, "unable to malloc memory for new "
"eocVLANTable_data.\n");
}
+ else
+ {
+ /* initialization of fields added for container comparison */
+ rtn->oid_index.len = 1;
+ rtn->oid_index.oids = &rtn->st_index;
+ }
return rtn;
} /* eocVLANTable_allocate_data */
@@ -468,7 +507,9 @@ eocVLANTable_release_data(eocVLANTable_data *data)
{
DEBUGMSGTL(("verbose:eocVLANTable:eocVLANTable_release_data","called\n"));
- free(data);
+ if (NULL == data)
+ return;
+ free (data);
} /* eocVLANTable_release_data */
/* *********************************************************************
@@ -476,7 +517,8 @@ eocVLANTable_release_data(eocVLANTable_data *data)
* allocate resources for a eocVLANTable_rowreq_ctx
*/
eocVLANTable_rowreq_ctx *
-eocVLANTable_allocate_rowreq_ctx(void *user_init_ctx)
+eocVLANTable_allocate_rowreq_ctx (eocVLANTable_data * data,
+ void *user_init_ctx)
{
eocVLANTable_rowreq_ctx *rowreq_ctx =
SNMP_MALLOC_TYPEDEF(eocVLANTable_rowreq_ctx);
@@ -488,6 +530,66 @@ eocVLANTable_allocate_rowreq_ctx(void *user_init_ctx)
"eocVLANTable_rowreq_ctx.\n");
return NULL;
}
+ else
+ {
+ if (NULL != data)
+ {
+ /*
+ * track if we got data from user
+ */
+ DEBUGMSGTL (("internal:eocVLANTable:eocVLANTable_allocate"
+ "_rowreq_ctx", "data got from user\n"));
+ rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER;
+ rowreq_ctx->data = data;
+
+ /* TEMP: maybe set column_exists_flags somewhere else? */
+ /* TODO: check if index flag can be set here? */
+
+ if (INVALID_EOCVLANINDEX == rowreq_ctx->data->eocVLANIndex)
+ {
+ DEBUGMSGTL (("internal:eocVLANTable:eocVLANTable_allocate"
+ "_rowreq_ctx", "config file index invalid\n"));
+ }
+ else
+ {
+ rowreq_ctx->column_exists_flags |= COLUMN_EOCVLANINDEX_FLAG;
+ }
+
+ if (NULL == rowreq_ctx->data->eocVLANName)
+ {
+ DEBUGMSGTL (("internal:eocVLANTable:eocVLANTable_allocate"
+ "_rowreq" "_ctx", "service name null\n"));
+ }
+ else
+ {
+ rowreq_ctx->column_exists_flags |= COLUMN_EOCVLANNAME_FLAG;
+ }
+
+ if (INVALID_EOCVLANMULTICASTFLAG ==
+ rowreq_ctx->data->eocMulticastVLANFlag)
+ {
+ DEBUGMSGTL (("internal:eocVLANTable:eocVLANTable_allocate"
+ "_rowreq" "_ctx", "max latency invalid\n"));
+ }
+ else
+ {
+ rowreq_ctx->column_exists_flags |=
+ COLUMN_EOCMULTICASTVLANFLAG_FLAG;
+ }
+
+ /* Row Status flag set to existing for allocation purposes */
+ rowreq_ctx->column_exists_flags |= COLUMN_EOCVLANROWSTATUS_FLAG;
+ }
+ else if (NULL == (rowreq_ctx->data = eocVLANTable_allocate_data ()))
+ {
+ SNMP_FREE (rowreq_ctx);
+ return NULL;
+ }
+ }
+
+ /*
+ * undo context will be allocated when needed (in *_undo_setup)
+ */
rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp;
@@ -520,8 +622,14 @@ eocVLANTable_release_rowreq_ctx(eocVLANTable_rowreq_ctx *rowreq_ctx)
eocVLANTable_rowreq_ctx_cleanup(rowreq_ctx);
- if(rowreq_ctx->undo)
- eocVLANTable_release_data(rowreq_ctx->undo);
+ if ((rowreq_ctx->data) && !(rowreq_ctx->rowreq_flags
+ & MFD_ROW_DATA_FROM_USER))
+ {
+ eocVLANTable_release_data (rowreq_ctx->data);
+ }
+
+ if (rowreq_ctx->undo)
+ eocVLANTable_release_data (rowreq_ctx->undo);
/*
* free index oid pointer
@@ -652,7 +760,7 @@ _mfd_eocVLANTable_rowreq_from_index(netsnmp_index *oid_idx, int * rc_ptr)
/*
* allocate new context
*/
- rowreq_ctx = eocVLANTable_allocate_rowreq_ctx(NULL);
+ rowreq_ctx = eocVLANTable_allocate_rowreq_ctx (NULL, NULL);
if (NULL == rowreq_ctx) {
*rc_ptr = MFD_ERROR;
return NULL; /* msg already logged */
@@ -957,8 +1065,8 @@ _eocVLANTable_check_column( eocVLANTable_rowreq_ctx *rowreq_ctx,
/* eocVLANName(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H */
case COLUMN_EOCVLANNAME:
- rc = netsnmp_check_vb_type_and_max_size( var, ASN_OCTET_STR,
- sizeof( rowreq_ctx->data.eocVLANName ) );
+ rc = netsnmp_check_vb_type_and_max_size (var, ASN_OCTET_STR,
+ sizeof (rowreq_ctx->data->eocVLANName));
/* check defined range(s). */
if( (SNMPERR_SUCCESS == rc)
&& ((var->val_len < 0) || (var->val_len > 64))
@@ -981,8 +1089,8 @@ _eocVLANTable_check_column( eocVLANTable_rowreq_ctx *rowreq_ctx,
/* eocMulticastVLANFlag(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h */
case COLUMN_EOCMULTICASTVLANFLAG:
- rc = netsnmp_check_vb_type_and_size( var, ASN_INTEGER,
- sizeof( rowreq_ctx->data.eocMulticastVLANFlag ) );
+ rc = netsnmp_check_vb_type_and_size (var, ASN_INTEGER,
+ sizeof (rowreq_ctx->data->eocMulticastVLANFlag));
/* check that the value is one of defined enums */
if( (SNMPERR_SUCCESS == rc)
&& ( *var->val.integer != EOCMULTICASTVLANFLAG_DISABLE )
@@ -1067,6 +1175,41 @@ _mfd_eocVLANTable_check_objects(netsnmp_mib_handler *handler,
/*----------------------------------------------------------------------
*
+ * SET: check dependencies
+ *
+ *---------------------------------------------------------------------*/
+/*
+ * @internal
+ * Check dependencies wrapper
+ */
+static int
+_mfd_eocVLANTable_check_dependencies (netsnmp_mib_handler * handler,
+ netsnmp_handler_registration * reginfo,
+ netsnmp_agent_request_info *
+ agtreq_info,
+ netsnmp_request_info * requests)
+{
+ int rc;
+ eocVLANTable_rowreq_ctx *rowreq_ctx =
+ netsnmp_container_table_row_extract (requests);
+ DEBUGMSGTL (("internal:eocVLANTable:_mfd_eocVLANTable_check_dependencies",
+ "called\n"));
+
+ netsnmp_assert (NULL != rowreq_ctx);
+
+ rc = eocVLANTable_check_dependencies (rowreq_ctx);
+ if (rc)
+ {
+ DEBUGMSGTL (("eocVLANTable:mfd", "error %d from "
+ "eocVLANTable_check_dependencies\n", rc));
+ netsnmp_request_set_error_all (requests, SNMP_VALIDATE_ERR (rc));
+ }
+
+ return SNMP_ERR_NOERROR;
+} /* _mfd_eocVLANTable_check_dependencies */
+
+/*----------------------------------------------------------------------
+ *
* SET: Undo setup
*
*---------------------------------------------------------------------*/
@@ -1112,6 +1255,39 @@ _eocVLANTable_undo_setup_column( eocVLANTable_rowreq_ctx *rowreq_ctx, int column
return rc;
} /* _eocVLANTable_undo_setup_column */
+/* TODO: check if this is really necessary? */
+int
+_mfd_eocVLAN_undo_setup_allocate (eocVLANTable_rowreq_ctx * rowreq_ctx)
+{
+ int rc = MFD_SUCCESS;
+
+ if (NULL == rowreq_ctx)
+ return MFD_ERROR;
+
+ /*
+ * other tables share our container/context and call
+ * this function. so we need to check and see if
+ * someone else already allocated data
+ */
+ if (NULL == rowreq_ctx->undo)
+ {
+ rowreq_ctx->undo = eocVLANTable_allocate_data ();
+ if (NULL == rowreq_ctx->undo)
+ {
+ /** msg already logged */
+ rc = SNMP_ERR_RESOURCEUNAVAILABLE;
+ }
+ else
+ {
+ /* TODO: check if something should be done here? */
+ }
+ }
+ ++rowreq_ctx->undo_ref_count;
+ DEBUGMSGTL(("internal:eocCNUServiceTable:_mfd_eocVLANTable_undo_setup_allocate",
+ "++undo_refcount = %d\n",rowreq_ctx->undo_ref_count));
+
+ return rc;
+}
/**
* @internal
@@ -1176,6 +1352,24 @@ _mfd_eocVLANTable_undo_setup(netsnmp_mib_handler *handler,
return SNMP_ERR_NOERROR;
} /* _mfd_eocVLANTable_undo_setup */
+void
+_mfd_eocVLANTable_undo_setup_release (eocVLANTable_rowreq_ctx * rowreq_ctx)
+{
+ DEBUGMSGTL (("internal:eocCNUServiceTable:_mfd_eocVLANTable_undo"
+ "_setup_release", "called\n"));
+
+ netsnmp_assert (rowreq_ctx->undo_ref_count > 0);
+ --rowreq_ctx->undo_ref_count;
+ snmp_log (LOG_ERR, "undo_refcount at %d\n", rowreq_ctx->undo_ref_count);
+
+ if (0 == rowreq_ctx->undo_ref_count)
+ {
+ eocVLANTable_release_data (rowreq_ctx->undo);
+ rowreq_ctx->undo = NULL;
+ }
+}
+
+
/**
* @internal
* undo setup
@@ -1213,10 +1407,7 @@ _mfd_eocVLANTable_undo_cleanup(netsnmp_mib_handler *handler,
/*
* release undo context, if needed
*/
- if(rowreq_ctx->undo) {
- eocVLANTable_release_data(rowreq_ctx->undo);
- rowreq_ctx->undo = NULL;
- }
+ _mfd_eocVLANTable_undo_setup_release (rowreq_ctx);
return SNMP_ERR_NOERROR;
@@ -1556,8 +1747,18 @@ _cache_load(netsnmp_cache *cache, void *vmagic)
/*
* call user code
*/
- return eocVLANTable_container_load((netsnmp_container*)cache->magic);
-} /* _cache_load */
+ if (adding_vlan)
+ {
+ snmp_log (LOG_ERR, "skipping eocVLANTable_cache_load, row adding "
+ "in progress\n");
+ return SNMP_ERR_NOERROR;
+ }
+ else
+ {
+ return eocVLANTable_container_load ((netsnmp_container *) cache->
+ magic);
+ }
+} /* _cache_load */
/**
* @internal
@@ -1576,8 +1777,16 @@ _cache_free(netsnmp_cache *cache, void *magic)
container = (netsnmp_container*)cache->magic;
- _container_free(container);
-} /* _cache_free */
+ if (!adding_vlan)
+ {
+ _container_free (container);
+ }
+ else
+ {
+ snmp_log (LOG_ERR, "skipping eocVLANTable_cache_free, row adding "
+ "in progress\n");
+ }
+} /* _cache_free */
/**
* @internal
diff --git a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.h b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.h
index f5198c7fd2..6b333fa680 100644
--- a/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.h
+++ b/cleopatre/application/spidnetsnmp/agent/mibgroup/mstar-eoc-mib/eocVLANGroup/eocVLANTable/eocVLANTable_interface.h
@@ -65,7 +65,8 @@ int eocVLANTable_container_size( void );
u_int eocVLANTable_dirty_get( void );
void eocVLANTable_dirty_set( u_int status );
- eocVLANTable_rowreq_ctx * eocVLANTable_allocate_rowreq_ctx(void *);
+eocVLANTable_rowreq_ctx *
+eocVLANTable_allocate_rowreq_ctx (eocVLANTable_data *, void *);
void eocVLANTable_release_rowreq_ctx(eocVLANTable_rowreq_ctx *rowreq_ctx);
int eocVLANTable_index_to_oid(netsnmp_index *oid_idx,