diff --git a/radix/radix.c b/radix/radix.c index 3a44268..3cbbb94 100644 --- a/radix/radix.c +++ b/radix/radix.c @@ -11,13 +11,13 @@ radix_node_t create_node(ipv6_t key, unsigned end_bit, unsigned rule) { return ret; } -static inline radix_node_t clone_node(radix_node_t n) { +static radix_node_t clone_node(radix_node_t n) { radix_node_t ret = calloc(1, sizeof(struct radix_node)); memcpy(ret, n, sizeof(struct radix_node)); return ret; } -static inline void split_node(radix_node_t n, unsigned bit) { +static void split_node(radix_node_t n, unsigned bit) { radix_node_t tmp = clone_node(n); n->_ip_end_bit = bit; n->_l = n->_r = tmp; @@ -100,7 +100,28 @@ int radix_insert(radix_holder_t t, ipv6_t key, int val, int mask) { } int radix_search(radix_holder_t t, ipv6_t key) { - + unsigned char b; + int ret = INVALID_RULE; + radix_node_t iter = t->_root; + int ibit = 0; + if (!iter) + return INVALID_RULE; + + + for (;ibit < 128; ++ibit) { + b = GET_BIT(key, ibit); + if (ibit < iter->_ip_end_bit && + b == GET_BIT(iter->_ip, ibit)) + continue; + + if (ibit == iter->_ip_end_bit) /* set result if full match */ + ret = iter->_rule_valid ? iter->_rule : ret; + + iter = b ? iter->_l : iter->_r; + if (!iter) + return ret; + } + return ret; } @@ -112,7 +133,7 @@ int radix_search(radix_holder_t t, ipv6_t key) { #define RULES_FILE "../data/routing-data" #define TEST_FILE "../data/test-data" -#define TEST_ROWS 5721 +#define TEST_ROWS 5527 #define READ_MODE "r" int parse_line(ipv6_t* key, int* val, int* mask, FILE* f) { /*! assumes only good input */ @@ -201,10 +222,9 @@ int main() { radix_holder_t t = create_holder(); printf("Loaded %d rules\n", load_input(t) ); - /* printf("Loaded %d tests\n", load_tests(&ips, &ref) ); printf("%d tests wrong\n", fire_tests(t, ips, ref, TEST_ROWS) ); - */ + destory_holder(t); return 0; } \ No newline at end of file