File Index
Files and directories
Sign in
FILE

prp_dup_discard_test.c

File preview with syntax highlighting.

linux-6.19.14/net/hsr/prp_dup_discard_test.c C
  1// SPDX-License-Identifier: GPL-2.0
  2#include <kunit/test.h>
  3
  4#include "hsr_main.h"
  5#include "hsr_framereg.h"
  6
  7struct 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
 14static 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
 34static 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
 49static 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
 64static 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
 82static 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
105static 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
156static 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
194static 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
203static struct kunit_suite prp_dup_discard_suite = {
204	.name = "prp_duplicate_discard",
205	.test_cases = prp_dup_discard_test_cases,
206};
207
208kunit_test_suite(prp_dup_discard_suite);
209
210MODULE_LICENSE("GPL");
211MODULE_DESCRIPTION("KUnit tests for PRP duplicate discard");
212MODULE_AUTHOR("Jaakko Karrenpalo <jkarrenpalo@gmail.com>");
~/ Read-only file preview.