32#define _COMPONENT_ "db"
39#define INIT_TABLE_CAPACITY 256
40#define INIT_ADJ_TRIBS_CAPACITY 32
42static trib_t g_trib = { 0 };
46entry_clone(
const entry_t *entry)
55 if (ATTR_IS_USED_ADVERTPATH(entry->
attrs.
use)) {
57 * entry->
attrs.advertpath_size);
59 * entry->
attrs.advertpath_size);
61 if (ATTR_IS_USED_ROUTEDPATH(entry->
attrs.
use)) {
63 * entry->
attrs.routedpath_size);
65 * entry->
attrs.routedpath_size);
67 if (ATTR_IS_USED_COMMUNITIES(entry->
attrs.
use)) {
69 * entry->
attrs.communities_size);
71 sizeof(community_t) * entry->
attrs.communities_size);
81 if (ATTR_IS_USED_ADVERTPATH(entry->
attrs.
use))
83 if (ATTR_IS_USED_ROUTEDPATH(entry->
attrs.
use))
85 if (ATTR_IS_USED_COMMUNITIES(entry->
attrs.
use))
93 t->capacity = INIT_TABLE_CAPACITY;
95 t->table = malloc(t->capacity *
sizeof(
entry_t*));
102 for (
size_t i = 0; i < src->size; i++)
109 for (
size_t i = 0; i < t->size; i++)
117 if (g_trib.local_routes.table)
124 table_init(&t->local_routes);
125 table_init(&t->ext_trib);
126 table_init(&t->loc_trib);
127 table_init(&t->optimized_loc_trib);
129 t->adj_tribs_capacity = INIT_ADJ_TRIBS_CAPACITY;
130 t->adj_tribs_size = 0;
131 t->adj_tribs_in = malloc(t->adj_tribs_capacity *
sizeof(
table_t));
140 if (trib->adj_tribs_capacity < trib->adj_tribs_size + 1) {
141 trib->adj_tribs_capacity *= 2;
142 trib->adj_tribs_in = realloc(trib->adj_tribs_in,
143 trib->adj_tribs_capacity *
sizeof(
table_t));
145 trib->adj_tribs_capacity *
sizeof(
table_t));
148 trib->adj_tribs_in[trib->adj_tribs_size] = in;
150 trib->adj_tribs_size++;
159 for (
size_t i = 0; i < trib->adj_tribs_size; i++) {
160 if (trib->adj_tribs_in[i] == in && trib->
adj_tribs_out[i] == out) {
163 memmove(&trib->adj_tribs_in[i], &trib->adj_tribs_in[i+1],
164 sizeof(
table_t*) * (trib->adj_tribs_size - i));
166 sizeof(
table_t*) * (trib->adj_tribs_size - i));
167 trib->adj_tribs_size--;
180 free(trib->adj_tribs_in);
188 if (table->capacity < table->size + 1) {
189 table->capacity *= 2;
190 table->table = realloc(table->table,
191 table->capacity *
sizeof(
entry_t*));
194 table->table[table->size++] = entry;
200 for (
size_t i = 0; i < table->size; i++)
225 if (e1->
attrs.routedpath_size != e2->
attrs.routedpath_size)
226 return e1->
attrs.routedpath_size < e2->
attrs.routedpath_size;
235 INFO(
"identical route preference for %s", e1->
prefix);
240table_find(
table_t *t, uint16_t
af,
const char *prefix)
242 for (
size_t i = 0; i < t->size; i++)
243 if (t->table[i]->
af ==
af && strcmp(t->table[i]->
prefix, prefix) == 0)
260 for (
size_t i = 0; i < t2->size; i++) {
261 entry_t **match = table_find(t1, t2->table[i]->
af, t2->table[i]->
prefix);
268 if (entry_compare(*match, t2->table[i], itad)) {
270 *match = entry_clone(t2->table[i]);
279 for (
size_t i = 0; i < src->size; i++) {
287apply_policy(
table_t *dst,
const table_t *src, uint32_t local_itad,
290 for (
size_t i = 0; i < src->size; i++) {
296 entry_t *e = entry_clone(src->table[i]);
298 for (
size_t j = 0; j < s->actions_size; j++) {
299 switch (s->actions[j].attribute) {
309 e->
attrs.routedpath_size = s->actions[j].value
310 + e->
attrs.routedpath_size;
312 e->
attrs.routedpath_size *
sizeof(uint32_t));
313 for (
size_t k = 0; k < s->actions[j].value; k++)
327 for (
size_t i = 0; i < trib->local_routes.size; i++) {
329 if (ATTR_IS_USED_NEXTHOP(a->
use))
331 if (ATTR_IS_USED_ADVERTPATH(a->
use))
333 if (ATTR_IS_USED_ROUTEDPATH(a->
use))
344 apply_policy(adj_trib_out, &trib->optimized_loc_trib, trib->
local_itad,
347 table_copy(adj_trib_out, &trib->optimized_loc_trib);
359 table_init(&scratch);
361 table_select_into(&trib->ext_trib, &trib->local_routes, trib->
local_itad);
362 for (
size_t i = 0; i < trib->adj_tribs_size; i++) {
365 if (trib->adj_tribs_in[i]->
routemap) {
367 apply_policy(&scratch, trib->adj_tribs_in[i], trib->
local_itad,
369 table_select_into(&trib->ext_trib, &scratch, trib->
local_itad);
371 table_select_into(&trib->ext_trib, trib->adj_tribs_in[i],
377 table_select_into(&trib->loc_trib, &trib->ext_trib, trib->
local_itad);
378 for (
size_t i = 0; i < trib->adj_tribs_size; i++)
380 table_select_into(&trib->loc_trib, trib->adj_tribs_in[i],
385 optimize_table(&trib->optimized_loc_trib, &trib->loc_trib);
387 for (
size_t i = 0; i < trib->adj_tribs_size; i++) {
399 size_t new_ents_size = 0, new_ents_capacity = INIT_TABLE_CAPACITY;
400 entry_t **new_ents = malloc(
sizeof(
entry_t*) * new_ents_capacity);
402 for (
size_t i = 0; i < table->size; i++) {
403 if (table->table[i]->
sent)
406 if (new_ents_size + 1 > new_ents_capacity) {
407 new_ents_capacity *= 2;
408 new_ents = realloc(new_ents,
sizeof(
entry_t*) * new_ents_capacity);
411 new_ents[new_ents_size++] = table->table[i];
414 *new_ents_out = new_ents;
415 return new_ents_size;
428 if (!ATTR_IS_USED_NEXTHOP(a1->
use) || !ATTR_IS_USED_NEXTHOP(a2->
use)) {
429 ERROR(
"reachable route compared without nexthop");
435 ((!ATTR_IS_USED_ADVERTPATH(a1->
use) || !ATTR_IS_USED_ADVERTPATH(a2->
use)) ||
436 (a1->advertpath_size == a2->advertpath_size &&
438 sizeof(uint32_t) * a1->advertpath_size))) &&
439 ((!ATTR_IS_USED_ROUTEDPATH(a1->
use) || !ATTR_IS_USED_ROUTEDPATH(a2->
use)) ||
440 (a1->routedpath_size == a2->routedpath_size &&
442 sizeof(uint32_t) * a1->routedpath_size))) &&
443 ((!ATTR_IS_USED_LOCALPREF(a1->
use) || !ATTR_IS_USED_LOCALPREF(a2->
use)) ||
445 ((!ATTR_IS_USED_METRIC(a1->
use) || !ATTR_IS_USED_METRIC(a2->
use)) ||
447 ((!ATTR_IS_USED_COMMUNITIES(a1->
use) || !ATTR_IS_USED_COMMUNITIES(a2->
use)) ||
448 (a1->communities_size == a2->communities_size &&
450 sizeof(uint32_t) * a1->communities_size)));
457 for (
size_t i = 0; i < groups_size; i++)
458 if (attrs_equals(&e->
attrs, &groups[i].attrs))
466 g->capacity = INIT_TABLE_CAPACITY;
475 if (g->size + 1 > g->capacity) {
478 sizeof(
entry_t*) * g->capacity);
489 size_t groups_size = 0, groups_capacity = entry_size;
492 for (
size_t i = 0; i < entry_size; i++) {
493 entry_group_t *ingroup = is_entry_in_group(entries[i], groups,
497 if (groups_size + 1 > groups_capacity) {
498 groups_capacity *= 2;
499 groups = realloc(groups,
sizeof(
entry_group_t) * groups_capacity);
502 ingroup = &groups[groups_size++];
503 group_init(ingroup, &entries[i]->attrs);
506 group_insert(ingroup, entries[i]);
510 *groups_out = groups;
#define ERROR(format,...)
log an error
Definition logging.h:56
#define INFO(format,...)
log informational event
Definition logging.h:62
const routemap_statement_t * routemap_match(const routemap_t *routemap, const char *route)
Match route against route map matchers.
Definition pib.c:367
@ ROUTEMAP_SET_METRIC
Definition pib.h:49
@ ROUTEMAP_SET_ITADPATH_PREPEND
Definition pib.h:51
@ ROUTEMAP_SET_NEXTHOP
Definition pib.h:50
@ ROUTEMAP_SET_LOCALPREF
Definition pib.h:48
Protocol definition header.
af
Address families.
Definition protocol.h:206
Groupable attributes that are related to a route.
Definition trib.h:51
char * nexthop
Definition trib.h:55
uint32_t local_pref
Definition trib.h:61
uint32_t nextitad
Definition trib.h:54
community_t * communities
Definition trib.h:63
uint32_t use
Definition trib.h:52
uint32_t * advertpath
Definition trib.h:56
int withdrawn
Definition trib.h:53
uint32_t metric
Definition trib.h:62
uint32_t * routedpath
Definition trib.h:58
entry_t ** entries
Definition trib.h:109
entry_attrs_t attrs
Definition trib.h:108
Route Entry.
Definition trib.h:75
int sent
Definition trib.h:95
uint16_t af
Definition trib.h:77
entry_type_t type
Definition trib.h:81
uint32_t learn_lsid
Definition trib.h:88
uint32_t learn_itad
Definition trib.h:86
entry_attrs_t attrs
Definition trib.h:93
time_t time
Definition trib.h:91
char * prefix
Definition trib.h:79
Route map statement.
Definition pib.h:69
Route map.
Definition pib.h:79
Route Table.
Definition trib.h:99
uint32_t peer_itad
Definition trib.h:100
routemap_t * routemap
Definition trib.h:103
Telephony Routing Information Base.
Definition trib.h:136
uint32_t local_itad
Definition trib.h:137
table_t ** adj_tribs_out
Definition trib.h:141
void trib_update_local(trib_t *trib)
Update local routes when ITAD is defined.
Definition trib.c:325
size_t get_new_entries(const table_t *table, entry_t ***new_ents_out)
Return array of new entry references to new.
Definition trib.c:397
size_t group_entries_by_attrs(entry_t **entries, size_t entry_size, entry_group_t **groups_out)
Group array of entry references by attributes.
Definition trib.c:485
void trib_destroy(trib_t *trib)
Deinit TRIB structure.
Definition trib.c:174
void trib_adj_pair_add(trib_t *trib, table_t *in, table_t *out)
Add and init pair of tables owned by caller.
Definition trib.c:138
void trib_table_insert(table_t *table, entry_t *entry)
Add route to table.
Definition trib.c:186
void trib_table_deinit(table_t *t)
Deinitialize table.
Definition trib.c:107
void entry_destroy(entry_t *entry)
Destroy entry.
Definition trib.c:77
void trib_update_adj_out(trib_t *trib, table_t *adj_trib_out)
Update an Adj-TRIB-Out.
Definition trib.c:339
trib_t * trib_new(uint32_t local_itad)
Initialize TRIB structure.
Definition trib.c:115
void trib_update_full(trib_t *trib)
Execute route selection.
Definition trib.c:351
void trib_table_clear(table_t *table)
Destroy all entries and clear table.
Definition trib.c:198
Telephony Routing Information Base.