1*1a9239bbSLinus Torvalds // SPDX-License-Identifier: GPL-2.0
2*1a9239bbSLinus Torvalds /*
3*1a9239bbSLinus Torvalds * This tests the blackhole_dev that is created during the
4*1a9239bbSLinus Torvalds * net subsystem initialization. The test this module performs is
5*1a9239bbSLinus Torvalds * by injecting an skb into the stack with skb->dev as the
6*1a9239bbSLinus Torvalds * blackhole_dev and expects kernel to behave in a sane manner
7*1a9239bbSLinus Torvalds * (in other words, *not crash*)!
8*1a9239bbSLinus Torvalds *
9*1a9239bbSLinus Torvalds * Copyright (c) 2018, Mahesh Bandewar <maheshb@google.com>
10*1a9239bbSLinus Torvalds */
11*1a9239bbSLinus Torvalds
12*1a9239bbSLinus Torvalds #include <kunit/test.h>
13*1a9239bbSLinus Torvalds #include <linux/module.h>
14*1a9239bbSLinus Torvalds #include <linux/skbuff.h>
15*1a9239bbSLinus Torvalds #include <linux/netdevice.h>
16*1a9239bbSLinus Torvalds #include <linux/udp.h>
17*1a9239bbSLinus Torvalds #include <linux/ipv6.h>
18*1a9239bbSLinus Torvalds
19*1a9239bbSLinus Torvalds #include <net/dst.h>
20*1a9239bbSLinus Torvalds
21*1a9239bbSLinus Torvalds #define SKB_SIZE 256
22*1a9239bbSLinus Torvalds #define HEAD_SIZE (14+40+8) /* Ether + IPv6 + UDP */
23*1a9239bbSLinus Torvalds #define TAIL_SIZE 32 /* random tail-room */
24*1a9239bbSLinus Torvalds
25*1a9239bbSLinus Torvalds #define UDP_PORT 1234
26*1a9239bbSLinus Torvalds
test_blackholedev(struct kunit * test)27*1a9239bbSLinus Torvalds static void test_blackholedev(struct kunit *test)
28*1a9239bbSLinus Torvalds {
29*1a9239bbSLinus Torvalds struct ipv6hdr *ip6h;
30*1a9239bbSLinus Torvalds struct sk_buff *skb;
31*1a9239bbSLinus Torvalds struct udphdr *uh;
32*1a9239bbSLinus Torvalds int data_len;
33*1a9239bbSLinus Torvalds
34*1a9239bbSLinus Torvalds skb = alloc_skb(SKB_SIZE, GFP_KERNEL);
35*1a9239bbSLinus Torvalds KUNIT_ASSERT_NOT_NULL(test, skb);
36*1a9239bbSLinus Torvalds
37*1a9239bbSLinus Torvalds /* Reserve head-room for the headers */
38*1a9239bbSLinus Torvalds skb_reserve(skb, HEAD_SIZE);
39*1a9239bbSLinus Torvalds
40*1a9239bbSLinus Torvalds /* Add data to the skb */
41*1a9239bbSLinus Torvalds data_len = SKB_SIZE - (HEAD_SIZE + TAIL_SIZE);
42*1a9239bbSLinus Torvalds memset(__skb_put(skb, data_len), 0xf, data_len);
43*1a9239bbSLinus Torvalds
44*1a9239bbSLinus Torvalds /* Add protocol data */
45*1a9239bbSLinus Torvalds /* (Transport) UDP */
46*1a9239bbSLinus Torvalds uh = (struct udphdr *)skb_push(skb, sizeof(struct udphdr));
47*1a9239bbSLinus Torvalds skb_set_transport_header(skb, 0);
48*1a9239bbSLinus Torvalds uh->source = uh->dest = htons(UDP_PORT);
49*1a9239bbSLinus Torvalds uh->len = htons(data_len);
50*1a9239bbSLinus Torvalds uh->check = 0;
51*1a9239bbSLinus Torvalds /* (Network) IPv6 */
52*1a9239bbSLinus Torvalds ip6h = (struct ipv6hdr *)skb_push(skb, sizeof(struct ipv6hdr));
53*1a9239bbSLinus Torvalds skb_set_network_header(skb, 0);
54*1a9239bbSLinus Torvalds ip6h->hop_limit = 32;
55*1a9239bbSLinus Torvalds ip6h->payload_len = htons(data_len + sizeof(struct udphdr));
56*1a9239bbSLinus Torvalds ip6h->nexthdr = IPPROTO_UDP;
57*1a9239bbSLinus Torvalds ip6h->saddr = in6addr_loopback;
58*1a9239bbSLinus Torvalds ip6h->daddr = in6addr_loopback;
59*1a9239bbSLinus Torvalds /* Ether */
60*1a9239bbSLinus Torvalds skb_push(skb, sizeof(struct ethhdr));
61*1a9239bbSLinus Torvalds skb_set_mac_header(skb, 0);
62*1a9239bbSLinus Torvalds
63*1a9239bbSLinus Torvalds skb->protocol = htons(ETH_P_IPV6);
64*1a9239bbSLinus Torvalds skb->pkt_type = PACKET_HOST;
65*1a9239bbSLinus Torvalds skb->dev = blackhole_netdev;
66*1a9239bbSLinus Torvalds
67*1a9239bbSLinus Torvalds /* Now attempt to send the packet */
68*1a9239bbSLinus Torvalds KUNIT_EXPECT_EQ(test, dev_queue_xmit(skb), NET_XMIT_SUCCESS);
69*1a9239bbSLinus Torvalds }
70*1a9239bbSLinus Torvalds
71*1a9239bbSLinus Torvalds static struct kunit_case blackholedev_cases[] = {
72*1a9239bbSLinus Torvalds KUNIT_CASE(test_blackholedev),
73*1a9239bbSLinus Torvalds {},
74*1a9239bbSLinus Torvalds };
75*1a9239bbSLinus Torvalds
76*1a9239bbSLinus Torvalds static struct kunit_suite blackholedev_suite = {
77*1a9239bbSLinus Torvalds .name = "blackholedev",
78*1a9239bbSLinus Torvalds .test_cases = blackholedev_cases,
79*1a9239bbSLinus Torvalds };
80*1a9239bbSLinus Torvalds
81*1a9239bbSLinus Torvalds kunit_test_suite(blackholedev_suite);
82*1a9239bbSLinus Torvalds
83*1a9239bbSLinus Torvalds MODULE_AUTHOR("Mahesh Bandewar <maheshb@google.com>");
84*1a9239bbSLinus Torvalds MODULE_DESCRIPTION("module test of the blackhole_dev");
85*1a9239bbSLinus Torvalds MODULE_LICENSE("GPL");
86