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; }
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr) { HashNode *searchResult; IX_ETH_DB_CHECK_REFERENCE(macAddr); searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); if (searchResult == NULL) { return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ } ixEthDBReleaseHashNode(searchResult); /* build a remove event and place it on the event queue */ return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID); }
/** * @brief Retrieves a user-defined field from a database record * * Note that this function is fully documented in the main component * header file. */ IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field) { HashNode *result = NULL; if (macAddr == NULL || field == NULL) { return IX_ETH_DB_INVALID_ARG; } if (recordType == IX_ETH_DB_FILTERING_RECORD) { result = ixEthDBSearch(macAddr, recordType); } else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD) { result = ixEthDBVlanSearch(macAddr, vlanID, recordType); } else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD) { IX_ETH_DB_CHECK_PORT_EXISTS(portID); result = ixEthDBPortSearch(macAddr, portID, recordType); } else { return IX_ETH_DB_INVALID_ARG; } if (result == NULL) { return IX_ETH_DB_NO_SUCH_ADDR; } *field = ((MacDescriptor *) result->data)->user; ixEthDBReleaseHashNode(result); return IX_ETH_DB_SUCCESS; }
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) { HashNode *searchResult; IX_ETH_DB_CHECK_REFERENCE(portID); IX_ETH_DB_CHECK_REFERENCE(macAddr); searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); if (searchResult == NULL) { return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ } /* return the port ID */ *portID = ((MacDescriptor *) searchResult->data)->portID; ixEthDBReleaseHashNode(searchResult); return IX_ETH_DB_SUCCESS; }
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) { HashNode *searchResult; MacDescriptor *descriptor; IX_ETH_DB_CHECK_REFERENCE(portID); IX_ETH_DB_CHECK_REFERENCE(macAddr); searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); if (searchResult == NULL) { return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ } descriptor = (MacDescriptor *) searchResult->data; /* return the port ID */ *portID = descriptor->portID; /* reset entry age */ if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) { descriptor->recordData.filteringData.age = 0; } else { descriptor->recordData.filteringVlanData.age = 0; } ixEthDBReleaseHashNode(searchResult); return IX_ETH_DB_SUCCESS; }
IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID) { IxNpeMhMessage message; IX_STATUS result; /* send EDB_GetMACAddressDatabase message */ FILL_GETMACADDRESSDATABASE(message, 0 /* reserved */, IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portID].updateMethod.npeUpdateZone)); IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); if (result == IX_SUCCESS) { /* analyze NPE copy */ UINT32 eltEntryOffset; UINT32 entryPortID; UINT32 eltBaseAddress = (UINT32) ixEthDBPortInfo[portID].updateMethod.npeUpdateZone; UINT32 eltSize = FULL_ELT_BYTE_SIZE; /* invalidate cache */ IX_OSAL_CACHE_INVALIDATE((void *) eltBaseAddress, eltSize); printf("Listing records in main learning tree for port %d\n", portID); for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE) { /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node * * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit] * therefore we can just use the pointer for database searches as only the first 6 bytes are checked */ void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset); if (IX_EDB_NPE_NODE_VALID(eltNodeAddress)) { HashNode *node; entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress)); /* search record */ node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_RECORD_TYPES); printf("%s - port %d - %s ", mac2string((unsigned char *) eltNodeAddress), entryPortID, IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) ? "active" : "inactive"); /* safety check, maybe user deleted record right before sync? */ if (node != NULL) { /* found record */ MacDescriptor *descriptor = (MacDescriptor *) node->data; printf("- %s ", descriptor->type == IX_ETH_DB_FILTERING_RECORD ? "filtering" : descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD ? "vlan" : descriptor->type == IX_ETH_DB_WIFI_RECORD ? "wifi" : "other (check main DB)"); if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) printf("- age %d - %s ", descriptor->recordData.filteringData.age, descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) printf("- age %d - %s - tci %d ", descriptor->recordData.filteringVlanData.age, descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic", descriptor->recordData.filteringVlanData.ieee802_1qTag); /* end transaction */ ixEthDBReleaseHashNode(node); } else { printf("- not synced"); } printf("\n"); } } } else { ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT, "EthDB: (ShowELT) Could not complete action (communication failure)\n", portID, 0, 0, 0, 0, 0); } }
/** * @brief synchronizes the database with tree * * @param portID port ID of the NPE whose tree is to be scanned * @param eltBaseAddress memory base address of the NPE serialized tree * @param eltSize size in bytes of the NPE serialized tree * * Scans the NPE learning tree and resets the age of active database records. * * @internal */ IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize) { UINT32 eltEntryOffset; UINT32 entryPortID; /* invalidate cache */ IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize); for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE) { /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node * * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit] * therefore we can just use the pointer for database searches as only the first 6 bytes are checked */ void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset); /* debug */ IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE); if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != TRUE) { IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n"); } else if (eltEntryOffset == ELT_ROOT_OFFSET) { IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n"); } if (IX_EDB_NPE_NODE_VALID(eltNodeAddress)) { entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress)); /* check only active entries belonging to this port */ if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID) && ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0)) { /* search record */ HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS); /* safety check, maybe user deleted record right before sync? */ if (node != NULL) { /* found record */ MacDescriptor *descriptor = (MacDescriptor *) node->data; IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress)); /* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */ if (!descriptor->recordData.filteringData.staticEntry) { if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) { descriptor->recordData.filteringData.age = AGE_RESET; } else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) { descriptor->recordData.filteringVlanData.age = AGE_RESET; } } /* end transaction */ ixEthDBReleaseHashNode(node); } } else { IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID); } } } }