Skip to content

Commit e540228

Browse files
committed
Merge pull request #6 from project-rig/remove-default-routes
Remove default routes
2 parents 2de92f8 + bc41a57 commit e540228

File tree

5 files changed

+202
-2
lines changed

5 files changed

+202
-2
lines changed

include/remove_default_routes.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include <stdio.h>
2+
#include <stdbool.h>
3+
#include "bitset.h"
4+
#include "routing_table.h"
5+
6+
#ifndef __REMOVE_DEFAULT_ROUTES_H__
7+
8+
static inline void remove_default_routes_minimise(table_t *table)
9+
{
10+
// Mark the entries to be removed from the table
11+
bitset_t remove;
12+
bitset_init(&remove, table->size);
13+
14+
// Work up the table from the bottom, marking entries to remove
15+
for (unsigned int i = table->size - 1; i < table->size; i--)
16+
{
17+
// Get the current entry
18+
entry_t entry = table->entries[i];
19+
20+
// See if it can be removed
21+
if (__builtin_popcount(entry.route) == 1 && // Only one output direction
22+
(entry.route & 0x3f) && // which is a link.
23+
__builtin_popcount(entry.source) == 1 && // Only one input direction
24+
(entry.source & 0x3f) && // which is a link.
25+
(entry.route >> 3) == (entry.source & 0x7) && // Source is opposite to sink
26+
(entry.source >> 3) == (entry.route & 0x7)) // Source is opposite to sink
27+
{
28+
// The entry can be removed iff. it doesn't intersect with any entry
29+
// further down the table.
30+
bool remove_entry = true;
31+
for (unsigned int j = i + 1; j < table->size; j++)
32+
{
33+
// If entry we're comparing with is already going to be removed, ignore
34+
// it.
35+
if (bitset_contains(&remove, j))
36+
{
37+
continue;
38+
}
39+
40+
keymask_t a = entry.keymask;
41+
keymask_t b = table->entries[j].keymask;
42+
43+
if (keymask_intersect(a, b))
44+
{
45+
remove_entry = false;
46+
break;
47+
}
48+
}
49+
50+
if (remove_entry)
51+
{
52+
// Mark this entry as being removed
53+
bitset_add(&remove, i);
54+
}
55+
}
56+
}
57+
58+
// Remove the selected entries from the table
59+
for (unsigned int insert = 0, read = 0; read < table->size; read++)
60+
{
61+
// Grab the current entry before we potentially overwrite it
62+
entry_t current = table->entries[read];
63+
64+
// Insert the entry if it isn't being removed
65+
if (!bitset_contains(&remove, read))
66+
{
67+
table->entries[insert++] = current;
68+
}
69+
}
70+
71+
// Update the table size
72+
table->size -= remove.count;
73+
74+
// Clear up
75+
bitset_delete(&remove);
76+
}
77+
78+
#define __REMOVE_DEFAULT_ROUTES_H__
79+
#endif // __REMOVE_DEFAULT_ROUTES_H__

tests/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
OBJECTS=tests.o test_bitset.o test_routing_table.o test_merge.o test_ordered_covering.o test_aliases.o test_mtrie.o
1+
OBJECTS=tests.o test_bitset.o test_routing_table.o test_merge.o test_ordered_covering.o test_aliases.o test_mtrie.o test_remove_default_routes.o
22
INC_DIR=../include/
33
CFLAGS+=-I ${INC_DIR} -fprofile-arcs -ftest-coverage -g --std=gnu99 -Wall -Werror
44
LDFLAGS+=$(shell pkg-config --cflags --libs check)
55

66
coverage : run_tests
7-
gcov test_bitset test_routing_table test_merge test_aliases test_ordered_covering test_mtrie
7+
gcov test_bitset test_routing_table test_merge test_aliases test_ordered_covering test_mtrie test_remove_default_routes
88

99
run_tests : tests
1010
valgrind --leak-check=full -q ./tests

