You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
2.6 KiB
144 lines
2.6 KiB
#include <netlink-private/types.h>
|
|
#include <netlink/route/cls/ematch.h>
|
|
|
|
#include <linux/netlink.h>
|
|
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
|
|
#include <check.h>
|
|
#include "util.h"
|
|
|
|
#define MAX_DEPTH 6
|
|
#define MAX_CHILDREN 5
|
|
|
|
static int current_depth = 0;
|
|
static int id = 1;
|
|
static long long array_size = 0;
|
|
|
|
static int *src_result = NULL, *dst_result = NULL;
|
|
|
|
static long long my_pow(long long x, long long y)
|
|
{
|
|
int ret = x;
|
|
|
|
if (y == 0)
|
|
return 1;
|
|
|
|
if (y < 0 || x == 0)
|
|
return 0;
|
|
|
|
while(--y) {
|
|
ret *= x;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static long int generate_random(long int max)
|
|
{
|
|
srandom(time(NULL) + id);
|
|
return (random() % max);
|
|
}
|
|
|
|
static int build_children(struct nl_list_head *parent)
|
|
{
|
|
int i, num = 0;
|
|
struct rtnl_ematch *child = NULL;
|
|
|
|
if (!parent)
|
|
return 0;
|
|
|
|
if (++current_depth > MAX_DEPTH) {
|
|
--current_depth;
|
|
return 0;
|
|
}
|
|
|
|
num = generate_random(MAX_CHILDREN + 1);
|
|
for (i = 0; i < num; ++i) {
|
|
child = rtnl_ematch_alloc();
|
|
if (!child) {
|
|
printf("Mem alloc error\n");
|
|
exit(1);
|
|
}
|
|
build_children(&child->e_childs);
|
|
child->e_id = id++;
|
|
nl_list_add_tail(&child->e_list, parent);
|
|
}
|
|
|
|
--current_depth;
|
|
return 0;
|
|
}
|
|
|
|
static void build_src_cgroup(struct rtnl_ematch_tree *tree)
|
|
{
|
|
build_children(&tree->et_list);
|
|
}
|
|
|
|
static void dump_ematch_list(struct nl_list_head *head, int *result, int *index)
|
|
{
|
|
struct rtnl_ematch *pos = NULL;
|
|
|
|
nl_list_for_each_entry(pos, head, e_list) {
|
|
if (!nl_list_empty(&pos->e_childs))
|
|
dump_ematch_list(&pos->e_childs, result, index);
|
|
result[*index] = pos->e_id;
|
|
(*index)++;
|
|
}
|
|
}
|
|
|
|
static void dump_ematch_tree(struct rtnl_ematch_tree *tree, int *result, int *index)
|
|
{
|
|
if (!tree)
|
|
return;
|
|
|
|
dump_ematch_list(&tree->et_list, result, index);
|
|
}
|
|
|
|
static int compare(int *r1, int *r2, int len)
|
|
{
|
|
int i = 0;
|
|
for (i = 0; i < len; ++i) {
|
|
if (r1[i] != r2[i])
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
START_TEST(ematch_tree_clone)
|
|
{
|
|
struct rtnl_ematch_tree *src = NULL, *dst = NULL;
|
|
int i = 0, j = 0;
|
|
|
|
array_size = (MAX_DEPTH * my_pow(MAX_CHILDREN, MAX_DEPTH)) / 2;
|
|
src_result = calloc(4, array_size);
|
|
dst_result = calloc(4, array_size);
|
|
|
|
src = rtnl_ematch_tree_alloc(2);
|
|
|
|
build_src_cgroup(src);
|
|
dump_ematch_tree(src, src_result, &i);
|
|
|
|
dst = rtnl_ematch_tree_clone(src);
|
|
dump_ematch_tree(dst, dst_result, &j);
|
|
|
|
fail_if(!dst);
|
|
fail_if(i != j);
|
|
fail_if(compare(src_result, dst_result, i));
|
|
|
|
free(src_result);
|
|
free(dst_result);
|
|
}
|
|
END_TEST
|
|
|
|
Suite *make_nl_ematch_tree_clone_suite(void)
|
|
{
|
|
Suite *suite = suite_create("Clone ematch tree");
|
|
|
|
TCase *ematch_tree = tcase_create("Core");
|
|
tcase_add_test(ematch_tree, ematch_tree_clone);
|
|
suite_add_tcase(suite, ematch_tree);
|
|
|
|
return suite;
|
|
}
|