Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions include/remove_default_routes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <stdio.h>
#include <stdbool.h>
#include "bitset.h"
#include "routing_table.h"

#ifndef __REMOVE_DEFAULT_ROUTES_H__

static inline void remove_default_routes_minimise(table_t *table)
{
// Mark the entries to be removed from the table
bitset_t remove;
bitset_init(&remove, table->size);

// Work up the table from the bottom, marking entries to remove
for (unsigned int i = table->size - 1; i < table->size; i--)
{
// Get the current entry
entry_t entry = table->entries[i];

// See if it can be removed
if (__builtin_popcount(entry.route) == 1 && // Only one output direction
(entry.route & 0x3f) && // which is a link.
__builtin_popcount(entry.source) == 1 && // Only one input direction
(entry.source & 0x3f) && // which is a link.
(entry.route >> 3) == (entry.source & 0x7) && // Source is opposite to sink
(entry.source >> 3) == (entry.route & 0x7)) // Source is opposite to sink
{
// The entry can be removed iff. it doesn't intersect with any entry
// further down the table.
bool remove_entry = true;
for (unsigned int j = i + 1; j < table->size; j++)
{
// If entry we're comparing with is already going to be removed, ignore
// it.
if (bitset_contains(&remove, j))
{
continue;
}

keymask_t a = entry.keymask;
keymask_t b = table->entries[j].keymask;

if (keymask_intersect(a, b))
{
remove_entry = false;
break;
}
}

if (remove_entry)
{
// Mark this entry as being removed
bitset_add(&remove, i);
}
}
}

// Remove the selected entries from the table
for (unsigned int insert = 0, read = 0; read < table->size; read++)
{
// Grab the current entry before we potentially overwrite it
entry_t current = table->entries[read];

// Insert the entry if it isn't being removed
if (!bitset_contains(&remove, read))
{
table->entries[insert++] = current;
}
}

// Update the table size
table->size -= remove.count;

// Clear up
bitset_delete(&remove);
}

#define __REMOVE_DEFAULT_ROUTES_H__
#endif // __REMOVE_DEFAULT_ROUTES_H__
4 changes: 2 additions & 2 deletions tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
OBJECTS=tests.o test_bitset.o test_routing_table.o test_merge.o test_ordered_covering.o test_aliases.o test_mtrie.o
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
INC_DIR=../include/
CFLAGS+=-I ${INC_DIR} -fprofile-arcs -ftest-coverage -g --std=gnu99 -Wall -Werror
LDFLAGS+=$(shell pkg-config --cflags --libs check)

coverage : run_tests
gcov test_bitset test_routing_table test_merge test_aliases test_ordered_covering test_mtrie
gcov test_bitset test_routing_table test_merge test_aliases test_ordered_covering test_mtrie test_remove_default_routes

run_tests : tests
valgrind --leak-check=full -q ./tests
Expand Down
117 changes: 117 additions & 0 deletions tests/test_remove_default_routes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "tests.h"
#include "routing_table.h"
#include "remove_default_routes.h"

// Remove default routes from the table:
//
// S -> 0000 -> N # Remove
// N -> 0001 -> N # Keep
// ? -> 0010 -> N # Keep
// N S -> 0011 -> N S # Keep
// 1 -> 0100 -> 1 # Keep
entry_t orthogonal_entries[] = {
{{0x0, 0xf}, 0b000100, 0b100000},
{{0x1, 0xf}, 0b000100, 0b000100},
{{0x2, 0xf}, 0b000100, (1 << 24)},
{{0x3, 0xf}, 0b100100, 0b100100},
{{0x4, 0xf}, 0b1000000, 0b1000000},
};
entry_t orthogonal_entries_results[] = {
{{0x1, 0xf}, 0b000100, 0b000100},
{{0x2, 0xf}, 0b000100, (1 << 24)},
{{0x3, 0xf}, 0b100100, 0b100100},
{{0x4, 0xf}, 0b1000000, 0b1000000},
};

// Remove default routes from the table:
//
// S -> 0000 -> N # Remove
// N -> 0001 -> N # Keep
// ? -> 0010 -> N # Keep
// N S -> 0011 -> N S # Keep
// W -> 0100 -> E # Remove
entry_t orthogonal_entries2[] = {
{{0x0, 0xf}, 0b000100, 0b100000},
{{0x1, 0xf}, 0b000100, 0b000100},
{{0x2, 0xf}, 0b000100, (1 << 24)},
{{0x3, 0xf}, 0b100100, 0b100100},
{{0x4, 0xf}, 0b000001, 0b001000},
};
entry_t orthogonal_entries2_results[] = {
{{0x1, 0xf}, 0b000100, 0b000100},
{{0x2, 0xf}, 0b000100, (1 << 24)},
{{0x3, 0xf}, 0b100100, 0b100100},
};

// Remove default routes from the table:
//
// S -> 1000 -> N # Remove
// S -> 0000 -> N # Keep
// ? -> 0XXX -> N # Keep
entry_t nonorthogonal_entries[] = {
{{0x8, 0xf}, 0b000100, 0b100000},
{{0x0, 0xf}, 0b000100, 0b100000},
{{0x0, 0x8}, 0b000100, (1 << 24)},
};
entry_t nonorthogonal_entries_results[] = {
{{0x0, 0xf}, 0b000100, 0b100000},
{{0x0, 0x8}, 0b000100, (1 << 24)},
};

// Set up the fixtures
table_t test_tables[] = {
{5, orthogonal_entries},
{5, orthogonal_entries2},
{3, nonorthogonal_entries},
};

table_t expected_tables[] = {
{4, orthogonal_entries_results},
{3, orthogonal_entries2_results},
{2, nonorthogonal_entries_results},
};


START_TEST(test_removal)
{
// Grab the tables
table_t table = test_tables[_i];
table_t expected = expected_tables[_i];

// Minimise
remove_default_routes_minimise(&table);

// Check the result
ck_assert_int_eq(table.size, expected.size);

// Check the tables are equivalent
for (unsigned int i = 0; i < table.size; i++)
{
// Get the entries
entry_t e = table.entries[i];
entry_t f = expected.entries[i];

ck_assert_int_eq(e.keymask.key, f.keymask.key);
ck_assert_int_eq(e.keymask.mask, f.keymask.mask);
ck_assert_int_eq(e.route, f.route);
ck_assert_int_eq(e.source, f.source);
}
}
END_TEST


Suite* remove_default_suite(void)
{
Suite *s;
TCase *tests;

s = suite_create("Remove Default Routes");
tests = tcase_create("Core");
suite_add_tcase(s, tests);

// Add the tests
tcase_add_loop_test(tests, test_removal,
0, sizeof(test_tables) / sizeof(table_t));

return s;
}
3 changes: 3 additions & 0 deletions tests/tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ int main(void)
Suite *s_mtrie = mtrie_suite();
srunner_add_suite(sr, s_mtrie);

Suite *s_rdr = remove_default_suite();
srunner_add_suite(sr, s_rdr);

// Run the tests
srunner_run_all(sr, CK_NORMAL);

Expand Down
1 change: 1 addition & 0 deletions tests/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Suite* merge_suite(void);
Suite* ordered_covering_suite(void);
Suite* aliases_suite(void);
Suite* mtrie_suite(void);
Suite* remove_default_suite(void);


#define __TEST_H__
Expand Down