/** * @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); }
/** * @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; }
/** * @brief sets the value of an EthDB property * * @param portID ID of the port * @param feature feature owning the property * @param property ID of the property * @param value location containing the property value * * This function implements a private property intended * only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE * property (the value is ignored), the availability of traffic classes is * frozen to whatever traffic class structure is currently in use. * This means that if VLAN_QOS has been enabled before EthAcc * initialization then all the defined traffic classes will be available; * otherwise only one traffic class (0) will be available. * * Note that this function is documented in the main component * header file, IxEthDB.h as not accepting any parameters. The * current implementation is only intended for the private use of EthAcc. * * Also note that once this function is called the effect is irreversible, * unless EthDB is complete unloaded and re-initialized. * * @return IX_ETH_DB_INVALID_ARG (no read-write properties are * supported in this release) */ IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value) { IX_ETH_DB_CHECK_PORT_EXISTS(portID); if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE)) { ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount; return IX_ETH_DB_SUCCESS; } return IX_ETH_DB_INVALID_ARG; }
/** * @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; }
/** * @brief returns the value of an EthDB property * * @param portID ID of the port * @param feature feature owning the property * @param property ID of the property * @param type location to store the property type into * @param value location to store the property value 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 ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value) { IX_ETH_DB_CHECK_PORT_EXISTS(portID); IX_ETH_DB_CHECK_REFERENCE(type); IX_ETH_DB_CHECK_REFERENCE(value); if (feature == IX_ETH_DB_VLAN_QOS) { if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY) { * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount; *type = IX_ETH_DB_INTEGER_PROPERTY; return IX_ETH_DB_SUCCESS; } else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY && property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY) { UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) { return IX_ETH_DB_FAIL; } * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta]; *type = IX_ETH_DB_INTEGER_PROPERTY; return IX_ETH_DB_SUCCESS; } } return IX_ETH_DB_INVALID_ARG; }
/** * @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; }
/** * @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; }