IxEthDBAPI.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /**
  2. * @file IxEthDBAPI.c
  3. *
  4. * @brief Implementation of the public API
  5. *
  6. * @par
  7. * IXP400 SW Release version 2.0
  8. *
  9. * -- Copyright Notice --
  10. *
  11. * @par
  12. * Copyright 2001-2005, Intel Corporation.
  13. * All rights reserved.
  14. *
  15. * @par
  16. * SPDX-License-Identifier: BSD-3-Clause
  17. * @par
  18. * -- End of Copyright Notice --
  19. */
  20. #include "IxEthDB_p.h"
  21. #include "IxFeatureCtrl.h"
  22. extern HashTable dbHashtable;
  23. extern IxEthDBPortMap overflowUpdatePortList;
  24. extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
  25. IX_ETH_DB_PUBLIC
  26. IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
  27. {
  28. IX_ETH_DB_CHECK_PORT(portID);
  29. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  30. IX_ETH_DB_CHECK_REFERENCE(macAddr);
  31. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
  32. return ixEthDBTriggerAddPortUpdate(macAddr, portID, true);
  33. }
  34. IX_ETH_DB_PUBLIC
  35. IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
  36. {
  37. IX_ETH_DB_CHECK_PORT(portID);
  38. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  39. IX_ETH_DB_CHECK_REFERENCE(macAddr);
  40. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
  41. return ixEthDBTriggerAddPortUpdate(macAddr, portID, false);
  42. }
  43. IX_ETH_DB_PUBLIC
  44. IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
  45. {
  46. HashNode *searchResult;
  47. IX_ETH_DB_CHECK_REFERENCE(macAddr);
  48. searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
  49. if (searchResult == NULL)
  50. {
  51. return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
  52. }
  53. ixEthDBReleaseHashNode(searchResult);
  54. /* build a remove event and place it on the event queue */
  55. return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
  56. }
  57. IX_ETH_DB_PUBLIC
  58. void ixEthDBDatabaseMaintenance()
  59. {
  60. HashIterator iterator;
  61. UINT32 portIndex;
  62. BOOL agingRequired = false;
  63. /* ports who will have deleted records and therefore will need updating */
  64. IxEthDBPortMap triggerPorts;
  65. if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
  66. ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
  67. {
  68. return;
  69. }
  70. SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
  71. /* check if there's at least a port that needs aging */
  72. for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
  73. {
  74. if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
  75. {
  76. agingRequired = true;
  77. }
  78. }
  79. if (agingRequired)
  80. {
  81. /* ask each NPE port to write back the database for aging inspection */
  82. for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
  83. {
  84. if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
  85. && ixEthDBPortInfo[portIndex].agingEnabled
  86. && ixEthDBPortInfo[portIndex].enabled)
  87. {
  88. IxNpeMhMessage message;
  89. IX_STATUS result;
  90. /* send EDB_GetMACAddressDatabase message */
  91. FILL_GETMACADDRESSDATABASE(message,
  92. 0 /* unused */,
  93. IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
  94. IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
  95. if (result == IX_SUCCESS)
  96. {
  97. /* analyze NPE copy */
  98. ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
  99. IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
  100. }
  101. else
  102. {
  103. ixEthDBPortInfo[portIndex].agingEnabled = false;
  104. ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = false;
  105. ixEthDBPortInfo[portIndex].updateMethod.userControlled = true;
  106. ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
  107. IX_OSAL_LOG_DEV_STDOUT,
  108. "EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n",
  109. portIndex, 0, 0, 0, 0, 0);
  110. ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
  111. }
  112. }
  113. }
  114. /* browse database and age entries */
  115. BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
  116. while (IS_ITERATOR_VALID(&iterator))
  117. {
  118. MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
  119. UINT32 *age = NULL;
  120. BOOL staticEntry = true;
  121. if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
  122. {
  123. age = &descriptor->recordData.filteringData.age;
  124. staticEntry = descriptor->recordData.filteringData.staticEntry;
  125. }
  126. else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
  127. {
  128. age = &descriptor->recordData.filteringVlanData.age;
  129. staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
  130. }
  131. else
  132. {
  133. staticEntry = true;
  134. }
  135. if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == false))
  136. {
  137. /* manually increment the age if the port has no such capability */
  138. if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
  139. {
  140. *age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
  141. }
  142. /* age entry if it exceeded the maximum time to live */
  143. if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
  144. {
  145. /* add port to the set of update trigger ports */
  146. JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
  147. /* delete entry */
  148. BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
  149. }
  150. else
  151. {
  152. /* move to the next record */
  153. BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
  154. }
  155. }
  156. else
  157. {
  158. /* move to the next record */
  159. BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
  160. }
  161. }
  162. /* update ports which lost records */
  163. ixEthDBUpdatePortLearningTrees(triggerPorts);
  164. }
  165. }
  166. IX_ETH_DB_PUBLIC
  167. IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
  168. {
  169. IxEthDBPortMap triggerPorts;
  170. HashIterator iterator;
  171. if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
  172. {
  173. return IX_ETH_DB_INVALID_PORT;
  174. }
  175. /* check if the user passes some extra bits */
  176. if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
  177. {
  178. return IX_ETH_DB_INVALID_ARG;
  179. }
  180. SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
  181. /* browse database and age entries */
  182. BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
  183. while (IS_ITERATOR_VALID(&iterator))
  184. {
  185. MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
  186. if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
  187. && ((descriptor->type & recordType) != 0))
  188. {
  189. /* add to trigger if automatic updates are required */
  190. if (ixEthDBPortUpdateRequired[descriptor->type])
  191. {
  192. /* add port to the set of update trigger ports */
  193. JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
  194. }
  195. /* delete entry */
  196. BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
  197. }
  198. else
  199. {
  200. /* move to the next record */
  201. BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
  202. }
  203. }
  204. /* update ports which lost records */
  205. ixEthDBUpdatePortLearningTrees(triggerPorts);
  206. return IX_ETH_DB_SUCCESS;
  207. }
  208. IX_ETH_DB_PUBLIC
  209. IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
  210. {
  211. HashNode *searchResult;
  212. IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
  213. IX_ETH_DB_CHECK_PORT(portID);
  214. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  215. IX_ETH_DB_CHECK_REFERENCE(macAddr);
  216. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
  217. searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
  218. if (searchResult == NULL)
  219. {
  220. return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
  221. }
  222. if (((MacDescriptor *) (searchResult->data))->portID == portID)
  223. {
  224. result = IX_ETH_DB_SUCCESS; /* address and port match */
  225. }
  226. ixEthDBReleaseHashNode(searchResult);
  227. return result;
  228. }
  229. IX_ETH_DB_PUBLIC
  230. IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
  231. {
  232. HashNode *searchResult;
  233. IX_ETH_DB_CHECK_REFERENCE(portID);
  234. IX_ETH_DB_CHECK_REFERENCE(macAddr);
  235. searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
  236. if (searchResult == NULL)
  237. {
  238. return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
  239. }
  240. /* return the port ID */
  241. *portID = ((MacDescriptor *) searchResult->data)->portID;
  242. ixEthDBReleaseHashNode(searchResult);
  243. return IX_ETH_DB_SUCCESS;
  244. }
  245. IX_ETH_DB_PUBLIC
  246. IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
  247. {
  248. IX_ETH_DB_CHECK_PORT(portID);
  249. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  250. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
  251. ixEthDBPortInfo[portID].agingEnabled = false;
  252. return IX_ETH_DB_SUCCESS;
  253. }
  254. IX_ETH_DB_PUBLIC
  255. IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
  256. {
  257. IX_ETH_DB_CHECK_PORT(portID);
  258. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  259. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
  260. ixEthDBPortInfo[portID].agingEnabled = true;
  261. return IX_ETH_DB_SUCCESS;
  262. }
  263. IX_ETH_DB_PUBLIC
  264. IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
  265. {
  266. HashNode *searchResult;
  267. MacDescriptor *descriptor;
  268. IX_ETH_DB_CHECK_REFERENCE(portID);
  269. IX_ETH_DB_CHECK_REFERENCE(macAddr);
  270. searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
  271. if (searchResult == NULL)
  272. {
  273. return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
  274. }
  275. descriptor = (MacDescriptor *) searchResult->data;
  276. /* return the port ID */
  277. *portID = descriptor->portID;
  278. /* reset entry age */
  279. if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
  280. {
  281. descriptor->recordData.filteringData.age = 0;
  282. }
  283. else
  284. {
  285. descriptor->recordData.filteringVlanData.age = 0;
  286. }
  287. ixEthDBReleaseHashNode(searchResult);
  288. return IX_ETH_DB_SUCCESS;
  289. }
  290. IX_ETH_DB_PUBLIC
  291. IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
  292. {
  293. IX_ETH_DB_CHECK_PORT(portID);
  294. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  295. IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
  296. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
  297. /* force bit at offset 255 to 0 (reserved) */
  298. dependencyPortMap[31] &= 0xFE;
  299. COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
  300. return IX_ETH_DB_SUCCESS;
  301. }
  302. IX_ETH_DB_PUBLIC
  303. IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
  304. {
  305. IX_ETH_DB_CHECK_PORT(portID);
  306. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  307. IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
  308. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
  309. COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
  310. return IX_ETH_DB_SUCCESS;
  311. }
  312. IX_ETH_DB_PUBLIC
  313. IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
  314. {
  315. IX_ETH_DB_CHECK_PORT(portID);
  316. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  317. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
  318. ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate;
  319. ixEthDBPortInfo[portID].updateMethod.userControlled = true;
  320. return IX_ETH_DB_SUCCESS;
  321. }