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