tests/test_remove_default_routes.c

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include "tests.h"
2+
#include "routing_table.h"
3+
#include "remove_default_routes.h"
4+
5+
// Remove default routes from the table:
6+
//
7+
// S -> 0000 -> N # Remove
8+
// N -> 0001 -> N # Keep
9+
// ? -> 0010 -> N # Keep
10+
// N S -> 0011 -> N S # Keep
11+
// 1 -> 0100 -> 1 # Keep
12+
entry_t orthogonal_entries[] = {
13+
{{0x0, 0xf}, 0b000100, 0b100000},
14+
{{0x1, 0xf}, 0b000100, 0b000100},
15+
{{0x2, 0xf}, 0b000100, (1 << 24)},
16+
{{0x3, 0xf}, 0b100100, 0b100100},
17+
{{0x4, 0xf}, 0b1000000, 0b1000000},
18+
};
19+
entry_t orthogonal_entries_results[] = {
20+
{{0x1, 0xf}, 0b000100, 0b000100},
21+
{{0x2, 0xf}, 0b000100, (1 << 24)},
22+
{{0x3, 0xf}, 0b100100, 0b100100},
23+
{{0x4, 0xf}, 0b1000000, 0b1000000},
24+
};
25+
26+
// Remove default routes from the table:
27+
//
28+
// S -> 0000 -> N # Remove
29+
// N -> 0001 -> N # Keep
30+
// ? -> 0010 -> N # Keep
31+
// N S -> 0011 -> N S # Keep
32+
// W -> 0100 -> E # Remove
33+
entry_t orthogonal_entries2[] = {
34+
{{0x0, 0xf}, 0b000100, 0b100000},
35+
{{0x1, 0xf}, 0b000100, 0b000100},
36+
{{0x2, 0xf}, 0b000100, (1 << 24)},
37+
{{0x3, 0xf}, 0b100100, 0b100100},
38+
{{0x4, 0xf}, 0b000001, 0b001000},
39+
};
40+
entry_t orthogonal_entries2_results[] = {
41+
{{0x1, 0xf}, 0b000100, 0b000100},
42+
{{0x2, 0xf}, 0b000100, (1 << 24)},
43+
{{0x3, 0xf}, 0b100100, 0b100100},
44+
};
45+
46+
// Remove default routes from the table:
47+
//
48+
// S -> 1000 -> N # Remove
49+
// S -> 0000 -> N # Keep
50+
// ? -> 0XXX -> N # Keep
51+
entry_t nonorthogonal_entries[] = {
52+
{{0x8, 0xf}, 0b000100, 0b100000},
53+
{{0x0, 0xf}, 0b000100, 0b100000},
54+
{{0x0, 0x8}, 0b000100, (1 << 24)},
55+
};
56+
entry_t nonorthogonal_entries_results[] = {
57+
{{0x0, 0xf}, 0b000100, 0b100000},
58+
{{0x0, 0x8}, 0b000100, (1 << 24)},
59+
};
60+
61+
// Set up the fixtures
62+
table_t test_tables[] = {
63+
{5, orthogonal_entries},
64+
{5, orthogonal_entries2},
65+
{3, nonorthogonal_entries},
66+
};
67+
68+
table_t expected_tables[] = {
69+
{4, orthogonal_entries_results},
70+
{3, orthogonal_entries2_results},
71+
{2, nonorthogonal_entries_results},
72+
};
73+
74+
75+
START_TEST(test_removal)
76+
{
77+
// Grab the tables
78+
table_t table = test_tables[_i];
79+
table_t expected = expected_tables[_i];
80+
81+
// Minimise
82+
remove_default_routes_minimise(&table);
83+
84+
// Check the result
85+
ck_assert_int_eq(table.size, expected.size);
86+
87+
// Check the tables are equivalent
88+
for (unsigned int i = 0; i < table.size; i++)
89+
{
90+
// Get the entries
91+
entry_t e = table.entries[i];
92+
entry_t f = expected.entries[i];
93+
94+
ck_assert_int_eq(e.keymask.key, f.keymask.key);
95+
ck_assert_int_eq(e.keymask.mask, f.keymask.mask);
96+
ck_assert_int_eq(e.route, f.route);
97+
ck_assert_int_eq(e.source, f.source);
98+
}
99+
}
100+
END_TEST
101+
102+
103+
Suite* remove_default_suite(void)
104+
{
105+
Suite *s;
106+
TCase *tests;
107+
108+
s = suite_create("Remove Default Routes");
109+
tests = tcase_create("Core");
110+
suite_add_tcase(s, tests);
111+
112+
// Add the tests
113+
tcase_add_loop_test(tests, test_removal,
114+
0, sizeof(test_tables) / sizeof(table_t));
115+
116+
return s;
117+
}

tests/tests.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ int main(void)
2323
Suite *s_mtrie = mtrie_suite();
2424
srunner_add_suite(sr, s_mtrie);
2525

26+
Suite *s_rdr = remove_default_suite();
27+
srunner_add_suite(sr, s_rdr);
28+
2629
// Run the tests
2730
srunner_run_all(sr, CK_NORMAL);
2831

tests/tests.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Suite* merge_suite(void);
99
Suite* ordered_covering_suite(void);
1010
Suite* aliases_suite(void);
1111
Suite* mtrie_suite(void);
12+
Suite* remove_default_suite(void);
1213

1314

1415
#define __TEST_H__

0 commit comments

Comments
 (0)