Exemplo n.º 1
0
/**
 * @brief sets the port maximum Tx and Rx frame sizes
 *
 * @param portID ID of the port to set the frame size on
 * @param maximumFrameSize maximum Tx and Rx frame sizes
 *
 * This function updates the internal data structures and
 * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
 *
 * Note that both the maximum Tx and Rx frame size are set
 * to the same value. This function is kept for compatibility
 * reasons.
 *
 * This function is fully documented in the main header 
 * file, IxEthDB.h.
 *
 * @return IX_ETH_DB_SUCCESS if the operation was
 * successfull or an appropriate error message otherwise
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
{
    IX_ETH_DB_CHECK_PORT_EXISTS(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    if (!ixEthDBPortInfo[portID].initialized)
    {
        return IX_ETH_DB_PORT_UNINITIALIZED;
    }

    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
    {
	if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) || 
	    (maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
	{
	    return IX_ETH_DB_INVALID_ARG;
	}
    }
    else
    {
        return IX_ETH_DB_NO_PERMISSION;
    }

    /* update internal structure */
    ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize;
    ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize;
    
    /* update the maximum frame size in the NPE */
    return ixEthDBPortFrameLengthsUpdate(portID);
}
Exemplo n.º 2
0
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
    HashNode *searchResult;
    IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;

    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_REFERENCE(macAddr);

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);

    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);

    if (searchResult == NULL)
    {
        return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
    }

    if (((MacDescriptor *) (searchResult->data))->portID == portID)
    {
        result = IX_ETH_DB_SUCCESS; /* address and port match */
    }

    ixEthDBReleaseHashNode(searchResult);

    return result;
}
Exemplo n.º 3
0
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
        
    IX_ETH_DB_CHECK_REFERENCE(macAddr);

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);

    return ixEthDBTriggerAddPortUpdate(macAddr, portID, FALSE);
}
Exemplo n.º 4
0
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
{
    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);

    ixEthDBPortInfo[portID].agingEnabled = TRUE;

    return IX_ETH_DB_SUCCESS;
}
Exemplo n.º 5
0
/**
 * @brief sets the MAC address of an NPE port
 *
 * @param portID port ID to set the MAC address on
 * @param macAddr pointer to the 6-byte MAC address
 *
 * This function is called by the EthAcc 
 * ixEthAccUnicastMacAddressSet() and should not be
 * manually invoked unless required by special circumstances.
 *
 * @return IX_ETH_DB_SUCCESS if the operation succeeded
 * or an appropriate error message otherwise
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
    IxNpeMhMessage message;
    IxOsalMutex *ackPortAddressLock;
    IX_STATUS result;

    /* use this macro instead CHECK_PORT
       as the port doesn't need to be enabled */
    IX_ETH_DB_CHECK_PORT_EXISTS(portID);

    IX_ETH_DB_CHECK_REFERENCE(macAddr);

    if (!ixEthDBPortInfo[portID].initialized)
    {
        return IX_ETH_DB_PORT_UNINITIALIZED;
    }

    ackPortAddressLock = &ixEthDBPortInfo[portID].npeAckLock;

    /* Operation stops here when Ethernet Learning is not enabled */
    if(IX_FEATURE_CTRL_SWCONFIG_DISABLED == 
       ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) 
    {
        return IX_ETH_DB_SUCCESS;
    }

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    /* exit if the port is not an Ethernet NPE */
    if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
    {
        return IX_ETH_DB_INVALID_PORT;
    }

    /* populate message */
    FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
    
    IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);

    /* send a SetPortAddress message */
    IX_ETHDB_SEND_NPE_MSG(IX_ETHNPE_PHYSICAL_ID_TO_NODE(portID), message, result);

    if (result == IX_SUCCESS)
    {
        ixEthDBPortInfo[portID].macAddressUploaded = TRUE;
    }

    return result;
}
Exemplo n.º 6
0
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
{
    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);    

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);

    ixEthDBPortInfo[portID].updateMethod.updateEnabled  = enableUpdate;
    ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE;

    return IX_ETH_DB_SUCCESS;
}
Exemplo n.º 7
0
/**
 * @brief retrieves the STP blocking state of a port
 *
 * @param portID ID of the port
 * @param blocked address to write the blocked status into
 *
 * Note that this function is documented in the main component
 * header file, IxEthDB.h.
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 * or an appropriate error message otherwise
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked)
{
    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);

    IX_ETH_DB_CHECK_REFERENCE(blocked);

    *blocked = ixEthDBPortInfo[portID].stpBlocked;

    return IX_ETH_DB_SUCCESS;
}
Exemplo n.º 8
0
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);

    COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);

    return IX_ETH_DB_SUCCESS;
}
Exemplo n.º 9
0
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);

    /* force bit at offset 255 to 0 (reserved) */
    dependencyPortMap[31] &= 0xFE;

    COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);

    return IX_ETH_DB_SUCCESS;
}
Exemplo n.º 10
0
/**
 * @brief sets the STP blocking state of a port
 *
 * @param portID ID of the port
 * @param blocked TRUE to block the port or FALSE to unblock it
 *
 * Note that this function is documented in the main component
 * header file, IxEthDB.h.
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 * or an appropriate error message otherwise
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked)
{
    IxNpeMhMessage message;
    IX_STATUS result;

    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);

    ixEthDBPortInfo[portID].stpBlocked = blocked;

    FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked);

    IX_ETHDB_SEND_NPE_MSG(IX_ETHNPE_PHYSICAL_ID_TO_NODE(portID), message, result);

    return result;
}
Exemplo n.º 11
0
/**
 * @brief disables a port
 *
 * @param portID ID of the port to disable
 *
 * This function is fully documented in the
 * main header file, IxEthDB.h
 *
 * @return IX_ETH_DB_SUCCESS if disabling was
 * successful or an appropriate error message 
 * otherwise
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
{
    HashIterator iterator;
    IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */
    BOOL result;
    PortInfo *portInfo;
    IxEthDBFeature learningEnabled;
    IxEthDBPriorityTable classZeroTable;

    IX_ETH_DB_CHECK_PORT_EXISTS(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    portInfo = &ixEthDBPortInfo[portID];

    if (!portInfo->enabled)
    {
        /* redundant */
        return IX_ETH_DB_SUCCESS;
    }

    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
    {
        /* save filtering state */
        ixEthDBPortState[portID].firewallMode            = portInfo->firewallMode;
        ixEthDBPortState[portID].frameFilter             = portInfo->frameFilter;
        ixEthDBPortState[portID].taggingAction           = portInfo->taggingAction;
        ixEthDBPortState[portID].stpBlocked              = portInfo->stpBlocked;
        ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled;
        ixEthDBPortState[portID].maxRxFrameSize          = portInfo->maxRxFrameSize;
        ixEthDBPortState[portID].maxTxFrameSize          = portInfo->maxTxFrameSize;

        memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet));
        memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet));
        memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable));

        ixEthDBPortState[portID].saved = TRUE;

        /* now turn off all EthDB filtering features on the port */

        /* VLAN & QoS */
        if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
        {
            ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
            ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, FALSE);
            ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
            ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH);

            memset(classZeroTable, 0, sizeof (classZeroTable));
            ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable);
        }

        /* STP */
        if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
        {
            ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, FALSE);
        }

        /* Firewall */
        if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
        {
            ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
            ixEthDBFirewallTableDownload((IxEthDBPortId) portID);
            ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, FALSE);
        }

        /* Frame size filter */
        ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE);

        /* WiFi */
        if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
        {
            ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID);
        }

        /* save and disable the learning feature bit */
        learningEnabled          = portInfo->featureStatus & IX_ETH_DB_LEARNING;
        portInfo->featureStatus &= ~IX_ETH_DB_LEARNING;
    }
    else
    {
        /* save the learning feature bit */
        learningEnabled          = portInfo->featureStatus & IX_ETH_DB_LEARNING;
    }
    
    SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
    
    ixEthDBUpdateLock();
    
    /* wipe out current entries for this port */
    BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));

    while (IS_ITERATOR_VALID(&iterator))
    {
        MacDescriptor *descriptor =  (MacDescriptor *) iterator.node->data;
    
        /* check if the port match. If so, remove the entry  */
        if (descriptor->portID == portID 
                && (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
                && !descriptor->recordData.filteringData.staticEntry)
        {
            /* delete entry */
            BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
            
            /* add port to the set of update trigger ports */
            JOIN_PORT_TO_MAP(triggerPorts, portID);
        }
        else
        {
            /* move to the next record */
            BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
        }
    }
    
    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
    {
        if (portInfo->updateMethod.searchTree != NULL)
        {
            ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree);
            portInfo->updateMethod.searchTree = NULL;
        }

        ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD);
    }

    /* mark as disabled */
    portInfo->enabled = FALSE;
    
    /* disable updates unless the user has specifically altered the default behavior */
    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
    {
        if (!portInfo->updateMethod.userControlled)
        {  
            portInfo->updateMethod.updateEnabled = FALSE;
        }
            
        /* make sure we re-initialize the NPE learning tree when the port is re-enabled */
        portInfo->updateMethod.treeInitialized = FALSE;
    }

    ixEthDBUpdateUnlock();

    /* restore learning feature bit */
    portInfo->featureStatus |= learningEnabled;

    /* if we've removed any records or lost any events make sure to force an update */
    IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts);

    if (!result)
    {
        ixEthDBUpdatePortLearningTrees(triggerPorts);
    }
    
    return IX_ETH_DB_SUCCESS;
}
Exemplo n.º 12
0
/**
 * @brief enables a port
 *
 * @param portID ID of the port to enable
 *
 * This function is fully documented in the main
 * header file, IxEthDB.h
 *
 * @return IX_ETH_DB_SUCCESS if enabling was
 * accomplished, or a meaningful error message otherwise
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
{
    IxEthDBPortMap triggerPorts;
    PortInfo *portInfo;

    IX_ETH_DB_CHECK_PORT_EXISTS(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    portInfo = &ixEthDBPortInfo[portID];
    
    if (portInfo->enabled)
    {
        /* redundant */
        return IX_ETH_DB_SUCCESS;
    }

    SET_DEPENDENCY_MAP(triggerPorts, portID);

    /* mark as enabled */
    portInfo->enabled = TRUE;

    /* Operation stops here when Ethernet Learning is not enabled */
    if(IX_FEATURE_CTRL_SWCONFIG_DISABLED == 
       ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) 
    {
        return IX_ETH_DB_SUCCESS;
    } 

    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded)
    {
        IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID);

        /* must use UnicastAddressSet() before enabling an NPE port */
        return IX_ETH_DB_MAC_UNINITIALIZED;
    }

    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
    {
        IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID);

        if (!portInfo->updateMethod.userControlled
                && ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0))
        {  
            portInfo->updateMethod.updateEnabled = TRUE;
        }
        
        /* if this is first time initialization then we already have
           write access to the tree and can AccessRelease directly */
        if (!portInfo->updateMethod.treeInitialized)
        {
            IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID);

            /* create an initial tree and release access into it */
            ixEthDBUpdatePortLearningTrees(triggerPorts);

            /* mark tree as being initialized */
            portInfo->updateMethod.treeInitialized = TRUE;
        }
    }

    if (ixEthDBPortState[portID].saved)
    {
        /* previous configuration data stored, restore state */
        if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
        {
            ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode);
            ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled);
        }

        if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
        {
            ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter);
            ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction);

            ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo);
            ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership);

            ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable);
        }

        if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
        {
            ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked);
        }

        ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize);
        ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize);

        /* discard previous save */
        ixEthDBPortState[portID].saved = FALSE;
    }

    IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID);

    return IX_ETH_DB_SUCCESS;
}
Exemplo n.º 13
0
/**
 * @brief displays all the filtering records belonging to a port
 *
 * @param portID ID of the port to display
 *
 * Note that this function is documented in the main component
 * header file, IxEthDB.h.
 *
 * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords() 
 * instead. Calling this function is equivalent to calling
 * ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD)
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID)
{
    IxEthDBStatus local_result;
    HashIterator iterator;
    PortInfo *portInfo;
    UINT32 recordCount = 0;

    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    portInfo = &ixEthDBPortInfo[portID];

    /* display table header */
    printf("Ethernet database records for port ID [%d]\n", portID);
    
    ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
    
    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
    {
        printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
    }
    else
    {
        printf("updates disabled (not an NPE)\n\n");
    }

    printf("    MAC address    |   Age  | Type \n");
    printf("___________________________________\n");

    /* browse database */
    BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));

    while (IS_ITERATOR_VALID(&iterator))
    {
      MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;

      if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD)
      {
          recordCount++;

          /* display entry */
          printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d  | %s\n",
              descriptor->macAddress[0],
              descriptor->macAddress[1],
              descriptor->macAddress[2],
              descriptor->macAddress[3],
              descriptor->macAddress[4],
              descriptor->macAddress[5],
              descriptor->recordData.filteringData.age,
              descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
      }

      /* move to the next record */
      BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);

      /* debug */
      if (local_result == IX_ETH_DB_BUSY)
      {
          return IX_ETH_DB_FAIL;
      }
    }

    /* display number of records */
    printf("\nFound %d records\n", recordCount);

    return IX_ETH_DB_SUCCESS;
}