Example #1
0
/**
 * @brief search a record in the Ethernet datbase
 *
 * @param macAddress MAC address to perform the search on
 * @param portID port ID to perform the search on
 * @param typeFilter type of records to consider for matching
 *
 * @warning if searching is successful an implicit write lock
 * to the search result is granted, therefore unlock the 
 * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
 *
 * @see ixEthDBReleaseHashNode()
 *
 * @return the search result, or NULL if a record with the given
 * MAC address/port ID combination was not found
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter)
{
    HashNode *searchResult = NULL;
    MacDescriptor reference;
    
    if (macAddress == NULL)
    {
        return NULL;
    }
    
    /* fill search fields */
    memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
    reference.portID = portID;
    
    /* set acceptable record types */
    reference.type = typeFilter;

    BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult));

    return searchResult;
}
Example #2
0
/**
 * @brief search a record in the Ethernet datbase
 *
 * @param macAddress MAC address to perform the search on
 * @param vlanID VLAN ID to perform the search on
 * @param typeFilter type of records to consider for matching
 *
 * @warning if searching is successful an implicit write lock
 * to the search result is granted, therefore unlock the 
 * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
 *
 * @see ixEthDBReleaseHashNode()
 *
 * @return the search result, or NULL if a record with the given
 * MAC address/VLAN ID combination was not found
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter)
{
    HashNode *searchResult = NULL;
    MacDescriptor reference;
    
    if (macAddress == NULL)
    {
        return NULL;
    }
    
    /* fill search fields */
    memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
    reference.recordData.filteringVlanData.ieee802_1qTag = 
            IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID);
    
    /* set acceptable record types */
    reference.type = typeFilter;

    BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult));

    return searchResult;
}
Example #3
0
/**
 * @brief search a record in the Ethernet datbase
 *
 * @param macAddress MAC address to perform the search on
 * @param typeFilter type of records to consider for matching
 *
 * @warning if searching is successful an implicit write lock
 * to the search result is granted, therefore unlock the 
 * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
 *
 * @see ixEthDBReleaseHashNode()
 *
 * @return the search result, or NULL if a record with the given
 * MAC address was not found
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
{
    HashNode *searchResult = NULL;
    MacDescriptor reference;
    
    TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;

    if (macAddress == NULL)
    {
        return NULL;
    }

    /* fill search fields */
    memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
    
    /* set acceptable record types */
    reference.type = typeFilter;
    
    BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult));

    return searchResult;
}
Example #4
0
/**
 * @brief adds a new entry to the Ethernet database
 *
 * @param newRecordTemplate address of the record template to use
 * @param updateTrigger port map containing the update triggers
 * resulting from this update operation
 *
 * Creates a new database entry, populates it with the data
 * copied from the given template and adds the record to the
 * database hash table.
 * It also checks whether the new record type is registered to trigger
 * automatic updates; if it is, the update trigger will contain the
 * port on which the record insertion was performed, as well as the
 * old port in case the addition was a record migration (from one port
 * to the other). The caller can use the updateTrigger to trigger
 * automatic updates on the ports changed as a result of this addition.
 *
 * @retval IX_ETH_DB_SUCCESS addition successful
 * @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool
 * @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger)
{
    IxEthDBStatus result;
    MacDescriptor *newDescriptor;
    IxEthDBPortId originalPortID;
    HashNode *node = NULL;

    BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node));

    TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;

    if (node == NULL)
    {
        /* not found, create a new one */
        newDescriptor = ixEthDBAllocMacDescriptor();

        if (newDescriptor == NULL)
        {
            return IX_ETH_DB_NOMEM; /* no memory */
        }

        /* old port does not exist, avoid unnecessary updates */
        originalPortID = newRecordTemplate->portID;
    }
    else
    {
        /* a node with the same key exists, will update node */
        newDescriptor = (MacDescriptor *) node->data;

        /* save original port id */
        originalPortID = newDescriptor->portID;
    }

    /* copy/update fields into new record */
    memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr));
    memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData));

    newDescriptor->type   = newRecordTemplate->type;
    newDescriptor->portID = newRecordTemplate->portID;
    newDescriptor->user   = newRecordTemplate->user;

    if (node == NULL)
    {
        /* new record, insert into hashtable */
        BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result);

        if (result != IX_ETH_DB_SUCCESS)
        {
            ixEthDBFreeMacDescriptor(newDescriptor);

            return result; /* insertion failed */
        }
    }

    if (node != NULL)
    {
        /* release access */
        ixEthDBReleaseHashNode(node);
    }

    /* trigger add/remove update if required by type */
    if (updateTrigger != NULL &&
        ixEthDBPortUpdateRequired[newRecordTemplate->type])
    {
        /* add new port to update list */
        JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID);

        /* check if record has moved, we'll need to update the old port as well */
        if (originalPortID != newDescriptor->portID)
        {
            JOIN_PORT_TO_MAP(updateTrigger, originalPortID);
        }
    }

    return IX_ETH_DB_SUCCESS;
}