Skip to content

Commit 2de92f8

Browse files
committed
Merge pull request #5 from project-rig/add-source-field
Add `source' field to routing table entries
2 parents 768cdd0 + 8740a55 commit 2de92f8

File tree

12 files changed

+297
-171
lines changed

12 files changed

+297
-171
lines changed

desktop/mtrie.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ int main(int argc, char *argv[])
7171
table.entries[i].keymask.key = t.key;
7272
table.entries[i].keymask.mask = t.mask;
7373
table.entries[i].route = t.route;
74+
table.entries[i].source = t.source;
7475
}
7576

7677
// Perform the minimisation
@@ -88,7 +89,7 @@ int main(int argc, char *argv[])
8889
// Copy relevant fields across
8990
table.entries[i].keymask.key,
9091
table.entries[i].keymask.mask,
91-
0x0, // No source
92+
table.entries[i].source,
9293
table.entries[i].route,
9394
};
9495
fwrite(&t, sizeof(fentry_t), 1, out_file);

desktop/ordered_covering.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ int main(int argc, char *argv[])
121121
table.entries[i].keymask.key = t.key;
122122
table.entries[i].keymask.mask = t.mask;
123123
table.entries[i].route = t.route;
124+
table.entries[i].source = t.source;
124125
}
125126

126127
// Sort the table
@@ -141,7 +142,7 @@ int main(int argc, char *argv[])
141142
// Copy relevant fields across
142143
table.entries[i].keymask.key,
143144
table.entries[i].keymask.mask,
144-
0x0, // No source
145+
table.entries[i].source,
145146
table.entries[i].route,
146147
};
147148
fwrite(&t, sizeof(fentry_t), 1, out_file);

include/aliases.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,20 @@
1212
/* Vector-like object ********************************************************/
1313

1414

15+
typedef struct _alias_element_t // Element of an alias list
16+
{
17+
keymask_t keymask; // Keymask of the element
18+
uint32_t source; // Source of packets matching the element
19+
} alias_element_t;
20+
21+
1522
typedef struct _alias_list_t
1623
{
1724
// Linked list of arrays
1825
unsigned int n_elements; // Elements in this instance
1926
unsigned int max_size; // Max number of elements in this instance
2027
struct _alias_list_t *next; // Next element in list of lists
21-
keymask_t data; // Data region
28+
alias_element_t data; // Data region
2229
} alias_list_t;
2330

2431

@@ -27,7 +34,7 @@ static inline alias_list_t* alias_list_new(unsigned int max_size)
2734
{
2835
// Compute how much memory to allocate
2936
unsigned int size = sizeof(alias_list_t) +
30-
(max_size - 1)*sizeof(keymask_t);
37+
(max_size - 1)*sizeof(alias_element_t);
3138

3239
// Allocate and then fill in values
3340
alias_list_t *as = MALLOC(size);
@@ -40,11 +47,14 @@ static inline alias_list_t* alias_list_new(unsigned int max_size)
4047

4148

4249
// Append an element to a list
43-
static inline bool alias_list_append(alias_list_t *as, keymask_t val)
50+
static inline bool alias_list_append(alias_list_t *as,
51+
keymask_t val,
52+
uint32_t source)
4453
{
4554
if (as->n_elements < as->max_size)
4655
{
47-
(&as->data)[as->n_elements] = val;
56+
(&as->data)[as->n_elements].keymask = val;
57+
(&as->data)[as->n_elements].source = source;
4858
as->n_elements++;
4959

5060
return true;
@@ -58,7 +68,7 @@ static inline bool alias_list_append(alias_list_t *as, keymask_t val)
5868

5969

6070
// Get an element from the list
61-
static inline keymask_t alias_list_get(alias_list_t *as, unsigned int i)
71+
static inline alias_element_t alias_list_get(alias_list_t *as, unsigned int i)
6272
{
6373
return (&as->data)[i];
6474
}

include/merge.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ typedef struct _merge_t
1010

1111
keymask_t keymask; // Keymask resulting from the merge
1212
uint32_t route; // Route taken by entries in the merge
13+
uint32_t source; // Collective source of entries in the route
1314
} merge_t;
1415

1516

@@ -23,6 +24,7 @@ static inline void merge_clear(merge_t* m)
2324
m->keymask.key = 0xffffffff; // !!!...
2425
m->keymask.mask = 0x00000000; // Matches nothing
2526
m->route = 0x0;
27+
m->source = 0x0;
2628
}
2729

2830

@@ -76,6 +78,7 @@ static inline void merge_add(merge_t* m, unsigned int i)
7678

7779
// Add the route
7880
m->route |= e.route;
81+
m->source |= e.source;
7982
}
8083
}
8184

@@ -95,6 +98,7 @@ static inline void merge_remove(merge_t* m, unsigned int i)
9598
{
9699
// Rebuild the key and mask from scratch
97100
m->route = 0x0;
101+
m->source = 0x0;
98102
m->keymask.key = 0xffffffff;
99103
m->keymask.mask = 0x000000000;
100104
for (unsigned int j = 0; j < m->table->size; j++)
@@ -104,6 +108,7 @@ static inline void merge_remove(merge_t* m, unsigned int i)
104108
if (bitset_contains(&(m->entries), j))
105109
{
106110
m->route |= e.route;
111+
m->source |= e.source;
107112
if (m->keymask.key == 0xffffffff && m->keymask.mask == 0x00000000)
108113
{
109114
// Initialise the keymask

include/mtrie.h

Lines changed: 101 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,20 @@
66

77
#ifndef __MTRIE_H__
88

9+
// Short routing table entry resulting from an m-trie
10+
typedef struct _mtrie_entry_t
11+
{
12+
keymask_t keymask; // Keymask of the entry
13+
uint32_t source; // Sources of packets in the entry
14+
} mtrie_entry_t;
15+
916
// m-Trie structure
1017
typedef struct _mtrie_node_t
1118
{
1219
struct _mtrie_node_t *parent; // Our parent
1320
uint32_t bit; // Bit represented by this Node
1421
struct _mtrie_node_t *child_0, *child_1, *child_X; // Children of this Node
22+
uint32_t source; // Source(s) of packets which "reach" this node
1523
} mtrie_t;
1624

1725
// Create a new (empty) node
@@ -23,6 +31,7 @@ static inline mtrie_t *mtrie_new_node(mtrie_t *parent, uint32_t bit)
2331
node->parent = parent;
2432
node->bit = bit;
2533
node->child_0 = node->child_1 = node->child_X = NULL;
34+
node->source = 0x0;
2635

2736
return node;
2837
}
@@ -69,8 +78,8 @@ static inline unsigned int mtrie_count(mtrie_t *node)
6978
}
7079

7180
// Extract routing table entries from a trie
72-
static inline keymask_t* _get_entries(
73-
mtrie_t *node, keymask_t *table, uint32_t pkey, uint32_t pmask
81+
static inline mtrie_entry_t* _get_entries(
82+
mtrie_t *node, mtrie_entry_t *table, uint32_t pkey, uint32_t pmask
7483
)
7584
{
7685
if (node == NULL)
@@ -81,8 +90,9 @@ static inline keymask_t* _get_entries(
8190
{
8291
// If this is a leaf then add an entry to the table representing this entry
8392
// and return a pointer to the next entry in the table.
84-
table->key = pkey;
85-
table->mask = pmask;
93+
table->keymask.key = pkey;
94+
table->keymask.mask = pmask;
95+
table->source = node->source;
8696

8797
// Point to the next table entry
8898
table++;
@@ -99,7 +109,7 @@ static inline keymask_t* _get_entries(
99109
return table;
100110
}
101111

102-
static inline void mtrie_get_entries(mtrie_t *node, keymask_t *table)
112+
static inline void mtrie_get_entries(mtrie_t *node, mtrie_entry_t *table)
103113
{
104114
_get_entries(node, table, 0x0, 0x0);
105115
}
@@ -132,7 +142,7 @@ static inline mtrie_t** get_child(mtrie_t *node, uint32_t key, uint32_t mask)
132142
}
133143

134144
// Traverse a path through the tree, adding elements as necessary
135-
static inline mtrie_t* mtrie_traverse(mtrie_t *node, uint32_t key, uint32_t mask)
145+
static inline mtrie_t* mtrie_traverse(mtrie_t *node, uint32_t key, uint32_t mask, uint32_t source)
136146
{
137147
if (node->bit) // If not a leaf
138148
{
@@ -152,11 +162,12 @@ static inline mtrie_t* mtrie_traverse(mtrie_t *node, uint32_t key, uint32_t mask
152162
}
153163

154164
// Delegate the traversal to the child
155-
return mtrie_traverse(*child, key, mask);
165+
return mtrie_traverse(*child, key, mask, source);
156166
}
157167
else
158168
{
159-
// If we are a leaf then return our parent
169+
// If we are a leaf then update our source and return our parent
170+
node->source |= source;
160171
return node->parent;
161172
}
162173
}
@@ -220,6 +231,59 @@ static inline bool mtrie_untraverse(mtrie_t *node, uint32_t key, uint32_t mask)
220231
}
221232
}
222233

234+
static inline uint32_t get_source_from_child(mtrie_t *node,
235+
uint32_t key,
236+
uint32_t mask)
237+
{
238+
if (node->bit) // If not a leaf
239+
{
240+
// See where to turn at this node
241+
mtrie_t **child = get_child(node, key, mask);
242+
243+
// If there is no child then the path does not exist or the given path was
244+
// invalid.
245+
if (!child || !*child)
246+
{
247+
return false;
248+
}
249+
250+
// Delegate the traversal to the child
251+
return get_source_from_child(*child, key, mask);
252+
}
253+
else
254+
{
255+
// If we are a leaf then return the source
256+
return node->source;
257+
}
258+
}
259+
260+
static inline void add_source_to_child(mtrie_t *node,
261+
uint32_t key,
262+
uint32_t mask,
263+
uint32_t source)
264+
{
265+
if (node->bit) // If not a leaf
266+
{
267+
// See where to turn at this node
268+
mtrie_t **child = get_child(node, key, mask);
269+
270+
// If there is no child then the path does not exist or the given path was
271+
// invalid.
272+
if (!child || !*child)
273+
{
274+
return;
275+
}
276+
277+
// Delegate the traversal to the child
278+
add_source_to_child(*child, key, mask, source);
279+
}
280+
else
281+
{
282+
// If we are a leaf then modify the source
283+
node->source |= source;
284+
}
285+
}
286+
223287
static inline void untraverse_in_child(mtrie_t **child, uint32_t key, uint32_t mask)
224288
{
225289
if (mtrie_untraverse(*child, key, mask))
@@ -229,10 +293,13 @@ static inline void untraverse_in_child(mtrie_t **child, uint32_t key, uint32_t m
229293
}
230294

231295
// Insert a new entry into the trie
232-
static inline void mtrie_insert(mtrie_t *root, uint32_t key, uint32_t mask)
296+
static inline void mtrie_insert(mtrie_t *root,
297+
uint32_t key,
298+
uint32_t mask,
299+
uint32_t source)
233300
{
234301
// Traverse a path through the trie and keep a reference to the leaf we reach
235-
mtrie_t *leaf = mtrie_traverse(root, key, mask);
302+
mtrie_t *leaf = mtrie_traverse(root, key, mask, source);
236303

237304
// Attempt to find overlapping paths
238305
while (leaf)
@@ -244,12 +311,16 @@ static inline void mtrie_insert(mtrie_t *root, uint32_t key, uint32_t mask)
244311
if (*child_0 != NULL && path_exists(*child_0, key, mask) &&
245312
*child_1 != NULL && path_exists(*child_1, key, mask))
246313
{
314+
// Get the combined sources from the existing children
315+
source = get_source_from_child(*child_0, key, mask) |
316+
get_source_from_child(*child_1, key, mask);
317+
247318
// Traverse the path in X and then untraverse in 0 and 1
248319
if (*child_X == NULL)
249320
{
250321
*child_X = mtrie_new_node(leaf, leaf->bit >> 1);
251322
}
252-
mtrie_traverse(*child_X, key, mask);
323+
mtrie_traverse(*child_X, key, mask, source);
253324

254325
// Untraverse in `0' and `1'
255326
untraverse_in_child(child_0, key, mask);
@@ -262,19 +333,31 @@ static inline void mtrie_insert(mtrie_t *root, uint32_t key, uint32_t mask)
262333
else if (*child_X != NULL && path_exists(*child_X, key, mask) &&
263334
*child_0 != NULL && path_exists(*child_0, key, mask))
264335
{
336+
// Get the source for packets matching the `0'
337+
source = get_source_from_child(*child_0, key, mask);
338+
265339
// Untraverse in `0'
266340
untraverse_in_child(child_0, key, mask);
267341

342+
// Add the sources to X
343+
add_source_to_child(*child_X, key, mask, source);
344+
268345
// Update the key and mask
269346
key &= ~(leaf->bit);
270347
mask &= ~(leaf->bit);
271348
}
272349
else if (*child_X != NULL && path_exists(*child_X, key, mask) &&
273350
*child_1 != NULL && path_exists(*child_1, key, mask))
274351
{
352+
// Get the source for packets matching the `1'
353+
source = get_source_from_child(*child_1, key, mask);
354+
275355
// Untraverse in `1'
276356
untraverse_in_child(child_1, key, mask);
277357

358+
// Add the sources to X
359+
add_source_to_child(*child_X, key, mask, source);
360+
278361
// Update the key and mask
279362
key &= ~(leaf->bit);
280363
mask &= ~(leaf->bit);
@@ -290,7 +373,7 @@ typedef struct _subtable
290373
{
291374
unsigned int n_entries; // Number of entries in the subtable
292375
uint32_t route; // Route of all entries in the subtable
293-
keymask_t *entries; // Entries in the subtable
376+
mtrie_entry_t *entries; // Entries in the subtable
294377

295378
struct _subtable *next; // Next subtable in the chain
296379
} subtable_t;
@@ -308,7 +391,7 @@ static inline subtable_t* subtable_new(
308391

309392
// Create a new subtable of the desired size
310393
*sb = MALLOC(sizeof(subtable_t));
311-
(*sb)->entries = MALLOC(sizeof(keymask_t) * size);
394+
(*sb)->entries = MALLOC(sizeof(mtrie_entry_t) * size);
312395
(*sb)->n_entries = size;
313396
(*sb)->route = route;
314397
(*sb)->next = NULL;
@@ -329,8 +412,9 @@ static inline void subtable_expand(subtable_t *sb, table_t *table)
329412
// Expand the current subtable
330413
for (unsigned int i = 0; i < sb->n_entries; i++)
331414
{
332-
next->keymask.key = sb->entries[i].key;
333-
next->keymask.mask = sb->entries[i].mask;
415+
next->keymask.key = sb->entries[i].keymask.key;
416+
next->keymask.mask = sb->entries[i].keymask.mask;
417+
next->source = sb->entries[i].source;
334418
next->route = sb->route;
335419

336420
next++;
@@ -401,7 +485,8 @@ static inline void mtrie_minimise(table_t *table)
401485
// Add to the trie
402486
uint32_t key = table->entries[j].keymask.key;
403487
uint32_t mask = table->entries[j].keymask.mask;
404-
mtrie_insert(trie, key, mask);
488+
uint32_t source = table->entries[j].source;
489+
mtrie_insert(trie, key, mask, source);
405490
}
406491
}
407492

0 commit comments

Comments
 (0)