diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2015-05-12 16:42:22 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2015-05-12 16:42:22 +0200 |
commit | 9fdf9d29b6b570205c36934aab7e50539e042102 (patch) | |
tree | f70ca684fe4ef875c9634a57896353b88c46df38 /nest/rt-attr.c | |
parent | 315f23a0470112ced04badbb117bc7854ee53e06 (diff) |
KRT: Add support for plenty of kernel route metrics
Linux kernel route metrics (RTA_METRICS netlink route attribute) are
represented and accessible as new route attributes:
krt_mtu, krt_window, krt_rtt, krt_rttvar, krt_sstresh, krt_cwnd, krt_advmss,
krt_reordering, krt_hoplimit, krt_initcwnd, krt_rto_min, krt_initrwnd,
krt_quickack, krt_lock_mtu, krt_lock_window, krt_lock_rtt, krt_lock_rttvar,
krt_lock_sstresh, krt_lock_cwnd, krt_lock_advmss, krt_lock_reordering,
krt_lock_hoplimit, krt_lock_rto_min, krt_feature_ecn, krt_feature_allfrag
Diffstat (limited to 'nest/rt-attr.c')
-rw-r--r-- | nest/rt-attr.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 938b2b44..c5537208 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -308,6 +308,82 @@ ea_find(ea_list *e, unsigned id) } /** + * ea_walk - walk through extended attributes + * @s: walk state structure + * @id: start of attribute ID interval + * @max: length of attribute ID interval + * + * Given an extended attribute list, ea_walk() walks through the list looking + * for first occurrences of attributes with ID in specified interval from @id to + * (@id + @max - 1), returning pointers to found &eattr structures, storing its + * walk state in @s for subsequent calls. + + * The function ea_walk() is supposed to be called in a loop, with initially + * zeroed walk state structure @s with filled the initial extended attribute + * list, returning one found attribute in each call or %NULL when no other + * attribute exists. The extended attribute list or the arguments should not be + * modified between calls. The maximum value of @max is 128. + */ +eattr * +ea_walk(struct ea_walk_state *s, uint id, uint max) +{ + ea_list *e = s->eattrs; + eattr *a = s->ea; + eattr *a_max; + + max = id + max; + + if (a) + goto step; + + for (; e; e = e->next) + { + if (e->flags & EALF_BISECT) + { + int l, r, m; + + l = 0; + r = e->count - 1; + while (l < r) + { + m = (l+r) / 2; + if (e->attrs[m].id < id) + l = m + 1; + else + r = m; + } + a = e->attrs + l; + } + else + a = e->attrs; + + step: + a_max = e->attrs + e->count; + for (; a < a_max; a++) + if ((a->id >= id) && (a->id < max)) + { + int n = a->id - id; + + if (BIT32_TEST(s->visited, n)) + continue; + + BIT32_SET(s->visited, n); + + if ((a->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF) + continue; + + s->eattrs = e; + s->ea = a; + return a; + } + else if (e->flags & EALF_BISECT) + break; + } + + return NULL; +} + +/** * ea_get_int - fetch an integer attribute * @e: attribute list * @id: attribute ID |