^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * This module tests the blackhole_dev that is created during the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * net subsystem initialization. The test this module performs is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * by injecting an skb into the stack with skb->dev as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * blackhole_dev and expects kernel to behave in a sane manner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (in other words, *not crash*)!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 2018, Mahesh Bandewar <maheshb@google.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/udp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/dst.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define SKB_SIZE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define HEAD_SIZE (14+40+8) /* Ether + IPv6 + UDP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define TAIL_SIZE 32 /* random tail-room */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define UDP_PORT 1234
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static int __init test_blackholedev_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct ipv6hdr *ip6h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct ethhdr *ethh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct udphdr *uh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) skb = alloc_skb(SKB_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Reserve head-room for the headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) skb_reserve(skb, HEAD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Add data to the skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) data_len = SKB_SIZE - (HEAD_SIZE + TAIL_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) memset(__skb_put(skb, data_len), 0xf, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Add protocol data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* (Transport) UDP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) uh = (struct udphdr *)skb_push(skb, sizeof(struct udphdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) skb_set_transport_header(skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) uh->source = uh->dest = htons(UDP_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) uh->len = htons(data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) uh->check = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* (Network) IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ip6h = (struct ipv6hdr *)skb_push(skb, sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) skb_set_network_header(skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ip6h->hop_limit = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ip6h->payload_len = data_len + sizeof(struct udphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ip6h->nexthdr = IPPROTO_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ip6h->saddr = in6addr_loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ip6h->daddr = in6addr_loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Ether */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ethh = (struct ethhdr *)skb_push(skb, sizeof(struct ethhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) skb_set_mac_header(skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) skb->protocol = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) skb->pkt_type = PACKET_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) skb->dev = blackhole_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Now attempt to send the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ret = dev_queue_xmit(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case NET_XMIT_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pr_warn("dev_queue_xmit() returned NET_XMIT_SUCCESS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case NET_XMIT_DROP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pr_warn("dev_queue_xmit() returned NET_XMIT_DROP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case NET_XMIT_CN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) pr_warn("dev_queue_xmit() returned NET_XMIT_CN\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) pr_err("dev_queue_xmit() returned UNKNOWN(%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static void __exit test_blackholedev_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) pr_warn("test_blackholedev module terminating.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) module_init(test_blackholedev_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) module_exit(test_blackholedev_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MODULE_AUTHOR("Mahesh Bandewar <maheshb@google.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) MODULE_LICENSE("GPL");