Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: net_test: add tests for IP tunnel flags conversion helpers

Now that there are helpers for converting IP tunnel flags between the
old __be16 format and the bitmap format, make sure they work as expected
by adding a couple of tests to the networking testing suite. The helpers
are all inline, so no dependencies on the related CONFIG_* (or a
standalone module) are needed.

Cover three possible cases:

1. No bits past BIT(15) are set, VTI/SIT bits are not set. This
conversion is almost a direct assignment.
2. No bits past BIT(15) are set, but VTI/SIT bit is set. During the
conversion, it must be transformed into BIT(16) in the bitmap,
but still compatible with the __be16 format.
3. The bitmap has bits past BIT(15) set (not the VTI/SIT one). The
result will be truncated.
Note that currently __IP_TUNNEL_FLAG_NUM is 17 (incl. special),
which means that the result of this case is currently
semi-false-positive. When BIT(17) is finally here, it will be
adjusted accordingly.

Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Alexander Lobakin and committed by
David S. Miller
5b2be2ab 5832c4a7

+125 -9
+1 -1
net/core/Makefile
··· 41 41 obj-$(CONFIG_BPF_SYSCALL) += sock_map.o 42 42 obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o 43 43 obj-$(CONFIG_OF) += of_net.o 44 - obj-$(CONFIG_NET_TEST) += gso_test.o 44 + obj-$(CONFIG_NET_TEST) += net_test.o
+124 -8
net/core/gso_test.c net/core/net_test.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 3 3 #include <kunit/test.h> 4 + 5 + /* GSO */ 6 + 4 7 #include <linux/skbuff.h> 5 8 6 9 static const char hdr[] = "abcdefgh"; ··· 261 258 consume_skb(skb); 262 259 } 263 260 264 - static struct kunit_case gso_test_cases[] = { 261 + /* IP tunnel flags */ 262 + 263 + #include <net/ip_tunnels.h> 264 + 265 + struct ip_tunnel_flags_test { 266 + const char *name; 267 + 268 + const u16 *src_bits; 269 + const u16 *exp_bits; 270 + u8 src_num; 271 + u8 exp_num; 272 + 273 + __be16 exp_val; 274 + bool exp_comp; 275 + }; 276 + 277 + #define IP_TUNNEL_FLAGS_TEST(n, src, comp, eval, exp) { \ 278 + .name = (n), \ 279 + .src_bits = (src), \ 280 + .src_num = ARRAY_SIZE(src), \ 281 + .exp_comp = (comp), \ 282 + .exp_val = (eval), \ 283 + .exp_bits = (exp), \ 284 + .exp_num = ARRAY_SIZE(exp), \ 285 + } 286 + 287 + /* These are __be16-compatible and can be compared as is */ 288 + static const u16 ip_tunnel_flags_1[] = { 289 + IP_TUNNEL_KEY_BIT, 290 + IP_TUNNEL_STRICT_BIT, 291 + IP_TUNNEL_ERSPAN_OPT_BIT, 292 + }; 293 + 294 + /* Due to the previous flags design limitation, setting either 295 + * ``IP_TUNNEL_CSUM_BIT`` (on Big Endian) or ``IP_TUNNEL_DONT_FRAGMENT_BIT`` 296 + * (on Little) also sets VTI/ISATAP bit. In the bitmap implementation, they 297 + * correspond to ``BIT(16)``, which is bigger than ``U16_MAX``, but still is 298 + * backward-compatible. 299 + */ 300 + #ifdef __LITTLE_ENDIAN 301 + #define IP_TUNNEL_CONFLICT_BIT IP_TUNNEL_DONT_FRAGMENT_BIT 302 + #else 303 + #define IP_TUNNEL_CONFLICT_BIT IP_TUNNEL_CSUM_BIT 304 + #endif 305 + 306 + static const u16 ip_tunnel_flags_2_src[] = { 307 + IP_TUNNEL_CONFLICT_BIT, 308 + }; 309 + 310 + static const u16 ip_tunnel_flags_2_exp[] = { 311 + IP_TUNNEL_CONFLICT_BIT, 312 + IP_TUNNEL_SIT_ISATAP_BIT, 313 + }; 314 + 315 + /* Bits 17 and higher are not compatible with __be16 flags */ 316 + static const u16 ip_tunnel_flags_3_src[] = { 317 + IP_TUNNEL_VXLAN_OPT_BIT, 318 + 17, 319 + 18, 320 + 20, 321 + }; 322 + 323 + static const u16 ip_tunnel_flags_3_exp[] = { 324 + IP_TUNNEL_VXLAN_OPT_BIT, 325 + }; 326 + 327 + static const struct ip_tunnel_flags_test ip_tunnel_flags_test[] = { 328 + IP_TUNNEL_FLAGS_TEST("compat", ip_tunnel_flags_1, true, 329 + cpu_to_be16(BIT(IP_TUNNEL_KEY_BIT) | 330 + BIT(IP_TUNNEL_STRICT_BIT) | 331 + BIT(IP_TUNNEL_ERSPAN_OPT_BIT)), 332 + ip_tunnel_flags_1), 333 + IP_TUNNEL_FLAGS_TEST("conflict", ip_tunnel_flags_2_src, true, 334 + VTI_ISVTI, ip_tunnel_flags_2_exp), 335 + IP_TUNNEL_FLAGS_TEST("new", ip_tunnel_flags_3_src, 336 + /* This must be set to ``false`` once 337 + * ``__IP_TUNNEL_FLAG_NUM`` goes above 17. 338 + */ 339 + true, cpu_to_be16(BIT(IP_TUNNEL_VXLAN_OPT_BIT)), 340 + ip_tunnel_flags_3_exp), 341 + }; 342 + 343 + static void 344 + ip_tunnel_flags_test_case_to_desc(const struct ip_tunnel_flags_test *t, 345 + char *desc) 346 + { 347 + strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 348 + } 349 + KUNIT_ARRAY_PARAM(ip_tunnel_flags_test, ip_tunnel_flags_test, 350 + ip_tunnel_flags_test_case_to_desc); 351 + 352 + static void ip_tunnel_flags_test_run(struct kunit *test) 353 + { 354 + const struct ip_tunnel_flags_test *t = test->param_value; 355 + IP_TUNNEL_DECLARE_FLAGS(src) = { }; 356 + IP_TUNNEL_DECLARE_FLAGS(exp) = { }; 357 + IP_TUNNEL_DECLARE_FLAGS(out); 358 + 359 + for (u32 j = 0; j < t->src_num; j++) 360 + __set_bit(t->src_bits[j], src); 361 + for (u32 j = 0; j < t->exp_num; j++) 362 + __set_bit(t->exp_bits[j], exp); 363 + 364 + KUNIT_ASSERT_EQ(test, t->exp_comp, 365 + ip_tunnel_flags_is_be16_compat(src)); 366 + KUNIT_ASSERT_EQ(test, (__force u16)t->exp_val, 367 + (__force u16)ip_tunnel_flags_to_be16(src)); 368 + 369 + ip_tunnel_flags_from_be16(out, t->exp_val); 370 + KUNIT_ASSERT_TRUE(test, __ipt_flag_op(bitmap_equal, exp, out)); 371 + } 372 + 373 + static struct kunit_case net_test_cases[] = { 265 374 KUNIT_CASE_PARAM(gso_test_func, gso_test_gen_params), 266 - {} 375 + KUNIT_CASE_PARAM(ip_tunnel_flags_test_run, 376 + ip_tunnel_flags_test_gen_params), 377 + { }, 267 378 }; 268 379 269 - static struct kunit_suite gso_test_suite = { 270 - .name = "net_core_gso", 271 - .test_cases = gso_test_cases, 380 + static struct kunit_suite net_test_suite = { 381 + .name = "net_core", 382 + .test_cases = net_test_cases, 272 383 }; 384 + kunit_test_suite(net_test_suite); 273 385 274 - kunit_test_suite(gso_test_suite); 275 - 386 + MODULE_DESCRIPTION("KUnit tests for networking core"); 276 387 MODULE_LICENSE("GPL"); 277 - MODULE_DESCRIPTION("KUnit tests for segmentation offload");