1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker
3*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
4*4dc78e53SAndroid Build Coastguard Worker
5*4dc78e53SAndroid Build Coastguard Worker #include <stdio.h>
6*4dc78e53SAndroid Build Coastguard Worker #include <time.h>
7*4dc78e53SAndroid Build Coastguard Worker #include <check.h>
8*4dc78e53SAndroid Build Coastguard Worker
9*4dc78e53SAndroid Build Coastguard Worker #include <linux/netlink.h>
10*4dc78e53SAndroid Build Coastguard Worker
11*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/ematch.h>
12*4dc78e53SAndroid Build Coastguard Worker
13*4dc78e53SAndroid Build Coastguard Worker #include "cksuite-all.h"
14*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-route/nl-route.h"
15*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-route/nl-priv-dynamic-route.h"
16*4dc78e53SAndroid Build Coastguard Worker
17*4dc78e53SAndroid Build Coastguard Worker #define MAX_DEPTH 6
18*4dc78e53SAndroid Build Coastguard Worker #define MAX_CHILDREN 5
19*4dc78e53SAndroid Build Coastguard Worker
20*4dc78e53SAndroid Build Coastguard Worker static int current_depth = 0;
21*4dc78e53SAndroid Build Coastguard Worker static int id = 1;
22*4dc78e53SAndroid Build Coastguard Worker static long long array_size = 0;
23*4dc78e53SAndroid Build Coastguard Worker
my_pow(long long x,long long y)24*4dc78e53SAndroid Build Coastguard Worker static long long my_pow(long long x, long long y)
25*4dc78e53SAndroid Build Coastguard Worker {
26*4dc78e53SAndroid Build Coastguard Worker int ret = x;
27*4dc78e53SAndroid Build Coastguard Worker
28*4dc78e53SAndroid Build Coastguard Worker if (y == 0)
29*4dc78e53SAndroid Build Coastguard Worker return 1;
30*4dc78e53SAndroid Build Coastguard Worker
31*4dc78e53SAndroid Build Coastguard Worker if (y < 0 || x == 0)
32*4dc78e53SAndroid Build Coastguard Worker return 0;
33*4dc78e53SAndroid Build Coastguard Worker
34*4dc78e53SAndroid Build Coastguard Worker while (--y) {
35*4dc78e53SAndroid Build Coastguard Worker ret *= x;
36*4dc78e53SAndroid Build Coastguard Worker }
37*4dc78e53SAndroid Build Coastguard Worker
38*4dc78e53SAndroid Build Coastguard Worker return ret;
39*4dc78e53SAndroid Build Coastguard Worker }
40*4dc78e53SAndroid Build Coastguard Worker
build_children(struct nl_list_head * parent)41*4dc78e53SAndroid Build Coastguard Worker static int build_children(struct nl_list_head *parent)
42*4dc78e53SAndroid Build Coastguard Worker {
43*4dc78e53SAndroid Build Coastguard Worker int i, num = 0;
44*4dc78e53SAndroid Build Coastguard Worker struct rtnl_ematch *child = NULL;
45*4dc78e53SAndroid Build Coastguard Worker
46*4dc78e53SAndroid Build Coastguard Worker if (!parent)
47*4dc78e53SAndroid Build Coastguard Worker return 0;
48*4dc78e53SAndroid Build Coastguard Worker
49*4dc78e53SAndroid Build Coastguard Worker if (++current_depth > MAX_DEPTH) {
50*4dc78e53SAndroid Build Coastguard Worker --current_depth;
51*4dc78e53SAndroid Build Coastguard Worker return 0;
52*4dc78e53SAndroid Build Coastguard Worker }
53*4dc78e53SAndroid Build Coastguard Worker
54*4dc78e53SAndroid Build Coastguard Worker num = _nltst_rand_u32() % ((unsigned)(MAX_CHILDREN + 1));
55*4dc78e53SAndroid Build Coastguard Worker for (i = 0; i < num; ++i) {
56*4dc78e53SAndroid Build Coastguard Worker child = rtnl_ematch_alloc();
57*4dc78e53SAndroid Build Coastguard Worker if (!child) {
58*4dc78e53SAndroid Build Coastguard Worker printf("Mem alloc error\n");
59*4dc78e53SAndroid Build Coastguard Worker exit(1);
60*4dc78e53SAndroid Build Coastguard Worker }
61*4dc78e53SAndroid Build Coastguard Worker build_children(&child->e_childs);
62*4dc78e53SAndroid Build Coastguard Worker child->e_id = id++;
63*4dc78e53SAndroid Build Coastguard Worker nl_list_add_tail(&child->e_list, parent);
64*4dc78e53SAndroid Build Coastguard Worker }
65*4dc78e53SAndroid Build Coastguard Worker
66*4dc78e53SAndroid Build Coastguard Worker --current_depth;
67*4dc78e53SAndroid Build Coastguard Worker return 0;
68*4dc78e53SAndroid Build Coastguard Worker }
69*4dc78e53SAndroid Build Coastguard Worker
build_src_cgroup(struct rtnl_ematch_tree * tree)70*4dc78e53SAndroid Build Coastguard Worker static void build_src_cgroup(struct rtnl_ematch_tree *tree)
71*4dc78e53SAndroid Build Coastguard Worker {
72*4dc78e53SAndroid Build Coastguard Worker build_children(&tree->et_list);
73*4dc78e53SAndroid Build Coastguard Worker }
74*4dc78e53SAndroid Build Coastguard Worker
dump_ematch_list(struct nl_list_head * head,int * result,int * index)75*4dc78e53SAndroid Build Coastguard Worker static void dump_ematch_list(struct nl_list_head *head, int *result, int *index)
76*4dc78e53SAndroid Build Coastguard Worker {
77*4dc78e53SAndroid Build Coastguard Worker struct rtnl_ematch *pos = NULL;
78*4dc78e53SAndroid Build Coastguard Worker
79*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry(pos, head, e_list) {
80*4dc78e53SAndroid Build Coastguard Worker if (!nl_list_empty(&pos->e_childs))
81*4dc78e53SAndroid Build Coastguard Worker dump_ematch_list(&pos->e_childs, result, index);
82*4dc78e53SAndroid Build Coastguard Worker result[*index] = pos->e_id;
83*4dc78e53SAndroid Build Coastguard Worker (*index)++;
84*4dc78e53SAndroid Build Coastguard Worker }
85*4dc78e53SAndroid Build Coastguard Worker }
86*4dc78e53SAndroid Build Coastguard Worker
dump_ematch_tree(struct rtnl_ematch_tree * tree,int * result,int * index)87*4dc78e53SAndroid Build Coastguard Worker static void dump_ematch_tree(struct rtnl_ematch_tree *tree, int *result,
88*4dc78e53SAndroid Build Coastguard Worker int *index)
89*4dc78e53SAndroid Build Coastguard Worker {
90*4dc78e53SAndroid Build Coastguard Worker if (!tree)
91*4dc78e53SAndroid Build Coastguard Worker return;
92*4dc78e53SAndroid Build Coastguard Worker
93*4dc78e53SAndroid Build Coastguard Worker dump_ematch_list(&tree->et_list, result, index);
94*4dc78e53SAndroid Build Coastguard Worker }
95*4dc78e53SAndroid Build Coastguard Worker
compare(int * r1,int * r2,int len)96*4dc78e53SAndroid Build Coastguard Worker static int compare(int *r1, int *r2, int len)
97*4dc78e53SAndroid Build Coastguard Worker {
98*4dc78e53SAndroid Build Coastguard Worker int i = 0;
99*4dc78e53SAndroid Build Coastguard Worker for (i = 0; i < len; ++i) {
100*4dc78e53SAndroid Build Coastguard Worker if (r1[i] != r2[i])
101*4dc78e53SAndroid Build Coastguard Worker return -1;
102*4dc78e53SAndroid Build Coastguard Worker }
103*4dc78e53SAndroid Build Coastguard Worker return 0;
104*4dc78e53SAndroid Build Coastguard Worker }
105*4dc78e53SAndroid Build Coastguard Worker
START_TEST(ematch_tree_clone)106*4dc78e53SAndroid Build Coastguard Worker START_TEST(ematch_tree_clone)
107*4dc78e53SAndroid Build Coastguard Worker {
108*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_ematch_tree struct rtnl_ematch_tree *src = NULL;
109*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_ematch_tree struct rtnl_ematch_tree *dst = NULL;
110*4dc78e53SAndroid Build Coastguard Worker _nl_auto_free int *src_result = NULL;
111*4dc78e53SAndroid Build Coastguard Worker _nl_auto_free int *dst_result = NULL;
112*4dc78e53SAndroid Build Coastguard Worker int i = 0;
113*4dc78e53SAndroid Build Coastguard Worker int j = 0;
114*4dc78e53SAndroid Build Coastguard Worker
115*4dc78e53SAndroid Build Coastguard Worker array_size = (MAX_DEPTH * my_pow(MAX_CHILDREN, MAX_DEPTH)) / 2;
116*4dc78e53SAndroid Build Coastguard Worker src_result = calloc(4, array_size);
117*4dc78e53SAndroid Build Coastguard Worker dst_result = calloc(4, array_size);
118*4dc78e53SAndroid Build Coastguard Worker
119*4dc78e53SAndroid Build Coastguard Worker src = rtnl_ematch_tree_alloc(2);
120*4dc78e53SAndroid Build Coastguard Worker
121*4dc78e53SAndroid Build Coastguard Worker build_src_cgroup(src);
122*4dc78e53SAndroid Build Coastguard Worker dump_ematch_tree(src, src_result, &i);
123*4dc78e53SAndroid Build Coastguard Worker
124*4dc78e53SAndroid Build Coastguard Worker dst = rtnl_ematch_tree_clone(src);
125*4dc78e53SAndroid Build Coastguard Worker dump_ematch_tree(dst, dst_result, &j);
126*4dc78e53SAndroid Build Coastguard Worker
127*4dc78e53SAndroid Build Coastguard Worker ck_assert(dst);
128*4dc78e53SAndroid Build Coastguard Worker ck_assert(i == j);
129*4dc78e53SAndroid Build Coastguard Worker ck_assert(!compare(src_result, dst_result, i));
130*4dc78e53SAndroid Build Coastguard Worker }
131*4dc78e53SAndroid Build Coastguard Worker END_TEST
132*4dc78e53SAndroid Build Coastguard Worker
make_nl_ematch_tree_clone_suite(void)133*4dc78e53SAndroid Build Coastguard Worker Suite *make_nl_ematch_tree_clone_suite(void)
134*4dc78e53SAndroid Build Coastguard Worker {
135*4dc78e53SAndroid Build Coastguard Worker Suite *suite = suite_create("Clone ematch tree");
136*4dc78e53SAndroid Build Coastguard Worker TCase *tc = tcase_create("Core");
137*4dc78e53SAndroid Build Coastguard Worker
138*4dc78e53SAndroid Build Coastguard Worker tcase_add_test(tc, ematch_tree_clone);
139*4dc78e53SAndroid Build Coastguard Worker suite_add_tcase(suite, tc);
140*4dc78e53SAndroid Build Coastguard Worker
141*4dc78e53SAndroid Build Coastguard Worker return suite;
142*4dc78e53SAndroid Build Coastguard Worker }
143