*/
static int SCRadixPrefixContainNetmaskAndSetUserData(SCRadixPrefix *prefix,
uint16_t netmask,
- int exact_match)
+ int exact_match,
+ void **user_data_result)
{
SCRadixUserData *user_data = NULL;
* netblock, i.e. an ip with a netmask of 32(ipv4) or 128(ipv6) */
if (exact_match) {
if (user_data->netmask == netmask) {
- prefix->user_data_result = user_data->user;
+ if (user_data_result)
+ *user_data_result = user_data->user;
return 1;
} else {
goto no_match;
/* Check for the user_data entry for this netmask_value */
while (user_data != NULL) {
if (user_data->netmask == netmask) {
- prefix->user_data_result = user_data->user;
+ if (user_data_result)
+ *user_data_result = user_data->user;
return 1;
}
user_data = user_data->next;
}
no_match:
+ if (user_data_result != NULL)
+ *user_data_result = NULL;
return 0;
}
* \param node Pointer to the node from where we have to climb the tree
*/
static inline SCRadixNode *SCRadixFindKeyIPNetblock(uint8_t *key_stream, uint8_t key_bitlen,
- SCRadixNode *node)
+ SCRadixNode *node, void **user_data_result)
{
SCRadixNode *netmask_node = NULL;
int mask = 0;
if (key_bitlen % 8 == 0 ||
(node->prefix->stream[bytes] & mask) == (key_stream[bytes] & mask)) {
- if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, netmask_node->netmasks[j], 0))
+ if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, netmask_node->netmasks[j], 0, user_data_result))
return node;
}
}
}
- return SCRadixFindKeyIPNetblock(key_stream, key_bitlen, netmask_node->parent);
+ return SCRadixFindKeyIPNetblock(key_stream, key_bitlen, netmask_node->parent, user_data_result);
}
/**
* \param exact_match The key to be searched is an ip address
*/
static SCRadixNode *SCRadixFindKey(uint8_t *key_stream, uint16_t key_bitlen,
- SCRadixTree *tree, int exact_match)
+ SCRadixTree *tree, int exact_match, void **user_data_result)
{
if (tree == NULL || tree->head == NULL)
return NULL;
if (key_bitlen % 8 == 0 ||
(node->prefix->stream[bytes] & mask) == (tmp_stream[bytes] & mask)) {
- if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, key_bitlen, 1)) {
+ if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, key_bitlen, 1, user_data_result)) {
return node;
}
}
return NULL;
}
- SCRadixNode *ret = SCRadixFindKeyIPNetblock(tmp_stream, key_bitlen, node);
+ SCRadixNode *ret = SCRadixFindKeyIPNetblock(tmp_stream, key_bitlen, node, user_data_result);
return ret;
}
* \param tree Pointer to the Radix tree instance
*/
SCRadixNode *SCRadixFindKeyGeneric(uint8_t *key_stream, uint16_t key_bitlen,
- SCRadixTree *tree)
+ SCRadixTree *tree, void **user_data_result)
{
- return SCRadixFindKey(key_stream, key_bitlen, tree, 1);
+ return SCRadixFindKey(key_stream, key_bitlen, tree, 1, user_data_result);
}
/**
* an IPV4 address
* \param tree Pointer to the Radix tree instance
*/
-SCRadixNode *SCRadixFindKeyIPV4ExactMatch(uint8_t *key_stream, SCRadixTree *tree)
+SCRadixNode *SCRadixFindKeyIPV4ExactMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
{
- return SCRadixFindKey(key_stream, 32, tree, 1);
+ return SCRadixFindKey(key_stream, 32, tree, 1, user_data_result);
}
/**
* an IPV4 address
* \param tree Pointer to the Radix tree instance
*/
-SCRadixNode *SCRadixFindKeyIPV4BestMatch(uint8_t *key_stream, SCRadixTree *tree)
+SCRadixNode *SCRadixFindKeyIPV4BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
{
- return SCRadixFindKey(key_stream, 32, tree, 0);
+ return SCRadixFindKey(key_stream, 32, tree, 0, user_data_result);
}
/**
* \param tree Pointer to the Radix tree instance
*/
SCRadixNode *SCRadixFindKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree,
- uint8_t netmask)
+ uint8_t netmask, void **user_data_result)
{
SCRadixNode *node = NULL;
- node = SCRadixFindKey(key_stream, 32, tree, 0);
+ node = SCRadixFindKey(key_stream, 32, tree, 0, user_data_result);
if (node == NULL)
return node;
- if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, netmask, 1))
+ if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, netmask, 1, user_data_result))
return node;
else
return NULL;
* \param tree Pointer to the Radix tree instance
*/
SCRadixNode *SCRadixFindKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree,
- uint8_t netmask)
+ uint8_t netmask, void **user_data_result)
{
SCRadixNode *node = NULL;
- node = SCRadixFindKey(key_stream, 128, tree, 0);
+ node = SCRadixFindKey(key_stream, 128, tree, 0, user_data_result);
if (node == NULL)
return node;
- if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, (uint16_t)netmask, 1))
+ if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, (uint16_t)netmask, 1, user_data_result))
return node;
else
return NULL;
* an IPV6 address
* \param tree Pointer to the Radix tree instance
*/
-SCRadixNode *SCRadixFindKeyIPV6ExactMatch(uint8_t *key_stream, SCRadixTree *tree)
+SCRadixNode *SCRadixFindKeyIPV6ExactMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
{
- return SCRadixFindKey(key_stream, 128, tree, 1);
+ return SCRadixFindKey(key_stream, 128, tree, 1, user_data_result);
}
/**
* an IPV6 address
* \param tree Pointer to the Radix tree instance
*/
-SCRadixNode *SCRadixFindKeyIPV6BestMatch(uint8_t *key_stream, SCRadixTree *tree)
+SCRadixNode *SCRadixFindKeyIPV6BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
{
- return SCRadixFindKey(key_stream, 128, tree, 0);
+ return SCRadixFindKey(key_stream, 128, tree, 0, user_data_result);
}
/**
#define SC_RADIX_BITTEST(x, y) ((x) & (y))
-/**
- * \brief Macro to fetch the user data from a node. It checks if node is a
- * valid pointer and if node->prefix is as well.
- *
- * \param node Variable name/expression containing the node
- * \param type User data type in which the node points to
- *
- * \returns User data within the node
- */
-#define SC_RADIX_NODE_USERDATA(node, type) \
- ((type *)(((node) != NULL) ? (((node)->prefix != NULL) ? \
- (node)->prefix->user_data_result : NULL) : NULL))
-
/**
* \brief Structure that hold the user data and the netmask associated with it.
*/
* with any of the the 32 or 128 netblocks. Also for non-ips, we store the
* netmask as 255 in SCRadixUserData->netmask */
SCRadixUserData *user_data;
-
- /* Used to hold the user data from radix tree search. More of a convenience
- * that lets anyone using the API, directly get a reference to the user
- * data which is associated with the search results */
- void *user_data_result;
} SCRadixPrefix;
/**
void SCRadixRemoveKeyIPV6Netblock(uint8_t *, SCRadixTree *, uint8_t);
void SCRadixRemoveKeyIPV6(uint8_t *, SCRadixTree *);
-SCRadixNode *SCRadixFindKeyGeneric(uint8_t *, uint16_t, SCRadixTree *);
+SCRadixNode *SCRadixFindKeyGeneric(uint8_t *, uint16_t, SCRadixTree *, void **);
-SCRadixNode *SCRadixFindKeyIPV4ExactMatch(uint8_t *, SCRadixTree *);
-SCRadixNode *SCRadixFindKeyIPV4Netblock(uint8_t *, SCRadixTree *, uint8_t);
-SCRadixNode *SCRadixFindKeyIPV4BestMatch(uint8_t *, SCRadixTree *);
+SCRadixNode *SCRadixFindKeyIPV4ExactMatch(uint8_t *, SCRadixTree *, void **);
+SCRadixNode *SCRadixFindKeyIPV4Netblock(uint8_t *, SCRadixTree *, uint8_t, void **);
+SCRadixNode *SCRadixFindKeyIPV4BestMatch(uint8_t *, SCRadixTree *, void **);
-SCRadixNode *SCRadixFindKeyIPV6ExactMatch(uint8_t *, SCRadixTree *);
-SCRadixNode *SCRadixFindKeyIPV6Netblock(uint8_t *, SCRadixTree *, uint8_t);
-SCRadixNode *SCRadixFindKeyIPV6BestMatch(uint8_t *, SCRadixTree *);
+SCRadixNode *SCRadixFindKeyIPV6ExactMatch(uint8_t *, SCRadixTree *, void **);
+SCRadixNode *SCRadixFindKeyIPV6Netblock(uint8_t *, SCRadixTree *, uint8_t, void **);
+SCRadixNode *SCRadixFindKeyIPV6BestMatch(uint8_t *, SCRadixTree *, void **);
void SCRadixPrintTree(SCRadixTree *);
void SCRadixPrintNodeInfo(SCRadixNode *, int, void (*PrintData)(void*));