xref: /aosp_15_r20/external/libnl/tests/cksuite-all-ematch-tree-clone.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
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