mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-26 02:42:58 +02:00
kernel: update to 5.10.5
todo: add armv5tel and aarch64 config and rootfiles. Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
This commit is contained in:
@@ -1,422 +0,0 @@
|
||||
diff -Naur linux-4.14.102.org/arch/x86/Kconfig linux-4.14.102/arch/x86/Kconfig
|
||||
--- linux-4.14.102.org/arch/x86/Kconfig 2019-02-20 10:20:56.000000000 +0100
|
||||
+++ linux-4.14.102/arch/x86/Kconfig 2019-02-22 17:56:37.185202293 +0100
|
||||
@@ -2715,6 +2715,7 @@
|
||||
- AC adapter status updates
|
||||
- Battery status updates
|
||||
|
||||
+
|
||||
config ALIX
|
||||
bool "PCEngines ALIX System Support (LED setup)"
|
||||
select GPIOLIB
|
||||
@@ -2753,6 +2754,18 @@
|
||||
|
||||
endif # X86_32
|
||||
|
||||
+config APULED
|
||||
+ bool "PCEngines APU Led Support"
|
||||
+ depends on DMI
|
||||
+ ---help---
|
||||
+ This option enables system support for the PCEngines APU1.
|
||||
+
|
||||
+config APU2LED
|
||||
+ bool "PCEngines APU2/3/4 Led Support"
|
||||
+ depends on DMI
|
||||
+ ---help---
|
||||
+ This option enables system support for the PCEngines APU2/3/4.
|
||||
+
|
||||
config AMD_NB
|
||||
def_bool y
|
||||
depends on CPU_SUP_AMD && PCI
|
||||
diff -Naur linux-4.14.102.org/arch/x86/platform/apu/apu2-led.c linux-4.14.102/arch/x86/platform/apu/apu2-led.c
|
||||
--- linux-4.14.102.org/arch/x86/platform/apu/apu2-led.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-4.14.102/arch/x86/platform/apu/apu2-led.c 2019-02-22 17:58:52.795665744 +0100
|
||||
@@ -0,0 +1,185 @@
|
||||
+/*
|
||||
+ * LEDs driver for PCEngines apu2/3/4
|
||||
+ *
|
||||
+ * this basic driver only set the output, configuration
|
||||
+ * has already done by bios/coreboot.
|
||||
+ * suspend/resume was not tested because IPFire not use it.
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Arne Fitzenreiter <arne_f@ipfire.org> ,
|
||||
+ * based on Christian Herzog's apu_led.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/leds.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <linux/dmi.h>
|
||||
+
|
||||
+#define DRVNAME "apu2-led"
|
||||
+#define BASEADDR (0xFED81610)
|
||||
+
|
||||
+static struct platform_device *pdev;
|
||||
+unsigned int *apu2_led_p1;
|
||||
+unsigned int *apu2_led_p2;
|
||||
+unsigned int *apu2_led_p3;
|
||||
+
|
||||
+static void apu2_led_set_1(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value) {
|
||||
+ if (value)
|
||||
+ iowrite32((ioread32(apu2_led_p1)&~BIT(22)), apu2_led_p1);
|
||||
+ else
|
||||
+ iowrite32((ioread32(apu2_led_p1)|BIT(22)), apu2_led_p1);
|
||||
+}
|
||||
+
|
||||
+static void apu2_led_set_2(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value) {
|
||||
+ if (value)
|
||||
+ iowrite32((ioread32(apu2_led_p2)&~BIT(22)), apu2_led_p2);
|
||||
+ else
|
||||
+ iowrite32((ioread32(apu2_led_p2)|BIT(22)), apu2_led_p2);
|
||||
+}
|
||||
+
|
||||
+static void apu2_led_set_3(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value) {
|
||||
+ if (value)
|
||||
+ iowrite32((ioread32(apu2_led_p3)&~BIT(22)), apu2_led_p3);
|
||||
+ else
|
||||
+ iowrite32((ioread32(apu2_led_p3)|BIT(22)), apu2_led_p3);
|
||||
+}
|
||||
+
|
||||
+static struct led_classdev apu2_led_1 = {
|
||||
+ .name = "apu:1",
|
||||
+ .brightness_set = apu2_led_set_1,
|
||||
+};
|
||||
+
|
||||
+static struct led_classdev apu2_led_2 = {
|
||||
+ .name = "apu:2",
|
||||
+ .brightness_set = apu2_led_set_2,
|
||||
+};
|
||||
+
|
||||
+static struct led_classdev apu2_led_3 = {
|
||||
+ .name = "apu:3",
|
||||
+ .brightness_set = apu2_led_set_3,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int apu2_led_suspend(struct platform_device *dev,
|
||||
+ pm_message_t state)
|
||||
+{
|
||||
+ led_classdev_suspend(&apu2_led_1);
|
||||
+ led_classdev_suspend(&apu2_led_2);
|
||||
+ led_classdev_suspend(&apu2_led_3);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int apu2_led_resume(struct platform_device *dev)
|
||||
+{
|
||||
+ led_classdev_resume(&apu2_led_1);
|
||||
+ led_classdev_resume(&apu2_led_2);
|
||||
+ led_classdev_resume(&apu2_led_3);
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define apu2_led_suspend NULL
|
||||
+#define apu2_led_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static int apu2_led_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = led_classdev_register(&pdev->dev, &apu2_led_1);
|
||||
+ if (ret == 0)
|
||||
+ {
|
||||
+ ret = led_classdev_register(&pdev->dev, &apu2_led_2);
|
||||
+ if (ret >= 0)
|
||||
+ {
|
||||
+ ret = led_classdev_register(&pdev->dev, &apu2_led_3);
|
||||
+ if (ret < 0)
|
||||
+ led_classdev_unregister(&apu2_led_2);
|
||||
+ }
|
||||
+ if (ret < 0)
|
||||
+ led_classdev_unregister(&apu2_led_1);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int apu2_led_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ led_classdev_unregister(&apu2_led_1);
|
||||
+ led_classdev_unregister(&apu2_led_2);
|
||||
+ led_classdev_unregister(&apu2_led_3);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver apu2_led_driver = {
|
||||
+ .probe = apu2_led_probe,
|
||||
+ .remove = apu2_led_remove,
|
||||
+ .suspend = apu2_led_suspend,
|
||||
+ .resume = apu2_led_resume,
|
||||
+ .driver = {
|
||||
+ .name = DRVNAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init apu2_led_init(void)
|
||||
+{
|
||||
+ int ret=0;
|
||||
+ const char *vendor, *product;
|
||||
+
|
||||
+ vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
||||
+ if (!vendor || strcmp(vendor, "PC Engines"))
|
||||
+ goto out;
|
||||
+
|
||||
+ product = dmi_get_system_info(DMI_PRODUCT_NAME);
|
||||
+ if (!product || ( strcmp(product, "PC Engines apu2") &&
|
||||
+ strcmp(product, "PC Engines apu3") &&
|
||||
+ strcmp(product, "PC Engines apu4") &&
|
||||
+ strcmp(product, "apu2") &&
|
||||
+ strcmp(product, "apu3") &&
|
||||
+ strcmp(product, "apu4") ) )
|
||||
+ goto out;
|
||||
+
|
||||
+ printk(KERN_INFO "%s: system is recognized as \"%s %s\"\n",
|
||||
+ KBUILD_MODNAME, vendor, product);
|
||||
+
|
||||
+ ret = platform_driver_register(&apu2_led_driver);
|
||||
+ if (ret < 0)
|
||||
+ goto out;
|
||||
+
|
||||
+ pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
|
||||
+ if (IS_ERR(pdev)) {
|
||||
+ ret = PTR_ERR(pdev);
|
||||
+ platform_driver_unregister(&apu2_led_driver);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ apu2_led_p1 = ioremap(BASEADDR, 4);
|
||||
+ apu2_led_p2 = ioremap(BASEADDR+4, 4);
|
||||
+ apu2_led_p3 = ioremap(BASEADDR+8, 4);
|
||||
+
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __exit apu2_led_exit(void)
|
||||
+{
|
||||
+ platform_device_unregister(pdev);
|
||||
+ platform_driver_unregister(&apu2_led_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(apu2_led_init);
|
||||
+module_exit(apu2_led_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Arne Fitzenreiter");
|
||||
+MODULE_DESCRIPTION("PCEngines apu2/3/4 LED driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -Naur linux-4.14.102.org/arch/x86/platform/apu/apu-led.c linux-4.14.102/arch/x86/platform/apu/apu-led.c
|
||||
--- linux-4.14.102.org/arch/x86/platform/apu/apu-led.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-4.14.102/arch/x86/platform/apu/apu-led.c 2019-02-22 17:57:45.062504777 +0100
|
||||
@@ -0,0 +1,183 @@
|
||||
+/*
|
||||
+ * LEDs driver for PCEngines apu
|
||||
+ *
|
||||
+ * Copyright (C) 2013 Christian Herzog <daduke@daduke.org>, based on
|
||||
+ * Petr Leibman's leds-alix
|
||||
+ * Hardware presence check added by Arne Fitzenreiter <arne_f@ipfire.org>
|
||||
+ * Based on leds-wrap.c
|
||||
+ * Hardware info taken from http://www.dpie.com/manuals/miniboards/kontron/KTD-S0043-0_KTA55_SoftwareGuide.pdf
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/leds.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <linux/dmi.h>
|
||||
+
|
||||
+#define DRVNAME "apu-led"
|
||||
+#define BASEADDR (0xFED801BD)
|
||||
+#define LEDON (0x8)
|
||||
+#define LEDOFF (0xC8)
|
||||
+
|
||||
+static struct platform_device *pdev;
|
||||
+unsigned int *apu_led_p1;
|
||||
+unsigned int *apu_led_p2;
|
||||
+unsigned int *apu_led_p3;
|
||||
+
|
||||
+static void apu_led_set_1(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value) {
|
||||
+ if (value)
|
||||
+ iowrite8(LEDON, apu_led_p1);
|
||||
+ else
|
||||
+ iowrite8(LEDOFF, apu_led_p1);
|
||||
+}
|
||||
+
|
||||
+static void apu_led_set_2(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value) {
|
||||
+ if (value)
|
||||
+ iowrite8(LEDON, apu_led_p2);
|
||||
+ else
|
||||
+ iowrite8(LEDOFF, apu_led_p2);
|
||||
+}
|
||||
+
|
||||
+static void apu_led_set_3(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value) {
|
||||
+ if (value)
|
||||
+ iowrite8(LEDON, apu_led_p3);
|
||||
+ else
|
||||
+ iowrite8(LEDOFF, apu_led_p3);
|
||||
+}
|
||||
+
|
||||
+static struct led_classdev apu_led_1 = {
|
||||
+ .name = "apu:1",
|
||||
+ .brightness_set = apu_led_set_1,
|
||||
+};
|
||||
+
|
||||
+static struct led_classdev apu_led_2 = {
|
||||
+ .name = "apu:2",
|
||||
+ .brightness_set = apu_led_set_2,
|
||||
+};
|
||||
+
|
||||
+static struct led_classdev apu_led_3 = {
|
||||
+ .name = "apu:3",
|
||||
+ .brightness_set = apu_led_set_3,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int apu_led_suspend(struct platform_device *dev,
|
||||
+ pm_message_t state)
|
||||
+{
|
||||
+ led_classdev_suspend(&apu_led_1);
|
||||
+ led_classdev_suspend(&apu_led_2);
|
||||
+ led_classdev_suspend(&apu_led_3);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int apu_led_resume(struct platform_device *dev)
|
||||
+{
|
||||
+ led_classdev_resume(&apu_led_1);
|
||||
+ led_classdev_resume(&apu_led_2);
|
||||
+ led_classdev_resume(&apu_led_3);
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define apu_led_suspend NULL
|
||||
+#define apu_led_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static int apu_led_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = led_classdev_register(&pdev->dev, &apu_led_1);
|
||||
+ if (ret == 0)
|
||||
+ {
|
||||
+ ret = led_classdev_register(&pdev->dev, &apu_led_2);
|
||||
+ if (ret >= 0)
|
||||
+ {
|
||||
+ ret = led_classdev_register(&pdev->dev, &apu_led_3);
|
||||
+ if (ret < 0)
|
||||
+ led_classdev_unregister(&apu_led_2);
|
||||
+ }
|
||||
+ if (ret < 0)
|
||||
+ led_classdev_unregister(&apu_led_1);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int apu_led_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ led_classdev_unregister(&apu_led_1);
|
||||
+ led_classdev_unregister(&apu_led_2);
|
||||
+ led_classdev_unregister(&apu_led_3);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver apu_led_driver = {
|
||||
+ .probe = apu_led_probe,
|
||||
+ .remove = apu_led_remove,
|
||||
+ .suspend = apu_led_suspend,
|
||||
+ .resume = apu_led_resume,
|
||||
+ .driver = {
|
||||
+ .name = DRVNAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init apu_led_init(void)
|
||||
+{
|
||||
+ int ret=0;
|
||||
+ const char *vendor, *product;
|
||||
+
|
||||
+ vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
||||
+ if (!vendor || strcmp(vendor, "PC Engines"))
|
||||
+ goto out;
|
||||
+
|
||||
+ product = dmi_get_system_info(DMI_PRODUCT_NAME);
|
||||
+ if (!product || ( strcmp(product, "APU") &&
|
||||
+ strcmp(product, "apu1") &&
|
||||
+ strcmp(product, "PC Engines apu1") ))
|
||||
+ goto out;
|
||||
+
|
||||
+ printk(KERN_INFO "%s: system is recognized as \"%s %s\"\n",
|
||||
+ KBUILD_MODNAME, vendor, product);
|
||||
+
|
||||
+ ret = platform_driver_register(&apu_led_driver);
|
||||
+ if (ret < 0)
|
||||
+ goto out;
|
||||
+
|
||||
+ pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
|
||||
+ if (IS_ERR(pdev)) {
|
||||
+ ret = PTR_ERR(pdev);
|
||||
+ platform_driver_unregister(&apu_led_driver);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ apu_led_p1 = ioremap(BASEADDR, 1);
|
||||
+ apu_led_p2 = ioremap(BASEADDR+1, 1);
|
||||
+ apu_led_p3 = ioremap(BASEADDR+2, 1);
|
||||
+
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __exit apu_led_exit(void)
|
||||
+{
|
||||
+ platform_device_unregister(pdev);
|
||||
+ platform_driver_unregister(&apu_led_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(apu_led_init);
|
||||
+module_exit(apu_led_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Christian Herzog");
|
||||
+MODULE_DESCRIPTION("PCEngines apu LED driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -Naur linux-4.14.102.org/arch/x86/platform/apu/Makefile linux-4.14.102/arch/x86/platform/apu/Makefile
|
||||
--- linux-4.14.102.org/arch/x86/platform/apu/Makefile 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-4.14.102/arch/x86/platform/apu/Makefile 2019-02-22 17:56:37.185202293 +0100
|
||||
@@ -0,0 +1,2 @@
|
||||
+obj-$(CONFIG_APULED) += apu-led.o
|
||||
+obj-$(CONFIG_APU2LED) += apu2-led.o
|
||||
diff -Naur linux-4.14.102.org/arch/x86/platform/Makefile linux-4.14.102/arch/x86/platform/Makefile
|
||||
--- linux-4.14.102.org/arch/x86/platform/Makefile 2019-02-20 10:20:56.000000000 +0100
|
||||
+++ linux-4.14.102/arch/x86/platform/Makefile 2019-02-22 17:56:37.185202293 +0100
|
||||
@@ -1,5 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Platform specific code goes here
|
||||
+obj-y += apu/
|
||||
obj-y += atom/
|
||||
obj-y += ce4100/
|
||||
obj-y += efi/
|
||||
@@ -1,18 +0,0 @@
|
||||
diff -Naur linux-4.14.173.org/include/linux/timer.h linux-4.14.173/include/linux/timer.h
|
||||
--- linux-4.14.173.org/include/linux/timer.h 2020-03-11 18:03:09.000000000 +0100
|
||||
+++ linux-4.14.173/include/linux/timer.h 2020-04-30 19:30:13.956596003 +0200
|
||||
@@ -180,6 +180,14 @@
|
||||
(TIMER_DATA_TYPE)timer, flags);
|
||||
}
|
||||
|
||||
+static inline void timer_setup_on_stack(struct timer_list *timer,
|
||||
+ void (*callback)(struct timer_list *),
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ __setup_timer_on_stack(timer, (TIMER_FUNC_TYPE)callback,
|
||||
+ (TIMER_DATA_TYPE)timer, flags);
|
||||
+}
|
||||
+
|
||||
#define from_timer(var, callback_timer, timer_fieldname) \
|
||||
container_of(callback_timer, typeof(*var), timer_fieldname)
|
||||
|
||||
@@ -1,471 +0,0 @@
|
||||
diff -Naur linux-4.9.16.org/drivers/leds/trigger/Kconfig linux-4.9.16/drivers/leds/trigger/Kconfig
|
||||
--- linux-4.9.16.org/drivers/leds/trigger/Kconfig 2017-03-18 12:15:30.000000000 +0100
|
||||
+++ linux-4.9.16/drivers/leds/trigger/Kconfig 2017-03-18 16:53:42.290859631 +0100
|
||||
@@ -126,4 +126,11 @@
|
||||
a different trigger.
|
||||
If unsure, say Y.
|
||||
|
||||
+config LEDS_TRIGGER_NETDEV
|
||||
+ tristate "LED Netdev Trigger"
|
||||
+ depends on NET && LEDS_TRIGGERS
|
||||
+ help
|
||||
+ This allows LEDs to be controlled by network device activity.
|
||||
+ If unsure, say Y.
|
||||
+
|
||||
endif # LEDS_TRIGGERS
|
||||
diff -Naur linux-4.9.16.org/drivers/leds/trigger/ledtrig-netdev.c linux-4.9.16/drivers/leds/trigger/ledtrig-netdev.c
|
||||
--- linux-4.9.16.org/drivers/leds/trigger/ledtrig-netdev.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-4.9.16/drivers/leds/trigger/ledtrig-netdev.c 2017-03-18 16:53:44.280859607 +0100
|
||||
@@ -0,0 +1,444 @@
|
||||
+/*
|
||||
+ * LED Kernel Netdev Trigger
|
||||
+ *
|
||||
+ * Toggles the LED to reflect the link and traffic state of a named net device
|
||||
+ *
|
||||
+ * Copyright 2007 Oliver Jowett <oliver@opencloud.com>
|
||||
+ *
|
||||
+ * Derived from ledtrig-timer.c which is:
|
||||
+ * Copyright 2005-2006 Openedhand Ltd.
|
||||
+ * Author: Richard Purdie <rpurdie@openedhand.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <linux/timer.h>
|
||||
+#include <linux/ctype.h>
|
||||
+#include <linux/leds.h>
|
||||
+
|
||||
+#include "../leds.h"
|
||||
+
|
||||
+/*
|
||||
+ * Configurable sysfs attributes:
|
||||
+ *
|
||||
+ * device_name - network device name to monitor
|
||||
+ *
|
||||
+ * interval - duration of LED blink, in milliseconds
|
||||
+ *
|
||||
+ * mode - either "none" (LED is off) or a space separated list of one or more of:
|
||||
+ * link: LED's normal state reflects whether the link is up (has carrier) or not
|
||||
+ * tx: LED blinks on transmitted data
|
||||
+ * rx: LED blinks on receive data
|
||||
+ *
|
||||
+ * Some suggestions:
|
||||
+ *
|
||||
+ * Simple link status LED:
|
||||
+ * $ echo netdev >someled/trigger
|
||||
+ * $ echo eth0 >someled/device_name
|
||||
+ * $ echo link >someled/mode
|
||||
+ *
|
||||
+ * Ethernet-style link/activity LED:
|
||||
+ * $ echo netdev >someled/trigger
|
||||
+ * $ echo eth0 >someled/device_name
|
||||
+ * $ echo "link tx rx" >someled/mode
|
||||
+ *
|
||||
+ * Modem-style tx/rx LEDs:
|
||||
+ * $ echo netdev >led1/trigger
|
||||
+ * $ echo ppp0 >led1/device_name
|
||||
+ * $ echo tx >led1/mode
|
||||
+ * $ echo netdev >led2/trigger
|
||||
+ * $ echo ppp0 >led2/device_name
|
||||
+ * $ echo rx >led2/mode
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#define MODE_LINK 1
|
||||
+#define MODE_TX 2
|
||||
+#define MODE_RX 4
|
||||
+
|
||||
+struct led_netdev_data {
|
||||
+ spinlock_t lock;
|
||||
+
|
||||
+ struct timer_list timer;
|
||||
+ struct notifier_block notifier;
|
||||
+
|
||||
+ struct led_classdev *led_cdev;
|
||||
+ struct net_device *net_dev;
|
||||
+
|
||||
+ char device_name[IFNAMSIZ];
|
||||
+ unsigned interval;
|
||||
+ unsigned mode;
|
||||
+ unsigned link_up;
|
||||
+ unsigned last_activity;
|
||||
+};
|
||||
+
|
||||
+static void set_baseline_state(struct led_netdev_data *trigger_data)
|
||||
+{
|
||||
+ if ((trigger_data->mode & MODE_LINK) != 0 && trigger_data->link_up)
|
||||
+ led_set_brightness(trigger_data->led_cdev, LED_FULL);
|
||||
+ else
|
||||
+ led_set_brightness(trigger_data->led_cdev, LED_OFF);
|
||||
+
|
||||
+ if ((trigger_data->mode & (MODE_TX | MODE_RX)) != 0 && trigger_data->link_up)
|
||||
+ mod_timer(&trigger_data->timer, jiffies + trigger_data->interval);
|
||||
+}
|
||||
+
|
||||
+static ssize_t led_device_name_show(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
+ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
|
||||
+
|
||||
+ spin_lock_bh(&trigger_data->lock);
|
||||
+ sprintf(buf, "%s\n", trigger_data->device_name);
|
||||
+ spin_unlock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ return strlen(buf) + 1;
|
||||
+}
|
||||
+
|
||||
+static ssize_t led_device_name_store(struct device *dev,
|
||||
+ struct device_attribute *attr, const char *buf, size_t size)
|
||||
+{
|
||||
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
+ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
|
||||
+
|
||||
+ if (size < 0 || size >= IFNAMSIZ)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ spin_lock_bh(&trigger_data->lock);
|
||||
+ del_timer_sync(&trigger_data->timer);
|
||||
+
|
||||
+ strcpy(trigger_data->device_name, buf);
|
||||
+ if (size > 0 && trigger_data->device_name[size-1] == '\n')
|
||||
+ trigger_data->device_name[size-1] = 0;
|
||||
+ trigger_data->link_up = 0;
|
||||
+ trigger_data->last_activity = 0;
|
||||
+
|
||||
+ if (trigger_data->device_name[0] != 0) {
|
||||
+ /* check for existing device to update from */
|
||||
+ trigger_data->net_dev = dev_get_by_name(&init_net, trigger_data->device_name);
|
||||
+ if (trigger_data->net_dev != NULL)
|
||||
+ trigger_data->link_up = (dev_get_flags(trigger_data->net_dev) & IFF_LOWER_UP) != 0;
|
||||
+ }
|
||||
+
|
||||
+ set_baseline_state(trigger_data);
|
||||
+ spin_unlock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ return size;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(device_name, 0644, led_device_name_show, led_device_name_store);
|
||||
+
|
||||
+static ssize_t led_mode_show(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
+ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
|
||||
+
|
||||
+ spin_lock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ if (trigger_data->mode == 0) {
|
||||
+ strcpy(buf, "none\n");
|
||||
+ } else {
|
||||
+ if (trigger_data->mode & MODE_LINK)
|
||||
+ strcat(buf, "link ");
|
||||
+ if (trigger_data->mode & MODE_TX)
|
||||
+ strcat(buf, "tx ");
|
||||
+ if (trigger_data->mode & MODE_RX)
|
||||
+ strcat(buf, "rx ");
|
||||
+ strcat(buf, "\n");
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ return strlen(buf)+1;
|
||||
+}
|
||||
+
|
||||
+static ssize_t led_mode_store(struct device *dev,
|
||||
+ struct device_attribute *attr, const char *buf, size_t size)
|
||||
+{
|
||||
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
+ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
|
||||
+ char copybuf[128];
|
||||
+ int new_mode = -1;
|
||||
+ char *p, *token;
|
||||
+
|
||||
+ /* take a copy since we don't want to trash the inbound buffer when using strsep */
|
||||
+ strncpy(copybuf, buf, sizeof(copybuf));
|
||||
+ copybuf[sizeof(copybuf) - 1] = 0;
|
||||
+ p = copybuf;
|
||||
+
|
||||
+ while ((token = strsep(&p, " \t\n")) != NULL) {
|
||||
+ if (!*token)
|
||||
+ continue;
|
||||
+
|
||||
+ if (new_mode == -1)
|
||||
+ new_mode = 0;
|
||||
+
|
||||
+ if (!strcmp(token, "none"))
|
||||
+ new_mode = 0;
|
||||
+ else if (!strcmp(token, "tx"))
|
||||
+ new_mode |= MODE_TX;
|
||||
+ else if (!strcmp(token, "rx"))
|
||||
+ new_mode |= MODE_RX;
|
||||
+ else if (!strcmp(token, "link"))
|
||||
+ new_mode |= MODE_LINK;
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (new_mode == -1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ spin_lock_bh(&trigger_data->lock);
|
||||
+ del_timer_sync(&trigger_data->timer);
|
||||
+
|
||||
+ trigger_data->mode = new_mode;
|
||||
+
|
||||
+ set_baseline_state(trigger_data);
|
||||
+ spin_unlock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ return size;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(mode, 0644, led_mode_show, led_mode_store);
|
||||
+
|
||||
+static ssize_t led_interval_show(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
+ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
|
||||
+
|
||||
+ spin_lock_bh(&trigger_data->lock);
|
||||
+ sprintf(buf, "%u\n", jiffies_to_msecs(trigger_data->interval));
|
||||
+ spin_unlock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ return strlen(buf) + 1;
|
||||
+}
|
||||
+
|
||||
+static ssize_t led_interval_store(struct device *dev,
|
||||
+ struct device_attribute *attr, const char *buf, size_t size)
|
||||
+{
|
||||
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
+ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
|
||||
+ int ret = -EINVAL;
|
||||
+ char *after;
|
||||
+ unsigned long value = simple_strtoul(buf, &after, 10);
|
||||
+ size_t count = after - buf;
|
||||
+
|
||||
+ if (isspace(*after))
|
||||
+ count++;
|
||||
+
|
||||
+ /* impose some basic bounds on the timer interval */
|
||||
+ if (count == size && value >= 5 && value <= 10000) {
|
||||
+ spin_lock_bh(&trigger_data->lock);
|
||||
+ del_timer_sync(&trigger_data->timer);
|
||||
+
|
||||
+ trigger_data->interval = msecs_to_jiffies(value);
|
||||
+
|
||||
+ set_baseline_state(trigger_data); /* resets timer */
|
||||
+ spin_unlock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ ret = count;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(interval, 0644, led_interval_show, led_interval_store);
|
||||
+
|
||||
+static int netdev_trig_notify(struct notifier_block *nb,
|
||||
+ unsigned long evt,
|
||||
+ void *dv)
|
||||
+{
|
||||
+ struct net_device *dev = netdev_notifier_info_to_dev((struct netdev_notifier_info *) dv);
|
||||
+ struct led_netdev_data *trigger_data = container_of(nb, struct led_netdev_data, notifier);
|
||||
+
|
||||
+ if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER && evt != NETDEV_CHANGENAME)
|
||||
+ return NOTIFY_DONE;
|
||||
+
|
||||
+ spin_lock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ if (strcmp(dev->name, trigger_data->device_name))
|
||||
+ goto done;
|
||||
+
|
||||
+ del_timer_sync(&trigger_data->timer);
|
||||
+
|
||||
+ if (evt == NETDEV_REGISTER || evt == NETDEV_CHANGENAME) {
|
||||
+ if (trigger_data->net_dev != NULL)
|
||||
+ dev_put(trigger_data->net_dev);
|
||||
+
|
||||
+ dev_hold(dev);
|
||||
+ trigger_data->net_dev = dev;
|
||||
+ trigger_data->link_up = 0;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (evt == NETDEV_UNREGISTER && trigger_data->net_dev != NULL) {
|
||||
+ dev_put(trigger_data->net_dev);
|
||||
+ trigger_data->net_dev = NULL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* UP / DOWN / CHANGE */
|
||||
+
|
||||
+ trigger_data->link_up = (evt != NETDEV_DOWN && netif_carrier_ok(dev));
|
||||
+ set_baseline_state(trigger_data);
|
||||
+
|
||||
+done:
|
||||
+ spin_unlock_bh(&trigger_data->lock);
|
||||
+ return NOTIFY_DONE;
|
||||
+}
|
||||
+
|
||||
+/* here's the real work! */
|
||||
+static void netdev_trig_timer(unsigned long arg)
|
||||
+{
|
||||
+ struct led_netdev_data *trigger_data = (struct led_netdev_data *)arg;
|
||||
+ struct rtnl_link_stats64 *dev_stats;
|
||||
+ unsigned new_activity;
|
||||
+ struct rtnl_link_stats64 temp;
|
||||
+
|
||||
+ if (!trigger_data->link_up || !trigger_data->net_dev || (trigger_data->mode & (MODE_TX | MODE_RX)) == 0) {
|
||||
+ /* we don't need to do timer work, just reflect link state. */
|
||||
+ led_set_brightness(trigger_data->led_cdev, ((trigger_data->mode & MODE_LINK) != 0 && trigger_data->link_up) ? LED_FULL : LED_OFF);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ dev_stats = dev_get_stats(trigger_data->net_dev, &temp);
|
||||
+ new_activity =
|
||||
+ ((trigger_data->mode & MODE_TX) ? dev_stats->tx_packets : 0) +
|
||||
+ ((trigger_data->mode & MODE_RX) ? dev_stats->rx_packets : 0);
|
||||
+
|
||||
+ if (trigger_data->mode & MODE_LINK) {
|
||||
+ /* base state is ON (link present) */
|
||||
+ /* if there's no link, we don't get this far and the LED is off */
|
||||
+
|
||||
+ /* OFF -> ON always */
|
||||
+ /* ON -> OFF on activity */
|
||||
+ if (trigger_data->led_cdev->brightness == LED_OFF) {
|
||||
+ led_set_brightness(trigger_data->led_cdev, LED_FULL);
|
||||
+ } else if (trigger_data->last_activity != new_activity) {
|
||||
+ led_set_brightness(trigger_data->led_cdev, LED_OFF);
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* base state is OFF */
|
||||
+ /* ON -> OFF always */
|
||||
+ /* OFF -> ON on activity */
|
||||
+ if (trigger_data->led_cdev->brightness == LED_FULL) {
|
||||
+ led_set_brightness(trigger_data->led_cdev, LED_OFF);
|
||||
+ } else if (trigger_data->last_activity != new_activity) {
|
||||
+ led_set_brightness(trigger_data->led_cdev, LED_FULL);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ trigger_data->last_activity = new_activity;
|
||||
+ mod_timer(&trigger_data->timer, jiffies + trigger_data->interval);
|
||||
+}
|
||||
+
|
||||
+static void netdev_trig_activate(struct led_classdev *led_cdev)
|
||||
+{
|
||||
+ struct led_netdev_data *trigger_data;
|
||||
+ int rc;
|
||||
+
|
||||
+ trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL);
|
||||
+ if (!trigger_data)
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock_init(&trigger_data->lock);
|
||||
+
|
||||
+ trigger_data->notifier.notifier_call = netdev_trig_notify;
|
||||
+ trigger_data->notifier.priority = 10;
|
||||
+
|
||||
+ setup_timer(&trigger_data->timer, netdev_trig_timer, (unsigned long) trigger_data);
|
||||
+
|
||||
+ trigger_data->led_cdev = led_cdev;
|
||||
+ trigger_data->net_dev = NULL;
|
||||
+ trigger_data->device_name[0] = 0;
|
||||
+
|
||||
+ trigger_data->mode = 0;
|
||||
+ trigger_data->interval = msecs_to_jiffies(50);
|
||||
+ trigger_data->link_up = 0;
|
||||
+ trigger_data->last_activity = 0;
|
||||
+
|
||||
+ led_cdev->trigger_data = trigger_data;
|
||||
+
|
||||
+ rc = device_create_file(led_cdev->dev, &dev_attr_device_name);
|
||||
+ if (rc)
|
||||
+ goto err_out;
|
||||
+ rc = device_create_file(led_cdev->dev, &dev_attr_mode);
|
||||
+ if (rc)
|
||||
+ goto err_out_device_name;
|
||||
+ rc = device_create_file(led_cdev->dev, &dev_attr_interval);
|
||||
+ if (rc)
|
||||
+ goto err_out_mode;
|
||||
+
|
||||
+ register_netdevice_notifier(&trigger_data->notifier);
|
||||
+ return;
|
||||
+
|
||||
+err_out_mode:
|
||||
+ device_remove_file(led_cdev->dev, &dev_attr_mode);
|
||||
+err_out_device_name:
|
||||
+ device_remove_file(led_cdev->dev, &dev_attr_device_name);
|
||||
+err_out:
|
||||
+ led_cdev->trigger_data = NULL;
|
||||
+ kfree(trigger_data);
|
||||
+}
|
||||
+
|
||||
+static void netdev_trig_deactivate(struct led_classdev *led_cdev)
|
||||
+{
|
||||
+ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
|
||||
+
|
||||
+ if (trigger_data) {
|
||||
+ unregister_netdevice_notifier(&trigger_data->notifier);
|
||||
+
|
||||
+ device_remove_file(led_cdev->dev, &dev_attr_device_name);
|
||||
+ device_remove_file(led_cdev->dev, &dev_attr_mode);
|
||||
+ device_remove_file(led_cdev->dev, &dev_attr_interval);
|
||||
+
|
||||
+ spin_lock_bh(&trigger_data->lock);
|
||||
+ del_timer_sync(&trigger_data->timer);
|
||||
+
|
||||
+ if (trigger_data->net_dev) {
|
||||
+ dev_put(trigger_data->net_dev);
|
||||
+ trigger_data->net_dev = NULL;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_bh(&trigger_data->lock);
|
||||
+
|
||||
+ kfree(trigger_data);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct led_trigger netdev_led_trigger = {
|
||||
+ .name = "netdev",
|
||||
+ .activate = netdev_trig_activate,
|
||||
+ .deactivate = netdev_trig_deactivate,
|
||||
+};
|
||||
+
|
||||
+static int __init netdev_trig_init(void)
|
||||
+{
|
||||
+ return led_trigger_register(&netdev_led_trigger);
|
||||
+}
|
||||
+
|
||||
+static void __exit netdev_trig_exit(void)
|
||||
+{
|
||||
+ led_trigger_unregister(&netdev_led_trigger);
|
||||
+}
|
||||
+
|
||||
+module_init(netdev_trig_init);
|
||||
+module_exit(netdev_trig_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Oliver Jowett <oliver@opencloud.com>");
|
||||
+MODULE_DESCRIPTION("Netdev LED trigger");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -Naur linux-4.9.16.org/drivers/leds/trigger/Makefile linux-4.9.16/drivers/leds/trigger/Makefile
|
||||
--- linux-4.9.16.org/drivers/leds/trigger/Makefile 2017-03-18 12:15:30.000000000 +0100
|
||||
+++ linux-4.9.16/drivers/leds/trigger/Makefile 2017-03-18 16:53:44.280859607 +0100
|
||||
@@ -10,3 +10,4 @@
|
||||
obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o
|
||||
obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o
|
||||
obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o
|
||||
+obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o
|
||||
@@ -1,22 +1,22 @@
|
||||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
|
||||
index 3172e14..798b8c9 100644
|
||||
index a828cf99c521..6d97e4d8623f 100644
|
||||
--- a/include/linux/skbuff.h
|
||||
+++ b/include/linux/skbuff.h
|
||||
@@ -700,6 +700,9 @@ struct sk_buff {
|
||||
@@ -757,6 +757,9 @@ struct sk_buff {
|
||||
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
unsigned long _nfct;
|
||||
#endif
|
||||
+#endif
|
||||
+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
|
||||
+ char layer7_flags[1];
|
||||
+#endif
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
||||
struct nf_bridge_info *nf_bridge;
|
||||
#endif
|
||||
unsigned int len,
|
||||
data_len;
|
||||
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
|
||||
index 792c3f6..f24a6ac 100644
|
||||
index 439379ca9ffa..9cab502ff226 100644
|
||||
--- a/include/net/netfilter/nf_conntrack.h
|
||||
+++ b/include/net/netfilter/nf_conntrack.h
|
||||
@@ -96,6 +96,23 @@ struct nf_conn {
|
||||
@@ -103,6 +103,23 @@ struct nf_conn {
|
||||
/* Extensions */
|
||||
struct nf_ct_ext *ext;
|
||||
|
||||
@@ -42,7 +42,7 @@ index 792c3f6..f24a6ac 100644
|
||||
};
|
||||
diff --git a/include/uapi/linux/netfilter/xt_layer7.h b/include/uapi/linux/netfilter/xt_layer7.h
|
||||
new file mode 100644
|
||||
index 0000000..147cd64
|
||||
index 000000000000..147cd6477858
|
||||
--- /dev/null
|
||||
+++ b/include/uapi/linux/netfilter/xt_layer7.h
|
||||
@@ -0,0 +1,13 @@
|
||||
@@ -60,10 +60,10 @@ index 0000000..147cd64
|
||||
+
|
||||
+#endif /* _XT_LAYER7_H */
|
||||
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
|
||||
index e4a13cc..0b0f501 100644
|
||||
index 52370211e46b..734b4d641469 100644
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -1282,6 +1282,26 @@ config NETFILTER_XT_MATCH_L2TP
|
||||
@@ -1355,6 +1355,26 @@ config NETFILTER_XT_MATCH_L2TP
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
@@ -91,10 +91,10 @@ index e4a13cc..0b0f501 100644
|
||||
tristate '"length" match support'
|
||||
depends on NETFILTER_ADVANCED
|
||||
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
|
||||
index f78ed24..268b7e7 100644
|
||||
index 0e0ded87e27b..6c383006af4e 100644
|
||||
--- a/net/netfilter/Makefile
|
||||
+++ b/net/netfilter/Makefile
|
||||
@@ -180,6 +180,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o
|
||||
@@ -203,6 +203,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
|
||||
@@ -103,10 +103,10 @@ index f78ed24..268b7e7 100644
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
|
||||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
|
||||
index 06520bf..0109de4 100644
|
||||
index 234b7cab37c3..05731ba4f5ff 100644
|
||||
--- a/net/netfilter/nf_conntrack_core.c
|
||||
+++ b/net/netfilter/nf_conntrack_core.c
|
||||
@@ -427,6 +427,11 @@ destroy_conntrack(struct nf_conntrack *nfct)
|
||||
@@ -617,6 +617,11 @@ destroy_conntrack(struct nf_conntrack *nfct)
|
||||
*/
|
||||
nf_ct_remove_expectations(ct);
|
||||
|
||||
@@ -119,10 +119,10 @@ index 06520bf..0109de4 100644
|
||||
|
||||
local_bh_enable();
|
||||
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
|
||||
index 5a101ca..88830c7 100644
|
||||
index 46c5557c1fec..6ef99967ae05 100644
|
||||
--- a/net/netfilter/nf_conntrack_standalone.c
|
||||
+++ b/net/netfilter/nf_conntrack_standalone.c
|
||||
@@ -353,6 +353,11 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||
@@ -366,6 +366,11 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||
ct_show_zone(s, ct, NF_CT_DEFAULT_ZONE_DIR);
|
||||
ct_show_delta_time(s, ct);
|
||||
|
||||
@@ -136,7 +136,7 @@ index 5a101ca..88830c7 100644
|
||||
if (seq_has_overflowed(s))
|
||||
diff --git a/net/netfilter/regexp/regexp.c b/net/netfilter/regexp/regexp.c
|
||||
new file mode 100644
|
||||
index 0000000..9006988
|
||||
index 000000000000..900698886531
|
||||
--- /dev/null
|
||||
+++ b/net/netfilter/regexp/regexp.c
|
||||
@@ -0,0 +1,1197 @@
|
||||
@@ -1339,7 +1339,7 @@ index 0000000..9006988
|
||||
+
|
||||
diff --git a/net/netfilter/regexp/regexp.h b/net/netfilter/regexp/regexp.h
|
||||
new file mode 100644
|
||||
index 0000000..a72eba7
|
||||
index 000000000000..a72eba71fb61
|
||||
--- /dev/null
|
||||
+++ b/net/netfilter/regexp/regexp.h
|
||||
@@ -0,0 +1,41 @@
|
||||
@@ -1386,7 +1386,7 @@ index 0000000..a72eba7
|
||||
+#endif
|
||||
diff --git a/net/netfilter/regexp/regmagic.h b/net/netfilter/regexp/regmagic.h
|
||||
new file mode 100644
|
||||
index 0000000..5acf447
|
||||
index 000000000000..5acf4478ff71
|
||||
--- /dev/null
|
||||
+++ b/net/netfilter/regexp/regmagic.h
|
||||
@@ -0,0 +1,5 @@
|
||||
@@ -1397,7 +1397,7 @@ index 0000000..5acf447
|
||||
+#define MAGIC 0234
|
||||
diff --git a/net/netfilter/regexp/regsub.c b/net/netfilter/regexp/regsub.c
|
||||
new file mode 100644
|
||||
index 0000000..339631f
|
||||
index 000000000000..339631f06f00
|
||||
--- /dev/null
|
||||
+++ b/net/netfilter/regexp/regsub.c
|
||||
@@ -0,0 +1,95 @@
|
||||
@@ -1498,10 +1498,10 @@ index 0000000..339631f
|
||||
+}
|
||||
diff --git a/net/netfilter/xt_layer7.c b/net/netfilter/xt_layer7.c
|
||||
new file mode 100644
|
||||
index 0000000..db7d061
|
||||
index 000000000000..a7eb760123bf
|
||||
--- /dev/null
|
||||
+++ b/net/netfilter/xt_layer7.c
|
||||
@@ -0,0 +1,665 @@
|
||||
@@ -0,0 +1,666 @@
|
||||
+/*
|
||||
+ Kernel module to match application layer (OSI layer 7) data in connections.
|
||||
+
|
||||
@@ -2068,6 +2068,7 @@ index 0000000..db7d061
|
||||
+ return (pattern_result ^ info->invert);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+// load nf_conntrack_ipv4
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
||||
+static int
|
||||
@@ -2112,31 +2113,31 @@ index 0000000..db7d061
|
||||
+ nf_ct_l3proto_module_put(match->family);
|
||||
+ }
|
||||
+#endif
|
||||
+*/
|
||||
+
|
||||
+static struct xt_match xt_layer7_match[] __read_mostly = {
|
||||
+{
|
||||
+ .name = "layer7",
|
||||
+ .family = NFPROTO_IPV4,
|
||||
+ .checkentry = check,
|
||||
+// .checkentry = check,
|
||||
+ .match = match,
|
||||
+ .destroy = destroy,
|
||||
+// .destroy = destroy,
|
||||
+ .matchsize = sizeof(struct xt_layer7_info),
|
||||
+ .me = THIS_MODULE
|
||||
+}
|
||||
+};
|
||||
+
|
||||
+static const struct file_operations layer7_numpackets_proc_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = layer7_numpackets_proc_open,
|
||||
+ .read = seq_read,
|
||||
+ .llseek = seq_lseek,
|
||||
+ .release = single_release,
|
||||
+ .write = layer7_numpackets_write_proc,
|
||||
+static const struct proc_ops layer7_numpackets_proc_fops = {
|
||||
+ .proc_open = layer7_numpackets_proc_open,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = single_release,
|
||||
+ .proc_write = layer7_numpackets_write_proc,
|
||||
+};
|
||||
+
|
||||
+static int __init xt_layer7_init(void)
|
||||
+{
|
||||
+ need_conntrack();
|
||||
+// need_conntrack();
|
||||
+
|
||||
+ // Register proc interface
|
||||
+ proc_create_data("layer7_numpackets", 0644,
|
||||
@@ -0,0 +1,43 @@
|
||||
From: Eric Biggers <ebiggers@kernel.org>
|
||||
To: linux-crypto@vger.kernel.org, Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Cc: Kees Cook <keescook@chromium.org>,
|
||||
Dmitry Vyukov <dvyukov@google.com>,
|
||||
Geert Uytterhoeven <geert@linux-m68k.org>,
|
||||
linux-security-module <linux-security-module@vger.kernel.org>,
|
||||
Linux ARM <linux-arm-kernel@lists.infradead.org>,
|
||||
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
|
||||
Laura Abbott <labbott@redhat.com>,
|
||||
Rik van Riel <riel@surriel.com>
|
||||
Subject: [PATCH] crypto: testmgr - allocate buffers with __GFP_COMP
|
||||
Date: Thu, 11 Apr 2019 12:28:27 -0700
|
||||
Message-ID: <20190411192827.72551-1-ebiggers@kernel.org> (raw)
|
||||
In-Reply-To: <20190411192607.GD225654@gmail.com>
|
||||
|
||||
From: Eric Biggers <ebiggers@google.com>
|
||||
|
||||
This is needed so that CONFIG_HARDENED_USERCOPY_PAGESPAN=y doesn't
|
||||
incorrectly report a buffer overflow when the destination of
|
||||
copy_from_iter() spans the page boundary in the 2-page buffer.
|
||||
|
||||
Fixes: 3f47a03df6e8 ("crypto: testmgr - add testvec_config struct and helper functions")
|
||||
Signed-off-by: Eric Biggers <ebiggers@google.com>
|
||||
---
|
||||
crypto/testmgr.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
|
||||
index 0f6bfb6ce6a46..3522c0bed2492 100644
|
||||
--- a/crypto/testmgr.c
|
||||
+++ b/crypto/testmgr.c
|
||||
@@ -156,7 +156,8 @@ static int __testmgr_alloc_buf(char *buf[XBUFSIZE], int order)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < XBUFSIZE; i++) {
|
||||
- buf[i] = (char *)__get_free_pages(GFP_KERNEL, order);
|
||||
+ buf[i] = (char *)__get_free_pages(GFP_KERNEL | __GFP_COMP,
|
||||
+ order);
|
||||
if (!buf[i])
|
||||
goto err_free_buf;
|
||||
}
|
||||
--
|
||||
2.21.0.392.gf8f6787159e-goog
|
||||
@@ -1,146 +0,0 @@
|
||||
From 50ee7529ec4500c88f8664560770a7a1b65db72b Mon Sep 17 00:00:00 2001
|
||||
From: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Date: Sat, 28 Sep 2019 16:53:52 -0700
|
||||
Subject: random: try to actively add entropy rather than passively wait for it
|
||||
|
||||
For 5.3 we had to revert a nice ext4 IO pattern improvement, because it
|
||||
caused a bootup regression due to lack of entropy at bootup together
|
||||
with arguably broken user space that was asking for secure random
|
||||
numbers when it really didn't need to.
|
||||
|
||||
See commit 72dbcf721566 (Revert "ext4: make __ext4_get_inode_loc plug").
|
||||
|
||||
This aims to solve the issue by actively generating entropy noise using
|
||||
the CPU cycle counter when waiting for the random number generator to
|
||||
initialize. This only works when you have a high-frequency time stamp
|
||||
counter available, but that's the case on all modern x86 CPU's, and on
|
||||
most other modern CPU's too.
|
||||
|
||||
What we do is to generate jitter entropy from the CPU cycle counter
|
||||
under a somewhat complex load: calling the scheduler while also
|
||||
guaranteeing a certain amount of timing noise by also triggering a
|
||||
timer.
|
||||
|
||||
I'm sure we can tweak this, and that people will want to look at other
|
||||
alternatives, but there's been a number of papers written on jitter
|
||||
entropy, and this should really be fairly conservative by crediting one
|
||||
bit of entropy for every timer-induced jump in the cycle counter. Not
|
||||
because the timer itself would be all that unpredictable, but because
|
||||
the interaction between the timer and the loop is going to be.
|
||||
|
||||
Even if (and perhaps particularly if) the timer actually happens on
|
||||
another CPU, the cacheline interaction between the loop that reads the
|
||||
cycle counter and the timer itself firing is going to add perturbations
|
||||
to the cycle counter values that get mixed into the entropy pool.
|
||||
|
||||
As Thomas pointed out, with a modern out-of-order CPU, even quite simple
|
||||
loops show a fair amount of hard-to-predict timing variability even in
|
||||
the absense of external interrupts. But this tries to take that further
|
||||
by actually having a fairly complex interaction.
|
||||
|
||||
This is not going to solve the entropy issue for architectures that have
|
||||
no CPU cycle counter, but it's not clear how (and if) that is solvable,
|
||||
and the hardware in question is largely starting to be irrelevant. And
|
||||
by doing this we can at least avoid some of the even more contentious
|
||||
approaches (like making the entropy waiting time out in order to avoid
|
||||
the possibly unbounded waiting).
|
||||
|
||||
Cc: Ahmed Darwish <darwish.07@gmail.com>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: Theodore Ts'o <tytso@mit.edu>
|
||||
Cc: Nicholas Mc Guire <hofrat@opentech.at>
|
||||
Cc: Andy Lutomirski <luto@kernel.org>
|
||||
Cc: Kees Cook <keescook@chromium.org>
|
||||
Cc: Willy Tarreau <w@1wt.eu>
|
||||
Cc: Alexander E. Patrakov <patrakov@gmail.com>
|
||||
Cc: Lennart Poettering <mzxreary@0pointer.de>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
drivers/char/random.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 61 insertions(+), 1 deletion(-)
|
||||
|
||||
(limited to 'drivers/char/random.c')
|
||||
|
||||
diff --git a/drivers/char/random.c b/drivers/char/random.c
|
||||
index 5d5ea4ce1442..2fda6166c1dd 100644
|
||||
--- a/drivers/char/random.c
|
||||
+++ b/drivers/char/random.c
|
||||
@@ -1731,6 +1731,56 @@ void get_random_bytes(void *buf, int nbytes)
|
||||
}
|
||||
EXPORT_SYMBOL(get_random_bytes);
|
||||
|
||||
+
|
||||
+/*
|
||||
+ * Each time the timer fires, we expect that we got an unpredictable
|
||||
+ * jump in the cycle counter. Even if the timer is running on another
|
||||
+ * CPU, the timer activity will be touching the stack of the CPU that is
|
||||
+ * generating entropy..
|
||||
+ *
|
||||
+ * Note that we don't re-arm the timer in the timer itself - we are
|
||||
+ * happy to be scheduled away, since that just makes the load more
|
||||
+ * complex, but we do not want the timer to keep ticking unless the
|
||||
+ * entropy loop is running.
|
||||
+ *
|
||||
+ * So the re-arming always happens in the entropy loop itself.
|
||||
+ */
|
||||
+static void entropy_timer(struct timer_list *t)
|
||||
+{
|
||||
+ credit_entropy_bits(&input_pool, 1);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * If we have an actual cycle counter, see if we can
|
||||
+ * generate enough entropy with timing noise
|
||||
+ */
|
||||
+static void try_to_generate_entropy(void)
|
||||
+{
|
||||
+ struct {
|
||||
+ unsigned long now;
|
||||
+ struct timer_list timer;
|
||||
+ } stack;
|
||||
+
|
||||
+ stack.now = random_get_entropy();
|
||||
+
|
||||
+ /* Slow counter - or none. Don't even bother */
|
||||
+ if (stack.now == random_get_entropy())
|
||||
+ return;
|
||||
+
|
||||
+ timer_setup_on_stack(&stack.timer, entropy_timer, 0);
|
||||
+ while (!crng_ready()) {
|
||||
+ if (!timer_pending(&stack.timer))
|
||||
+ mod_timer(&stack.timer, jiffies+1);
|
||||
+ mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
|
||||
+ schedule();
|
||||
+ stack.now = random_get_entropy();
|
||||
+ }
|
||||
+
|
||||
+ del_timer_sync(&stack.timer);
|
||||
+ destroy_timer_on_stack(&stack.timer);
|
||||
+ mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Wait for the urandom pool to be seeded and thus guaranteed to supply
|
||||
* cryptographically secure random numbers. This applies to: the /dev/urandom
|
||||
@@ -1745,7 +1795,17 @@ int wait_for_random_bytes(void)
|
||||
{
|
||||
if (likely(crng_ready()))
|
||||
return 0;
|
||||
- return wait_event_interruptible(crng_init_wait, crng_ready());
|
||||
+
|
||||
+ do {
|
||||
+ int ret;
|
||||
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
|
||||
+ if (ret)
|
||||
+ return ret > 0 ? 0 : ret;
|
||||
+
|
||||
+ try_to_generate_entropy();
|
||||
+ } while (!crng_ready());
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(wait_for_random_bytes);
|
||||
|
||||
--
|
||||
cgit 1.2-0.3.lf.el7
|
||||
|
||||
Reference in New Issue
Block a user