Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: GPL-2.0-only
  2
  3#include <linux/debugfs.h>
  4#include <linux/fault-inject.h>
  5#include <linux/netdevice.h>
  6#include <linux/skbuff.h>
  7
  8static struct {
  9	struct fault_attr attr;
 10	char devname[IFNAMSIZ];
 11	bool filtered;
 12} skb_realloc = {
 13	.attr = FAULT_ATTR_INITIALIZER,
 14	.filtered = false,
 15};
 16
 17static bool should_fail_net_realloc_skb(struct sk_buff *skb)
 18{
 19	struct net_device *net = skb->dev;
 20
 21	if (skb_realloc.filtered &&
 22	    strncmp(net->name, skb_realloc.devname, IFNAMSIZ))
 23		/* device name filter set, but names do not match */
 24		return false;
 25
 26	if (!should_fail(&skb_realloc.attr, 1))
 27		return false;
 28
 29	return true;
 30}
 31ALLOW_ERROR_INJECTION(should_fail_net_realloc_skb, TRUE);
 32
 33void skb_might_realloc(struct sk_buff *skb)
 34{
 35	if (!should_fail_net_realloc_skb(skb))
 36		return;
 37
 38	pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
 39}
 40EXPORT_SYMBOL(skb_might_realloc);
 41
 42static int __init fail_skb_realloc_setup(char *str)
 43{
 44	return setup_fault_attr(&skb_realloc.attr, str);
 45}
 46__setup("fail_skb_realloc=", fail_skb_realloc_setup);
 47
 48static void reset_settings(void)
 49{
 50	skb_realloc.filtered = false;
 51	memset(&skb_realloc.devname, 0, IFNAMSIZ);
 52}
 53
 54static ssize_t devname_write(struct file *file, const char __user *buffer,
 55			     size_t count, loff_t *ppos)
 56{
 57	ssize_t ret;
 58
 59	reset_settings();
 60	ret = simple_write_to_buffer(&skb_realloc.devname, IFNAMSIZ,
 61				     ppos, buffer, count);
 62	if (ret < 0)
 63		return ret;
 64
 65	skb_realloc.devname[IFNAMSIZ - 1] = '\0';
 66	/* Remove a possible \n at the end of devname */
 67	strim(skb_realloc.devname);
 68
 69	if (strnlen(skb_realloc.devname, IFNAMSIZ))
 70		skb_realloc.filtered = true;
 71
 72	return count;
 73}
 74
 75static ssize_t devname_read(struct file *file,
 76			    char __user *buffer,
 77			    size_t size, loff_t *ppos)
 78{
 79	if (!skb_realloc.filtered)
 80		return 0;
 81
 82	return simple_read_from_buffer(buffer, size, ppos, &skb_realloc.devname,
 83				       strlen(skb_realloc.devname));
 84}
 85
 86static const struct file_operations devname_ops = {
 87	.write = devname_write,
 88	.read = devname_read,
 89};
 90
 91static int __init fail_skb_realloc_debugfs(void)
 92{
 93	umode_t mode = S_IFREG | 0600;
 94	struct dentry *dir;
 95
 96	dir = fault_create_debugfs_attr("fail_skb_realloc", NULL,
 97					&skb_realloc.attr);
 98	if (IS_ERR(dir))
 99		return PTR_ERR(dir);
100
101	debugfs_create_file("devname", mode, dir, NULL, &devname_ops);
102
103	return 0;
104}
105
106late_initcall(fail_skb_realloc_debugfs);