Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/hsr/prp_dup_discard_test.c
52936 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <kunit/test.h>
3
4
#include "hsr_main.h"
5
#include "hsr_framereg.h"
6
7
MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
8
9
struct prp_test_data {
10
struct hsr_port port;
11
struct hsr_port port_rcv;
12
struct hsr_frame_info frame;
13
struct hsr_node node;
14
};
15
16
static struct prp_test_data *build_prp_test_data(struct kunit *test)
17
{
18
size_t block_sz;
19
20
struct prp_test_data *data = kunit_kzalloc(test,
21
sizeof(struct prp_test_data), GFP_USER);
22
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, data);
23
24
data->node.seq_port_cnt = 1;
25
block_sz = hsr_seq_block_size(&data->node);
26
data->node.block_buf = kunit_kcalloc(test, HSR_MAX_SEQ_BLOCKS, block_sz,
27
GFP_ATOMIC);
28
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, data->node.block_buf);
29
30
xa_init(&data->node.seq_blocks);
31
spin_lock_init(&data->node.seq_out_lock);
32
33
data->frame.node_src = &data->node;
34
data->frame.port_rcv = &data->port_rcv;
35
data->port_rcv.type = HSR_PT_SLAVE_A;
36
data->port.type = HSR_PT_MASTER;
37
38
return data;
39
}
40
41
static void check_prp_frame_seen(struct kunit *test, struct prp_test_data *data,
42
u16 sequence_nr)
43
{
44
u16 block_idx, seq_bit;
45
struct hsr_seq_block *block;
46
47
block_idx = sequence_nr >> HSR_SEQ_BLOCK_SHIFT;
48
block = xa_load(&data->node.seq_blocks, block_idx);
49
KUNIT_EXPECT_NOT_NULL(test, block);
50
51
seq_bit = sequence_nr & HSR_SEQ_BLOCK_MASK;
52
KUNIT_EXPECT_TRUE(test, test_bit(seq_bit, block->seq_nrs[0]));
53
}
54
55
static void check_prp_frame_unseen(struct kunit *test,
56
struct prp_test_data *data, u16 sequence_nr)
57
{
58
u16 block_idx, seq_bit;
59
struct hsr_seq_block *block;
60
61
block_idx = sequence_nr >> HSR_SEQ_BLOCK_SHIFT;
62
block = hsr_get_seq_block(&data->node, block_idx);
63
KUNIT_EXPECT_NOT_NULL(test, block);
64
65
seq_bit = sequence_nr & HSR_SEQ_BLOCK_MASK;
66
KUNIT_EXPECT_FALSE(test, test_bit(seq_bit, block->seq_nrs[0]));
67
}
68
69
static void prp_dup_discard_forward(struct kunit *test)
70
{
71
/* Normal situation, both LANs in sync. Next frame is forwarded */
72
struct prp_test_data *data = build_prp_test_data(test);
73
74
data->frame.sequence_nr = 2;
75
KUNIT_EXPECT_EQ(test, 0,
76
prp_register_frame_out(&data->port, &data->frame));
77
check_prp_frame_seen(test, data, data->frame.sequence_nr);
78
}
79
80
static void prp_dup_discard_drop_duplicate(struct kunit *test)
81
{
82
struct prp_test_data *data = build_prp_test_data(test);
83
84
data->frame.sequence_nr = 2;
85
KUNIT_EXPECT_EQ(test, 0,
86
prp_register_frame_out(&data->port, &data->frame));
87
check_prp_frame_seen(test, data, data->frame.sequence_nr);
88
89
KUNIT_EXPECT_EQ(test, 1,
90
prp_register_frame_out(&data->port, &data->frame));
91
check_prp_frame_seen(test, data, data->frame.sequence_nr);
92
}
93
94
static void prp_dup_discard_entry_timeout(struct kunit *test)
95
{
96
/* Timeout situation, node hasn't sent anything for a while */
97
struct prp_test_data *data = build_prp_test_data(test);
98
struct hsr_seq_block *block;
99
u16 block_idx;
100
101
data->frame.sequence_nr = 7;
102
KUNIT_EXPECT_EQ(test, 0,
103
prp_register_frame_out(&data->port, &data->frame));
104
check_prp_frame_seen(test, data, data->frame.sequence_nr);
105
106
data->frame.sequence_nr = 11;
107
KUNIT_EXPECT_EQ(test, 0,
108
prp_register_frame_out(&data->port, &data->frame));
109
check_prp_frame_seen(test, data, data->frame.sequence_nr);
110
111
block_idx = data->frame.sequence_nr >> HSR_SEQ_BLOCK_SHIFT;
112
block = hsr_get_seq_block(&data->node, block_idx);
113
block->time = jiffies - msecs_to_jiffies(HSR_ENTRY_FORGET_TIME) - 1;
114
115
KUNIT_EXPECT_EQ(test, 0,
116
prp_register_frame_out(&data->port, &data->frame));
117
check_prp_frame_seen(test, data, data->frame.sequence_nr);
118
check_prp_frame_unseen(test, data, 7);
119
}
120
121
static void prp_dup_discard_out_of_sequence(struct kunit *test)
122
{
123
/* One frame is received out of sequence on both LANs */
124
struct prp_test_data *data = build_prp_test_data(test);
125
126
/* initial frame, should be accepted */
127
data->frame.sequence_nr = 9;
128
KUNIT_EXPECT_EQ(test, 0,
129
prp_register_frame_out(&data->port, &data->frame));
130
check_prp_frame_seen(test, data, data->frame.sequence_nr);
131
132
/* 1st old frame, should be accepted */
133
data->frame.sequence_nr = 8;
134
KUNIT_EXPECT_EQ(test, 0,
135
prp_register_frame_out(&data->port, &data->frame));
136
check_prp_frame_seen(test, data, data->frame.sequence_nr);
137
138
/* 2nd frame should be dropped */
139
data->frame.sequence_nr = 8;
140
data->port_rcv.type = HSR_PT_SLAVE_B;
141
KUNIT_EXPECT_EQ(test, 1,
142
prp_register_frame_out(&data->port, &data->frame));
143
144
/* Next frame, this is forwarded */
145
data->frame.sequence_nr = 10;
146
data->port_rcv.type = HSR_PT_SLAVE_A;
147
KUNIT_EXPECT_EQ(test, 0,
148
prp_register_frame_out(&data->port, &data->frame));
149
check_prp_frame_seen(test, data, data->frame.sequence_nr);
150
151
/* and next one is dropped */
152
data->frame.sequence_nr = 10;
153
data->port_rcv.type = HSR_PT_SLAVE_B;
154
KUNIT_EXPECT_EQ(test, 1,
155
prp_register_frame_out(&data->port, &data->frame));
156
}
157
158
static void prp_dup_discard_lan_b_late(struct kunit *test)
159
{
160
/* LAN B is behind */
161
struct prp_test_data *data = build_prp_test_data(test);
162
163
data->frame.sequence_nr = 9;
164
KUNIT_EXPECT_EQ(test, 0,
165
prp_register_frame_out(&data->port, &data->frame));
166
check_prp_frame_seen(test, data, data->frame.sequence_nr);
167
168
data->frame.sequence_nr = 10;
169
KUNIT_EXPECT_EQ(test, 0,
170
prp_register_frame_out(&data->port, &data->frame));
171
check_prp_frame_seen(test, data, data->frame.sequence_nr);
172
173
data->frame.sequence_nr = 9;
174
data->port_rcv.type = HSR_PT_SLAVE_B;
175
KUNIT_EXPECT_EQ(test, 1,
176
prp_register_frame_out(&data->port, &data->frame));
177
178
data->frame.sequence_nr = 10;
179
data->port_rcv.type = HSR_PT_SLAVE_B;
180
KUNIT_EXPECT_EQ(test, 1,
181
prp_register_frame_out(&data->port, &data->frame));
182
}
183
184
static struct kunit_case prp_dup_discard_test_cases[] = {
185
KUNIT_CASE(prp_dup_discard_forward),
186
KUNIT_CASE(prp_dup_discard_drop_duplicate),
187
KUNIT_CASE(prp_dup_discard_entry_timeout),
188
KUNIT_CASE(prp_dup_discard_out_of_sequence),
189
KUNIT_CASE(prp_dup_discard_lan_b_late),
190
{}
191
};
192
193
static struct kunit_suite prp_dup_discard_suite = {
194
.name = "prp_duplicate_discard",
195
.test_cases = prp_dup_discard_test_cases,
196
};
197
198
kunit_test_suite(prp_dup_discard_suite);
199
200
MODULE_LICENSE("GPL");
201
MODULE_DESCRIPTION("KUnit tests for PRP duplicate discard");
202
MODULE_AUTHOR("Jaakko Karrenpalo <[email protected]>");
203
204