blob: 023cf50248707fb99330c4c5e3b646b5834199be [file] [log] [blame]
Wolfgang Denkba94a1b2006-05-30 15:56:48 +02001/**
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
Wolfgang Denkcb3761e2013-07-28 22:12:47 +020016 * SPDX-License-Identifier: BSD-3-Clause
Wolfgang Denkba94a1b2006-05-30 15:56:48 +020017 * @par
18 * -- End of Copyright Notice --
19 */
20
21#include "IxEthDB_p.h"
22#include "IxFeatureCtrl.h"
23
24extern HashTable dbHashtable;
25extern IxEthDBPortMap overflowUpdatePortList;
26extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
27
28IX_ETH_DB_PUBLIC
29IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
30{
31 IX_ETH_DB_CHECK_PORT(portID);
32
33 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
34
35 IX_ETH_DB_CHECK_REFERENCE(macAddr);
36
37 IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
38
York Sun472d5462013-04-01 11:29:11 -070039 return ixEthDBTriggerAddPortUpdate(macAddr, portID, true);
Wolfgang Denkba94a1b2006-05-30 15:56:48 +020040}
41
42IX_ETH_DB_PUBLIC
43IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
44{
45 IX_ETH_DB_CHECK_PORT(portID);
46
47 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
48
49 IX_ETH_DB_CHECK_REFERENCE(macAddr);
50
51 IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
52
York Sun472d5462013-04-01 11:29:11 -070053 return ixEthDBTriggerAddPortUpdate(macAddr, portID, false);
Wolfgang Denkba94a1b2006-05-30 15:56:48 +020054}
55
56IX_ETH_DB_PUBLIC
57IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
58{
59 HashNode *searchResult;
60
61 IX_ETH_DB_CHECK_REFERENCE(macAddr);
62
63 searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
64
65 if (searchResult == NULL)
66 {
67 return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
68 }
69
70 ixEthDBReleaseHashNode(searchResult);
71
72 /* build a remove event and place it on the event queue */
73 return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
74}
75
76IX_ETH_DB_PUBLIC
77void ixEthDBDatabaseMaintenance()
78{
79 HashIterator iterator;
80 UINT32 portIndex;
York Sun472d5462013-04-01 11:29:11 -070081 BOOL agingRequired = false;
Wolfgang Denkba94a1b2006-05-30 15:56:48 +020082
83 /* ports who will have deleted records and therefore will need updating */
84 IxEthDBPortMap triggerPorts;
85
86 if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
87 ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
88 {
89 return;
90 }
91
92 SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
93
94 /* check if there's at least a port that needs aging */
95 for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
96 {
97 if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
98 {
York Sun472d5462013-04-01 11:29:11 -070099 agingRequired = true;
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200100 }
101 }
102
103 if (agingRequired)
104 {
105 /* ask each NPE port to write back the database for aging inspection */
106 for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
107 {
108 if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
109 && ixEthDBPortInfo[portIndex].agingEnabled
110 && ixEthDBPortInfo[portIndex].enabled)
111 {
112 IxNpeMhMessage message;
113 IX_STATUS result;
114
115 /* send EDB_GetMACAddressDatabase message */
116 FILL_GETMACADDRESSDATABASE(message,
117 0 /* unused */,
118 IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
119
120 IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
121
122 if (result == IX_SUCCESS)
123 {
124 /* analyze NPE copy */
125 ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
126
127 IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
128 }
129 else
130 {
York Sun472d5462013-04-01 11:29:11 -0700131 ixEthDBPortInfo[portIndex].agingEnabled = false;
132 ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = false;
133 ixEthDBPortInfo[portIndex].updateMethod.userControlled = true;
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200134
135 ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
136 IX_OSAL_LOG_DEV_STDOUT,
137 "EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n",
138 portIndex, 0, 0, 0, 0, 0);
139
140 ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
141 }
142 }
143 }
144
145 /* browse database and age entries */
146 BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
147
148 while (IS_ITERATOR_VALID(&iterator))
149 {
150 MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
151 UINT32 *age = NULL;
York Sun472d5462013-04-01 11:29:11 -0700152 BOOL staticEntry = true;
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200153
154 if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
155 {
156 age = &descriptor->recordData.filteringData.age;
157 staticEntry = descriptor->recordData.filteringData.staticEntry;
158 }
159 else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
160 {
161 age = &descriptor->recordData.filteringVlanData.age;
162 staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
163 }
164 else
165 {
York Sun472d5462013-04-01 11:29:11 -0700166 staticEntry = true;
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200167 }
168
York Sun472d5462013-04-01 11:29:11 -0700169 if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == false))
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200170 {
171 /* manually increment the age if the port has no such capability */
172 if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
173 {
174 *age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
175 }
176
177 /* age entry if it exceeded the maximum time to live */
178 if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
179 {
180 /* add port to the set of update trigger ports */
181 JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
182
183 /* delete entry */
184 BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
185 }
186 else
187 {
188 /* move to the next record */
189 BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
190 }
191 }
192 else
193 {
194 /* move to the next record */
195 BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
196 }
197 }
198
199 /* update ports which lost records */
200 ixEthDBUpdatePortLearningTrees(triggerPorts);
201 }
202}
203
204IX_ETH_DB_PUBLIC
205IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
206{
207 IxEthDBPortMap triggerPorts;
208 HashIterator iterator;
209
210 if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
211 {
212 return IX_ETH_DB_INVALID_PORT;
213 }
214
215 /* check if the user passes some extra bits */
216 if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
217 {
218 return IX_ETH_DB_INVALID_ARG;
219 }
220
221 SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
222
223 /* browse database and age entries */
224 BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
225
226 while (IS_ITERATOR_VALID(&iterator))
227 {
228 MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
229
230 if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
231 && ((descriptor->type & recordType) != 0))
232 {
233 /* add to trigger if automatic updates are required */
234 if (ixEthDBPortUpdateRequired[descriptor->type])
235 {
236 /* add port to the set of update trigger ports */
237 JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
238 }
239
240 /* delete entry */
241 BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
242 }
243 else
244 {
245 /* move to the next record */
246 BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
247 }
248 }
249
250 /* update ports which lost records */
251 ixEthDBUpdatePortLearningTrees(triggerPorts);
252
253 return IX_ETH_DB_SUCCESS;
254}
255
256IX_ETH_DB_PUBLIC
257IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
258{
259 HashNode *searchResult;
260 IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
261
262 IX_ETH_DB_CHECK_PORT(portID);
263
264 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
265
266 IX_ETH_DB_CHECK_REFERENCE(macAddr);
267
268 IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
269
270 searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
271
272 if (searchResult == NULL)
273 {
274 return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
275 }
276
277 if (((MacDescriptor *) (searchResult->data))->portID == portID)
278 {
279 result = IX_ETH_DB_SUCCESS; /* address and port match */
280 }
281
282 ixEthDBReleaseHashNode(searchResult);
283
284 return result;
285}
286
287IX_ETH_DB_PUBLIC
288IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
289{
290 HashNode *searchResult;
291
292 IX_ETH_DB_CHECK_REFERENCE(portID);
293
294 IX_ETH_DB_CHECK_REFERENCE(macAddr);
295
296 searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
297
298 if (searchResult == NULL)
299 {
300 return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
301 }
302
303 /* return the port ID */
304 *portID = ((MacDescriptor *) searchResult->data)->portID;
305
306 ixEthDBReleaseHashNode(searchResult);
307
308 return IX_ETH_DB_SUCCESS;
309}
310
311IX_ETH_DB_PUBLIC
312IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
313{
314 IX_ETH_DB_CHECK_PORT(portID);
315
316 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
317
318 IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
319
York Sun472d5462013-04-01 11:29:11 -0700320 ixEthDBPortInfo[portID].agingEnabled = false;
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200321
322 return IX_ETH_DB_SUCCESS;
323}
324
325IX_ETH_DB_PUBLIC
326IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
327{
328 IX_ETH_DB_CHECK_PORT(portID);
329
330 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
331
332 IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
333
York Sun472d5462013-04-01 11:29:11 -0700334 ixEthDBPortInfo[portID].agingEnabled = true;
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200335
336 return IX_ETH_DB_SUCCESS;
337}
338
339IX_ETH_DB_PUBLIC
340IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
341{
342 HashNode *searchResult;
343 MacDescriptor *descriptor;
344
345 IX_ETH_DB_CHECK_REFERENCE(portID);
346
347 IX_ETH_DB_CHECK_REFERENCE(macAddr);
348
349 searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
350
351 if (searchResult == NULL)
352 {
353 return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
354 }
355
356 descriptor = (MacDescriptor *) searchResult->data;
357
358 /* return the port ID */
359 *portID = descriptor->portID;
360
361 /* reset entry age */
362 if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
363 {
364 descriptor->recordData.filteringData.age = 0;
365 }
366 else
367 {
368 descriptor->recordData.filteringVlanData.age = 0;
369 }
370
371 ixEthDBReleaseHashNode(searchResult);
372
373 return IX_ETH_DB_SUCCESS;
374}
375
376IX_ETH_DB_PUBLIC
377IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
378{
379 IX_ETH_DB_CHECK_PORT(portID);
380
381 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
382
383 IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
384
385 IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
386
387 /* force bit at offset 255 to 0 (reserved) */
388 dependencyPortMap[31] &= 0xFE;
389
390 COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
391
392 return IX_ETH_DB_SUCCESS;
393}
394
395IX_ETH_DB_PUBLIC
396IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
397{
398 IX_ETH_DB_CHECK_PORT(portID);
399
400 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
401
402 IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
403
404 IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
405
406 COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
407
408 return IX_ETH_DB_SUCCESS;
409}
410
411IX_ETH_DB_PUBLIC
412IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
413{
414 IX_ETH_DB_CHECK_PORT(portID);
415
416 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
417
418 IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
419
420 ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate;
York Sun472d5462013-04-01 11:29:11 -0700421 ixEthDBPortInfo[portID].updateMethod.userControlled = true;
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200422
423 return IX_ETH_DB_SUCCESS;
424}