mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Update OpenWRT
This commit is contained in:
parent
55c3e7cde4
commit
948aebf05a
1080 changed files with 8134 additions and 328613 deletions
|
@ -1,210 +0,0 @@
|
|||
From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 7 Jul 2017 16:56:48 +0200
|
||||
Subject: build: add a hack for removing non-essential module info
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
include/linux/module.h | 13 ++++++++-----
|
||||
include/linux/moduleparam.h | 15 ++++++++++++---
|
||||
init/Kconfig | 7 +++++++
|
||||
kernel/module.c | 5 ++++-
|
||||
scripts/mod/modpost.c | 12 ++++++++++++
|
||||
5 files changed, 43 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/include/linux/module.h
|
||||
+++ b/include/linux/module.h
|
||||
@@ -163,6 +163,7 @@ extern void cleanup_module(void);
|
||||
|
||||
/* Generic info of form tag = "info" */
|
||||
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
|
||||
+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info)
|
||||
|
||||
/* For userspace: you can also call me... */
|
||||
#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
|
||||
@@ -232,12 +233,12 @@ extern void cleanup_module(void);
|
||||
* Author(s), use "Name <email>" or just "Name", for multiple
|
||||
* authors use multiple MODULE_AUTHOR() statements/lines.
|
||||
*/
|
||||
-#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
|
||||
+#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author)
|
||||
|
||||
/* What your module does. */
|
||||
-#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
|
||||
+#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description)
|
||||
|
||||
-#ifdef MODULE
|
||||
+#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED)
|
||||
/* Creates an alias so file2alias.c can find device table. */
|
||||
#define MODULE_DEVICE_TABLE(type, name) \
|
||||
extern typeof(name) __mod_##type##__##name##_device_table \
|
||||
@@ -264,7 +265,9 @@ extern typeof(name) __mod_##type##__##na
|
||||
*/
|
||||
|
||||
#if defined(MODULE) || !defined(CONFIG_SYSFS)
|
||||
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
|
||||
+#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version)
|
||||
+#elif defined(CONFIG_MODULE_STRIPPED)
|
||||
+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version)
|
||||
#else
|
||||
#define MODULE_VERSION(_version) \
|
||||
MODULE_INFO(version, _version); \
|
||||
@@ -287,7 +290,7 @@ extern typeof(name) __mod_##type##__##na
|
||||
/* Optional firmware file (or files) needed by the module
|
||||
* format is simply firmware file name. Multiple firmware
|
||||
* files require multiple MODULE_FIRMWARE() specifiers */
|
||||
-#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
|
||||
+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware)
|
||||
|
||||
#define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, __stringify(ns))
|
||||
|
||||
--- a/include/linux/moduleparam.h
|
||||
+++ b/include/linux/moduleparam.h
|
||||
@@ -20,6 +20,16 @@
|
||||
/* Chosen so that structs with an unsigned long line up. */
|
||||
#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
|
||||
|
||||
+/* This struct is here for syntactic coherency, it is not used */
|
||||
+#define __MODULE_INFO_DISABLED(name) \
|
||||
+ struct __UNIQUE_ID(name) {}
|
||||
+
|
||||
+#ifdef CONFIG_MODULE_STRIPPED
|
||||
+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name)
|
||||
+#else
|
||||
+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info)
|
||||
+#endif
|
||||
+
|
||||
#define __MODULE_INFO(tag, name, info) \
|
||||
static const char __UNIQUE_ID(name)[] \
|
||||
__used __section(".modinfo") __aligned(1) \
|
||||
@@ -31,7 +41,7 @@
|
||||
/* One for each parameter, describing how to use it. Some files do
|
||||
multiple of these per line, so can't just use MODULE_INFO. */
|
||||
#define MODULE_PARM_DESC(_parm, desc) \
|
||||
- __MODULE_INFO(parm, _parm, #_parm ":" desc)
|
||||
+ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc)
|
||||
|
||||
struct kernel_param;
|
||||
|
||||
--- a/kernel/module/Kconfig
|
||||
+++ b/kernel/module/Kconfig
|
||||
@@ -290,4 +290,11 @@ config MODULES_TREE_LOOKUP
|
||||
def_bool y
|
||||
depends on PERF_EVENTS || TRACING || CFI_CLANG
|
||||
|
||||
+config MODULE_STRIPPED
|
||||
+ bool "Reduce module size"
|
||||
+ depends on MODULES
|
||||
+ help
|
||||
+ Remove module parameter descriptions, author info, version, aliases,
|
||||
+ device tables, etc.
|
||||
+
|
||||
endif # MODULES
|
||||
--- a/kernel/module/main.c
|
||||
+++ b/kernel/module/main.c
|
||||
@@ -988,6 +988,7 @@ size_t modinfo_attrs_count = ARRAY_SIZE(
|
||||
|
||||
static const char vermagic[] = VERMAGIC_STRING;
|
||||
|
||||
+#if defined(CONFIG_MODVERSIONS) || !defined(CONFIG_MODULE_STRIPPED)
|
||||
int try_to_force_load(struct module *mod, const char *reason)
|
||||
{
|
||||
#ifdef CONFIG_MODULE_FORCE_LOAD
|
||||
@@ -999,6 +1000,7 @@ int try_to_force_load(struct module *mod
|
||||
return -ENOEXEC;
|
||||
#endif
|
||||
}
|
||||
+#endif
|
||||
|
||||
static char *get_modinfo(const struct load_info *info, const char *tag);
|
||||
static char *get_next_modinfo(const struct load_info *info, const char *tag,
|
||||
@@ -1950,9 +1952,11 @@ static int setup_load_info(struct load_i
|
||||
|
||||
static int check_modinfo(struct module *mod, struct load_info *info, int flags)
|
||||
{
|
||||
- const char *modmagic = get_modinfo(info, "vermagic");
|
||||
int err;
|
||||
|
||||
+#ifndef CONFIG_MODULE_STRIPPED
|
||||
+ const char *modmagic = get_modinfo(info, "vermagic");
|
||||
+
|
||||
if (flags & MODULE_INIT_IGNORE_VERMAGIC)
|
||||
modmagic = NULL;
|
||||
|
||||
@@ -1973,6 +1977,7 @@ static int check_modinfo(struct module *
|
||||
mod->name);
|
||||
add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
|
||||
}
|
||||
+#endif
|
||||
|
||||
check_modinfo_retpoline(mod, info);
|
||||
|
||||
--- a/scripts/mod/modpost.c
|
||||
+++ b/scripts/mod/modpost.c
|
||||
@@ -1817,7 +1817,9 @@ static void read_symbols(const char *mod
|
||||
symname = remove_dot(info.strtab + sym->st_name);
|
||||
|
||||
handle_symbol(mod, &info, sym, symname);
|
||||
+#ifndef CONFIG_MODULE_STRIPPED
|
||||
handle_moddevtable(mod, &info, sym, symname);
|
||||
+#endif
|
||||
}
|
||||
|
||||
for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
|
||||
@@ -1980,8 +1982,10 @@ static void add_header(struct buffer *b,
|
||||
buf_printf(b, "BUILD_SALT;\n");
|
||||
buf_printf(b, "BUILD_LTO_INFO;\n");
|
||||
buf_printf(b, "\n");
|
||||
+#ifndef CONFIG_MODULE_STRIPPED
|
||||
buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
|
||||
buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
|
||||
+#endif
|
||||
buf_printf(b, "\n");
|
||||
buf_printf(b, "__visible struct module __this_module\n");
|
||||
buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
|
||||
@@ -1995,8 +1999,10 @@ static void add_header(struct buffer *b,
|
||||
buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
|
||||
buf_printf(b, "};\n");
|
||||
|
||||
+#ifndef CONFIG_MODULE_STRIPPED
|
||||
if (!external_module)
|
||||
buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
|
||||
+#endif
|
||||
|
||||
buf_printf(b,
|
||||
"\n"
|
||||
@@ -2004,8 +2010,10 @@ static void add_header(struct buffer *b,
|
||||
"MODULE_INFO(retpoline, \"Y\");\n"
|
||||
"#endif\n");
|
||||
|
||||
+#ifndef CONFIG_MODULE_STRIPPED
|
||||
if (strstarts(mod->name, "drivers/staging"))
|
||||
buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
|
||||
+#endif
|
||||
|
||||
if (strstarts(mod->name, "tools/testing"))
|
||||
buf_printf(b, "\nMODULE_INFO(test, \"Y\");\n");
|
||||
@@ -2101,11 +2109,13 @@ static void add_depends(struct buffer *b
|
||||
|
||||
static void add_srcversion(struct buffer *b, struct module *mod)
|
||||
{
|
||||
+#ifndef CONFIG_MODULE_STRIPPED
|
||||
if (mod->srcversion[0]) {
|
||||
buf_printf(b, "\n");
|
||||
buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
|
||||
mod->srcversion);
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
static void write_buf(struct buffer *b, const char *fname)
|
||||
@@ -2191,7 +2201,9 @@ static void write_mod_c_file(struct modu
|
||||
add_exported_symbols(&buf, mod);
|
||||
add_versions(&buf, mod);
|
||||
add_depends(&buf, mod);
|
||||
+#ifndef CONFIG_MODULE_STRIPPED
|
||||
add_moddevtable(&buf, mod);
|
||||
+#endif
|
||||
add_srcversion(&buf, mod);
|
||||
|
||||
ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);
|
|
@ -1,20 +0,0 @@
|
|||
From 300d26562ce4dc427154cb247beb75db4b1f0774 Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:29:57 +0200
|
||||
Subject: [PATCH] scripts/Kconfig: Kconfig exit
|
||||
|
||||
---
|
||||
scripts/kconfig/conf.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/scripts/kconfig/conf.c
|
||||
+++ b/scripts/kconfig/conf.c
|
||||
@@ -432,6 +432,8 @@ static int conf_sym(struct menu *menu)
|
||||
break;
|
||||
continue;
|
||||
case 0:
|
||||
+ if (!sym_has_value(sym) && !tty_stdio && getenv("FAIL_ON_UNCONFIGURED"))
|
||||
+ exit(1);
|
||||
newval = oldval;
|
||||
break;
|
||||
case '?':
|
File diff suppressed because it is too large
Load diff
|
@ -1,22 +0,0 @@
|
|||
From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
Date: Wed, 5 Feb 2020 18:36:43 +0000
|
||||
Subject: [PATCH] file2alias: build on macos
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
scripts/mod/file2alias.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/scripts/mod/file2alias.c
|
||||
+++ b/scripts/mod/file2alias.c
|
||||
@@ -38,6 +38,9 @@ typedef struct {
|
||||
__u8 b[16];
|
||||
} guid_t;
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+#define uuid_t compat_uuid_t
|
||||
+#endif
|
||||
/* backwards compatibility, don't use in new code */
|
||||
typedef struct {
|
||||
__u8 b[16];
|
|
@ -1,93 +0,0 @@
|
|||
From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 7 Jul 2017 17:03:16 +0200
|
||||
Subject: fix portability of some includes files in tools/ used on the host
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
tools/include/tools/be_byteshift.h | 4 ++++
|
||||
tools/include/tools/le_byteshift.h | 4 ++++
|
||||
tools/include/tools/linux_types.h | 22 ++++++++++++++++++++++
|
||||
3 files changed, 30 insertions(+)
|
||||
create mode 100644 tools/include/tools/linux_types.h
|
||||
|
||||
--- a/tools/include/tools/be_byteshift.h
|
||||
+++ b/tools/include/tools/be_byteshift.h
|
||||
@@ -2,6 +2,10 @@
|
||||
#ifndef _TOOLS_BE_BYTESHIFT_H
|
||||
#define _TOOLS_BE_BYTESHIFT_H
|
||||
|
||||
+#ifndef __linux__
|
||||
+#include "linux_types.h"
|
||||
+#endif
|
||||
+
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint16_t __get_unaligned_be16(const uint8_t *p)
|
||||
--- a/tools/include/tools/le_byteshift.h
|
||||
+++ b/tools/include/tools/le_byteshift.h
|
||||
@@ -2,6 +2,10 @@
|
||||
#ifndef _TOOLS_LE_BYTESHIFT_H
|
||||
#define _TOOLS_LE_BYTESHIFT_H
|
||||
|
||||
+#ifndef __linux__
|
||||
+#include "linux_types.h"
|
||||
+#endif
|
||||
+
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint16_t __get_unaligned_le16(const uint8_t *p)
|
||||
--- /dev/null
|
||||
+++ b/tools/include/tools/linux_types.h
|
||||
@@ -0,0 +1,26 @@
|
||||
+#ifndef __LINUX_TYPES_H
|
||||
+#define __LINUX_TYPES_H
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+typedef int8_t __s8;
|
||||
+typedef uint8_t __u8;
|
||||
+typedef uint8_t __be8;
|
||||
+typedef uint8_t __le8;
|
||||
+
|
||||
+typedef int16_t __s16;
|
||||
+typedef uint16_t __u16;
|
||||
+typedef uint16_t __be16;
|
||||
+typedef uint16_t __le16;
|
||||
+
|
||||
+typedef int32_t __s32;
|
||||
+typedef uint32_t __u32;
|
||||
+typedef uint32_t __be32;
|
||||
+typedef uint32_t __le32;
|
||||
+
|
||||
+typedef int64_t __s64;
|
||||
+typedef uint64_t __u64;
|
||||
+typedef uint64_t __be64;
|
||||
+typedef uint64_t __le64;
|
||||
+
|
||||
+#endif
|
||||
--- a/tools/include/linux/types.h
|
||||
+++ b/tools/include/linux/types.h
|
||||
@@ -10,8 +10,12 @@
|
||||
#define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */
|
||||
#endif
|
||||
|
||||
+#ifndef __linux__
|
||||
+#include <tools/linux_types.h>
|
||||
+#else
|
||||
#include <asm/types.h>
|
||||
#include <asm/posix_types.h>
|
||||
+#endif
|
||||
|
||||
struct page;
|
||||
struct kmem_cache;
|
||||
--- a/tools/perf/pmu-events/jevents.py
|
||||
+++ b/tools/perf/pmu-events/jevents.py
|
||||
@@ -684,6 +684,7 @@ def main() -> None:
|
||||
#include "util/header.h"
|
||||
#include "util/pmu.h"
|
||||
#include <string.h>
|
||||
+#include <strings.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct compact_pmu_event {
|
|
@ -1,24 +0,0 @@
|
|||
From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 7 Jul 2017 17:04:08 +0200
|
||||
Subject: kernel: fix linux/spi/spidev.h portability issues with musl
|
||||
|
||||
Felix will try to get this define included into musl
|
||||
|
||||
lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
include/uapi/linux/spi/spidev.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/include/uapi/linux/spi/spidev.h
|
||||
+++ b/include/uapi/linux/spi/spidev.h
|
||||
@@ -93,7 +93,7 @@ struct spi_ioc_transfer {
|
||||
|
||||
/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
|
||||
#define SPI_MSGSIZE(N) \
|
||||
- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
|
||||
+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \
|
||||
? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
|
||||
#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 15 Jul 2017 23:42:36 +0200
|
||||
Subject: use -ffunction-sections, -fdata-sections and --gc-sections
|
||||
|
||||
In combination with kernel symbol export stripping this significantly reduces
|
||||
the kernel image size. Used on both ARM and MIPS architectures.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
---
|
||||
--- a/arch/arm/Kconfig
|
||||
+++ b/arch/arm/Kconfig
|
||||
@@ -122,6 +122,7 @@ config ARM
|
||||
select HAVE_UID16
|
||||
select HAVE_VIRT_CPU_ACCOUNTING_GEN
|
||||
select IRQ_FORCED_THREADING
|
||||
+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||
select MODULES_USE_ELF_REL
|
||||
select NEED_DMA_MAP_STATE
|
||||
select OF_EARLY_FLATTREE if OF
|
||||
--- a/arch/arm/boot/compressed/Makefile
|
||||
+++ b/arch/arm/boot/compressed/Makefile
|
||||
@@ -91,6 +91,7 @@ endif
|
||||
ifeq ($(CONFIG_USE_OF),y)
|
||||
OBJS += $(libfdt_objs) fdt_check_mem_start.o
|
||||
endif
|
||||
+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL))
|
||||
|
||||
OBJS += lib1funcs.o ashldi3.o bswapsdi2.o
|
||||
|
||||
--- a/arch/arm/kernel/vmlinux.lds.S
|
||||
+++ b/arch/arm/kernel/vmlinux.lds.S
|
||||
@@ -75,7 +75,7 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
||||
__start___ex_table = .;
|
||||
- ARM_MMU_KEEP(*(__ex_table))
|
||||
+ KEEP(*(__ex_table))
|
||||
__stop___ex_table = .;
|
||||
}
|
||||
|
||||
@@ -100,24 +100,24 @@ SECTIONS
|
||||
}
|
||||
.init.arch.info : {
|
||||
__arch_info_begin = .;
|
||||
- *(.arch.info.init)
|
||||
+ KEEP(*(.arch.info.init))
|
||||
__arch_info_end = .;
|
||||
}
|
||||
.init.tagtable : {
|
||||
__tagtable_begin = .;
|
||||
- *(.taglist.init)
|
||||
+ KEEP(*(.taglist.init))
|
||||
__tagtable_end = .;
|
||||
}
|
||||
#ifdef CONFIG_SMP_ON_UP
|
||||
.init.smpalt : {
|
||||
__smpalt_begin = .;
|
||||
- *(.alt.smp.init)
|
||||
+ KEEP(*(.alt.smp.init))
|
||||
__smpalt_end = .;
|
||||
}
|
||||
#endif
|
||||
.init.pv_table : {
|
||||
__pv_table_begin = .;
|
||||
- *(.pv_table)
|
||||
+ KEEP(*(.pv_table))
|
||||
__pv_table_end = .;
|
||||
}
|
||||
|
||||
--- a/arch/arm/include/asm/vmlinux.lds.h
|
||||
+++ b/arch/arm/include/asm/vmlinux.lds.h
|
||||
@@ -42,13 +42,13 @@
|
||||
#define PROC_INFO \
|
||||
. = ALIGN(4); \
|
||||
__proc_info_begin = .; \
|
||||
- *(.proc.info.init) \
|
||||
+ KEEP(*(.proc.info.init)) \
|
||||
__proc_info_end = .;
|
||||
|
||||
#define IDMAP_TEXT \
|
||||
ALIGN_FUNCTION(); \
|
||||
__idmap_text_start = .; \
|
||||
- *(.idmap.text) \
|
||||
+ KEEP(*(.idmap.text)) \
|
||||
__idmap_text_end = .; \
|
||||
|
||||
#define ARM_DISCARD \
|
||||
@@ -109,12 +109,12 @@
|
||||
. = ALIGN(8); \
|
||||
.ARM.unwind_idx : { \
|
||||
__start_unwind_idx = .; \
|
||||
- *(.ARM.exidx*) \
|
||||
+ KEEP(*(.ARM.exidx*)) \
|
||||
__stop_unwind_idx = .; \
|
||||
} \
|
||||
.ARM.unwind_tab : { \
|
||||
__start_unwind_tab = .; \
|
||||
- *(.ARM.extab*) \
|
||||
+ KEEP(*(.ARM.extab*)) \
|
||||
__stop_unwind_tab = .; \
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
__vectors_lma = .; \
|
||||
OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \
|
||||
.vectors { \
|
||||
- *(.vectors) \
|
||||
+ KEEP(*(.vectors)) \
|
||||
} \
|
||||
.vectors.bhb.loop8 { \
|
||||
*(.vectors.bhb.loop8) \
|
||||
@@ -144,7 +144,7 @@
|
||||
\
|
||||
__stubs_lma = .; \
|
||||
.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \
|
||||
- *(.stubs) \
|
||||
+ KEEP(*(.stubs)) \
|
||||
} \
|
||||
ARM_LMA(__stubs, .stubs); \
|
||||
. = __stubs_lma + SIZEOF(.stubs); \
|
|
@ -1,126 +0,0 @@
|
|||
From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 7 Jul 2017 17:05:53 +0200
|
||||
Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image
|
||||
|
||||
lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++---
|
||||
include/linux/export.h | 9 ++++++++-
|
||||
scripts/Makefile.build | 2 +-
|
||||
3 files changed, 24 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/include/asm-generic/vmlinux.lds.h
|
||||
+++ b/include/asm-generic/vmlinux.lds.h
|
||||
@@ -81,6 +81,16 @@
|
||||
#define RO_EXCEPTION_TABLE
|
||||
#endif
|
||||
|
||||
+#ifndef SYMTAB_KEEP
|
||||
+#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*)))
|
||||
+#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*)))
|
||||
+#endif
|
||||
+
|
||||
+#ifndef SYMTAB_DISCARD
|
||||
+#define SYMTAB_DISCARD
|
||||
+#define SYMTAB_DISCARD_GPL
|
||||
+#endif
|
||||
+
|
||||
/* Align . to a 8 byte boundary equals to maximum function alignment. */
|
||||
#define ALIGN_FUNCTION() . = ALIGN(8)
|
||||
|
||||
@@ -512,14 +522,14 @@
|
||||
/* Kernel symbol table: Normal symbols */ \
|
||||
__ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
|
||||
__start___ksymtab = .; \
|
||||
- KEEP(*(SORT(___ksymtab+*))) \
|
||||
+ SYMTAB_KEEP \
|
||||
__stop___ksymtab = .; \
|
||||
} \
|
||||
\
|
||||
/* Kernel symbol table: GPL-only symbols */ \
|
||||
__ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
|
||||
__start___ksymtab_gpl = .; \
|
||||
- KEEP(*(SORT(___ksymtab_gpl+*))) \
|
||||
+ SYMTAB_KEEP_GPL \
|
||||
__stop___ksymtab_gpl = .; \
|
||||
} \
|
||||
\
|
||||
@@ -539,7 +549,7 @@
|
||||
\
|
||||
/* Kernel symbol table: strings */ \
|
||||
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
|
||||
- *(__ksymtab_strings) \
|
||||
+ *(__ksymtab_strings+*) \
|
||||
} \
|
||||
\
|
||||
/* __*init sections */ \
|
||||
@@ -1043,6 +1053,8 @@
|
||||
#define COMMON_DISCARDS \
|
||||
SANITIZER_DISCARDS \
|
||||
PATCHABLE_DISCARDS \
|
||||
+ SYMTAB_DISCARD \
|
||||
+ SYMTAB_DISCARD_GPL \
|
||||
*(.discard) \
|
||||
*(.discard.*) \
|
||||
*(.modinfo) \
|
||||
--- a/include/linux/export.h
|
||||
+++ b/include/linux/export.h
|
||||
@@ -72,6 +72,12 @@ struct kernel_symbol {
|
||||
|
||||
#else
|
||||
|
||||
+#ifdef MODULE
|
||||
+#define __EXPORT_SUFFIX(sym)
|
||||
+#else
|
||||
+#define __EXPORT_SUFFIX(sym) "+" #sym
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* For every exported symbol, do the following:
|
||||
*
|
||||
@@ -87,7 +93,7 @@ struct kernel_symbol {
|
||||
extern typeof(sym) sym; \
|
||||
extern const char __kstrtab_##sym[]; \
|
||||
extern const char __kstrtabns_##sym[]; \
|
||||
- asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \
|
||||
+ asm(" .section \"__ksymtab_strings" __EXPORT_SUFFIX(sym) "\",\"aMS\",%progbits,1 \n" \
|
||||
"__kstrtab_" #sym ": \n" \
|
||||
" .asciz \"" #sym "\" \n" \
|
||||
"__kstrtabns_" #sym ": \n" \
|
||||
--- a/include/asm-generic/export.h
|
||||
+++ b/include/asm-generic/export.h
|
||||
@@ -31,6 +31,12 @@
|
||||
#endif
|
||||
.endm
|
||||
|
||||
+#ifdef MODULE
|
||||
+#define __EXPORT_SUFFIX(name)
|
||||
+#else
|
||||
+#define __EXPORT_SUFFIX(name) + #name
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* note on .section use: we specify progbits since usage of the "M" (SHF_MERGE)
|
||||
* section flag requires it. Use '%progbits' instead of '@progbits' since the
|
||||
@@ -44,7 +50,7 @@
|
||||
__ksymtab_\name:
|
||||
__put \val, __kstrtab_\name
|
||||
.previous
|
||||
- .section __ksymtab_strings,"aMS",%progbits,1
|
||||
+ .section __ksymtab_strings __EXPORT_SUFFIX(name),"aMS",%progbits,1
|
||||
__kstrtab_\name:
|
||||
.asciz "\name"
|
||||
.previous
|
||||
--- a/scripts/Makefile.build
|
||||
+++ b/scripts/Makefile.build
|
||||
@@ -388,7 +388,7 @@ targets += $(real-dtb-y) $(lib-y) $(alwa
|
||||
# Linker scripts preprocessor (.lds.S -> .lds)
|
||||
# ---------------------------------------------------------------------------
|
||||
quiet_cmd_cpp_lds_S = LDS $@
|
||||
- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \
|
||||
+ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \
|
||||
-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
|
||||
|
||||
$(obj)/%.lds: $(src)/%.lds.S FORCE
|
|
@ -1,38 +0,0 @@
|
|||
From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001
|
||||
From: Imre Kaloz <kaloz@openwrt.org>
|
||||
Date: Fri, 7 Jul 2017 17:06:55 +0200
|
||||
Subject: use the openwrt lzma options for now
|
||||
|
||||
lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c
|
||||
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
|
||||
---
|
||||
lib/decompress.c | 1 +
|
||||
scripts/Makefile.lib | 2 +-
|
||||
usr/gen_initramfs_list.sh | 10 +++++-----
|
||||
3 files changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/lib/decompress.c
|
||||
+++ b/lib/decompress.c
|
||||
@@ -53,6 +53,7 @@ static const struct compress_format comp
|
||||
{ {0x1f, 0x9e}, "gzip", gunzip },
|
||||
{ {0x42, 0x5a}, "bzip2", bunzip2 },
|
||||
{ {0x5d, 0x00}, "lzma", unlzma },
|
||||
+ { {0x6d, 0x00}, "lzma-openwrt", unlzma },
|
||||
{ {0xfd, 0x37}, "xz", unxz },
|
||||
{ {0x89, 0x4c}, "lzo", unlzo },
|
||||
{ {0x02, 0x21}, "lz4", unlz4 },
|
||||
--- a/scripts/Makefile.lib
|
||||
+++ b/scripts/Makefile.lib
|
||||
@@ -443,10 +443,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
quiet_cmd_lzma = LZMA $@
|
||||
- cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@
|
||||
+ cmd_lzma = cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so > $@
|
||||
|
||||
quiet_cmd_lzma_with_size = LZMA $@
|
||||
- cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
|
||||
+ cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@
|
||||
|
||||
quiet_cmd_lzo = LZO $@
|
||||
cmd_lzo = cat $(real-prereqs) | $(KLZOP) -9 > $@
|
|
@ -1,27 +0,0 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Subject: hack: net: remove bogus netfilter dependencies
|
||||
|
||||
lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
net/netfilter/Kconfig | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -253,7 +253,6 @@ config NF_CONNTRACK_FTP
|
||||
|
||||
config NF_CONNTRACK_H323
|
||||
tristate "H.323 protocol support"
|
||||
- depends on IPV6 || IPV6=n
|
||||
depends on NETFILTER_ADVANCED
|
||||
help
|
||||
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
|
||||
@@ -1118,7 +1117,6 @@ config NETFILTER_XT_TARGET_SECMARK
|
||||
|
||||
config NETFILTER_XT_TARGET_TCPMSS
|
||||
tristate '"TCPMSS" target support'
|
||||
- depends on IPV6 || IPV6=n
|
||||
default m if NETFILTER_ADVANCED=n
|
||||
help
|
||||
This option adds a `TCPMSS' target, which allows you to alter the
|
|
@ -1,199 +0,0 @@
|
|||
From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Fri, 7 Jul 2017 17:09:21 +0200
|
||||
Subject: kconfig: owrt specifc dependencies
|
||||
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
---
|
||||
crypto/Kconfig | 10 +++++-----
|
||||
drivers/bcma/Kconfig | 1 +
|
||||
drivers/ssb/Kconfig | 3 ++-
|
||||
lib/Kconfig | 8 ++++----
|
||||
net/netfilter/Kconfig | 2 +-
|
||||
net/wireless/Kconfig | 17 ++++++++++-------
|
||||
sound/core/Kconfig | 4 ++--
|
||||
7 files changed, 25 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/crypto/Kconfig
|
||||
+++ b/crypto/Kconfig
|
||||
@@ -55,7 +55,7 @@ config CRYPTO_FIPS_VERSION
|
||||
By default the KERNELRELEASE value is used.
|
||||
|
||||
config CRYPTO_ALGAPI
|
||||
- tristate
|
||||
+ tristate "ALGAPI"
|
||||
select CRYPTO_ALGAPI2
|
||||
help
|
||||
This option provides the API for cryptographic algorithms.
|
||||
@@ -64,7 +64,7 @@ config CRYPTO_ALGAPI2
|
||||
tristate
|
||||
|
||||
config CRYPTO_AEAD
|
||||
- tristate
|
||||
+ tristate "AEAD"
|
||||
select CRYPTO_AEAD2
|
||||
select CRYPTO_ALGAPI
|
||||
|
||||
@@ -75,7 +75,7 @@ config CRYPTO_AEAD2
|
||||
select CRYPTO_RNG2
|
||||
|
||||
config CRYPTO_SKCIPHER
|
||||
- tristate
|
||||
+ tristate "SKCIPHER"
|
||||
select CRYPTO_SKCIPHER2
|
||||
select CRYPTO_ALGAPI
|
||||
|
||||
@@ -85,7 +85,7 @@ config CRYPTO_SKCIPHER2
|
||||
select CRYPTO_RNG2
|
||||
|
||||
config CRYPTO_HASH
|
||||
- tristate
|
||||
+ tristate "HASH"
|
||||
select CRYPTO_HASH2
|
||||
select CRYPTO_ALGAPI
|
||||
|
||||
@@ -94,7 +94,7 @@ config CRYPTO_HASH2
|
||||
select CRYPTO_ALGAPI2
|
||||
|
||||
config CRYPTO_RNG
|
||||
- tristate
|
||||
+ tristate "RNG"
|
||||
select CRYPTO_RNG2
|
||||
select CRYPTO_ALGAPI
|
||||
|
||||
--- a/drivers/bcma/Kconfig
|
||||
+++ b/drivers/bcma/Kconfig
|
||||
@@ -16,6 +16,7 @@ if BCMA
|
||||
# Support for Block-I/O. SELECT this from the driver that needs it.
|
||||
config BCMA_BLOCKIO
|
||||
bool
|
||||
+ default y
|
||||
|
||||
config BCMA_HOST_PCI_POSSIBLE
|
||||
bool
|
||||
--- a/drivers/ssb/Kconfig
|
||||
+++ b/drivers/ssb/Kconfig
|
||||
@@ -29,6 +29,7 @@ config SSB_SPROM
|
||||
config SSB_BLOCKIO
|
||||
bool
|
||||
depends on SSB
|
||||
+ default y
|
||||
|
||||
config SSB_PCIHOST_POSSIBLE
|
||||
bool
|
||||
@@ -49,7 +50,7 @@ config SSB_PCIHOST
|
||||
config SSB_B43_PCI_BRIDGE
|
||||
bool
|
||||
depends on SSB_PCIHOST
|
||||
- default n
|
||||
+ default y
|
||||
|
||||
config SSB_PCMCIAHOST_POSSIBLE
|
||||
bool
|
||||
--- a/lib/Kconfig
|
||||
+++ b/lib/Kconfig
|
||||
@@ -457,16 +457,16 @@ config BCH_CONST_T
|
||||
# Textsearch support is select'ed if needed
|
||||
#
|
||||
config TEXTSEARCH
|
||||
- bool
|
||||
+ bool "Textsearch support"
|
||||
|
||||
config TEXTSEARCH_KMP
|
||||
- tristate
|
||||
+ tristate "Textsearch KMP"
|
||||
|
||||
config TEXTSEARCH_BM
|
||||
- tristate
|
||||
+ tristate "Textsearch BM"
|
||||
|
||||
config TEXTSEARCH_FSM
|
||||
- tristate
|
||||
+ tristate "Textsearch FSM"
|
||||
|
||||
config BTREE
|
||||
bool
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -22,7 +22,7 @@ config NETFILTER_SKIP_EGRESS
|
||||
def_bool NETFILTER_EGRESS && (NET_CLS_ACT || IFB)
|
||||
|
||||
config NETFILTER_NETLINK
|
||||
- tristate
|
||||
+ tristate "Netfilter NFNETLINK interface"
|
||||
|
||||
config NETFILTER_FAMILY_BRIDGE
|
||||
bool
|
||||
--- a/net/wireless/Kconfig
|
||||
+++ b/net/wireless/Kconfig
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config WIRELESS_EXT
|
||||
- bool
|
||||
+ bool "Wireless extensions"
|
||||
|
||||
config WEXT_CORE
|
||||
def_bool y
|
||||
@@ -12,10 +12,10 @@ config WEXT_PROC
|
||||
depends on WEXT_CORE
|
||||
|
||||
config WEXT_SPY
|
||||
- bool
|
||||
+ bool "WEXT_SPY"
|
||||
|
||||
config WEXT_PRIV
|
||||
- bool
|
||||
+ bool "WEXT_PRIV"
|
||||
|
||||
config CFG80211
|
||||
tristate "cfg80211 - wireless configuration API"
|
||||
@@ -208,7 +208,7 @@ config CFG80211_WEXT_EXPORT
|
||||
endif # CFG80211
|
||||
|
||||
config LIB80211
|
||||
- tristate
|
||||
+ tristate "LIB80211"
|
||||
default n
|
||||
help
|
||||
This options enables a library of common routines used
|
||||
@@ -217,17 +217,17 @@ config LIB80211
|
||||
Drivers should select this themselves if needed.
|
||||
|
||||
config LIB80211_CRYPT_WEP
|
||||
- tristate
|
||||
+ tristate "LIB80211_CRYPT_WEP"
|
||||
select CRYPTO_LIB_ARC4
|
||||
|
||||
config LIB80211_CRYPT_CCMP
|
||||
- tristate
|
||||
+ tristate "LIB80211_CRYPT_CCMP"
|
||||
select CRYPTO
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_CCM
|
||||
|
||||
config LIB80211_CRYPT_TKIP
|
||||
- tristate
|
||||
+ tristate "LIB80211_CRYPT_TKIP"
|
||||
select CRYPTO_LIB_ARC4
|
||||
|
||||
config LIB80211_DEBUG
|
||||
--- a/sound/core/Kconfig
|
||||
+++ b/sound/core/Kconfig
|
||||
@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM
|
||||
tristate
|
||||
|
||||
config SND_HWDEP
|
||||
- tristate
|
||||
+ tristate "Sound hardware support"
|
||||
|
||||
config SND_SEQ_DEVICE
|
||||
tristate
|
||||
@@ -27,7 +27,7 @@ config SND_RAWMIDI
|
||||
select SND_SEQ_DEVICE if SND_SEQUENCER != n
|
||||
|
||||
config SND_COMPRESS_OFFLOAD
|
||||
- tristate
|
||||
+ tristate "Compression offloading support"
|
||||
|
||||
config SND_JACK
|
||||
bool
|
|
@ -1,32 +0,0 @@
|
|||
From dcd966fa7ca63f38cf7147e1184d13d66e2ca340 Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:33:30 +0200
|
||||
Subject: [PATCH] Kconfig: add tristate for OID and ASNI string
|
||||
|
||||
---
|
||||
init/Kconfig | 2 +-
|
||||
lib/Kconfig | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/init/Kconfig
|
||||
+++ b/init/Kconfig
|
||||
@@ -2003,7 +2003,7 @@ config PADATA
|
||||
bool
|
||||
|
||||
config ASN1
|
||||
- tristate
|
||||
+ tristate "ASN1"
|
||||
help
|
||||
Build a simple ASN.1 grammar compiler that produces a bytecode output
|
||||
that can be interpreted by the ASN.1 stream decoder and used to
|
||||
--- a/lib/Kconfig
|
||||
+++ b/lib/Kconfig
|
||||
@@ -637,7 +637,7 @@ config LIBFDT
|
||||
bool
|
||||
|
||||
config OID_REGISTRY
|
||||
- tristate
|
||||
+ tristate "OID"
|
||||
help
|
||||
Enable fast lookup object identifier registry.
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 15 Jul 2017 21:12:38 +0200
|
||||
Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules
|
||||
|
||||
lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
drivers/base/regmap/Kconfig | 15 ++++++++++-----
|
||||
drivers/base/regmap/Makefile | 12 ++++++++----
|
||||
drivers/base/regmap/regmap.c | 3 +++
|
||||
include/linux/regmap.h | 2 +-
|
||||
4 files changed, 22 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/base/regmap/Kconfig
|
||||
+++ b/drivers/base/regmap/Kconfig
|
||||
@@ -4,10 +4,9 @@
|
||||
# subsystems should select the appropriate symbols.
|
||||
|
||||
config REGMAP
|
||||
- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO)
|
||||
select IRQ_DOMAIN if REGMAP_IRQ
|
||||
select MDIO_BUS if REGMAP_MDIO
|
||||
- bool
|
||||
+ tristate
|
||||
|
||||
config REGCACHE_COMPRESSED
|
||||
select LZO_COMPRESS
|
||||
@@ -15,53 +14,67 @@ config REGCACHE_COMPRESSED
|
||||
bool
|
||||
|
||||
config REGMAP_AC97
|
||||
+ select REGMAP
|
||||
tristate
|
||||
|
||||
config REGMAP_I2C
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on I2C
|
||||
|
||||
config REGMAP_SLIMBUS
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on SLIMBUS
|
||||
|
||||
config REGMAP_SPI
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on SPI
|
||||
|
||||
config REGMAP_SPMI
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on SPMI
|
||||
|
||||
config REGMAP_W1
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on W1
|
||||
|
||||
config REGMAP_MDIO
|
||||
+ select REGMAP
|
||||
tristate
|
||||
|
||||
config REGMAP_MMIO
|
||||
+ select REGMAP
|
||||
tristate
|
||||
|
||||
config REGMAP_IRQ
|
||||
+ select REGMAP
|
||||
bool
|
||||
|
||||
config REGMAP_SOUNDWIRE
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on SOUNDWIRE
|
||||
|
||||
config REGMAP_SOUNDWIRE_MBQ
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on SOUNDWIRE
|
||||
|
||||
config REGMAP_SCCB
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on I2C
|
||||
|
||||
config REGMAP_I3C
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on I3C
|
||||
|
||||
config REGMAP_SPI_AVMM
|
||||
+ select REGMAP
|
||||
tristate
|
||||
depends on SPI
|
||||
--- a/drivers/base/regmap/Makefile
|
||||
+++ b/drivers/base/regmap/Makefile
|
||||
@@ -2,10 +2,14 @@
|
||||
# For include/trace/define_trace.h to include trace.h
|
||||
CFLAGS_regmap.o := -I$(src)
|
||||
|
||||
-obj-$(CONFIG_REGMAP) += regmap.o regcache.o
|
||||
-obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o
|
||||
-obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o
|
||||
-obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
|
||||
+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o
|
||||
+ifdef CONFIG_DEBUG_FS
|
||||
+regmap-core-objs += regmap-debugfs.o
|
||||
+endif
|
||||
+ifdef CONFIG_REGCACHE_COMPRESSED
|
||||
+regmap-core-objs += regcache-lzo.o
|
||||
+endif
|
||||
+obj-$(CONFIG_REGMAP) += regmap-core.o
|
||||
obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
|
||||
obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
|
||||
obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o
|
||||
--- a/drivers/base/regmap/regmap.c
|
||||
+++ b/drivers/base/regmap/regmap.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/export.h>
|
||||
+#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/property.h>
|
||||
@@ -3505,3 +3506,5 @@ static int __init regmap_initcall(void)
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(regmap_initcall);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/include/linux/regmap.h
|
||||
+++ b/include/linux/regmap.h
|
||||
@@ -180,7 +180,7 @@ struct reg_sequence {
|
||||
__ret ?: __tmp; \
|
||||
})
|
||||
|
||||
-#ifdef CONFIG_REGMAP
|
||||
+#if IS_REACHABLE(CONFIG_REGMAP)
|
||||
|
||||
enum regmap_endian {
|
||||
/* Unspecified -> 0 -> Backwards compatible default */
|
|
@ -1,52 +0,0 @@
|
|||
From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 7 Jul 2017 17:12:51 +0200
|
||||
Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run
|
||||
|
||||
Reduces kernel size after LZMA by about 5k on MIPS
|
||||
|
||||
lede-commit: 044c316167e076479a344c59905e5b435b84a77f
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
crypto/Kconfig | 13 ++++++-------
|
||||
crypto/algboss.c | 4 ++++
|
||||
2 files changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/crypto/Kconfig
|
||||
+++ b/crypto/Kconfig
|
||||
@@ -142,13 +142,13 @@ config CRYPTO_MANAGER
|
||||
cbc(aes).
|
||||
|
||||
config CRYPTO_MANAGER2
|
||||
- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y)
|
||||
- select CRYPTO_AEAD2
|
||||
- select CRYPTO_HASH2
|
||||
- select CRYPTO_SKCIPHER2
|
||||
- select CRYPTO_AKCIPHER2
|
||||
- select CRYPTO_KPP2
|
||||
- select CRYPTO_ACOMP2
|
||||
+ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS)
|
||||
+ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS
|
||||
+ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS
|
||||
+ select CRYPTO_SKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS
|
||||
+ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS
|
||||
+ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS
|
||||
+ select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS
|
||||
|
||||
config CRYPTO_USER
|
||||
tristate "Userspace cryptographic algorithm configuration"
|
||||
--- a/crypto/algboss.c
|
||||
+++ b/crypto/algboss.c
|
||||
@@ -211,8 +211,12 @@ static int cryptomgr_schedule_test(struc
|
||||
type = alg->cra_flags;
|
||||
|
||||
/* Do not test internal algorithms. */
|
||||
+#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
|
||||
+ type |= CRYPTO_ALG_TESTED;
|
||||
+#else
|
||||
if (type & CRYPTO_ALG_INTERNAL)
|
||||
type |= CRYPTO_ALG_TESTED;
|
||||
+#endif
|
||||
|
||||
param->type = type;
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
From 241e5d3f7b0dd3c01f8c7fa83cbc9a3882286d53 Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:35:18 +0200
|
||||
Subject: [PATCH] lib/crypto: add tristate string for ARC4
|
||||
|
||||
This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We
|
||||
need this to be able to compile this into the kernel and make use of it
|
||||
from backports.
|
||||
|
||||
---
|
||||
lib/crypto/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/lib/crypto/Kconfig
|
||||
+++ b/lib/crypto/Kconfig
|
||||
@@ -9,7 +9,7 @@ config CRYPTO_LIB_AES
|
||||
tristate
|
||||
|
||||
config CRYPTO_LIB_ARC4
|
||||
- tristate
|
||||
+ tristate "ARC4 cipher library"
|
||||
|
||||
config CRYPTO_ARCH_HAVE_LIB_BLAKE2S
|
||||
bool
|
|
@ -1,84 +0,0 @@
|
|||
From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Fri, 7 Jul 2017 17:13:44 +0200
|
||||
Subject: rfkill: add fake rfkill support
|
||||
|
||||
allow building of modules depending on RFKILL even if RFKILL is not enabled.
|
||||
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
---
|
||||
include/linux/rfkill.h | 2 +-
|
||||
net/Makefile | 2 +-
|
||||
net/rfkill/Kconfig | 14 +++++++++-----
|
||||
net/rfkill/Makefile | 2 +-
|
||||
4 files changed, 12 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/include/linux/rfkill.h
|
||||
+++ b/include/linux/rfkill.h
|
||||
@@ -64,7 +64,7 @@ struct rfkill_ops {
|
||||
int (*set_block)(void *data, bool blocked);
|
||||
};
|
||||
|
||||
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
|
||||
+#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE)
|
||||
/**
|
||||
* rfkill_alloc - Allocate rfkill structure
|
||||
* @name: name of the struct -- the string is not copied internally
|
||||
--- a/net/Makefile
|
||||
+++ b/net/Makefile
|
||||
@@ -51,7 +51,7 @@ obj-$(CONFIG_TIPC) += tipc/
|
||||
obj-$(CONFIG_NETLABEL) += netlabel/
|
||||
obj-$(CONFIG_IUCV) += iucv/
|
||||
obj-$(CONFIG_SMC) += smc/
|
||||
-obj-$(CONFIG_RFKILL) += rfkill/
|
||||
+obj-$(CONFIG_RFKILL_FULL) += rfkill/
|
||||
obj-$(CONFIG_NET_9P) += 9p/
|
||||
obj-$(CONFIG_CAIF) += caif/
|
||||
obj-$(CONFIG_DCB) += dcb/
|
||||
--- a/net/rfkill/Kconfig
|
||||
+++ b/net/rfkill/Kconfig
|
||||
@@ -2,7 +2,11 @@
|
||||
#
|
||||
# RF switch subsystem configuration
|
||||
#
|
||||
-menuconfig RFKILL
|
||||
+config RFKILL
|
||||
+ bool
|
||||
+ default y
|
||||
+
|
||||
+menuconfig RFKILL_FULL
|
||||
tristate "RF switch subsystem support"
|
||||
help
|
||||
Say Y here if you want to have control over RF switches
|
||||
@@ -14,19 +18,19 @@ menuconfig RFKILL
|
||||
# LED trigger support
|
||||
config RFKILL_LEDS
|
||||
bool
|
||||
- depends on RFKILL
|
||||
+ depends on RFKILL_FULL
|
||||
depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS
|
||||
default y
|
||||
|
||||
config RFKILL_INPUT
|
||||
bool "RF switch input support" if EXPERT
|
||||
- depends on RFKILL
|
||||
+ depends on RFKILL_FULL
|
||||
depends on INPUT = y || RFKILL = INPUT
|
||||
default y if !EXPERT
|
||||
|
||||
config RFKILL_GPIO
|
||||
tristate "GPIO RFKILL driver"
|
||||
- depends on RFKILL
|
||||
+ depends on RFKILL_FULL
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
default n
|
||||
help
|
||||
--- a/net/rfkill/Makefile
|
||||
+++ b/net/rfkill/Makefile
|
||||
@@ -5,5 +5,5 @@
|
||||
|
||||
rfkill-y += core.o
|
||||
rfkill-$(CONFIG_RFKILL_INPUT) += input.o
|
||||
-obj-$(CONFIG_RFKILL) += rfkill.o
|
||||
+obj-$(CONFIG_RFKILL_FULL) += rfkill.o
|
||||
obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o
|
|
@ -1,64 +0,0 @@
|
|||
From: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
|
||||
Date: Fri, 7 Jun 2013 18:35:22 -0500
|
||||
Subject: MIPS: r4k_cache: use more efficient cache blast
|
||||
|
||||
Optimize the compiler output for larger cache blast cases that are
|
||||
common for DMA-based networking.
|
||||
|
||||
Signed-off-by: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
--- a/arch/mips/include/asm/r4kcache.h
|
||||
+++ b/arch/mips/include/asm/r4kcache.h
|
||||
@@ -286,14 +286,46 @@ static inline void prot##extra##blast_##
|
||||
unsigned long end) \
|
||||
{ \
|
||||
unsigned long lsize = cpu_##desc##_line_size(); \
|
||||
+ unsigned long lsize_2 = lsize * 2; \
|
||||
+ unsigned long lsize_3 = lsize * 3; \
|
||||
+ unsigned long lsize_4 = lsize * 4; \
|
||||
+ unsigned long lsize_5 = lsize * 5; \
|
||||
+ unsigned long lsize_6 = lsize * 6; \
|
||||
+ unsigned long lsize_7 = lsize * 7; \
|
||||
+ unsigned long lsize_8 = lsize * 8; \
|
||||
unsigned long addr = start & ~(lsize - 1); \
|
||||
- unsigned long aend = (end - 1) & ~(lsize - 1); \
|
||||
+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \
|
||||
+ int lines = (aend - addr) / lsize; \
|
||||
\
|
||||
- while (1) { \
|
||||
+ while (lines >= 8) { \
|
||||
+ prot##cache_op(hitop, addr); \
|
||||
+ prot##cache_op(hitop, addr + lsize); \
|
||||
+ prot##cache_op(hitop, addr + lsize_2); \
|
||||
+ prot##cache_op(hitop, addr + lsize_3); \
|
||||
+ prot##cache_op(hitop, addr + lsize_4); \
|
||||
+ prot##cache_op(hitop, addr + lsize_5); \
|
||||
+ prot##cache_op(hitop, addr + lsize_6); \
|
||||
+ prot##cache_op(hitop, addr + lsize_7); \
|
||||
+ addr += lsize_8; \
|
||||
+ lines -= 8; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (lines & 0x4) { \
|
||||
+ prot##cache_op(hitop, addr); \
|
||||
+ prot##cache_op(hitop, addr + lsize); \
|
||||
+ prot##cache_op(hitop, addr + lsize_2); \
|
||||
+ prot##cache_op(hitop, addr + lsize_3); \
|
||||
+ addr += lsize_4; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (lines & 0x2) { \
|
||||
+ prot##cache_op(hitop, addr); \
|
||||
+ prot##cache_op(hitop, addr + lsize); \
|
||||
+ addr += lsize_2; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (lines & 0x1) { \
|
||||
prot##cache_op(hitop, addr); \
|
||||
- if (addr == aend) \
|
||||
- break; \
|
||||
- addr += lsize; \
|
||||
} \
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
From 107c0964cb8db7ca28ac5199426414fdab3c274d Mon Sep 17 00:00:00 2001
|
||||
From: "Alexandros C. Couloumbis" <alex@ozo.com>
|
||||
Date: Fri, 7 Jul 2017 17:14:51 +0200
|
||||
Subject: hack: arch: powerpc: drop register save/restore library from modules
|
||||
|
||||
Upstream GCC uses a libgcc function for saving/restoring registers. This
|
||||
makes the code bigger, and upstream kernels need to carry that function
|
||||
for every single kernel module. Our GCC is patched to avoid those
|
||||
references, so we can drop the extra bloat for modules.
|
||||
|
||||
lede-commit: e8e1084654f50904e6bf77b70b2de3f137d7b3ec
|
||||
Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com>
|
||||
---
|
||||
arch/powerpc/Makefile | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/arch/powerpc/Makefile
|
||||
+++ b/arch/powerpc/Makefile
|
||||
@@ -42,19 +42,6 @@ machine-$(CONFIG_PPC64) += 64
|
||||
machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le
|
||||
UTS_MACHINE := $(subst $(space),,$(machine-y))
|
||||
|
||||
-# XXX This needs to be before we override LD below
|
||||
-ifdef CONFIG_PPC32
|
||||
-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
|
||||
-else
|
||||
-ifeq ($(call ld-ifversion, -ge, 22500, y),y)
|
||||
-# Have the linker provide sfpr if possible.
|
||||
-# There is a corresponding test in arch/powerpc/lib/Makefile
|
||||
-KBUILD_LDFLAGS_MODULE += --save-restore-funcs
|
||||
-else
|
||||
-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
|
||||
-endif
|
||||
-endif
|
||||
-
|
||||
ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
KBUILD_CFLAGS += -mlittle-endian
|
||||
KBUILD_LDFLAGS += -EL
|
|
@ -1,112 +0,0 @@
|
|||
From 0bccc3722bdd88e8ae995e77ef9f7b77ee4cbdee Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 7 Apr 2021 22:45:54 +0100
|
||||
Subject: [PATCH 2/2] mtd: blktrans: call add disks after mtd device
|
||||
To: linux-mtd@lists.infradead.org
|
||||
Cc: Vignesh Raghavendra <vigneshr@ti.com>,
|
||||
Richard Weinberger <richard@nod.at>,
|
||||
Miquel Raynal <miquel.raynal@bootlin.com>,
|
||||
David Woodhouse <dwmw2@infradead.org>
|
||||
|
||||
Calling device_add_disk while holding mtd_table_mutex leads
|
||||
to deadlock in case part_bits!=0 as block partition parsers
|
||||
will try to open the newly created disks, trying to acquire
|
||||
mutex once again.
|
||||
Move device_add_disk to additional function called after
|
||||
add partitions of an MTD device have been added and locks
|
||||
have been released.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/mtd/mtd_blkdevs.c | 33 ++++++++++++++++++++++++++-------
|
||||
drivers/mtd/mtdcore.c | 3 +++
|
||||
include/linux/mtd/blktrans.h | 1 +
|
||||
3 files changed, 30 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/mtd_blkdevs.c
|
||||
+++ b/drivers/mtd/mtd_blkdevs.c
|
||||
@@ -386,19 +386,8 @@ int add_mtd_blktrans_dev(struct mtd_blkt
|
||||
if (new->readonly)
|
||||
set_disk_ro(gd, 1);
|
||||
|
||||
- ret = device_add_disk(&new->mtd->dev, gd, NULL);
|
||||
- if (ret)
|
||||
- goto out_cleanup_disk;
|
||||
-
|
||||
- if (new->disk_attributes) {
|
||||
- ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
|
||||
- new->disk_attributes);
|
||||
- WARN_ON(ret);
|
||||
- }
|
||||
return 0;
|
||||
|
||||
-out_cleanup_disk:
|
||||
- put_disk(new->disk);
|
||||
out_free_tag_set:
|
||||
blk_mq_free_tag_set(new->tag_set);
|
||||
out_kfree_tag_set:
|
||||
@@ -408,6 +397,35 @@ out_list_del:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+void register_mtd_blktrans_devs(void)
|
||||
+{
|
||||
+ struct mtd_blktrans_ops *tr;
|
||||
+ struct mtd_blktrans_dev *dev, *next;
|
||||
+ int ret;
|
||||
+
|
||||
+ list_for_each_entry(tr, &blktrans_majors, list) {
|
||||
+ list_for_each_entry_safe(dev, next, &tr->devs, list) {
|
||||
+ if (disk_live(dev->disk))
|
||||
+ continue;
|
||||
+
|
||||
+ ret = device_add_disk(&dev->mtd->dev, dev->disk, NULL);
|
||||
+ if (ret)
|
||||
+ goto out_cleanup_disk;
|
||||
+
|
||||
+ if (dev->disk_attributes) {
|
||||
+ ret = sysfs_create_group(&disk_to_dev(dev->disk)->kobj,
|
||||
+ dev->disk_attributes);
|
||||
+ WARN_ON(ret);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+
|
||||
+out_cleanup_disk:
|
||||
+ put_disk(dev->disk);
|
||||
+}
|
||||
+
|
||||
int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
|
||||
{
|
||||
unsigned long flags;
|
||||
--- a/drivers/mtd/mtdcore.c
|
||||
+++ b/drivers/mtd/mtdcore.c
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
+#include <linux/mtd/blktrans.h>
|
||||
|
||||
#include "mtdcore.h"
|
||||
|
||||
@@ -1057,6 +1058,8 @@ int mtd_device_parse_register(struct mtd
|
||||
|
||||
ret = mtd_otp_nvmem_add(mtd);
|
||||
|
||||
+ register_mtd_blktrans_devs();
|
||||
+
|
||||
out:
|
||||
if (ret && device_is_registered(&mtd->dev))
|
||||
del_mtd_device(mtd);
|
||||
--- a/include/linux/mtd/blktrans.h
|
||||
+++ b/include/linux/mtd/blktrans.h
|
||||
@@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struc
|
||||
extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
|
||||
extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
|
||||
extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev);
|
||||
+extern void register_mtd_blktrans_devs(void);
|
||||
|
||||
/**
|
||||
* module_mtd_blktrans() - Helper macro for registering a mtd blktrans driver
|
|
@ -1,191 +0,0 @@
|
|||
From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:37:33 +0200
|
||||
Subject: [PATCH] kernel: add block fit partition parser
|
||||
|
||||
---
|
||||
block/blk.h | 2 ++
|
||||
block/partitions/Kconfig | 7 +++++++
|
||||
block/partitions/Makefile | 1 +
|
||||
block/partitions/check.h | 3 +++
|
||||
block/partitions/core.c | 17 +++++++++++++++++
|
||||
block/partitions/efi.c | 8 ++++++++
|
||||
block/partitions/efi.h | 3 +++
|
||||
block/partitions/msdos.c | 10 ++++++++++
|
||||
drivers/mtd/mtd_blkdevs.c | 2 ++
|
||||
drivers/mtd/ubi/block.c | 3 +++
|
||||
include/linux/msdos_partition.h | 1 +
|
||||
11 files changed, 57 insertions(+)
|
||||
|
||||
--- a/block/blk.h
|
||||
+++ b/block/blk.h
|
||||
@@ -414,6 +414,8 @@ void blk_free_ext_minor(unsigned int min
|
||||
#define ADDPART_FLAG_NONE 0
|
||||
#define ADDPART_FLAG_RAID 1
|
||||
#define ADDPART_FLAG_WHOLEDISK 2
|
||||
+#define ADDPART_FLAG_READONLY 4
|
||||
+#define ADDPART_FLAG_ROOTDEV 8
|
||||
int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
|
||||
sector_t length);
|
||||
int bdev_del_partition(struct gendisk *disk, int partno);
|
||||
--- a/block/partitions/Kconfig
|
||||
+++ b/block/partitions/Kconfig
|
||||
@@ -103,6 +103,13 @@ config ATARI_PARTITION
|
||||
Say Y here if you would like to use hard disks under Linux which
|
||||
were partitioned under the Atari OS.
|
||||
|
||||
+config FIT_PARTITION
|
||||
+ bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
|
||||
+ default n
|
||||
+ help
|
||||
+ Say Y here if your system needs to mount the filesystem part of
|
||||
+ a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
|
||||
+
|
||||
config IBM_PARTITION
|
||||
bool "IBM disk label and partition support"
|
||||
depends on PARTITION_ADVANCED && S390
|
||||
--- a/block/partitions/Makefile
|
||||
+++ b/block/partitions/Makefile
|
||||
@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
|
||||
obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
|
||||
obj-$(CONFIG_ATARI_PARTITION) += atari.o
|
||||
obj-$(CONFIG_AIX_PARTITION) += aix.o
|
||||
+obj-$(CONFIG_FIT_PARTITION) += fit.o
|
||||
obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
|
||||
obj-$(CONFIG_MAC_PARTITION) += mac.o
|
||||
obj-$(CONFIG_LDM_PARTITION) += ldm.o
|
||||
--- a/block/partitions/check.h
|
||||
+++ b/block/partitions/check.h
|
||||
@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partit
|
||||
int atari_partition(struct parsed_partitions *state);
|
||||
int cmdline_partition(struct parsed_partitions *state);
|
||||
int efi_partition(struct parsed_partitions *state);
|
||||
+int fit_partition(struct parsed_partitions *state);
|
||||
int ibm_partition(struct parsed_partitions *);
|
||||
int karma_partition(struct parsed_partitions *state);
|
||||
int ldm_partition(struct parsed_partitions *state);
|
||||
@@ -67,3 +68,5 @@ int sgi_partition(struct parsed_partitio
|
||||
int sun_partition(struct parsed_partitions *state);
|
||||
int sysv68_partition(struct parsed_partitions *state);
|
||||
int ultrix_partition(struct parsed_partitions *state);
|
||||
+
|
||||
+int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain);
|
||||
--- a/block/partitions/core.c
|
||||
+++ b/block/partitions/core.c
|
||||
@@ -10,6 +10,10 @@
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/raid/detect.h>
|
||||
+#ifdef CONFIG_FIT_PARTITION
|
||||
+#include <linux/root_dev.h>
|
||||
+#endif
|
||||
+
|
||||
#include "check.h"
|
||||
|
||||
static int (*check_part[])(struct parsed_partitions *) = {
|
||||
@@ -46,6 +50,9 @@ static int (*check_part[])(struct parsed
|
||||
#ifdef CONFIG_EFI_PARTITION
|
||||
efi_partition, /* this must come before msdos */
|
||||
#endif
|
||||
+#ifdef CONFIG_FIT_PARTITION
|
||||
+ fit_partition,
|
||||
+#endif
|
||||
#ifdef CONFIG_SGI_PARTITION
|
||||
sgi_partition,
|
||||
#endif
|
||||
@@ -398,6 +405,11 @@ static struct block_device *add_partitio
|
||||
goto out_del;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_FIT_PARTITION
|
||||
+ if (flags & ADDPART_FLAG_READONLY)
|
||||
+ bdev->bd_read_only = true;
|
||||
+#endif
|
||||
+
|
||||
/* everything is up and running, commence */
|
||||
err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
|
||||
if (err)
|
||||
@@ -585,6 +597,11 @@ static bool blk_add_partition(struct gen
|
||||
(state->parts[p].flags & ADDPART_FLAG_RAID))
|
||||
md_autodetect_dev(part->bd_dev);
|
||||
|
||||
+#ifdef CONFIG_FIT_PARTITION
|
||||
+ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0)
|
||||
+ ROOT_DEV = part->bd_dev;
|
||||
+#endif
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
--- a/block/partitions/efi.c
|
||||
+++ b/block/partitions/efi.c
|
||||
@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio
|
||||
gpt_entry *ptes = NULL;
|
||||
u32 i;
|
||||
unsigned ssz = queue_logical_block_size(state->disk->queue) / 512;
|
||||
+#ifdef CONFIG_FIT_PARTITION
|
||||
+ u32 extra_slot = 64;
|
||||
+#endif
|
||||
|
||||
if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
|
||||
kfree(gpt);
|
||||
@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio
|
||||
ARRAY_SIZE(ptes[i].partition_name));
|
||||
utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
|
||||
state->parts[i + 1].has_info = true;
|
||||
+#ifdef CONFIG_FIT_PARTITION
|
||||
+ /* If this is a U-Boot FIT volume it may have subpartitions */
|
||||
+ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
|
||||
+ (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
|
||||
+#endif
|
||||
}
|
||||
kfree(ptes);
|
||||
kfree(gpt);
|
||||
--- a/block/partitions/efi.h
|
||||
+++ b/block/partitions/efi.h
|
||||
@@ -51,6 +51,9 @@
|
||||
#define PARTITION_LINUX_LVM_GUID \
|
||||
EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
|
||||
0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
|
||||
+#define PARTITION_LINUX_FIT_GUID \
|
||||
+ EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
|
||||
+ 0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
|
||||
|
||||
typedef struct _gpt_header {
|
||||
__le64 signature;
|
||||
--- a/block/partitions/msdos.c
|
||||
+++ b/block/partitions/msdos.c
|
||||
@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa
|
||||
#endif /* CONFIG_MINIX_SUBPARTITION */
|
||||
}
|
||||
|
||||
+static void parse_fit_mbr(struct parsed_partitions *state,
|
||||
+ sector_t offset, sector_t size, int origin)
|
||||
+{
|
||||
+#ifdef CONFIG_FIT_PARTITION
|
||||
+ u32 extra_slot = 64;
|
||||
+ (void) parse_fit_partitions(state, offset, size, &extra_slot, 1);
|
||||
+#endif /* CONFIG_FIT_PARTITION */
|
||||
+}
|
||||
+
|
||||
static struct {
|
||||
unsigned char id;
|
||||
void (*parse)(struct parsed_partitions *, sector_t, sector_t, int);
|
||||
@@ -575,6 +584,7 @@ static struct {
|
||||
{UNIXWARE_PARTITION, parse_unixware},
|
||||
{SOLARIS_X86_PARTITION, parse_solaris_x86},
|
||||
{NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
|
||||
+ {FIT_PARTITION, parse_fit_mbr},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
--- a/include/linux/msdos_partition.h
|
||||
+++ b/include/linux/msdos_partition.h
|
||||
@@ -31,6 +31,7 @@ enum msdos_sys_ind {
|
||||
LINUX_LVM_PARTITION = 0x8e,
|
||||
LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */
|
||||
|
||||
+ FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */
|
||||
SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */
|
||||
NEW_SOLARIS_X86_PARTITION = 0xbf,
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
From: Gabor Juhos <juhosg@openwrt.org>
|
||||
Subject: kernel/3.1[02]: move MTD root device setup code to mtdcore
|
||||
|
||||
The current code only allows to automatically set
|
||||
root device on MTD partitions. Move the code to MTD
|
||||
core to allow to use it with all MTD devices.
|
||||
|
||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
---
|
||||
drivers/mtd/mtdcore.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/mtdcore.c
|
||||
+++ b/drivers/mtd/mtdcore.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/debugfs.h>
|
||||
+#include <linux/root_dev.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
@@ -751,6 +752,16 @@ int add_mtd_device(struct mtd_info *mtd)
|
||||
of this try_ nonsense, and no bitching about it
|
||||
either. :) */
|
||||
__module_get(THIS_MODULE);
|
||||
+
|
||||
+ if (!strcmp(mtd->name, "rootfs") &&
|
||||
+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
|
||||
+ ROOT_DEV == 0) {
|
||||
+ unsigned int index = mtd->index;
|
||||
+ pr_notice("mtd: device %d (%s) set to be root filesystem\n",
|
||||
+ mtd->index, mtd->name);
|
||||
+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, index);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
|
||||
fail_nvmem_add:
|
|
@ -1,120 +0,0 @@
|
|||
From 6fa9e3678eb002246df1280322b6a024853950a5 Mon Sep 17 00:00:00 2001
|
||||
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Date: Mon, 11 Oct 2021 00:53:14 +0200
|
||||
Subject: [PATCH] drivers: mtd: parsers: add nvmem support to cmdlinepart
|
||||
|
||||
Assuming cmdlinepart is only one level deep partition scheme and that
|
||||
static partition are also defined in DTS, we can assign an of_node for
|
||||
partition declared from bootargs. cmdlinepart have priority than
|
||||
fiexed-partition parser so in this specific case the parser doesn't
|
||||
assign an of_node. Fix this by searching a defined of_node using a
|
||||
similar fixed_partition parser and if a partition is found with the same
|
||||
label, check that it has the same offset and size and return the DT
|
||||
of_node to correctly use NVMEM cells.
|
||||
|
||||
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/mtd/parsers/cmdlinepart.c | 71 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 71 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/parsers/cmdlinepart.c
|
||||
+++ b/drivers/mtd/parsers/cmdlinepart.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
+#include <linux/of.h>
|
||||
|
||||
/* debug macro */
|
||||
#if 0
|
||||
@@ -323,6 +324,68 @@ static int mtdpart_setup_real(char *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int search_fixed_partition(struct mtd_info *master,
|
||||
+ struct mtd_partition *target_part,
|
||||
+ struct mtd_partition *fixed_part)
|
||||
+{
|
||||
+ struct device_node *mtd_node;
|
||||
+ struct device_node *ofpart_node;
|
||||
+ struct device_node *pp;
|
||||
+ struct mtd_partition part;
|
||||
+ const char *partname;
|
||||
+
|
||||
+ mtd_node = mtd_get_of_node(master);
|
||||
+ if (!mtd_node)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ofpart_node = of_get_child_by_name(mtd_node, "partitions");
|
||||
+
|
||||
+ for_each_child_of_node(ofpart_node, pp) {
|
||||
+ const __be32 *reg;
|
||||
+ int len;
|
||||
+ int a_cells, s_cells;
|
||||
+
|
||||
+ reg = of_get_property(pp, "reg", &len);
|
||||
+ if (!reg) {
|
||||
+ pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n",
|
||||
+ master->name, pp,
|
||||
+ mtd_node);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ a_cells = of_n_addr_cells(pp);
|
||||
+ s_cells = of_n_size_cells(pp);
|
||||
+ if (len / 4 != a_cells + s_cells) {
|
||||
+ pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n",
|
||||
+ master->name, pp,
|
||||
+ mtd_node);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ part.offset = of_read_number(reg, a_cells);
|
||||
+ part.size = of_read_number(reg + a_cells, s_cells);
|
||||
+ part.of_node = pp;
|
||||
+
|
||||
+ partname = of_get_property(pp, "label", &len);
|
||||
+ if (!partname)
|
||||
+ partname = of_get_property(pp, "name", &len);
|
||||
+ part.name = partname;
|
||||
+
|
||||
+ if (!strncmp(target_part->name, part.name, len)) {
|
||||
+ if (part.offset != target_part->offset)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (part.size != target_part->size)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ memcpy(fixed_part, &part, sizeof(struct mtd_partition));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Main function to be called from the MTD mapping driver/device to
|
||||
* obtain the partitioning information. At this point the command line
|
||||
@@ -338,6 +401,7 @@ static int parse_cmdline_partitions(stru
|
||||
int i, err;
|
||||
struct cmdline_mtd_partition *part;
|
||||
const char *mtd_id = master->name;
|
||||
+ struct mtd_partition fixed_part;
|
||||
|
||||
/* parse command line */
|
||||
if (!cmdline_parsed) {
|
||||
@@ -382,6 +446,13 @@ static int parse_cmdline_partitions(stru
|
||||
sizeof(*part->parts) * (part->num_parts - i));
|
||||
i--;
|
||||
}
|
||||
+
|
||||
+ err = search_fixed_partition(master, &part->parts[i], &fixed_part);
|
||||
+ if (!err) {
|
||||
+ part->parts[i].of_node = fixed_part.of_node;
|
||||
+ pr_info("Found partition defined in DT for %s. Assigning OF node to support nvmem.",
|
||||
+ part->parts[i].name);
|
||||
+ }
|
||||
}
|
||||
|
||||
*pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts,
|
|
@ -1,33 +0,0 @@
|
|||
From ac84397efb3b3868c71c10ad7521161773228a17 Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:41:44 +0200
|
||||
Subject: [PATCH] mtd/nand: add MediaTek NAND bad block managment table
|
||||
|
||||
---
|
||||
drivers/mtd/nand/Kconfig | 4 ++++
|
||||
drivers/mtd/nand/Makefile | 1 +
|
||||
2 files changed, 5 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/nand/Kconfig
|
||||
+++ b/drivers/mtd/nand/Kconfig
|
||||
@@ -46,6 +46,10 @@ config MTD_NAND_ECC_SW_BCH
|
||||
ECC codes. They are used with NAND devices requiring more than 1 bit
|
||||
of error correction.
|
||||
|
||||
+config MTD_NAND_MTK_BMT
|
||||
+ bool "Support MediaTek NAND Bad-block Management Table"
|
||||
+ default n
|
||||
+
|
||||
config MTD_NAND_ECC_MXIC
|
||||
bool "Macronix external hardware ECC engine"
|
||||
depends on HAS_IOMEM
|
||||
--- a/drivers/mtd/nand/Makefile
|
||||
+++ b/drivers/mtd/nand/Makefile
|
||||
@@ -3,6 +3,7 @@
|
||||
nandcore-objs := core.o bbt.o
|
||||
obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
|
||||
obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
|
||||
+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o
|
||||
|
||||
obj-y += onenand/
|
||||
obj-y += raw/
|
|
@ -1,846 +0,0 @@
|
|||
From 11c3fae5afa6cac444d12622e2cf5af60a99c1ef Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:43:15 +0200
|
||||
Subject: [PATCH] net/bridge: add bridge offload
|
||||
|
||||
---
|
||||
include/linux/if_bridge.h | 1 +
|
||||
net/bridge/Makefile | 2 +-
|
||||
net/bridge/br.c | 8 +
|
||||
net/bridge/br_device.c | 2 +
|
||||
net/bridge/br_fdb.c | 5 +
|
||||
net/bridge/br_forward.c | 3 +
|
||||
net/bridge/br_if.c | 6 +-
|
||||
net/bridge/br_input.c | 5 +
|
||||
net/bridge/br_offload.c | 438 ++++++++++++++++++++++++++++++++
|
||||
net/bridge/br_private.h | 22 +-
|
||||
net/bridge/br_private_offload.h | 23 ++
|
||||
net/bridge/br_stp.c | 3 +
|
||||
net/bridge/br_sysfs_br.c | 35 +++
|
||||
net/bridge/br_sysfs_if.c | 2 +
|
||||
net/bridge/br_vlan_tunnel.c | 3 +
|
||||
15 files changed, 555 insertions(+), 3 deletions(-)
|
||||
create mode 100644 net/bridge/br_offload.c
|
||||
create mode 100644 net/bridge/br_private_offload.h
|
||||
|
||||
--- a/include/linux/if_bridge.h
|
||||
+++ b/include/linux/if_bridge.h
|
||||
@@ -60,6 +60,7 @@ struct br_ip_list {
|
||||
#define BR_TX_FWD_OFFLOAD BIT(20)
|
||||
#define BR_PORT_LOCKED BIT(21)
|
||||
#define BR_BPDU_FILTER BIT(22)
|
||||
+#define BR_OFFLOAD BIT(23)
|
||||
|
||||
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
|
||||
|
||||
--- a/net/bridge/Makefile
|
||||
+++ b/net/bridge/Makefile
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
obj-$(CONFIG_BRIDGE) += bridge.o
|
||||
|
||||
-bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \
|
||||
+bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o br_offload.o \
|
||||
br_ioctl.o br_stp.o br_stp_bpdu.o \
|
||||
br_stp_if.o br_stp_timer.o br_netlink.o \
|
||||
br_netlink_tunnel.o br_arp_nd_proxy.o
|
||||
--- a/net/bridge/br.c
|
||||
+++ b/net/bridge/br.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <net/switchdev.h>
|
||||
|
||||
#include "br_private.h"
|
||||
+#include "br_private_offload.h"
|
||||
|
||||
/*
|
||||
* Handle changes in state of network devices enslaved to a bridge.
|
||||
@@ -389,6 +390,10 @@ static int __init br_init(void)
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
+ err = br_offload_init();
|
||||
+ if (err)
|
||||
+ goto err_out0;
|
||||
+
|
||||
err = register_pernet_subsys(&br_net_ops);
|
||||
if (err)
|
||||
goto err_out1;
|
||||
@@ -438,6 +443,8 @@ err_out3:
|
||||
err_out2:
|
||||
unregister_pernet_subsys(&br_net_ops);
|
||||
err_out1:
|
||||
+ br_offload_fini();
|
||||
+err_out0:
|
||||
br_fdb_fini();
|
||||
err_out:
|
||||
stp_proto_unregister(&br_stp_proto);
|
||||
@@ -460,6 +467,7 @@ static void __exit br_deinit(void)
|
||||
#if IS_ENABLED(CONFIG_ATM_LANE)
|
||||
br_fdb_test_addr_hook = NULL;
|
||||
#endif
|
||||
+ br_offload_fini();
|
||||
br_fdb_fini();
|
||||
}
|
||||
|
||||
--- a/net/bridge/br_device.c
|
||||
+++ b/net/bridge/br_device.c
|
||||
@@ -525,6 +525,8 @@ void br_dev_setup(struct net_device *dev
|
||||
br->bridge_hello_time = br->hello_time = 2 * HZ;
|
||||
br->bridge_forward_delay = br->forward_delay = 15 * HZ;
|
||||
br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME;
|
||||
+ br->offload_cache_size = 128;
|
||||
+ br->offload_cache_reserved = 8;
|
||||
dev->max_mtu = ETH_MAX_MTU;
|
||||
|
||||
br_netfilter_rtable_init(br);
|
||||
--- a/net/bridge/br_fdb.c
|
||||
+++ b/net/bridge/br_fdb.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <net/switchdev.h>
|
||||
#include <trace/events/bridge.h>
|
||||
#include "br_private.h"
|
||||
+#include "br_private_offload.h"
|
||||
|
||||
static const struct rhashtable_params br_fdb_rht_params = {
|
||||
.head_offset = offsetof(struct net_bridge_fdb_entry, rhnode),
|
||||
@@ -185,6 +186,8 @@ static void fdb_notify(struct net_bridge
|
||||
struct sk_buff *skb;
|
||||
int err = -ENOBUFS;
|
||||
|
||||
+ br_offload_fdb_update(fdb);
|
||||
+
|
||||
if (swdev_notify)
|
||||
br_switchdev_fdb_notify(br, fdb, type);
|
||||
|
||||
@@ -393,6 +396,8 @@ static struct net_bridge_fdb_entry *fdb_
|
||||
fdb->key.vlan_id = vid;
|
||||
fdb->flags = flags;
|
||||
fdb->updated = fdb->used = jiffies;
|
||||
+ INIT_HLIST_HEAD(&fdb->offload_in);
|
||||
+ INIT_HLIST_HEAD(&fdb->offload_out);
|
||||
err = rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, &fdb->rhnode,
|
||||
br_fdb_rht_params);
|
||||
if (err) {
|
||||
--- a/net/bridge/br_forward.c
|
||||
+++ b/net/bridge/br_forward.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/netfilter_bridge.h>
|
||||
#include "br_private.h"
|
||||
+#include "br_private_offload.h"
|
||||
|
||||
/* Don't forward packets to originating port or forwarding disabled */
|
||||
static inline int should_deliver(const struct net_bridge_port *p,
|
||||
@@ -32,6 +33,8 @@ static inline int should_deliver(const s
|
||||
|
||||
int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
+ br_offload_output(skb);
|
||||
+
|
||||
skb_push(skb, ETH_HLEN);
|
||||
if (!is_skb_forwardable(skb->dev, skb))
|
||||
goto drop;
|
||||
--- a/net/bridge/br_if.c
|
||||
+++ b/net/bridge/br_if.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
#include "br_private.h"
|
||||
+#include "br_private_offload.h"
|
||||
|
||||
/*
|
||||
* Determine initial path cost based on speed.
|
||||
@@ -437,7 +438,7 @@ static struct net_bridge_port *new_nbp(s
|
||||
p->path_cost = port_cost(dev);
|
||||
p->priority = 0x8000 >> BR_PORT_BITS;
|
||||
p->port_no = index;
|
||||
- p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
|
||||
+ p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD | BR_OFFLOAD;
|
||||
br_init_port(p);
|
||||
br_set_state(p, BR_STATE_DISABLED);
|
||||
br_stp_port_timer_init(p);
|
||||
@@ -761,6 +762,9 @@ void br_port_flags_change(struct net_bri
|
||||
|
||||
if (mask & BR_NEIGH_SUPPRESS)
|
||||
br_recalculate_neigh_suppress_enabled(br);
|
||||
+
|
||||
+ if (mask & BR_OFFLOAD)
|
||||
+ br_offload_port_state(p);
|
||||
}
|
||||
|
||||
bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag)
|
||||
--- a/net/bridge/br_input.c
|
||||
+++ b/net/bridge/br_input.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/rculist.h>
|
||||
#include "br_private.h"
|
||||
#include "br_private_tunnel.h"
|
||||
+#include "br_private_offload.h"
|
||||
|
||||
static int
|
||||
br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
@@ -189,6 +190,7 @@ int br_handle_frame_finish(struct net *n
|
||||
dst->used = now;
|
||||
br_forward(dst->dst, skb, local_rcv, false);
|
||||
} else {
|
||||
+ br_offload_skb_disable(skb);
|
||||
if (!mcast_hit)
|
||||
br_flood(br, skb, pkt_type, local_rcv, false);
|
||||
else
|
||||
@@ -322,6 +324,9 @@ static rx_handler_result_t br_handle_fra
|
||||
memset(skb->cb, 0, sizeof(struct br_input_skb_cb));
|
||||
|
||||
p = br_port_get_rcu(skb->dev);
|
||||
+ if (br_offload_input(p, skb))
|
||||
+ return RX_HANDLER_CONSUMED;
|
||||
+
|
||||
if (p->flags & BR_VLAN_TUNNEL)
|
||||
br_handle_ingress_vlan_tunnel(skb, p, nbp_vlan_group_rcu(p));
|
||||
|
||||
--- /dev/null
|
||||
+++ b/net/bridge/br_offload.c
|
||||
@@ -0,0 +1,438 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/workqueue.h>
|
||||
+#include "br_private.h"
|
||||
+#include "br_private_offload.h"
|
||||
+
|
||||
+static DEFINE_SPINLOCK(offload_lock);
|
||||
+
|
||||
+struct bridge_flow_key {
|
||||
+ u8 dest[ETH_ALEN];
|
||||
+ u8 src[ETH_ALEN];
|
||||
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||
+ u16 vlan_tag;
|
||||
+ bool vlan_present;
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+struct bridge_flow {
|
||||
+ struct net_bridge_port *port;
|
||||
+ struct rhash_head node;
|
||||
+ struct bridge_flow_key key;
|
||||
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||
+ bool vlan_out_present;
|
||||
+ u16 vlan_out;
|
||||
+#endif
|
||||
+
|
||||
+ unsigned long used;
|
||||
+ struct net_bridge_fdb_entry *fdb_in, *fdb_out;
|
||||
+ struct hlist_node fdb_list_in, fdb_list_out;
|
||||
+
|
||||
+ struct rcu_head rcu;
|
||||
+};
|
||||
+
|
||||
+static const struct rhashtable_params flow_params = {
|
||||
+ .automatic_shrinking = true,
|
||||
+ .head_offset = offsetof(struct bridge_flow, node),
|
||||
+ .key_len = sizeof(struct bridge_flow_key),
|
||||
+ .key_offset = offsetof(struct bridge_flow, key),
|
||||
+};
|
||||
+
|
||||
+static struct kmem_cache *offload_cache __read_mostly;
|
||||
+
|
||||
+static void
|
||||
+flow_rcu_free(struct rcu_head *head)
|
||||
+{
|
||||
+ struct bridge_flow *flow;
|
||||
+
|
||||
+ flow = container_of(head, struct bridge_flow, rcu);
|
||||
+ kmem_cache_free(offload_cache, flow);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+__br_offload_flow_free(struct bridge_flow *flow)
|
||||
+{
|
||||
+ flow->used = 0;
|
||||
+ hlist_del(&flow->fdb_list_in);
|
||||
+ hlist_del(&flow->fdb_list_out);
|
||||
+
|
||||
+ call_rcu(&flow->rcu, flow_rcu_free);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+br_offload_flow_free(struct bridge_flow *flow)
|
||||
+{
|
||||
+ if (rhashtable_remove_fast(&flow->port->offload.rht, &flow->node,
|
||||
+ flow_params) != 0)
|
||||
+ return;
|
||||
+
|
||||
+ __br_offload_flow_free(flow);
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+br_offload_flow_fdb_refresh_time(struct bridge_flow *flow,
|
||||
+ struct net_bridge_fdb_entry *fdb)
|
||||
+{
|
||||
+ if (!time_after(flow->used, fdb->updated))
|
||||
+ return false;
|
||||
+
|
||||
+ fdb->updated = flow->used;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+br_offload_flow_refresh_time(struct bridge_flow *flow)
|
||||
+{
|
||||
+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_in);
|
||||
+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+br_offload_destroy_cb(void *ptr, void *arg)
|
||||
+{
|
||||
+ struct bridge_flow *flow = ptr;
|
||||
+
|
||||
+ __br_offload_flow_free(flow);
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+br_offload_need_gc(struct net_bridge_port *p)
|
||||
+{
|
||||
+ return (atomic_read(&p->offload.rht.nelems) +
|
||||
+ p->br->offload_cache_reserved) >= p->br->offload_cache_size;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+br_offload_gc_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct rhashtable_iter hti;
|
||||
+ struct net_bridge_port *p;
|
||||
+ struct bridge_flow *gc_flow = NULL;
|
||||
+ struct bridge_flow *flow;
|
||||
+ unsigned long gc_used;
|
||||
+
|
||||
+ p = container_of(work, struct net_bridge_port, offload.gc_work);
|
||||
+
|
||||
+ if (!br_offload_need_gc(p))
|
||||
+ return;
|
||||
+
|
||||
+ rhashtable_walk_enter(&p->offload.rht, &hti);
|
||||
+ rhashtable_walk_start(&hti);
|
||||
+ while ((flow = rhashtable_walk_next(&hti)) != NULL) {
|
||||
+ unsigned long used;
|
||||
+
|
||||
+ if (IS_ERR(flow))
|
||||
+ continue;
|
||||
+
|
||||
+ used = READ_ONCE(flow->used);
|
||||
+ if (!used)
|
||||
+ continue;
|
||||
+
|
||||
+ if (gc_flow && !time_before(used, gc_used))
|
||||
+ continue;
|
||||
+
|
||||
+ gc_flow = flow;
|
||||
+ gc_used = used;
|
||||
+ }
|
||||
+ rhashtable_walk_stop(&hti);
|
||||
+ rhashtable_walk_exit(&hti);
|
||||
+
|
||||
+ if (!gc_flow)
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock_bh(&offload_lock);
|
||||
+ if (br_offload_need_gc(p) && gc_flow &&
|
||||
+ gc_flow->used == gc_used)
|
||||
+ br_offload_flow_free(gc_flow);
|
||||
+ if (p->offload.enabled && br_offload_need_gc(p))
|
||||
+ queue_work(system_long_wq, work);
|
||||
+ spin_unlock_bh(&offload_lock);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+void br_offload_port_state(struct net_bridge_port *p)
|
||||
+{
|
||||
+ struct net_bridge_port_offload *o = &p->offload;
|
||||
+ bool enabled = true;
|
||||
+ bool flush = false;
|
||||
+
|
||||
+ if (p->state != BR_STATE_FORWARDING ||
|
||||
+ !(p->flags & BR_OFFLOAD))
|
||||
+ enabled = false;
|
||||
+
|
||||
+ spin_lock_bh(&offload_lock);
|
||||
+ if (o->enabled == enabled)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (enabled) {
|
||||
+ if (!o->gc_work.func)
|
||||
+ INIT_WORK(&o->gc_work, br_offload_gc_work);
|
||||
+ rhashtable_init(&o->rht, &flow_params);
|
||||
+ } else {
|
||||
+ flush = true;
|
||||
+ rhashtable_free_and_destroy(&o->rht, br_offload_destroy_cb, o);
|
||||
+ }
|
||||
+
|
||||
+ o->enabled = enabled;
|
||||
+
|
||||
+out:
|
||||
+ spin_unlock_bh(&offload_lock);
|
||||
+
|
||||
+ if (flush)
|
||||
+ flush_work(&o->gc_work);
|
||||
+}
|
||||
+
|
||||
+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb)
|
||||
+{
|
||||
+ struct bridge_flow *f;
|
||||
+ struct hlist_node *tmp;
|
||||
+
|
||||
+ spin_lock_bh(&offload_lock);
|
||||
+
|
||||
+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_in, fdb_list_in)
|
||||
+ br_offload_flow_free(f);
|
||||
+
|
||||
+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_out, fdb_list_out)
|
||||
+ br_offload_flow_free(f);
|
||||
+
|
||||
+ spin_unlock_bh(&offload_lock);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+br_offload_prepare_key(struct net_bridge_port *p, struct bridge_flow_key *key,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ memset(key, 0, sizeof(*key));
|
||||
+ memcpy(key, eth_hdr(skb), 2 * ETH_ALEN);
|
||||
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||
+ if (!br_opt_get(p->br, BROPT_VLAN_ENABLED))
|
||||
+ return;
|
||||
+
|
||||
+ if (!skb_vlan_tag_present(skb) || skb->vlan_proto != p->br->vlan_proto)
|
||||
+ return;
|
||||
+
|
||||
+ key->vlan_present = true;
|
||||
+ key->vlan_tag = skb_vlan_tag_get_id(skb);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void br_offload_output(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct net_bridge_port_offload *o;
|
||||
+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb;
|
||||
+ struct net_bridge_port *p, *inp;
|
||||
+ struct net_device *dev;
|
||||
+ struct net_bridge_fdb_entry *fdb_in, *fdb_out;
|
||||
+ struct net_bridge_vlan_group *vg;
|
||||
+ struct bridge_flow_key key;
|
||||
+ struct bridge_flow *flow;
|
||||
+ u16 vlan;
|
||||
+
|
||||
+ if (!cb->offload)
|
||||
+ return;
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+
|
||||
+ p = br_port_get_rcu(skb->dev);
|
||||
+ if (!p)
|
||||
+ goto out;
|
||||
+
|
||||
+ o = &p->offload;
|
||||
+ if (!o->enabled)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size)
|
||||
+ goto out;
|
||||
+
|
||||
+ dev = dev_get_by_index_rcu(dev_net(p->br->dev), cb->input_ifindex);
|
||||
+ if (!dev)
|
||||
+ goto out;
|
||||
+
|
||||
+ inp = br_port_get_rcu(dev);
|
||||
+ if (!inp)
|
||||
+ goto out;
|
||||
+
|
||||
+ vg = nbp_vlan_group_rcu(inp);
|
||||
+ vlan = cb->input_vlan_present ? cb->input_vlan_tag : br_get_pvid(vg);
|
||||
+ fdb_in = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_source, vlan);
|
||||
+ if (!fdb_in || !fdb_in->dst)
|
||||
+ goto out;
|
||||
+
|
||||
+ vg = nbp_vlan_group_rcu(p);
|
||||
+ vlan = skb_vlan_tag_present(skb) ? skb_vlan_tag_get_id(skb) : br_get_pvid(vg);
|
||||
+ fdb_out = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_dest, vlan);
|
||||
+ if (!fdb_out || !fdb_out->dst)
|
||||
+ goto out;
|
||||
+
|
||||
+ br_offload_prepare_key(p, &key, skb);
|
||||
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||
+ key.vlan_present = cb->input_vlan_present;
|
||||
+ key.vlan_tag = cb->input_vlan_tag;
|
||||
+#endif
|
||||
+
|
||||
+ flow = kmem_cache_alloc(offload_cache, GFP_ATOMIC);
|
||||
+ flow->port = inp;
|
||||
+ memcpy(&flow->key, &key, sizeof(key));
|
||||
+
|
||||
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||
+ flow->vlan_out_present = skb_vlan_tag_present(skb);
|
||||
+ flow->vlan_out = skb_vlan_tag_get(skb);
|
||||
+#endif
|
||||
+
|
||||
+ flow->fdb_in = fdb_in;
|
||||
+ flow->fdb_out = fdb_out;
|
||||
+ flow->used = jiffies;
|
||||
+
|
||||
+ spin_lock_bh(&offload_lock);
|
||||
+ if (!o->enabled ||
|
||||
+ atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size ||
|
||||
+ rhashtable_insert_fast(&inp->offload.rht, &flow->node, flow_params)) {
|
||||
+ kmem_cache_free(offload_cache, flow);
|
||||
+ goto out_unlock;
|
||||
+ }
|
||||
+
|
||||
+ hlist_add_head(&flow->fdb_list_in, &fdb_in->offload_in);
|
||||
+ hlist_add_head(&flow->fdb_list_out, &fdb_out->offload_out);
|
||||
+
|
||||
+ if (br_offload_need_gc(p))
|
||||
+ queue_work(system_long_wq, &p->offload.gc_work);
|
||||
+
|
||||
+out_unlock:
|
||||
+ spin_unlock_bh(&offload_lock);
|
||||
+
|
||||
+out:
|
||||
+ rcu_read_unlock();
|
||||
+}
|
||||
+
|
||||
+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct net_bridge_port_offload *o = &p->offload;
|
||||
+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb;
|
||||
+ struct bridge_flow_key key;
|
||||
+ struct net_bridge_port *dst;
|
||||
+ struct bridge_flow *flow;
|
||||
+ unsigned long now = jiffies;
|
||||
+ bool ret = false;
|
||||
+
|
||||
+ if (skb->len < sizeof(key))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!o->enabled)
|
||||
+ return false;
|
||||
+
|
||||
+ if (is_multicast_ether_addr(eth_hdr(skb)->h_dest))
|
||||
+ return false;
|
||||
+
|
||||
+ br_offload_prepare_key(p, &key, skb);
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ flow = rhashtable_lookup(&o->rht, &key, flow_params);
|
||||
+ if (!flow) {
|
||||
+ cb->offload = 1;
|
||||
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||
+ cb->input_vlan_present = key.vlan_present != 0;
|
||||
+ cb->input_vlan_tag = key.vlan_tag;
|
||||
+#endif
|
||||
+ cb->input_ifindex = p->dev->ifindex;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (flow->fdb_in->dst != p)
|
||||
+ goto out;
|
||||
+
|
||||
+ dst = flow->fdb_out->dst;
|
||||
+ if (!dst)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = true;
|
||||
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||
+ if (!flow->vlan_out_present && key.vlan_present) {
|
||||
+ __vlan_hwaccel_clear_tag(skb);
|
||||
+ } else if (flow->vlan_out_present) {
|
||||
+ if (skb_vlan_tag_present(skb) &&
|
||||
+ skb->vlan_proto != p->br->vlan_proto) {
|
||||
+ /* Protocol-mismatch, empty out vlan_tci for new tag */
|
||||
+ skb_push(skb, ETH_HLEN);
|
||||
+ skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
|
||||
+ skb_vlan_tag_get(skb));
|
||||
+ if (unlikely(!skb))
|
||||
+ goto out;
|
||||
+
|
||||
+ skb_pull(skb, ETH_HLEN);
|
||||
+ skb_reset_mac_len(skb);
|
||||
+ }
|
||||
+
|
||||
+ __vlan_hwaccel_put_tag(skb, p->br->vlan_proto,
|
||||
+ flow->vlan_out);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ skb->dev = dst->dev;
|
||||
+ skb_push(skb, ETH_HLEN);
|
||||
+
|
||||
+ if (skb_warn_if_lro(skb) || !is_skb_forwardable(skb->dev, skb)) {
|
||||
+ kfree_skb(skb);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (now - flow->used >= HZ) {
|
||||
+ flow->used = now;
|
||||
+ br_offload_flow_refresh_time(flow);
|
||||
+ }
|
||||
+
|
||||
+ skb_forward_csum(skb);
|
||||
+ dev_queue_xmit(skb);
|
||||
+
|
||||
+out:
|
||||
+ rcu_read_unlock();
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+br_offload_check_gc(struct net_bridge *br)
|
||||
+{
|
||||
+ struct net_bridge_port *p;
|
||||
+
|
||||
+ spin_lock_bh(&br->lock);
|
||||
+ list_for_each_entry(p, &br->port_list, list)
|
||||
+ if (br_offload_need_gc(p))
|
||||
+ queue_work(system_long_wq, &p->offload.gc_work);
|
||||
+ spin_unlock_bh(&br->lock);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ br->offload_cache_size = val;
|
||||
+ br_offload_check_gc(br);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ br->offload_cache_reserved = val;
|
||||
+ br_offload_check_gc(br);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int __init br_offload_init(void)
|
||||
+{
|
||||
+ offload_cache = kmem_cache_create("bridge_offload_cache",
|
||||
+ sizeof(struct bridge_flow),
|
||||
+ 0, SLAB_HWCACHE_ALIGN, NULL);
|
||||
+ if (!offload_cache)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void br_offload_fini(void)
|
||||
+{
|
||||
+ kmem_cache_destroy(offload_cache);
|
||||
+}
|
||||
--- a/net/bridge/br_private.h
|
||||
+++ b/net/bridge/br_private.h
|
||||
@@ -271,7 +271,13 @@ struct net_bridge_fdb_entry {
|
||||
unsigned long updated ____cacheline_aligned_in_smp;
|
||||
unsigned long used;
|
||||
|
||||
- struct rcu_head rcu;
|
||||
+ union {
|
||||
+ struct {
|
||||
+ struct hlist_head offload_in;
|
||||
+ struct hlist_head offload_out;
|
||||
+ };
|
||||
+ struct rcu_head rcu;
|
||||
+ };
|
||||
};
|
||||
|
||||
struct net_bridge_fdb_flush_desc {
|
||||
@@ -353,6 +359,12 @@ struct net_bridge_mdb_entry {
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
+struct net_bridge_port_offload {
|
||||
+ struct rhashtable rht;
|
||||
+ struct work_struct gc_work;
|
||||
+ bool enabled;
|
||||
+};
|
||||
+
|
||||
struct net_bridge_port {
|
||||
struct net_bridge *br;
|
||||
struct net_device *dev;
|
||||
@@ -414,6 +426,7 @@ struct net_bridge_port {
|
||||
u16 backup_redirected_cnt;
|
||||
|
||||
struct bridge_stp_xstats stp_xstats;
|
||||
+ struct net_bridge_port_offload offload;
|
||||
};
|
||||
|
||||
#define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj)
|
||||
@@ -531,6 +544,9 @@ struct net_bridge {
|
||||
struct kobject *ifobj;
|
||||
u32 auto_cnt;
|
||||
|
||||
+ u32 offload_cache_size;
|
||||
+ u32 offload_cache_reserved;
|
||||
+
|
||||
#ifdef CONFIG_NET_SWITCHDEV
|
||||
/* Counter used to make sure that hardware domains get unique
|
||||
* identifiers in case a bridge spans multiple switchdev instances.
|
||||
@@ -565,6 +581,10 @@ struct br_input_skb_cb {
|
||||
#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
|
||||
u8 br_netfilter_broute:1;
|
||||
#endif
|
||||
+ u8 offload:1;
|
||||
+ u8 input_vlan_present:1;
|
||||
+ u16 input_vlan_tag;
|
||||
+ int input_ifindex;
|
||||
|
||||
#ifdef CONFIG_NET_SWITCHDEV
|
||||
/* Set if TX data plane offloading is used towards at least one
|
||||
--- /dev/null
|
||||
+++ b/net/bridge/br_private_offload.h
|
||||
@@ -0,0 +1,23 @@
|
||||
+#ifndef __BR_OFFLOAD_H
|
||||
+#define __BR_OFFLOAD_H
|
||||
+
|
||||
+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb);
|
||||
+void br_offload_output(struct sk_buff *skb);
|
||||
+void br_offload_port_state(struct net_bridge_port *p);
|
||||
+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb);
|
||||
+int br_offload_init(void);
|
||||
+void br_offload_fini(void);
|
||||
+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
+
|
||||
+static inline void br_offload_skb_disable(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb;
|
||||
+
|
||||
+ if (cb->offload)
|
||||
+ cb->offload = 0;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
--- a/net/bridge/br_stp.c
|
||||
+++ b/net/bridge/br_stp.c
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "br_private.h"
|
||||
#include "br_private_stp.h"
|
||||
+#include "br_private_offload.h"
|
||||
|
||||
/* since time values in bpdu are in jiffies and then scaled (1/256)
|
||||
* before sending, make sure that is at least one STP tick.
|
||||
@@ -58,6 +59,8 @@ void br_set_state(struct net_bridge_port
|
||||
(unsigned int) p->port_no, p->dev->name,
|
||||
br_port_state_names[p->state]);
|
||||
|
||||
+ br_offload_port_state(p);
|
||||
+
|
||||
if (p->br->stp_enabled == BR_KERNEL_STP) {
|
||||
switch (p->state) {
|
||||
case BR_STATE_BLOCKING:
|
||||
--- a/net/bridge/br_sysfs_br.c
|
||||
+++ b/net/bridge/br_sysfs_br.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/sched/signal.h>
|
||||
|
||||
#include "br_private.h"
|
||||
+#include "br_private_offload.h"
|
||||
|
||||
/* IMPORTANT: new bridge options must be added with netlink support only
|
||||
* please do not add new sysfs entries
|
||||
@@ -933,6 +934,38 @@ static ssize_t vlan_stats_per_port_store
|
||||
static DEVICE_ATTR_RW(vlan_stats_per_port);
|
||||
#endif
|
||||
|
||||
+static ssize_t offload_cache_size_show(struct device *d,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct net_bridge *br = to_bridge(d);
|
||||
+ return sprintf(buf, "%u\n", br->offload_cache_size);
|
||||
+}
|
||||
+
|
||||
+static ssize_t offload_cache_size_store(struct device *d,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t len)
|
||||
+{
|
||||
+ return store_bridge_parm(d, buf, len, br_offload_set_cache_size);
|
||||
+}
|
||||
+static DEVICE_ATTR_RW(offload_cache_size);
|
||||
+
|
||||
+static ssize_t offload_cache_reserved_show(struct device *d,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct net_bridge *br = to_bridge(d);
|
||||
+ return sprintf(buf, "%u\n", br->offload_cache_reserved);
|
||||
+}
|
||||
+
|
||||
+static ssize_t offload_cache_reserved_store(struct device *d,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t len)
|
||||
+{
|
||||
+ return store_bridge_parm(d, buf, len, br_offload_set_cache_reserved);
|
||||
+}
|
||||
+static DEVICE_ATTR_RW(offload_cache_reserved);
|
||||
+
|
||||
static struct attribute *bridge_attrs[] = {
|
||||
&dev_attr_forward_delay.attr,
|
||||
&dev_attr_hello_time.attr,
|
||||
@@ -987,6 +1020,8 @@ static struct attribute *bridge_attrs[]
|
||||
&dev_attr_vlan_stats_enabled.attr,
|
||||
&dev_attr_vlan_stats_per_port.attr,
|
||||
#endif
|
||||
+ &dev_attr_offload_cache_size.attr,
|
||||
+ &dev_attr_offload_cache_reserved.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
--- a/net/bridge/br_sysfs_if.c
|
||||
+++ b/net/bridge/br_sysfs_if.c
|
||||
@@ -241,6 +241,7 @@ BRPORT_ATTR_FLAG(broadcast_flood, BR_BCA
|
||||
BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS);
|
||||
BRPORT_ATTR_FLAG(isolated, BR_ISOLATED);
|
||||
BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER);
|
||||
+BRPORT_ATTR_FLAG(offload, BR_OFFLOAD);
|
||||
|
||||
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
|
||||
static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
|
||||
@@ -295,6 +296,7 @@ static const struct brport_attribute *br
|
||||
&brport_attr_isolated,
|
||||
&brport_attr_bpdu_filter,
|
||||
&brport_attr_backup_port,
|
||||
+ &brport_attr_offload,
|
||||
NULL
|
||||
};
|
||||
|
||||
--- a/net/bridge/br_vlan_tunnel.c
|
||||
+++ b/net/bridge/br_vlan_tunnel.c
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "br_private.h"
|
||||
#include "br_private_tunnel.h"
|
||||
+#include "br_private_offload.h"
|
||||
|
||||
static inline int br_vlan_tunid_cmp(struct rhashtable_compare_arg *arg,
|
||||
const void *ptr)
|
||||
@@ -180,6 +181,7 @@ void br_handle_ingress_vlan_tunnel(struc
|
||||
skb_dst_drop(skb);
|
||||
|
||||
__vlan_hwaccel_put_tag(skb, p->br->vlan_proto, vlan->vid);
|
||||
+ br_offload_skb_disable(skb);
|
||||
}
|
||||
|
||||
int br_handle_egress_vlan_tunnel(struct sk_buff *skb,
|
||||
@@ -201,6 +203,7 @@ int br_handle_egress_vlan_tunnel(struct
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ br_offload_skb_disable(skb);
|
||||
tunnel_dst = rcu_dereference(vlan->tinfo.tunnel_dst);
|
||||
if (tunnel_dst && dst_hold_safe(&tunnel_dst->dst))
|
||||
skb_dst_set(skb, &tunnel_dst->dst);
|
|
@ -1,112 +0,0 @@
|
|||
From: Yousong Zhou <yszhou4tech@gmail.com>
|
||||
Subject: [PATCH] ath79: add nvmem cell mac-address-ascii support
|
||||
|
||||
This is needed for devices with mac address stored in ascii format, e.g.
|
||||
HiWiFi HC6361 to be ported in the following patch.
|
||||
|
||||
Submitted-by: Yousong Zhou <yszhou4tech@gmail.com>
|
||||
---
|
||||
net/ethernet/eth.c | 83 ++++++++++++------
|
||||
1 files changed, 72 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/net/ethernet/eth.c
|
||||
+++ b/net/ethernet/eth.c
|
||||
@@ -531,6 +531,63 @@ int eth_platform_get_mac_address(struct
|
||||
}
|
||||
EXPORT_SYMBOL(eth_platform_get_mac_address);
|
||||
|
||||
+static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell)
|
||||
+{
|
||||
+ size_t len;
|
||||
+ void *mac;
|
||||
+
|
||||
+ mac = nvmem_cell_read(cell, &len);
|
||||
+ if (IS_ERR(mac))
|
||||
+ return PTR_ERR(mac);
|
||||
+ if (len != ETH_ALEN) {
|
||||
+ kfree(mac);
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+ return mac;
|
||||
+}
|
||||
+
|
||||
+static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell)
|
||||
+{
|
||||
+ size_t len;
|
||||
+ int ret;
|
||||
+ void *mac_ascii;
|
||||
+ u8 *mac;
|
||||
+
|
||||
+ mac_ascii = nvmem_cell_read(cell, &len);
|
||||
+ if (IS_ERR(mac_ascii))
|
||||
+ return PTR_ERR(mac_ascii);
|
||||
+ if (len != ETH_ALEN*2+5) {
|
||||
+ kfree(mac_ascii);
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+ mac = kmalloc(ETH_ALEN, GFP_KERNEL);
|
||||
+ if (!mac) {
|
||||
+ kfree(mac_ascii);
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+ }
|
||||
+ ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
|
||||
+ &mac[0], &mac[1], &mac[2],
|
||||
+ &mac[3], &mac[4], &mac[5]);
|
||||
+ kfree(mac_ascii);
|
||||
+ if (ret == ETH_ALEN)
|
||||
+ return mac;
|
||||
+ kfree(mac);
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+}
|
||||
+
|
||||
+static struct nvmem_cell_mac_address_property {
|
||||
+ char *name;
|
||||
+ void *(*read)(struct nvmem_cell *);
|
||||
+} nvmem_cell_mac_address_properties[] = {
|
||||
+ {
|
||||
+ .name = "mac-address",
|
||||
+ .read = nvmem_cell_get_mac_address,
|
||||
+ }, {
|
||||
+ .name = "mac-address-ascii",
|
||||
+ .read = nvmem_cell_get_mac_address_ascii,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* platform_get_ethdev_address - Set netdev's MAC address from a given device
|
||||
* @dev: Pointer to the device
|
||||
@@ -564,19 +621,23 @@ int nvmem_get_mac_address(struct device
|
||||
{
|
||||
struct nvmem_cell *cell;
|
||||
const void *mac;
|
||||
- size_t len;
|
||||
+ struct nvmem_cell_mac_address_property *property;
|
||||
+ int i;
|
||||
|
||||
- cell = nvmem_cell_get(dev, "mac-address");
|
||||
- if (IS_ERR(cell))
|
||||
- return PTR_ERR(cell);
|
||||
-
|
||||
- mac = nvmem_cell_read(cell, &len);
|
||||
- nvmem_cell_put(cell);
|
||||
-
|
||||
- if (IS_ERR(mac))
|
||||
- return PTR_ERR(mac);
|
||||
+ for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
|
||||
+ property = &nvmem_cell_mac_address_properties[i];
|
||||
+ cell = nvmem_cell_get(dev, property->name);
|
||||
+ if (IS_ERR(cell)) {
|
||||
+ if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
|
||||
+ return PTR_ERR(cell);
|
||||
+ continue;
|
||||
+ }
|
||||
+ mac = property->read(cell);
|
||||
+ nvmem_cell_put(cell);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
|
||||
+ if (!is_valid_ether_addr(mac)) {
|
||||
kfree(mac);
|
||||
return -EINVAL;
|
||||
}
|
|
@ -1,213 +0,0 @@
|
|||
From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
Date: Sat, 23 Mar 2019 09:29:49 +0000
|
||||
Subject: [PATCH] netfilter: connmark: introduce set-dscpmark
|
||||
|
||||
set-dscpmark is a method of storing the DSCP of an ip packet into
|
||||
conntrack mark. In combination with a suitable tc filter action
|
||||
(act_ctinfo) DSCP values are able to be stored in the mark on egress and
|
||||
restored on ingress across links that otherwise alter or bleach DSCP.
|
||||
|
||||
This is useful for qdiscs such as CAKE which are able to shape according
|
||||
to policies based on DSCP.
|
||||
|
||||
Ingress classification is traditionally a challenging task since
|
||||
iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT
|
||||
lookups, hence are unable to see internal IPv4 addresses as used on the
|
||||
typical home masquerading gateway.
|
||||
|
||||
x_tables CONNMARK set-dscpmark target solves the problem of storing the
|
||||
DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc
|
||||
action to restore.
|
||||
|
||||
The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a
|
||||
32bit 'statemask'. The dscp mask must be 6 contiguous bits and
|
||||
represents the area where the DSCP will be stored in the connmark. The
|
||||
state mask is a minimum 1 bit length mask that must not overlap with the
|
||||
dscpmask. It represents a flag which is set when the DSCP has been
|
||||
stored in the conntrack mark. This is useful to implement a 'one shot'
|
||||
iptables based classification where the 'complicated' iptables rules are
|
||||
only run once to classify the connection on initial (egress) packet and
|
||||
subsequent packets are all marked/restored with the same DSCP. A state
|
||||
mask of zero disables the setting of a status bit/s.
|
||||
|
||||
example syntax with a suitably modified iptables user space application:
|
||||
|
||||
iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000
|
||||
|
||||
Would store the DSCP in the top 6 bits of the 32bit mark field, and use
|
||||
the LSB of the top byte as the 'DSCP has been stored' marker.
|
||||
|
||||
|----0xFC----conntrack mark----000000---|
|
||||
| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
|
||||
| DSCP | unused | flag |unused |
|
||||
|-----------------------0x01---000000---|
|
||||
^ ^
|
||||
| |
|
||||
---| Conditional flag
|
||||
| set this when dscp
|
||||
|-ip diffserv-| stored in mark
|
||||
| 6 bits |
|
||||
|-------------|
|
||||
|
||||
an identically configured tc action to restore looks like:
|
||||
|
||||
tc filter show dev eth0 ingress
|
||||
filter parent ffff: protocol all pref 10 u32 chain 0
|
||||
filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1
|
||||
filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw
|
||||
match 00000000/00000000 at 0
|
||||
action order 1: ctinfo zone 0 pipe
|
||||
index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000
|
||||
|
||||
action order 2: mirred (Egress Redirect to device ifb4eth0) stolen
|
||||
index 1 ref 1 bind 1
|
||||
|
||||
|----0xFC----conntrack mark----000000---|
|
||||
| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
|
||||
| DSCP | unused | flag |unused |
|
||||
|-----------------------0x01---000000---|
|
||||
| |
|
||||
| |
|
||||
---| Conditional flag
|
||||
v only restore if set
|
||||
|-ip diffserv-|
|
||||
| 6 bits |
|
||||
|-------------|
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
include/uapi/linux/netfilter/xt_connmark.h | 10 ++++
|
||||
net/netfilter/xt_connmark.c | 55 ++++++++++++++++++----
|
||||
2 files changed, 57 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/include/uapi/linux/netfilter/xt_connmark.h
|
||||
+++ b/include/uapi/linux/netfilter/xt_connmark.h
|
||||
@@ -15,6 +15,11 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
+ XT_CONNMARK_VALUE = (1 << 0),
|
||||
+ XT_CONNMARK_DSCP = (1 << 1)
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
D_SHIFT_LEFT = 0,
|
||||
D_SHIFT_RIGHT,
|
||||
};
|
||||
@@ -29,6 +34,11 @@ struct xt_connmark_tginfo2 {
|
||||
__u8 shift_dir, shift_bits, mode;
|
||||
};
|
||||
|
||||
+struct xt_connmark_tginfo3 {
|
||||
+ __u32 ctmark, ctmask, nfmask;
|
||||
+ __u8 shift_dir, shift_bits, mode, func;
|
||||
+};
|
||||
+
|
||||
struct xt_connmark_mtinfo1 {
|
||||
__u32 mark, mask;
|
||||
__u8 invert;
|
||||
--- a/net/netfilter/xt_connmark.c
|
||||
+++ b/net/netfilter/xt_connmark.c
|
||||
@@ -24,13 +24,14 @@ MODULE_ALIAS("ipt_connmark");
|
||||
MODULE_ALIAS("ip6t_connmark");
|
||||
|
||||
static unsigned int
|
||||
-connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
|
||||
+connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info)
|
||||
{
|
||||
enum ip_conntrack_info ctinfo;
|
||||
u_int32_t new_targetmark;
|
||||
struct nf_conn *ct;
|
||||
u_int32_t newmark;
|
||||
u_int32_t oldmark;
|
||||
+ u_int8_t dscp;
|
||||
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
if (ct == NULL)
|
||||
@@ -39,12 +40,24 @@ connmark_tg_shift(struct sk_buff *skb, c
|
||||
switch (info->mode) {
|
||||
case XT_CONNMARK_SET:
|
||||
oldmark = READ_ONCE(ct->mark);
|
||||
- newmark = (oldmark & ~info->ctmask) ^ info->ctmark;
|
||||
- if (info->shift_dir == D_SHIFT_RIGHT)
|
||||
- newmark >>= info->shift_bits;
|
||||
- else
|
||||
- newmark <<= info->shift_bits;
|
||||
+ newmark = ct->mark;
|
||||
+ if (info->func & XT_CONNMARK_VALUE) {
|
||||
+ newmark = (newmark & ~info->ctmask) ^ info->ctmark;
|
||||
+ if (info->shift_dir == D_SHIFT_RIGHT)
|
||||
+ newmark >>= info->shift_bits;
|
||||
+ else
|
||||
+ newmark <<= info->shift_bits;
|
||||
+ } else if (info->func & XT_CONNMARK_DSCP) {
|
||||
+ if (skb->protocol == htons(ETH_P_IP))
|
||||
+ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
|
||||
+ else if (skb->protocol == htons(ETH_P_IPV6))
|
||||
+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
|
||||
+ else /* protocol doesn't have diffserv */
|
||||
+ break;
|
||||
|
||||
+ newmark = (newmark & ~info->ctmark) |
|
||||
+ (info->ctmask | (dscp << info->shift_bits));
|
||||
+ }
|
||||
if (READ_ONCE(ct->mark) != newmark) {
|
||||
WRITE_ONCE(ct->mark, newmark);
|
||||
nf_conntrack_event_cache(IPCT_MARK, ct);
|
||||
@@ -83,20 +96,36 @@ static unsigned int
|
||||
connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_connmark_tginfo1 *info = par->targinfo;
|
||||
- const struct xt_connmark_tginfo2 info2 = {
|
||||
+ const struct xt_connmark_tginfo3 info3 = {
|
||||
.ctmark = info->ctmark,
|
||||
.ctmask = info->ctmask,
|
||||
.nfmask = info->nfmask,
|
||||
.mode = info->mode,
|
||||
+ .func = XT_CONNMARK_VALUE
|
||||
};
|
||||
|
||||
- return connmark_tg_shift(skb, &info2);
|
||||
+ return connmark_tg_shift(skb, &info3);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_connmark_tginfo2 *info = par->targinfo;
|
||||
+ const struct xt_connmark_tginfo3 info3 = {
|
||||
+ .ctmark = info->ctmark,
|
||||
+ .ctmask = info->ctmask,
|
||||
+ .nfmask = info->nfmask,
|
||||
+ .mode = info->mode,
|
||||
+ .func = XT_CONNMARK_VALUE
|
||||
+ };
|
||||
+
|
||||
+ return connmark_tg_shift(skb, &info3);
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
+{
|
||||
+ const struct xt_connmark_tginfo3 *info = par->targinfo;
|
||||
|
||||
return connmark_tg_shift(skb, info);
|
||||
}
|
||||
@@ -167,6 +196,16 @@ static struct xt_target connmark_tg_reg[
|
||||
.targetsize = sizeof(struct xt_connmark_tginfo2),
|
||||
.destroy = connmark_tg_destroy,
|
||||
.me = THIS_MODULE,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "CONNMARK",
|
||||
+ .revision = 3,
|
||||
+ .family = NFPROTO_UNSPEC,
|
||||
+ .checkentry = connmark_tg_check,
|
||||
+ .target = connmark_tg_v3,
|
||||
+ .targetsize = sizeof(struct xt_connmark_tginfo3),
|
||||
+ .destroy = connmark_tg_destroy,
|
||||
+ .me = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
|
@ -1,798 +0,0 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 20 Feb 2018 15:56:02 +0100
|
||||
Subject: [PATCH] netfilter: add xt_FLOWOFFLOAD target
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
create mode 100644 net/netfilter/xt_OFFLOAD.c
|
||||
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -1023,6 +1023,15 @@ config NETFILTER_XT_TARGET_NOTRACK
|
||||
depends on NETFILTER_ADVANCED
|
||||
select NETFILTER_XT_TARGET_CT
|
||||
|
||||
+config NETFILTER_XT_TARGET_FLOWOFFLOAD
|
||||
+ tristate '"FLOWOFFLOAD" target support'
|
||||
+ depends on NF_FLOW_TABLE
|
||||
+ depends on NETFILTER_INGRESS
|
||||
+ help
|
||||
+ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload
|
||||
+ module to speed up processing of packets by bypassing the usual
|
||||
+ netfilter chains
|
||||
+
|
||||
config NETFILTER_XT_TARGET_RATEEST
|
||||
tristate '"RATEEST" target support'
|
||||
depends on NETFILTER_ADVANCED
|
||||
--- a/net/netfilter/Makefile
|
||||
+++ b/net/netfilter/Makefile
|
||||
@@ -154,6 +154,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
|
||||
+obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
||||
--- /dev/null
|
||||
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
||||
@@ -0,0 +1,697 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
|
||||
+ *
|
||||
+ * 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/init.h>
|
||||
+#include <linux/netfilter.h>
|
||||
+#include <linux/netfilter/xt_FLOWOFFLOAD.h>
|
||||
+#include <linux/if_vlan.h>
|
||||
+#include <net/ip.h>
|
||||
+#include <net/netfilter/nf_conntrack.h>
|
||||
+#include <net/netfilter/nf_conntrack_extend.h>
|
||||
+#include <net/netfilter/nf_conntrack_helper.h>
|
||||
+#include <net/netfilter/nf_flow_table.h>
|
||||
+
|
||||
+struct xt_flowoffload_hook {
|
||||
+ struct hlist_node list;
|
||||
+ struct nf_hook_ops ops;
|
||||
+ struct net *net;
|
||||
+ bool registered;
|
||||
+ bool used;
|
||||
+};
|
||||
+
|
||||
+struct xt_flowoffload_table {
|
||||
+ struct nf_flowtable ft;
|
||||
+ struct hlist_head hooks;
|
||||
+ struct delayed_work work;
|
||||
+};
|
||||
+
|
||||
+struct nf_forward_info {
|
||||
+ const struct net_device *indev;
|
||||
+ const struct net_device *outdev;
|
||||
+ const struct net_device *hw_outdev;
|
||||
+ struct id {
|
||||
+ __u16 id;
|
||||
+ __be16 proto;
|
||||
+ } encap[NF_FLOW_TABLE_ENCAP_MAX];
|
||||
+ u8 num_encaps;
|
||||
+ u8 ingress_vlans;
|
||||
+ u8 h_source[ETH_ALEN];
|
||||
+ u8 h_dest[ETH_ALEN];
|
||||
+ enum flow_offload_xmit_type xmit_type;
|
||||
+};
|
||||
+
|
||||
+static DEFINE_SPINLOCK(hooks_lock);
|
||||
+
|
||||
+struct xt_flowoffload_table flowtable[2];
|
||||
+
|
||||
+static unsigned int
|
||||
+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
|
||||
+ const struct nf_hook_state *state)
|
||||
+{
|
||||
+ struct vlan_ethhdr *veth;
|
||||
+ __be16 proto;
|
||||
+
|
||||
+ switch (skb->protocol) {
|
||||
+ case htons(ETH_P_8021Q):
|
||||
+ veth = (struct vlan_ethhdr *)skb_mac_header(skb);
|
||||
+ proto = veth->h_vlan_encapsulated_proto;
|
||||
+ break;
|
||||
+ case htons(ETH_P_PPP_SES):
|
||||
+ proto = nf_flow_pppoe_proto(skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ proto = skb->protocol;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (proto) {
|
||||
+ case htons(ETH_P_IP):
|
||||
+ return nf_flow_offload_ip_hook(priv, skb, state);
|
||||
+ case htons(ETH_P_IPV6):
|
||||
+ return nf_flow_offload_ipv6_hook(priv, skb, state);
|
||||
+ }
|
||||
+
|
||||
+ return NF_ACCEPT;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+xt_flowoffload_create_hook(struct xt_flowoffload_table *table,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ struct xt_flowoffload_hook *hook;
|
||||
+ struct nf_hook_ops *ops;
|
||||
+
|
||||
+ hook = kzalloc(sizeof(*hook), GFP_ATOMIC);
|
||||
+ if (!hook)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ops = &hook->ops;
|
||||
+ ops->pf = NFPROTO_NETDEV;
|
||||
+ ops->hooknum = NF_NETDEV_INGRESS;
|
||||
+ ops->priority = 10;
|
||||
+ ops->priv = &table->ft;
|
||||
+ ops->hook = xt_flowoffload_net_hook;
|
||||
+ ops->dev = dev;
|
||||
+
|
||||
+ hlist_add_head(&hook->list, &table->hooks);
|
||||
+ mod_delayed_work(system_power_efficient_wq, &table->work, 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct xt_flowoffload_hook *
|
||||
+flow_offload_lookup_hook(struct xt_flowoffload_table *table,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ struct xt_flowoffload_hook *hook;
|
||||
+
|
||||
+ hlist_for_each_entry(hook, &table->hooks, list) {
|
||||
+ if (hook->ops.dev == dev)
|
||||
+ return hook;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xt_flowoffload_check_device(struct xt_flowoffload_table *table,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ struct xt_flowoffload_hook *hook;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock_bh(&hooks_lock);
|
||||
+ hook = flow_offload_lookup_hook(table, dev);
|
||||
+ if (hook)
|
||||
+ hook->used = true;
|
||||
+ else
|
||||
+ xt_flowoffload_create_hook(table, dev);
|
||||
+ spin_unlock_bh(&hooks_lock);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xt_flowoffload_register_hooks(struct xt_flowoffload_table *table)
|
||||
+{
|
||||
+ struct xt_flowoffload_hook *hook;
|
||||
+
|
||||
+restart:
|
||||
+ hlist_for_each_entry(hook, &table->hooks, list) {
|
||||
+ if (hook->registered)
|
||||
+ continue;
|
||||
+
|
||||
+ hook->registered = true;
|
||||
+ hook->net = dev_net(hook->ops.dev);
|
||||
+ spin_unlock_bh(&hooks_lock);
|
||||
+ nf_register_net_hook(hook->net, &hook->ops);
|
||||
+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
|
||||
+ table->ft.type->setup(&table->ft, hook->ops.dev,
|
||||
+ FLOW_BLOCK_BIND);
|
||||
+ spin_lock_bh(&hooks_lock);
|
||||
+ goto restart;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table)
|
||||
+{
|
||||
+ struct xt_flowoffload_hook *hook;
|
||||
+ bool active = false;
|
||||
+
|
||||
+restart:
|
||||
+ spin_lock_bh(&hooks_lock);
|
||||
+ hlist_for_each_entry(hook, &table->hooks, list) {
|
||||
+ if (hook->used || !hook->registered) {
|
||||
+ active = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ hlist_del(&hook->list);
|
||||
+ spin_unlock_bh(&hooks_lock);
|
||||
+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
|
||||
+ table->ft.type->setup(&table->ft, hook->ops.dev,
|
||||
+ FLOW_BLOCK_UNBIND);
|
||||
+ nf_unregister_net_hook(hook->net, &hook->ops);
|
||||
+ kfree(hook);
|
||||
+ goto restart;
|
||||
+ }
|
||||
+ spin_unlock_bh(&hooks_lock);
|
||||
+
|
||||
+ return active;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xt_flowoffload_check_hook(struct nf_flowtable *flowtable,
|
||||
+ struct flow_offload *flow, void *data)
|
||||
+{
|
||||
+ struct xt_flowoffload_table *table;
|
||||
+ struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple;
|
||||
+ struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple;
|
||||
+ struct xt_flowoffload_hook *hook;
|
||||
+
|
||||
+ table = container_of(flowtable, struct xt_flowoffload_table, ft);
|
||||
+
|
||||
+ spin_lock_bh(&hooks_lock);
|
||||
+ hlist_for_each_entry(hook, &table->hooks, list) {
|
||||
+ if (hook->ops.dev->ifindex != tuple0->iifidx &&
|
||||
+ hook->ops.dev->ifindex != tuple1->iifidx)
|
||||
+ continue;
|
||||
+
|
||||
+ hook->used = true;
|
||||
+ }
|
||||
+ spin_unlock_bh(&hooks_lock);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xt_flowoffload_hook_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct xt_flowoffload_table *table;
|
||||
+ struct xt_flowoffload_hook *hook;
|
||||
+ int err;
|
||||
+
|
||||
+ table = container_of(work, struct xt_flowoffload_table, work.work);
|
||||
+
|
||||
+ spin_lock_bh(&hooks_lock);
|
||||
+ xt_flowoffload_register_hooks(table);
|
||||
+ hlist_for_each_entry(hook, &table->hooks, list)
|
||||
+ hook->used = false;
|
||||
+ spin_unlock_bh(&hooks_lock);
|
||||
+
|
||||
+ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook,
|
||||
+ NULL);
|
||||
+ if (err && err != -EAGAIN)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!xt_flowoffload_cleanup_hooks(table))
|
||||
+ return;
|
||||
+
|
||||
+out:
|
||||
+ queue_delayed_work(system_power_efficient_wq, &table->work, HZ);
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+xt_flowoffload_skip(struct sk_buff *skb, int family)
|
||||
+{
|
||||
+ if (skb_sec_path(skb))
|
||||
+ return true;
|
||||
+
|
||||
+ if (family == NFPROTO_IPV4) {
|
||||
+ const struct ip_options *opt = &(IPCB(skb)->opt);
|
||||
+
|
||||
+ if (unlikely(opt->optlen))
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static enum flow_offload_xmit_type nf_xmit_type(struct dst_entry *dst)
|
||||
+{
|
||||
+ if (dst_xfrm(dst))
|
||||
+ return FLOW_OFFLOAD_XMIT_XFRM;
|
||||
+
|
||||
+ return FLOW_OFFLOAD_XMIT_NEIGH;
|
||||
+}
|
||||
+
|
||||
+static void nf_default_forward_path(struct nf_flow_route *route,
|
||||
+ struct dst_entry *dst_cache,
|
||||
+ enum ip_conntrack_dir dir,
|
||||
+ struct net_device **dev)
|
||||
+{
|
||||
+ dev[!dir] = dst_cache->dev;
|
||||
+ route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex;
|
||||
+ route->tuple[dir].dst = dst_cache;
|
||||
+ route->tuple[dir].xmit_type = nf_xmit_type(dst_cache);
|
||||
+}
|
||||
+
|
||||
+static bool nf_is_valid_ether_device(const struct net_device *dev)
|
||||
+{
|
||||
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static void nf_dev_path_info(const struct net_device_path_stack *stack,
|
||||
+ struct nf_forward_info *info,
|
||||
+ unsigned char *ha)
|
||||
+{
|
||||
+ const struct net_device_path *path;
|
||||
+ int i;
|
||||
+
|
||||
+ memcpy(info->h_dest, ha, ETH_ALEN);
|
||||
+
|
||||
+ for (i = 0; i < stack->num_paths; i++) {
|
||||
+ path = &stack->path[i];
|
||||
+ switch (path->type) {
|
||||
+ case DEV_PATH_ETHERNET:
|
||||
+ case DEV_PATH_DSA:
|
||||
+ case DEV_PATH_VLAN:
|
||||
+ case DEV_PATH_PPPOE:
|
||||
+ info->indev = path->dev;
|
||||
+ if (is_zero_ether_addr(info->h_source))
|
||||
+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||
+
|
||||
+ if (path->type == DEV_PATH_ETHERNET)
|
||||
+ break;
|
||||
+ if (path->type == DEV_PATH_DSA) {
|
||||
+ i = stack->num_paths;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */
|
||||
+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
|
||||
+ info->indev = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!info->outdev)
|
||||
+ info->outdev = path->dev;
|
||||
+ info->encap[info->num_encaps].id = path->encap.id;
|
||||
+ info->encap[info->num_encaps].proto = path->encap.proto;
|
||||
+ info->num_encaps++;
|
||||
+ if (path->type == DEV_PATH_PPPOE)
|
||||
+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
|
||||
+ break;
|
||||
+ case DEV_PATH_BRIDGE:
|
||||
+ if (is_zero_ether_addr(info->h_source))
|
||||
+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||
+
|
||||
+ switch (path->bridge.vlan_mode) {
|
||||
+ case DEV_PATH_BR_VLAN_UNTAG_HW:
|
||||
+ info->ingress_vlans |= BIT(info->num_encaps - 1);
|
||||
+ break;
|
||||
+ case DEV_PATH_BR_VLAN_TAG:
|
||||
+ info->encap[info->num_encaps].id = path->bridge.vlan_id;
|
||||
+ info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
|
||||
+ info->num_encaps++;
|
||||
+ break;
|
||||
+ case DEV_PATH_BR_VLAN_UNTAG:
|
||||
+ info->num_encaps--;
|
||||
+ break;
|
||||
+ case DEV_PATH_BR_VLAN_KEEP:
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ info->indev = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!info->outdev)
|
||||
+ info->outdev = info->indev;
|
||||
+
|
||||
+ info->hw_outdev = info->indev;
|
||||
+
|
||||
+ if (nf_is_valid_ether_device(info->indev))
|
||||
+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
|
||||
+}
|
||||
+
|
||||
+static int nf_dev_fill_forward_path(const struct nf_flow_route *route,
|
||||
+ const struct dst_entry *dst_cache,
|
||||
+ const struct nf_conn *ct,
|
||||
+ enum ip_conntrack_dir dir, u8 *ha,
|
||||
+ struct net_device_path_stack *stack)
|
||||
+{
|
||||
+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
|
||||
+ struct net_device *dev = dst_cache->dev;
|
||||
+ struct neighbour *n;
|
||||
+ u8 nud_state;
|
||||
+
|
||||
+ if (!nf_is_valid_ether_device(dev))
|
||||
+ goto out;
|
||||
+
|
||||
+ n = dst_neigh_lookup(dst_cache, daddr);
|
||||
+ if (!n)
|
||||
+ return -1;
|
||||
+
|
||||
+ read_lock_bh(&n->lock);
|
||||
+ nud_state = n->nud_state;
|
||||
+ ether_addr_copy(ha, n->ha);
|
||||
+ read_unlock_bh(&n->lock);
|
||||
+ neigh_release(n);
|
||||
+
|
||||
+ if (!(nud_state & NUD_VALID))
|
||||
+ return -1;
|
||||
+
|
||||
+out:
|
||||
+ return dev_fill_forward_path(dev, ha, stack);
|
||||
+}
|
||||
+
|
||||
+static void nf_dev_forward_path(struct nf_flow_route *route,
|
||||
+ const struct nf_conn *ct,
|
||||
+ enum ip_conntrack_dir dir,
|
||||
+ struct net_device **devs)
|
||||
+{
|
||||
+ const struct dst_entry *dst = route->tuple[dir].dst;
|
||||
+ struct net_device_path_stack stack;
|
||||
+ struct nf_forward_info info = {};
|
||||
+ unsigned char ha[ETH_ALEN];
|
||||
+ int i;
|
||||
+
|
||||
+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
|
||||
+ nf_dev_path_info(&stack, &info, ha);
|
||||
+
|
||||
+ devs[!dir] = (struct net_device *)info.indev;
|
||||
+ if (!info.indev)
|
||||
+ return;
|
||||
+
|
||||
+ route->tuple[!dir].in.ifindex = info.indev->ifindex;
|
||||
+ for (i = 0; i < info.num_encaps; i++) {
|
||||
+ route->tuple[!dir].in.encap[i].id = info.encap[i].id;
|
||||
+ route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
|
||||
+ }
|
||||
+ route->tuple[!dir].in.num_encaps = info.num_encaps;
|
||||
+ route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
|
||||
+
|
||||
+ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
|
||||
+ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
|
||||
+ memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
|
||||
+ route->tuple[dir].out.ifindex = info.outdev->ifindex;
|
||||
+ route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex;
|
||||
+ route->tuple[dir].xmit_type = info.xmit_type;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
|
||||
+ const struct xt_action_param *par,
|
||||
+ struct nf_flow_route *route, enum ip_conntrack_dir dir,
|
||||
+ struct net_device **devs)
|
||||
+{
|
||||
+ struct dst_entry *this_dst = skb_dst(skb);
|
||||
+ struct dst_entry *other_dst = NULL;
|
||||
+ struct flowi fl;
|
||||
+
|
||||
+ memset(&fl, 0, sizeof(fl));
|
||||
+ switch (xt_family(par)) {
|
||||
+ case NFPROTO_IPV4:
|
||||
+ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip;
|
||||
+ fl.u.ip4.flowi4_oif = xt_in(par)->ifindex;
|
||||
+ break;
|
||||
+ case NFPROTO_IPV6:
|
||||
+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
|
||||
+ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6;
|
||||
+ fl.u.ip6.flowi6_oif = xt_in(par)->ifindex;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par));
|
||||
+ if (!other_dst)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ nf_default_forward_path(route, this_dst, dir, devs);
|
||||
+ nf_default_forward_path(route, other_dst, !dir, devs);
|
||||
+
|
||||
+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH &&
|
||||
+ route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
|
||||
+ nf_dev_forward_path(route, ct, dir, devs);
|
||||
+ nf_dev_forward_path(route, ct, !dir, devs);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
+{
|
||||
+ struct xt_flowoffload_table *table;
|
||||
+ const struct xt_flowoffload_target_info *info = par->targinfo;
|
||||
+ struct tcphdr _tcph, *tcph = NULL;
|
||||
+ enum ip_conntrack_info ctinfo;
|
||||
+ enum ip_conntrack_dir dir;
|
||||
+ struct nf_flow_route route = {};
|
||||
+ struct flow_offload *flow = NULL;
|
||||
+ struct net_device *devs[2] = {};
|
||||
+ struct nf_conn *ct;
|
||||
+ struct net *net;
|
||||
+
|
||||
+ if (xt_flowoffload_skip(skb, xt_family(par)))
|
||||
+ return XT_CONTINUE;
|
||||
+
|
||||
+ ct = nf_ct_get(skb, &ctinfo);
|
||||
+ if (ct == NULL)
|
||||
+ return XT_CONTINUE;
|
||||
+
|
||||
+ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) {
|
||||
+ case IPPROTO_TCP:
|
||||
+ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED)
|
||||
+ return XT_CONTINUE;
|
||||
+
|
||||
+ tcph = skb_header_pointer(skb, par->thoff,
|
||||
+ sizeof(_tcph), &_tcph);
|
||||
+ if (unlikely(!tcph || tcph->fin || tcph->rst))
|
||||
+ return XT_CONTINUE;
|
||||
+ break;
|
||||
+ case IPPROTO_UDP:
|
||||
+ break;
|
||||
+ default:
|
||||
+ return XT_CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
|
||||
+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH))
|
||||
+ return XT_CONTINUE;
|
||||
+
|
||||
+ if (!nf_ct_is_confirmed(ct))
|
||||
+ return XT_CONTINUE;
|
||||
+
|
||||
+ devs[dir] = xt_out(par);
|
||||
+ devs[!dir] = xt_in(par);
|
||||
+
|
||||
+ if (!devs[dir] || !devs[!dir])
|
||||
+ return XT_CONTINUE;
|
||||
+
|
||||
+ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
|
||||
+ return XT_CONTINUE;
|
||||
+
|
||||
+ dir = CTINFO2DIR(ctinfo);
|
||||
+
|
||||
+ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0)
|
||||
+ goto err_flow_route;
|
||||
+
|
||||
+ flow = flow_offload_alloc(ct);
|
||||
+ if (!flow)
|
||||
+ goto err_flow_alloc;
|
||||
+
|
||||
+ if (flow_offload_route_init(flow, &route) < 0)
|
||||
+ goto err_flow_add;
|
||||
+
|
||||
+ if (tcph) {
|
||||
+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
||||
+ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
||||
+ }
|
||||
+
|
||||
+ table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)];
|
||||
+
|
||||
+ net = read_pnet(&table->ft.net);
|
||||
+ if (!net)
|
||||
+ write_pnet(&table->ft.net, xt_net(par));
|
||||
+
|
||||
+ if (flow_offload_add(&table->ft, flow) < 0)
|
||||
+ goto err_flow_add;
|
||||
+
|
||||
+ xt_flowoffload_check_device(table, devs[0]);
|
||||
+ xt_flowoffload_check_device(table, devs[1]);
|
||||
+
|
||||
+ dst_release(route.tuple[!dir].dst);
|
||||
+
|
||||
+ return XT_CONTINUE;
|
||||
+
|
||||
+err_flow_add:
|
||||
+ flow_offload_free(flow);
|
||||
+err_flow_alloc:
|
||||
+ dst_release(route.tuple[!dir].dst);
|
||||
+err_flow_route:
|
||||
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
||||
+
|
||||
+ return XT_CONTINUE;
|
||||
+}
|
||||
+
|
||||
+static int flowoffload_chk(const struct xt_tgchk_param *par)
|
||||
+{
|
||||
+ struct xt_flowoffload_target_info *info = par->targinfo;
|
||||
+
|
||||
+ if (info->flags & ~XT_FLOWOFFLOAD_MASK)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct xt_target offload_tg_reg __read_mostly = {
|
||||
+ .family = NFPROTO_UNSPEC,
|
||||
+ .name = "FLOWOFFLOAD",
|
||||
+ .revision = 0,
|
||||
+ .targetsize = sizeof(struct xt_flowoffload_target_info),
|
||||
+ .usersize = sizeof(struct xt_flowoffload_target_info),
|
||||
+ .checkentry = flowoffload_chk,
|
||||
+ .target = flowoffload_tg,
|
||||
+ .me = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int flow_offload_netdev_event(struct notifier_block *this,
|
||||
+ unsigned long event, void *ptr)
|
||||
+{
|
||||
+ struct xt_flowoffload_hook *hook0, *hook1;
|
||||
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
+
|
||||
+ if (event != NETDEV_UNREGISTER)
|
||||
+ return NOTIFY_DONE;
|
||||
+
|
||||
+ spin_lock_bh(&hooks_lock);
|
||||
+ hook0 = flow_offload_lookup_hook(&flowtable[0], dev);
|
||||
+ if (hook0)
|
||||
+ hlist_del(&hook0->list);
|
||||
+
|
||||
+ hook1 = flow_offload_lookup_hook(&flowtable[1], dev);
|
||||
+ if (hook1)
|
||||
+ hlist_del(&hook1->list);
|
||||
+ spin_unlock_bh(&hooks_lock);
|
||||
+
|
||||
+ if (hook0) {
|
||||
+ nf_unregister_net_hook(hook0->net, &hook0->ops);
|
||||
+ kfree(hook0);
|
||||
+ }
|
||||
+
|
||||
+ if (hook1) {
|
||||
+ nf_unregister_net_hook(hook1->net, &hook1->ops);
|
||||
+ kfree(hook1);
|
||||
+ }
|
||||
+
|
||||
+ nf_flow_table_cleanup(dev);
|
||||
+
|
||||
+ return NOTIFY_DONE;
|
||||
+}
|
||||
+
|
||||
+static struct notifier_block flow_offload_netdev_notifier = {
|
||||
+ .notifier_call = flow_offload_netdev_event,
|
||||
+};
|
||||
+
|
||||
+static int nf_flow_rule_route_inet(struct net *net,
|
||||
+ const struct flow_offload *flow,
|
||||
+ enum flow_offload_tuple_dir dir,
|
||||
+ struct nf_flow_rule *flow_rule)
|
||||
+{
|
||||
+ const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
|
||||
+ int err;
|
||||
+
|
||||
+ switch (flow_tuple->l3proto) {
|
||||
+ case NFPROTO_IPV4:
|
||||
+ err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule);
|
||||
+ break;
|
||||
+ case NFPROTO_IPV6:
|
||||
+ err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule);
|
||||
+ break;
|
||||
+ default:
|
||||
+ err = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static struct nf_flowtable_type flowtable_inet = {
|
||||
+ .family = NFPROTO_INET,
|
||||
+ .init = nf_flow_table_init,
|
||||
+ .setup = nf_flow_table_offload_setup,
|
||||
+ .action = nf_flow_rule_route_inet,
|
||||
+ .free = nf_flow_table_free,
|
||||
+ .hook = xt_flowoffload_net_hook,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int init_flowtable(struct xt_flowoffload_table *tbl)
|
||||
+{
|
||||
+ INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work);
|
||||
+ tbl->ft.type = &flowtable_inet;
|
||||
+
|
||||
+ return nf_flow_table_init(&tbl->ft);
|
||||
+}
|
||||
+
|
||||
+static int __init xt_flowoffload_tg_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ register_netdevice_notifier(&flow_offload_netdev_notifier);
|
||||
+
|
||||
+ ret = init_flowtable(&flowtable[0]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = init_flowtable(&flowtable[1]);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ flowtable[1].ft.flags = NF_FLOWTABLE_HW_OFFLOAD;
|
||||
+
|
||||
+ ret = xt_register_target(&offload_tg_reg);
|
||||
+ if (ret)
|
||||
+ goto cleanup2;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+cleanup2:
|
||||
+ nf_flow_table_free(&flowtable[1].ft);
|
||||
+cleanup:
|
||||
+ nf_flow_table_free(&flowtable[0].ft);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __exit xt_flowoffload_tg_exit(void)
|
||||
+{
|
||||
+ xt_unregister_target(&offload_tg_reg);
|
||||
+ unregister_netdevice_notifier(&flow_offload_netdev_notifier);
|
||||
+ nf_flow_table_free(&flowtable[0].ft);
|
||||
+ nf_flow_table_free(&flowtable[1].ft);
|
||||
+}
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+module_init(xt_flowoffload_tg_init);
|
||||
+module_exit(xt_flowoffload_tg_exit);
|
||||
--- a/net/netfilter/nf_flow_table_core.c
|
||||
+++ b/net/netfilter/nf_flow_table_core.c
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ip6_route.h>
|
||||
-#include <net/netfilter/nf_tables.h>
|
||||
#include <net/netfilter/nf_flow_table.h>
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <net/netfilter/nf_conntrack_core.h>
|
||||
@@ -381,8 +380,7 @@ flow_offload_lookup(struct nf_flowtable
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(flow_offload_lookup);
|
||||
|
||||
-static int
|
||||
-nf_flow_table_iterate(struct nf_flowtable *flow_table,
|
||||
+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
|
||||
void (*iter)(struct nf_flowtable *flowtable,
|
||||
struct flow_offload *flow, void *data),
|
||||
void *data)
|
||||
@@ -436,6 +434,7 @@ static void nf_flow_offload_gc_step(stru
|
||||
nf_flow_offload_stats(flow_table, flow);
|
||||
}
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(nf_flow_table_iterate);
|
||||
|
||||
void nf_flow_table_gc_run(struct nf_flowtable *flow_table)
|
||||
{
|
||||
--- /dev/null
|
||||
+++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
+#ifndef _XT_FLOWOFFLOAD_H
|
||||
+#define _XT_FLOWOFFLOAD_H
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+enum {
|
||||
+ XT_FLOWOFFLOAD_HW = 1 << 0,
|
||||
+
|
||||
+ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW
|
||||
+};
|
||||
+
|
||||
+struct xt_flowoffload_target_info {
|
||||
+ __u32 flags;
|
||||
+};
|
||||
+
|
||||
+#endif /* _XT_FLOWOFFLOAD_H */
|
||||
--- a/include/net/netfilter/nf_flow_table.h
|
||||
+++ b/include/net/netfilter/nf_flow_table.h
|
||||
@@ -280,6 +280,11 @@ void nf_flow_table_free(struct nf_flowta
|
||||
|
||||
void flow_offload_teardown(struct flow_offload *flow);
|
||||
|
||||
+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
|
||||
+ void (*iter)(struct nf_flowtable *flowtable,
|
||||
+ struct flow_offload *flow, void *data),
|
||||
+ void *data);
|
||||
+
|
||||
void nf_flow_snat_port(const struct flow_offload *flow,
|
||||
struct sk_buff *skb, unsigned int thoff,
|
||||
u8 protocol, enum flow_offload_tuple_dir dir);
|
|
@ -1,24 +0,0 @@
|
|||
From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001
|
||||
From: Imre Kaloz <kaloz@openwrt.org>
|
||||
Date: Fri, 7 Jul 2017 17:21:05 +0200
|
||||
Subject: mac80211: increase wireless mesh header size
|
||||
|
||||
lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1
|
||||
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
|
||||
---
|
||||
include/linux/netdevice.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/include/linux/netdevice.h
|
||||
+++ b/include/linux/netdevice.h
|
||||
@@ -150,8 +150,8 @@ static inline bool dev_xmit_complete(int
|
||||
|
||||
#if defined(CONFIG_HYPERV_NET)
|
||||
# define LL_MAX_HEADER 128
|
||||
-#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
|
||||
-# if defined(CONFIG_MAC80211_MESH)
|
||||
+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1
|
||||
+# if defined(CONFIG_MAC80211_MESH) || 1
|
||||
# define LL_MAX_HEADER 128
|
||||
# else
|
||||
# define LL_MAX_HEADER 96
|
|
@ -1,27 +0,0 @@
|
|||
From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 7 Jul 2017 17:21:53 +0200
|
||||
Subject: hack: net: fq_codel: tune defaults for small devices
|
||||
|
||||
Assume that x86_64 devices always have a big memory and do not need this
|
||||
optimization compared to devices with only 32 MB or 64 MB RAM.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
net/sched/sch_fq_codel.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/net/sched/sch_fq_codel.c
|
||||
+++ b/net/sched/sch_fq_codel.c
|
||||
@@ -471,7 +471,11 @@ static int fq_codel_init(struct Qdisc *s
|
||||
|
||||
sch->limit = 10*1024;
|
||||
q->flows_cnt = 1024;
|
||||
+#ifdef CONFIG_X86_64
|
||||
q->memory_limit = 32 << 20; /* 32 MBytes */
|
||||
+#else
|
||||
+ q->memory_limit = 4 << 20; /* 4 MBytes */
|
||||
+#endif
|
||||
q->drop_batch_size = 64;
|
||||
q->quantum = psched_mtu(qdisc_dev(sch));
|
||||
INIT_LIST_HEAD(&q->new_flows);
|
|
@ -1,25 +0,0 @@
|
|||
From 804fbb3f2ec9283f7b778e057a68bfff440a0be6 Mon Sep 17 00:00:00 2001
|
||||
From: Rui Salvaterra <rsalvaterra@gmail.com>
|
||||
Date: Wed, 30 Mar 2022 22:51:55 +0100
|
||||
Subject: [PATCH] kernel: ct: size the hashtable more adequately
|
||||
|
||||
To set the default size of the connection tracking hash table, a divider of
|
||||
16384 becomes inadequate for a router handling lots of connections. Divide by
|
||||
2048 instead, making the default size scale better with the available RAM.
|
||||
|
||||
Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
|
||||
---
|
||||
net/netfilter/nf_conntrack_core.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/net/netfilter/nf_conntrack_core.c
|
||||
+++ b/net/netfilter/nf_conntrack_core.c
|
||||
@@ -2698,7 +2698,7 @@ int nf_conntrack_init_start(void)
|
||||
|
||||
if (!nf_conntrack_htable_size) {
|
||||
nf_conntrack_htable_size
|
||||
- = (((nr_pages << PAGE_SHIFT) / 16384)
|
||||
+ = (((nr_pages << PAGE_SHIFT) / 2048)
|
||||
/ sizeof(struct hlist_head));
|
||||
if (BITS_PER_LONG >= 64 &&
|
||||
nr_pages > (4 * (1024 * 1024 * 1024 / PAGE_SIZE)))
|
|
@ -1,131 +0,0 @@
|
|||
From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 7 Jul 2017 17:24:23 +0200
|
||||
Subject: net: swconfig: adds openwrt switch layer
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
drivers/net/phy/Kconfig | 83 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/net/phy/Makefile | 15 +++++++++
|
||||
include/uapi/linux/Kbuild | 1 +
|
||||
3 files changed, 99 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -61,6 +61,80 @@ config SFP
|
||||
depends on HWMON || HWMON=n
|
||||
select MDIO_I2C
|
||||
|
||||
+comment "Switch configuration API + drivers"
|
||||
+
|
||||
+config SWCONFIG
|
||||
+ tristate "Switch configuration API"
|
||||
+ help
|
||||
+ Switch configuration API using netlink. This allows
|
||||
+ you to configure the VLAN features of certain switches.
|
||||
+
|
||||
+config SWCONFIG_LEDS
|
||||
+ bool "Switch LED trigger support"
|
||||
+ depends on (SWCONFIG && LEDS_TRIGGERS)
|
||||
+
|
||||
+config ADM6996_PHY
|
||||
+ tristate "Driver for ADM6996 switches"
|
||||
+ select SWCONFIG
|
||||
+ help
|
||||
+ Currently supports the ADM6996FC and ADM6996M switches.
|
||||
+ Support for FC is very limited.
|
||||
+
|
||||
+config AR8216_PHY
|
||||
+ tristate "Driver for Atheros AR8216/8327 switches"
|
||||
+ select SWCONFIG
|
||||
+ select ETHERNET_PACKET_MANGLE
|
||||
+
|
||||
+config AR8216_PHY_LEDS
|
||||
+ bool "Atheros AR8216 switch LED support"
|
||||
+ depends on (AR8216_PHY && LEDS_CLASS)
|
||||
+
|
||||
+source "drivers/net/phy/b53/Kconfig"
|
||||
+
|
||||
+config IP17XX_PHY
|
||||
+ tristate "Driver for IC+ IP17xx switches"
|
||||
+ select SWCONFIG
|
||||
+
|
||||
+config PSB6970_PHY
|
||||
+ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch"
|
||||
+ select SWCONFIG
|
||||
+
|
||||
+config RTL8306_PHY
|
||||
+ tristate "Driver for Realtek RTL8306S switches"
|
||||
+ select SWCONFIG
|
||||
+
|
||||
+config RTL8366_SMI
|
||||
+ tristate "Driver for the RTL8366 SMI interface"
|
||||
+ depends on GPIOLIB
|
||||
+ help
|
||||
+ This module implements the SMI interface protocol which is used
|
||||
+ by some RTL8366 ethernet switch devices via the generic GPIO API.
|
||||
+
|
||||
+if RTL8366_SMI
|
||||
+
|
||||
+config RTL8366_SMI_DEBUG_FS
|
||||
+ bool "RTL8366 SMI interface debugfs support"
|
||||
+ depends on DEBUG_FS
|
||||
+ default n
|
||||
+
|
||||
+config RTL8366S_PHY
|
||||
+ tristate "Driver for the Realtek RTL8366S switch"
|
||||
+ select SWCONFIG
|
||||
+
|
||||
+config RTL8366RB_PHY
|
||||
+ tristate "Driver for the Realtek RTL8366RB switch"
|
||||
+ select SWCONFIG
|
||||
+
|
||||
+config RTL8367_PHY
|
||||
+ tristate "Driver for the Realtek RTL8367R/M switches"
|
||||
+ select SWCONFIG
|
||||
+
|
||||
+config RTL8367B_PHY
|
||||
+ tristate "Driver fot the Realtek RTL8367R-VB switch"
|
||||
+ select SWCONFIG
|
||||
+
|
||||
+endif # RTL8366_SMI
|
||||
+
|
||||
comment "MII PHY device drivers"
|
||||
|
||||
config AMD_PHY
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -24,6 +24,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_
|
||||
obj-$(CONFIG_PHYLINK) += phylink.o
|
||||
obj-$(CONFIG_PHYLIB) += libphy.o
|
||||
|
||||
+obj-$(CONFIG_SWCONFIG) += swconfig.o
|
||||
+obj-$(CONFIG_ADM6996_PHY) += adm6996.o
|
||||
+obj-$(CONFIG_AR8216_PHY) += ar8xxx.o
|
||||
+ar8xxx-y += ar8216.o
|
||||
+ar8xxx-y += ar8327.o
|
||||
+obj-$(CONFIG_SWCONFIG_B53) += b53/
|
||||
+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
|
||||
+obj-$(CONFIG_PSB6970_PHY) += psb6970.o
|
||||
+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
|
||||
+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o
|
||||
+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o
|
||||
+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o
|
||||
+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o
|
||||
+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o
|
||||
+
|
||||
obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o
|
||||
|
||||
obj-$(CONFIG_SFP) += sfp.o
|
||||
--- a/include/linux/platform_data/b53.h
|
||||
+++ b/include/linux/platform_data/b53.h
|
||||
@@ -29,6 +29,9 @@ struct b53_platform_data {
|
||||
u32 chip_id;
|
||||
u16 enabled_ports;
|
||||
|
||||
+ /* allow to specify an ethX alias */
|
||||
+ const char *alias;
|
||||
+
|
||||
/* only used by MMAP'd driver */
|
||||
unsigned big_endian:1;
|
||||
void __iomem *regs;
|
|
@ -1,21 +0,0 @@
|
|||
From ebd924d773223593142d417c41d4ee6fa16f1805 Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:45:56 +0200
|
||||
Subject: [PATCH] net/dsa/mv88e6xxx: disable ATU violation
|
||||
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -3461,6 +3461,9 @@ static int mv88e6xxx_setup_port(struct m
|
||||
else
|
||||
reg = 1 << port;
|
||||
|
||||
+ /* Disable ATU member violation interrupt */
|
||||
+ reg |= MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG;
|
||||
+
|
||||
err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
|
||||
reg);
|
||||
if (err)
|
|
@ -1,120 +0,0 @@
|
|||
From: Birger Koblitz <git@birger-koblitz.de>
|
||||
Date: Sun, 5 Sep 2021 15:13:10 +0200
|
||||
Subject: [PATCH] kernel: Add AQR113C and AQR813 support
|
||||
|
||||
This hack adds support for the Aquantia 4th generation, 10GBit
|
||||
PHYs AQR113C and AQR813.
|
||||
|
||||
Signed-off-by: Birger Koblitz <git@birger-koblitz.de>
|
||||
|
||||
--- a/drivers/net/phy/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia_main.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#define PHY_ID_AQCS109 0x03a1b5c2
|
||||
#define PHY_ID_AQR405 0x03a1b4b0
|
||||
#define PHY_ID_AQR113C 0x31c31c12
|
||||
+#define PHY_ID_AQR813 0x31c31cb2
|
||||
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
|
||||
@@ -415,6 +416,49 @@ static int aqr107_read_rate(struct phy_d
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int aqr113c_read_status(struct phy_device *phydev)
|
||||
+{
|
||||
+ int val, ret;
|
||||
+
|
||||
+ ret = aqr_read_status(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
|
||||
+ return 0;
|
||||
+
|
||||
+ // On AQR113C, the speed returned by aqr_read_status is wrong
|
||||
+ aqr107_read_rate(phydev);
|
||||
+
|
||||
+ val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+
|
||||
+ switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
|
||||
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
|
||||
+ phydev->interface = PHY_INTERFACE_MODE_10GKR;
|
||||
+ break;
|
||||
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
|
||||
+ phydev->interface = PHY_INTERFACE_MODE_10GBASER;
|
||||
+ break;
|
||||
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
|
||||
+ phydev->interface = PHY_INTERFACE_MODE_USXGMII;
|
||||
+ break;
|
||||
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
|
||||
+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
|
||||
+ break;
|
||||
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
|
||||
+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ phydev->interface = PHY_INTERFACE_MODE_NA;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Read downshifted rate from vendor register */
|
||||
+ return aqr107_read_rate(phydev);
|
||||
+}
|
||||
+
|
||||
static int aqr107_read_status(struct phy_device *phydev)
|
||||
{
|
||||
int val, ret;
|
||||
@@ -554,7 +598,7 @@ static void aqr107_chip_info(struct phy_
|
||||
build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);
|
||||
prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);
|
||||
|
||||
- phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
|
||||
+ phydev_info(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
|
||||
fw_major, fw_minor, build_id, prov_id);
|
||||
}
|
||||
|
||||
@@ -809,7 +853,7 @@ static struct phy_driver aqr_driver[] =
|
||||
.config_aneg = aqr_config_aneg,
|
||||
.config_intr = aqr_config_intr,
|
||||
.handle_interrupt = aqr_handle_interrupt,
|
||||
- .read_status = aqr107_read_status,
|
||||
+ .read_status = aqr113c_read_status,
|
||||
.get_tunable = aqr107_get_tunable,
|
||||
.set_tunable = aqr107_set_tunable,
|
||||
.suspend = aqr107_suspend,
|
||||
@@ -819,6 +863,24 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
},
|
||||
+{
|
||||
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
|
||||
+ .name = "Aquantia AQR813",
|
||||
+ .probe = aqr107_probe,
|
||||
+ .config_init = aqr107_config_init,
|
||||
+ .config_aneg = aqr_config_aneg,
|
||||
+ .config_intr = aqr_config_intr,
|
||||
+ .handle_interrupt = aqr_handle_interrupt,
|
||||
+ .read_status = aqr113c_read_status,
|
||||
+ .get_tunable = aqr107_get_tunable,
|
||||
+ .set_tunable = aqr107_set_tunable,
|
||||
+ .suspend = aqr107_suspend,
|
||||
+ .resume = aqr107_resume,
|
||||
+ .get_sset_count = aqr107_get_sset_count,
|
||||
+ .get_strings = aqr107_get_strings,
|
||||
+ .get_stats = aqr107_get_stats,
|
||||
+ .link_change_notify = aqr107_link_change_notify,
|
||||
+},
|
||||
};
|
||||
|
||||
module_phy_driver(aqr_driver);
|
||||
@@ -832,6 +894,7 @@ static struct mdio_device_id __maybe_unu
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
|
||||
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
|
||||
{ }
|
||||
};
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 7 Jul 2017 17:25:00 +0200
|
||||
Subject: net: add packet mangeling
|
||||
|
||||
ar8216 switches have a hardware bug, which renders normal 802.1q support
|
||||
unusable. Packet mangling is required to fix up the vlan for incoming
|
||||
packets.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
include/linux/netdevice.h | 11 +++++++++++
|
||||
include/linux/skbuff.h | 14 ++++----------
|
||||
net/Kconfig | 6 ++++++
|
||||
net/core/dev.c | 20 +++++++++++++++-----
|
||||
net/core/skbuff.c | 17 +++++++++++++++++
|
||||
net/ethernet/eth.c | 6 ++++++
|
||||
6 files changed, 59 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/include/linux/netdevice.h
|
||||
+++ b/include/linux/netdevice.h
|
||||
@@ -1695,6 +1695,7 @@ enum netdev_priv_flags {
|
||||
IFF_LIVE_RENAME_OK = 1<<30,
|
||||
IFF_TX_SKB_NO_LINEAR = BIT_ULL(31),
|
||||
IFF_CHANGE_PROTO_DOWN = BIT_ULL(32),
|
||||
+ IFF_NO_IP_ALIGN = BIT_ULL(33),
|
||||
};
|
||||
|
||||
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
|
||||
@@ -1729,6 +1730,7 @@ enum netdev_priv_flags {
|
||||
#define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
|
||||
#define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK
|
||||
#define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR
|
||||
+#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN
|
||||
|
||||
/* Specifies the type of the struct net_device::ml_priv pointer */
|
||||
enum netdev_ml_priv_type {
|
||||
@@ -2097,6 +2099,11 @@ struct net_device {
|
||||
const struct tlsdev_ops *tlsdev_ops;
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
+ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb);
|
||||
+ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb);
|
||||
+#endif
|
||||
+
|
||||
const struct header_ops *header_ops;
|
||||
|
||||
unsigned char operstate;
|
||||
@@ -2172,6 +2179,10 @@ struct net_device {
|
||||
struct mctp_dev __rcu *mctp_ptr;
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
+ void *phy_ptr; /* PHY device specific data */
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Cache lines mostly used on receive path (including eth_type_trans())
|
||||
*/
|
||||
--- a/include/linux/skbuff.h
|
||||
+++ b/include/linux/skbuff.h
|
||||
@@ -3021,6 +3021,10 @@ static inline int pskb_trim(struct sk_bu
|
||||
return (len < skb->len) ? __pskb_trim(skb, len) : 0;
|
||||
}
|
||||
|
||||
+extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
|
||||
+ unsigned int length, gfp_t gfp);
|
||||
+
|
||||
+
|
||||
/**
|
||||
* pskb_trim_unique - remove end from a paged unique (not cloned) buffer
|
||||
* @skb: buffer to alter
|
||||
@@ -3170,16 +3174,6 @@ static inline struct sk_buff *dev_alloc_
|
||||
}
|
||||
|
||||
|
||||
-static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
|
||||
- unsigned int length, gfp_t gfp)
|
||||
-{
|
||||
- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
|
||||
-
|
||||
- if (NET_IP_ALIGN && skb)
|
||||
- skb_reserve(skb, NET_IP_ALIGN);
|
||||
- return skb;
|
||||
-}
|
||||
-
|
||||
static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
|
||||
unsigned int length)
|
||||
{
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -26,6 +26,12 @@ menuconfig NET
|
||||
|
||||
if NET
|
||||
|
||||
+config ETHERNET_PACKET_MANGLE
|
||||
+ bool
|
||||
+ help
|
||||
+ This option can be selected by phy drivers that need to mangle
|
||||
+ packets going in or out of an ethernet device.
|
||||
+
|
||||
config WANT_COMPAT_NETLINK_MESSAGES
|
||||
bool
|
||||
help
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -3585,6 +3585,11 @@ static int xmit_one(struct sk_buff *skb,
|
||||
if (dev_nit_active(dev))
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
|
||||
+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
+ if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb)))
|
||||
+ return NETDEV_TX_OK;
|
||||
+#endif
|
||||
+
|
||||
len = skb->len;
|
||||
trace_net_dev_start_xmit(skb, dev);
|
||||
rc = netdev_start_xmit(skb, dev, txq, more);
|
||||
--- a/net/core/skbuff.c
|
||||
+++ b/net/core/skbuff.c
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/mpls.h>
|
||||
#include <linux/kcov.h>
|
||||
+#include <linux/if.h>
|
||||
|
||||
#include <net/protocol.h>
|
||||
#include <net/dst.h>
|
||||
@@ -707,6 +708,22 @@ skb_fail:
|
||||
}
|
||||
EXPORT_SYMBOL(__napi_alloc_skb);
|
||||
|
||||
+struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
|
||||
+ unsigned int length, gfp_t gfp)
|
||||
+{
|
||||
+ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
|
||||
+
|
||||
+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
+ if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
|
||||
+ return skb;
|
||||
+#endif
|
||||
+
|
||||
+ if (NET_IP_ALIGN && skb)
|
||||
+ skb_reserve(skb, NET_IP_ALIGN);
|
||||
+ return skb;
|
||||
+}
|
||||
+EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
|
||||
+
|
||||
void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
|
||||
int size, unsigned int truesize)
|
||||
{
|
||||
--- a/net/ethernet/eth.c
|
||||
+++ b/net/ethernet/eth.c
|
||||
@@ -171,6 +171,12 @@ __be16 eth_type_trans(struct sk_buff *sk
|
||||
const struct ethhdr *eth;
|
||||
|
||||
skb->dev = dev;
|
||||
+
|
||||
+#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
+ if (dev->eth_mangle_rx)
|
||||
+ dev->eth_mangle_rx(dev, skb);
|
||||
+#endif
|
||||
+
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
eth = (struct ethhdr *)skb->data;
|
|
@ -1,148 +0,0 @@
|
|||
From 5f62951fba63a9f9cfff564209426bdea5fcc371 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Marginean <alexandru.marginean@nxp.com>
|
||||
Date: Tue, 27 Aug 2019 15:16:56 +0300
|
||||
Subject: [PATCH] drivers: net: phy: aquantia: enable AQR112 and AQR412
|
||||
|
||||
Adds support for AQR112 and AQR412 which is mostly based on existing code
|
||||
with the addition of code configuring the protocol on system side.
|
||||
This allows changing the system side protocol without having to deploy a
|
||||
different firmware on the PHY.
|
||||
|
||||
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
|
||||
---
|
||||
drivers/net/phy/aquantia_main.c | 88 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 88 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia_main.c
|
||||
@@ -24,6 +24,8 @@
|
||||
#define PHY_ID_AQR405 0x03a1b4b0
|
||||
#define PHY_ID_AQR113C 0x31c31c12
|
||||
#define PHY_ID_AQR813 0x31c31cb2
|
||||
+#define PHY_ID_AQR112 0x03a1b662
|
||||
+#define PHY_ID_AQR412 0x03a1b712
|
||||
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
|
||||
@@ -151,6 +153,29 @@
|
||||
#define AQR107_OP_IN_PROG_SLEEP 1000
|
||||
#define AQR107_OP_IN_PROG_TIMEOUT 100000
|
||||
|
||||
+/* registers in MDIO_MMD_VEND1 region */
|
||||
+#define AQUANTIA_VND1_GLOBAL_SC 0x000
|
||||
+#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb)
|
||||
+
|
||||
+/* global start rate, the protocol associated with this speed is used by default
|
||||
+ * on SI.
|
||||
+ */
|
||||
+#define AQUANTIA_VND1_GSTART_RATE 0x31a
|
||||
+#define AQUANTIA_VND1_GSTART_RATE_OFF 0
|
||||
+#define AQUANTIA_VND1_GSTART_RATE_100M 1
|
||||
+#define AQUANTIA_VND1_GSTART_RATE_1G 2
|
||||
+#define AQUANTIA_VND1_GSTART_RATE_10G 3
|
||||
+#define AQUANTIA_VND1_GSTART_RATE_2_5G 4
|
||||
+#define AQUANTIA_VND1_GSTART_RATE_5G 5
|
||||
+
|
||||
+/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */
|
||||
+#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b
|
||||
+#define AQUANTIA_VND1_GSYSCFG_100M 0
|
||||
+#define AQUANTIA_VND1_GSYSCFG_1G 1
|
||||
+#define AQUANTIA_VND1_GSYSCFG_2_5G 2
|
||||
+#define AQUANTIA_VND1_GSYSCFG_5G 3
|
||||
+#define AQUANTIA_VND1_GSYSCFG_10G 4
|
||||
+
|
||||
struct aqr107_hw_stat {
|
||||
const char *name;
|
||||
int reg;
|
||||
@@ -282,6 +307,51 @@ static int aqr_config_aneg(struct phy_de
|
||||
return genphy_c45_check_and_restart_aneg(phydev, changed);
|
||||
}
|
||||
|
||||
+static struct {
|
||||
+ u16 syscfg;
|
||||
+ int cnt;
|
||||
+ u16 start_rate;
|
||||
+} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = {
|
||||
+ [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G,
|
||||
+ AQUANTIA_VND1_GSTART_RATE_1G},
|
||||
+ [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G,
|
||||
+ AQUANTIA_VND1_GSTART_RATE_2_5G},
|
||||
+ [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G,
|
||||
+ AQUANTIA_VND1_GSTART_RATE_10G},
|
||||
+ [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G,
|
||||
+ AQUANTIA_VND1_GSTART_RATE_10G},
|
||||
+};
|
||||
+
|
||||
+/* Sets up protocol on system side before calling aqr_config_aneg */
|
||||
+static int aqr_config_aneg_set_prot(struct phy_device *phydev)
|
||||
+{
|
||||
+ int if_type = phydev->interface;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!aquantia_syscfg[if_type].cnt)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* set PHY in low power mode so we can configure protocols */
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC,
|
||||
+ AQUANTIA_VND1_GLOBAL_SC_LP);
|
||||
+ mdelay(10);
|
||||
+
|
||||
+ /* set the default rate to enable the SI link */
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
|
||||
+ aquantia_syscfg[if_type].start_rate);
|
||||
+
|
||||
+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++)
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
|
||||
+ AQUANTIA_VND1_GSYSCFG_BASE + i,
|
||||
+ aquantia_syscfg[if_type].syscfg);
|
||||
+
|
||||
+ /* wake PHY back up */
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0);
|
||||
+ mdelay(10);
|
||||
+
|
||||
+ return aqr_config_aneg(phydev);
|
||||
+}
|
||||
+
|
||||
static int aqr_config_intr(struct phy_device *phydev)
|
||||
{
|
||||
bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
|
||||
@@ -881,6 +951,30 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
},
|
||||
+{
|
||||
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112),
|
||||
+ .name = "Aquantia AQR112",
|
||||
+ .probe = aqr107_probe,
|
||||
+ .config_aneg = aqr_config_aneg_set_prot,
|
||||
+ .config_intr = aqr_config_intr,
|
||||
+ .handle_interrupt = aqr_handle_interrupt,
|
||||
+ .read_status = aqr107_read_status,
|
||||
+ .get_sset_count = aqr107_get_sset_count,
|
||||
+ .get_strings = aqr107_get_strings,
|
||||
+ .get_stats = aqr107_get_stats,
|
||||
+},
|
||||
+{
|
||||
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
|
||||
+ .name = "Aquantia AQR412",
|
||||
+ .probe = aqr107_probe,
|
||||
+ .config_aneg = aqr_config_aneg_set_prot,
|
||||
+ .config_intr = aqr_config_intr,
|
||||
+ .handle_interrupt = aqr_handle_interrupt,
|
||||
+ .read_status = aqr107_read_status,
|
||||
+ .get_sset_count = aqr107_get_sset_count,
|
||||
+ .get_strings = aqr107_get_strings,
|
||||
+ .get_stats = aqr107_get_stats,
|
||||
+},
|
||||
};
|
||||
|
||||
module_phy_driver(aqr_driver);
|
||||
@@ -895,6 +989,8 @@ static struct mdio_device_id __maybe_unu
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
|
||||
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
|
||||
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
|
||||
{ }
|
||||
};
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From 5f008cb22f60da4e10375f22266c1a4e20b1252e Mon Sep 17 00:00:00 2001
|
||||
From: Alex Marginean <alexandru.marginean@nxp.com>
|
||||
Date: Fri, 20 Sep 2019 18:22:52 +0300
|
||||
Subject: [PATCH] drivers: net: phy: aquantia: fix system side protocol
|
||||
misconfiguration
|
||||
|
||||
Do not set up protocols for speeds that are not supported by FW. Enabling
|
||||
these protocols leads to link issues on system side.
|
||||
|
||||
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
|
||||
---
|
||||
drivers/net/phy/aquantia_main.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/phy/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia_main.c
|
||||
@@ -340,10 +340,16 @@ static int aqr_config_aneg_set_prot(stru
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
|
||||
aquantia_syscfg[if_type].start_rate);
|
||||
|
||||
- for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++)
|
||||
+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) {
|
||||
+ u16 reg = phy_read_mmd(phydev, MDIO_MMD_VEND1,
|
||||
+ AQUANTIA_VND1_GSYSCFG_BASE + i);
|
||||
+ if (!reg)
|
||||
+ continue;
|
||||
+
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1,
|
||||
AQUANTIA_VND1_GSYSCFG_BASE + i,
|
||||
aquantia_syscfg[if_type].syscfg);
|
||||
+ }
|
||||
|
||||
/* wake PHY back up */
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0);
|
|
@ -1,43 +0,0 @@
|
|||
From 2e677e4ae8f8330f68013163b060d0fda3a43095 Mon Sep 17 00:00:00 2001
|
||||
From: "Langer, Thomas" <tlanger@maxlinear.com>
|
||||
Date: Fri, 9 Jul 2021 17:36:46 +0200
|
||||
Subject: [PATCH] PONRTSYS-8842: aquantia: Add AQR113 driver support
|
||||
|
||||
Add a new entry for AQR113 PHY_ID
|
||||
---
|
||||
drivers/net/phy/aquantia_main.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia_main.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#define PHY_ID_AQR813 0x31c31cb2
|
||||
#define PHY_ID_AQR112 0x03a1b662
|
||||
#define PHY_ID_AQR412 0x03a1b712
|
||||
+#define PHY_ID_AQR113 0x31c31c40
|
||||
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
|
||||
@@ -981,6 +982,14 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
},
|
||||
+{
|
||||
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113),
|
||||
+ .name = "Aquantia AQR113",
|
||||
+ .config_aneg = aqr_config_aneg,
|
||||
+ .config_intr = aqr_config_intr,
|
||||
+ .handle_interrupt = aqr_handle_interrupt,
|
||||
+ .read_status = aqr107_read_status,
|
||||
+},
|
||||
};
|
||||
|
||||
module_phy_driver(aqr_driver);
|
||||
@@ -997,6 +1006,7 @@ static struct mdio_device_id __maybe_unu
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
|
||||
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
|
||||
{ }
|
||||
};
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
From 3b92ee7b7899b6beffb2b484c58326e36612a873 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 23 Dec 2021 14:52:56 +0000
|
||||
Subject: [PATCH] net: phy: aquantia: add PHY_ID for AQR112R
|
||||
|
||||
As advised by Ian Chang this PHY is used in Puzzle devices.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/aquantia_main.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia_main.c
|
||||
@@ -27,6 +27,8 @@
|
||||
#define PHY_ID_AQR112 0x03a1b662
|
||||
#define PHY_ID_AQR412 0x03a1b712
|
||||
#define PHY_ID_AQR113 0x31c31c40
|
||||
+#define PHY_ID_AQR112C 0x03a1b790
|
||||
+#define PHY_ID_AQR112R 0x31c31d12
|
||||
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
|
||||
@@ -990,6 +992,30 @@ static struct phy_driver aqr_driver[] =
|
||||
.handle_interrupt = aqr_handle_interrupt,
|
||||
.read_status = aqr107_read_status,
|
||||
},
|
||||
+{
|
||||
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C),
|
||||
+ .name = "Aquantia AQR112C",
|
||||
+ .probe = aqr107_probe,
|
||||
+ .config_aneg = aqr_config_aneg_set_prot,
|
||||
+ .config_intr = aqr_config_intr,
|
||||
+ .handle_interrupt = aqr_handle_interrupt,
|
||||
+ .read_status = aqr107_read_status,
|
||||
+ .get_sset_count = aqr107_get_sset_count,
|
||||
+ .get_strings = aqr107_get_strings,
|
||||
+ .get_stats = aqr107_get_stats,
|
||||
+},
|
||||
+{
|
||||
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R),
|
||||
+ .name = "Aquantia AQR112R",
|
||||
+ .probe = aqr107_probe,
|
||||
+ .config_aneg = aqr_config_aneg_set_prot,
|
||||
+ .config_intr = aqr_config_intr,
|
||||
+ .handle_interrupt = aqr_handle_interrupt,
|
||||
+ .read_status = aqr107_read_status,
|
||||
+ .get_sset_count = aqr107_get_sset_count,
|
||||
+ .get_strings = aqr107_get_strings,
|
||||
+ .get_stats = aqr107_get_stats,
|
||||
+},
|
||||
};
|
||||
|
||||
module_phy_driver(aqr_driver);
|
||||
@@ -1007,6 +1033,8 @@ static struct mdio_device_id __maybe_unu
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
|
||||
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) },
|
||||
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) },
|
||||
{ }
|
||||
};
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
From 82985725e071f2a5735052f18e109a32aeac3a0b Mon Sep 17 00:00:00 2001
|
||||
From: David Bauer <mail@david-bauer.net>
|
||||
Date: Sun, 26 Jul 2020 02:38:31 +0200
|
||||
Subject: [PATCH] net: usb: r8152: add LED configuration from OF
|
||||
|
||||
This adds the ability to configure the LED configuration register using
|
||||
OF. This way, the correct value for board specific LED configuration can
|
||||
be determined.
|
||||
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
---
|
||||
drivers/net/usb/r8152.c | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
--- a/drivers/net/usb/r8152.c
|
||||
+++ b/drivers/net/usb/r8152.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/mii.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/usb.h>
|
||||
+#include <linux/of.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/uaccess.h>
|
||||
@@ -6871,6 +6872,22 @@ static void rtl_tally_reset(struct r8152
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data);
|
||||
}
|
||||
|
||||
+static int r8152_led_configuration(struct r8152 *tp)
|
||||
+{
|
||||
+ u32 led_data;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = of_property_read_u32(tp->udev->dev.of_node, "realtek,led-data",
|
||||
+ &led_data);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, led_data);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void r8152b_init(struct r8152 *tp)
|
||||
{
|
||||
u32 ocp_data;
|
||||
@@ -6912,6 +6929,8 @@ static void r8152b_init(struct r8152 *tp
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
|
||||
ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN);
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
|
||||
+
|
||||
+ r8152_led_configuration(tp);
|
||||
}
|
||||
|
||||
static void r8153_init(struct r8152 *tp)
|
||||
@@ -7052,6 +7071,8 @@ static void r8153_init(struct r8152 *tp)
|
||||
tp->coalesce = COALESCE_SLOW;
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ r8152_led_configuration(tp);
|
||||
}
|
||||
|
||||
static void r8153b_init(struct r8152 *tp)
|
||||
@@ -7134,6 +7155,8 @@ static void r8153b_init(struct r8152 *tp
|
||||
rtl_tally_reset(tp);
|
||||
|
||||
tp->coalesce = 15000; /* 15 us */
|
||||
+
|
||||
+ r8152_led_configuration(tp);
|
||||
}
|
||||
|
||||
static void r8153c_init(struct r8152 *tp)
|
|
@ -1,54 +0,0 @@
|
|||
From 3ee05f4aa64fc86af3be5bc176ba5808de9260a7 Mon Sep 17 00:00:00 2001
|
||||
From: David Bauer <mail@david-bauer.net>
|
||||
Date: Sun, 26 Jul 2020 15:30:33 +0200
|
||||
Subject: [PATCH] dt-bindings: net: add RTL8152 binding documentation
|
||||
|
||||
Add binding documentation for the Realtek RTL8152 / RTL8153 USB ethernet
|
||||
adapters.
|
||||
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
---
|
||||
.../bindings/net/realtek,rtl8152.yaml | 36 +++++++++++++++++++
|
||||
1 file changed, 36 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8152.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml
|
||||
@@ -0,0 +1,36 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/net/realtek,rtl8152.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Realtek RTL8152/RTL8153 series USB ethernet
|
||||
+
|
||||
+maintainers:
|
||||
+ - David Bauer <mail@david-bauer.net>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - realtek,rtl8152
|
||||
+ - realtek,rtl8153
|
||||
+
|
||||
+ reg:
|
||||
+ description: The device number on the USB bus
|
||||
+
|
||||
+ realtek,led-data:
|
||||
+ description: Value to be written to the LED configuration register.
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ usb-eth@2 {
|
||||
+ compatible = "realtek,rtl8153";
|
||||
+ reg = <2>;
|
||||
+ realtek,led-data = <0x87>;
|
||||
+ };
|
||||
\ No newline at end of file
|
|
@ -1,98 +0,0 @@
|
|||
From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001
|
||||
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
Date: Fri, 7 Jul 2017 17:26:01 +0200
|
||||
Subject: bcm53xx: bgmac: use srab switch driver
|
||||
|
||||
use the srab switch driver on these SoCs.
|
||||
|
||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
---
|
||||
drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 +
|
||||
drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++++
|
||||
drivers/net/ethernet/broadcom/bgmac.h | 4 ++++
|
||||
3 files changed, 29 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
|
||||
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
|
||||
@@ -280,6 +280,7 @@ static int bgmac_probe(struct bcma_devic
|
||||
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
|
||||
bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
|
||||
bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
|
||||
+ bgmac->feature_flags |= BGMAC_FEAT_SRAB;
|
||||
break;
|
||||
default:
|
||||
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
|
||||
--- a/drivers/net/ethernet/broadcom/bgmac.c
|
||||
+++ b/drivers/net/ethernet/broadcom/bgmac.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/interrupt.h>
|
||||
+#include <linux/platform_data/b53.h>
|
||||
#include <linux/bcm47xx_nvram.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/phy_fixed.h>
|
||||
@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et
|
||||
.set_link_ksettings = phy_ethtool_set_link_ksettings,
|
||||
};
|
||||
|
||||
+static struct b53_platform_data bgmac_b53_pdata = {
|
||||
+};
|
||||
+
|
||||
+static struct platform_device bgmac_b53_dev = {
|
||||
+ .name = "b53-srab-switch",
|
||||
+ .id = -1,
|
||||
+ .dev = {
|
||||
+ .platform_data = &bgmac_b53_pdata,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
/**************************************************
|
||||
* MII
|
||||
**************************************************/
|
||||
@@ -1542,6 +1554,14 @@ int bgmac_enet_probe(struct bgmac *bgmac
|
||||
/* Omit FCS from max MTU size */
|
||||
net_dev->max_mtu = BGMAC_RX_MAX_FRAME_SIZE - ETH_FCS_LEN;
|
||||
|
||||
+ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) {
|
||||
+ bgmac_b53_pdata.regs = ioremap(0x18007000, 0x1000);
|
||||
+
|
||||
+ err = platform_device_register(&bgmac_b53_dev);
|
||||
+ if (!err)
|
||||
+ bgmac->b53_device = &bgmac_b53_dev;
|
||||
+ }
|
||||
+
|
||||
err = register_netdev(bgmac->net_dev);
|
||||
if (err) {
|
||||
dev_err(bgmac->dev, "Cannot register net device\n");
|
||||
@@ -1564,6 +1584,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe);
|
||||
|
||||
void bgmac_enet_remove(struct bgmac *bgmac)
|
||||
{
|
||||
+ if (bgmac->b53_device)
|
||||
+ platform_device_unregister(&bgmac_b53_dev);
|
||||
+ bgmac->b53_device = NULL;
|
||||
+
|
||||
unregister_netdev(bgmac->net_dev);
|
||||
phy_disconnect(bgmac->net_dev->phydev);
|
||||
netif_napi_del(&bgmac->napi);
|
||||
--- a/drivers/net/ethernet/broadcom/bgmac.h
|
||||
+++ b/drivers/net/ethernet/broadcom/bgmac.h
|
||||
@@ -388,6 +388,7 @@
|
||||
#define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18)
|
||||
#define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19)
|
||||
#define BGMAC_FEAT_IDM_MASK BIT(20)
|
||||
+#define BGMAC_FEAT_SRAB BIT(21)
|
||||
|
||||
struct bgmac_slot_info {
|
||||
union {
|
||||
@@ -493,6 +494,9 @@ struct bgmac {
|
||||
void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
|
||||
u32 set);
|
||||
int (*phy_connect)(struct bgmac *bgmac);
|
||||
+
|
||||
+ /* platform device for associated switch */
|
||||
+ struct platform_device *b53_device;
|
||||
};
|
||||
|
||||
struct bgmac *bgmac_alloc(struct device *dev);
|
|
@ -1,43 +0,0 @@
|
|||
From f81700b6bb2eda3756247bce472d8eaf6f466f61 Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:49:26 +0200
|
||||
Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
|
||||
|
||||
---
|
||||
drivers/net/usb/qmi_wwan.c | 1 +
|
||||
drivers/usb/serial/option.c | 7 +++++++
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
--- a/drivers/net/usb/qmi_wwan.c
|
||||
+++ b/drivers/net/usb/qmi_wwan.c
|
||||
@@ -1088,6 +1088,7 @@ static const struct usb_device_id produc
|
||||
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */
|
||||
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */
|
||||
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */
|
||||
+ {QMI_MATCH_FF_FF_FF(0x05c6, 0xf601)}, /* MeigLink SLM750 */
|
||||
|
||||
/* 3. Combined interface devices matching on interface number */
|
||||
{QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -244,6 +244,8 @@ static void option_instat_callback(struc
|
||||
#define UBLOX_PRODUCT_R410M 0x90b2
|
||||
/* These Yuga products use Qualcomm's vendor ID */
|
||||
#define YUGA_PRODUCT_CLM920_NC5 0x9625
|
||||
+/* These MeigLink products use Qualcomm's vendor ID */
|
||||
+#define MEIGLINK_PRODUCT_SLM750 0xf601
|
||||
|
||||
#define QUECTEL_VENDOR_ID 0x2c7c
|
||||
/* These Quectel products use Quectel's vendor ID */
|
||||
@@ -1155,6 +1157,11 @@ static const struct usb_device_id option
|
||||
.driver_info = ZLP },
|
||||
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
|
||||
.driver_info = RSVD(4) },
|
||||
+ /* Meiglink products using Qualcomm vendor ID */
|
||||
+ // Works OK. In case of some issues check macros that are used by Quectel Products
|
||||
+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0xff, 0xff),
|
||||
+ .driver_info = NUMEP2 },
|
||||
+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
|
||||
.driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
|
|
@ -1,63 +0,0 @@
|
|||
From 7cc39a6bedbd85f3ff7e16845f310e4ce8d9833f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 6 Sep 2022 00:31:19 +0100
|
||||
Subject: [PATCH] net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
|
||||
To: netdev@vger.kernel.org,
|
||||
linux-kernel@vger.kernel.org,
|
||||
Russell King <linux@armlinux.org.uk>,
|
||||
Andrew Lunn <andrew@lunn.ch>,
|
||||
Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Cc: David S. Miller <davem@davemloft.net>,
|
||||
Eric Dumazet <edumazet@google.com>,
|
||||
Jakub Kicinski <kuba@kernel.org>,
|
||||
Paolo Abeni <pabeni@redhat.com>,
|
||||
Josef Schlehofer <pepe.schlehofer@gmail.com>
|
||||
|
||||
This copper module comes with broken TX_FAULT indicator which must be
|
||||
ignored for it to work. Implement ignoring TX_FAULT state bit also
|
||||
during reset/insertion and mute the warning telling the user that the
|
||||
module indicates TX_FAULT.
|
||||
|
||||
Co-authored-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/sfp.c | 14 +++++++++++---
|
||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/sfp.c
|
||||
+++ b/drivers/net/phy/sfp.c
|
||||
@@ -394,6 +394,9 @@ static const struct sfp_quirk sfp_quirks
|
||||
SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
|
||||
sfp_fixup_ignore_tx_fault),
|
||||
|
||||
+ // OEM SFP-GE-T is 1000Base-T module
|
||||
+ SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
|
||||
+
|
||||
// Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
|
||||
// 2500MBd NRZ in their EEPROM
|
||||
SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
|
||||
@@ -2328,7 +2331,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
* or t_start_up, so assume there is a fault.
|
||||
*/
|
||||
sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
|
||||
- sfp->sm_fault_retries == N_FAULT_INIT);
|
||||
+ !sfp->tx_fault_ignore &&
|
||||
+ (sfp->sm_fault_retries == N_FAULT_INIT));
|
||||
} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
|
||||
init_done:
|
||||
/* Create mdiobus and start trying for PHY */
|
||||
@@ -2557,10 +2561,12 @@ static void sfp_check_state(struct sfp *
|
||||
mutex_lock(&sfp->st_mutex);
|
||||
state = sfp_get_state(sfp);
|
||||
changed = state ^ sfp->state;
|
||||
- if (sfp->tx_fault_ignore)
|
||||
+ if (sfp->tx_fault_ignore) {
|
||||
changed &= SFP_F_PRESENT | SFP_F_LOS;
|
||||
- else
|
||||
+ state &= ~SFP_F_TX_FAULT;
|
||||
+ } else {
|
||||
changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
|
||||
+ }
|
||||
|
||||
for (i = 0; i < GPIO_MAX; i++)
|
||||
if (changed & BIT(i))
|
|
@ -1,162 +0,0 @@
|
|||
From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 12 Aug 2014 20:49:27 +0200
|
||||
Subject: [PATCH 30/36] GPIO: add named gpio exports
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
--- a/drivers/gpio/gpiolib-of.c
|
||||
+++ b/drivers/gpio/gpiolib-of.c
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
|
||||
#include "gpiolib.h"
|
||||
#include "gpiolib-of.h"
|
||||
@@ -1030,3 +1032,72 @@ void of_gpio_dev_init(struct gpio_chip *
|
||||
else
|
||||
gc->of_node = gdev->dev.of_node;
|
||||
}
|
||||
+
|
||||
+#ifdef CONFIG_GPIO_SYSFS
|
||||
+
|
||||
+static struct of_device_id gpio_export_ids[] = {
|
||||
+ { .compatible = "gpio-export" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+static int of_gpio_export_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct device_node *cnp;
|
||||
+ u32 val;
|
||||
+ int nb = 0;
|
||||
+
|
||||
+ for_each_child_of_node(np, cnp) {
|
||||
+ const char *name = NULL;
|
||||
+ int gpio;
|
||||
+ bool dmc;
|
||||
+ int max_gpio = 1;
|
||||
+ int i;
|
||||
+
|
||||
+ of_property_read_string(cnp, "gpio-export,name", &name);
|
||||
+
|
||||
+ if (!name)
|
||||
+ max_gpio = of_gpio_count(cnp);
|
||||
+
|
||||
+ for (i = 0; i < max_gpio; i++) {
|
||||
+ unsigned flags = 0;
|
||||
+ enum of_gpio_flags of_flags;
|
||||
+
|
||||
+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
|
||||
+ if (!gpio_is_valid(gpio))
|
||||
+ return gpio;
|
||||
+
|
||||
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
|
||||
+ flags |= GPIOF_ACTIVE_LOW;
|
||||
+
|
||||
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
|
||||
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||
+ else
|
||||
+ flags |= GPIOF_IN;
|
||||
+
|
||||
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
|
||||
+ continue;
|
||||
+
|
||||
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
|
||||
+ gpio_export_with_name(gpio, dmc, name);
|
||||
+ nb++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gpio_export_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "gpio-export",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(gpio_export_ids),
|
||||
+ },
|
||||
+ .probe = of_gpio_export_probe,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(gpio_export_driver);
|
||||
+
|
||||
+#endif
|
||||
--- a/include/asm-generic/gpio.h
|
||||
+++ b/include/asm-generic/gpio.h
|
||||
@@ -125,6 +125,12 @@ static inline int gpio_export(unsigned g
|
||||
return gpiod_export(gpio_to_desc(gpio), direction_may_change);
|
||||
}
|
||||
|
||||
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||
+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
|
||||
+{
|
||||
+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
|
||||
+}
|
||||
+
|
||||
static inline int gpio_export_link(struct device *dev, const char *name,
|
||||
unsigned gpio)
|
||||
{
|
||||
--- a/include/linux/gpio/consumer.h
|
||||
+++ b/include/linux/gpio/consumer.h
|
||||
@@ -715,6 +715,7 @@ static inline struct gpio_desc *acpi_get
|
||||
|
||||
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
|
||||
|
||||
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||
int gpiod_export_link(struct device *dev, const char *name,
|
||||
struct gpio_desc *desc);
|
||||
@@ -722,6 +723,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||
|
||||
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
|
||||
|
||||
+static inline int _gpiod_export(struct gpio_desc *desc,
|
||||
+ bool direction_may_change,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
static inline int gpiod_export(struct gpio_desc *desc,
|
||||
bool direction_may_change)
|
||||
{
|
||||
--- a/drivers/gpio/gpiolib-sysfs.c
|
||||
+++ b/drivers/gpio/gpiolib-sysfs.c
|
||||
@@ -544,7 +544,7 @@ static struct class gpio_class = {
|
||||
*
|
||||
* Returns zero on success, else an error.
|
||||
*/
|
||||
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
|
||||
{
|
||||
struct gpio_chip *chip;
|
||||
struct gpio_device *gdev;
|
||||
@@ -606,6 +606,8 @@ int gpiod_export(struct gpio_desc *desc,
|
||||
offset = gpio_chip_hwgpio(desc);
|
||||
if (chip->names && chip->names[offset])
|
||||
ioname = chip->names[offset];
|
||||
+ if (name)
|
||||
+ ioname = name;
|
||||
|
||||
dev = device_create_with_groups(&gpio_class, &gdev->dev,
|
||||
MKDEV(0, 0), data, gpio_groups,
|
||||
@@ -627,6 +629,12 @@ err_unlock:
|
||||
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
|
||||
return status;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(__gpiod_export);
|
||||
+
|
||||
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
+{
|
||||
+ return __gpiod_export(desc, direction_may_change, NULL);
|
||||
+}
|
||||
EXPORT_SYMBOL_GPL(gpiod_export);
|
||||
|
||||
static int match_export(struct device *dev, const void *desc)
|
|
@ -1,175 +0,0 @@
|
|||
From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 8 Jul 2017 08:16:31 +0200
|
||||
Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
net/Kconfig | 3 +++
|
||||
net/core/Makefile | 3 ++-
|
||||
net/core/sock.c | 2 ++
|
||||
net/ipv4/Kconfig | 1 +
|
||||
net/netlink/Kconfig | 1 +
|
||||
net/packet/Kconfig | 1 +
|
||||
net/unix/Kconfig | 1 +
|
||||
7 files changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -104,6 +104,9 @@ source "net/mptcp/Kconfig"
|
||||
|
||||
endif # if INET
|
||||
|
||||
+config SOCK_DIAG
|
||||
+ bool
|
||||
+
|
||||
config NETWORK_SECMARK
|
||||
bool "Security Marking"
|
||||
help
|
||||
--- a/net/core/Makefile
|
||||
+++ b/net/core/Makefile
|
||||
@@ -11,11 +11,12 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.
|
||||
|
||||
obj-y += dev.o dev_addr_lists.o dst.o netevent.o \
|
||||
neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
|
||||
- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
|
||||
+ dev_ioctl.o tso.o sock_reuseport.o \
|
||||
fib_notifier.o xdp.o flow_offload.o gro.o
|
||||
|
||||
obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o
|
||||
|
||||
+obj-$(CONFIG_SOCK_DIAG) += sock_diag.o
|
||||
obj-y += net-sysfs.o
|
||||
obj-$(CONFIG_PAGE_POOL) += page_pool.o
|
||||
obj-$(CONFIG_PROC_FS) += net-procfs.o
|
||||
--- a/net/core/sock.c
|
||||
+++ b/net/core/sock.c
|
||||
@@ -114,6 +114,7 @@
|
||||
#include <linux/memcontrol.h>
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/compat.h>
|
||||
+#include <linux/cookie.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
@@ -145,6 +146,7 @@
|
||||
|
||||
static DEFINE_MUTEX(proto_list_mutex);
|
||||
static LIST_HEAD(proto_list);
|
||||
+DEFINE_COOKIE(sock_cookie);
|
||||
|
||||
static void sock_def_write_space_wfree(struct sock *sk);
|
||||
static void sock_def_write_space(struct sock *sk);
|
||||
@@ -582,6 +584,18 @@ discard_and_relse:
|
||||
}
|
||||
EXPORT_SYMBOL(__sk_receive_skb);
|
||||
|
||||
+u64 __sock_gen_cookie(struct sock *sk)
|
||||
+{
|
||||
+ while (1) {
|
||||
+ u64 res = atomic64_read(&sk->sk_cookie);
|
||||
+
|
||||
+ if (res)
|
||||
+ return res;
|
||||
+ res = gen_cookie_next(&sock_cookie);
|
||||
+ atomic64_cmpxchg(&sk->sk_cookie, 0, res);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *,
|
||||
u32));
|
||||
INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *,
|
||||
@@ -2172,9 +2186,11 @@ static void __sk_free(struct sock *sk)
|
||||
if (likely(sk->sk_net_refcnt))
|
||||
sock_inuse_add(sock_net(sk), -1);
|
||||
|
||||
+#ifdef CONFIG_SOCK_DIAG
|
||||
if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk)))
|
||||
sock_diag_broadcast_destroy(sk);
|
||||
else
|
||||
+#endif
|
||||
sk_destruct(sk);
|
||||
}
|
||||
|
||||
--- a/net/core/sock_diag.c
|
||||
+++ b/net/core/sock_diag.c
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/nospec.h>
|
||||
-#include <linux/cookie.h>
|
||||
#include <linux/inet_diag.h>
|
||||
#include <linux/sock_diag.h>
|
||||
|
||||
@@ -21,20 +20,6 @@ static int (*inet_rcv_compat)(struct sk_
|
||||
static DEFINE_MUTEX(sock_diag_table_mutex);
|
||||
static struct workqueue_struct *broadcast_wq;
|
||||
|
||||
-DEFINE_COOKIE(sock_cookie);
|
||||
-
|
||||
-u64 __sock_gen_cookie(struct sock *sk)
|
||||
-{
|
||||
- while (1) {
|
||||
- u64 res = atomic64_read(&sk->sk_cookie);
|
||||
-
|
||||
- if (res)
|
||||
- return res;
|
||||
- res = gen_cookie_next(&sock_cookie);
|
||||
- atomic64_cmpxchg(&sk->sk_cookie, 0, res);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie)
|
||||
{
|
||||
u64 res;
|
||||
--- a/net/ipv4/Kconfig
|
||||
+++ b/net/ipv4/Kconfig
|
||||
@@ -423,6 +423,7 @@ config INET_TUNNEL
|
||||
|
||||
config INET_DIAG
|
||||
tristate "INET: socket monitoring interface"
|
||||
+ select SOCK_DIAG
|
||||
default y
|
||||
help
|
||||
Support for INET (TCP, DCCP, etc) socket monitoring interface used by
|
||||
--- a/net/netlink/Kconfig
|
||||
+++ b/net/netlink/Kconfig
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
config NETLINK_DIAG
|
||||
tristate "NETLINK: socket monitoring interface"
|
||||
+ select SOCK_DIAG
|
||||
default n
|
||||
help
|
||||
Support for NETLINK socket monitoring interface used by the ss tool.
|
||||
--- a/net/netlink/genetlink.c
|
||||
+++ b/net/netlink/genetlink.c
|
||||
@@ -380,8 +380,6 @@ static int genl_validate_ops(const struc
|
||||
genl_get_cmd_by_index(i, family, &op);
|
||||
if (op.dumpit == NULL && op.doit == NULL)
|
||||
return -EINVAL;
|
||||
- if (WARN_ON(op.cmd >= family->resv_start_op && op.validate))
|
||||
- return -EINVAL;
|
||||
for (j = i + 1; j < genl_get_cmd_cnt(family); j++) {
|
||||
struct genl_ops op2;
|
||||
|
||||
--- a/net/packet/Kconfig
|
||||
+++ b/net/packet/Kconfig
|
||||
@@ -19,6 +19,7 @@ config PACKET
|
||||
config PACKET_DIAG
|
||||
tristate "Packet: sockets monitoring interface"
|
||||
depends on PACKET
|
||||
+ select SOCK_DIAG
|
||||
default n
|
||||
help
|
||||
Support for PF_PACKET sockets monitoring interface used by the ss tool.
|
||||
--- a/net/unix/Kconfig
|
||||
+++ b/net/unix/Kconfig
|
||||
@@ -33,6 +33,7 @@ config AF_UNIX_OOB
|
||||
config UNIX_DIAG
|
||||
tristate "UNIX: socket monitoring interface"
|
||||
depends on UNIX
|
||||
+ select SOCK_DIAG
|
||||
default n
|
||||
help
|
||||
Support for UNIX socket monitoring interface used by the ss tool.
|
|
@ -1,408 +0,0 @@
|
|||
From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 8 Jul 2017 08:20:09 +0200
|
||||
Subject: debloat: procfs
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
fs/locks.c | 2 ++
|
||||
fs/proc/Kconfig | 5 +++++
|
||||
fs/proc/consoles.c | 3 +++
|
||||
fs/proc/proc_tty.c | 11 ++++++++++-
|
||||
include/net/snmp.h | 18 +++++++++++++++++-
|
||||
ipc/msg.c | 3 +++
|
||||
ipc/sem.c | 2 ++
|
||||
ipc/shm.c | 2 ++
|
||||
ipc/util.c | 3 +++
|
||||
kernel/exec_domain.c | 2 ++
|
||||
kernel/irq/proc.c | 9 +++++++++
|
||||
kernel/time/timer_list.c | 2 ++
|
||||
mm/vmalloc.c | 2 ++
|
||||
mm/vmstat.c | 8 +++++---
|
||||
net/8021q/vlanproc.c | 6 ++++++
|
||||
net/core/net-procfs.c | 18 ++++++++++++------
|
||||
net/core/sock.c | 2 ++
|
||||
net/ipv4/fib_trie.c | 18 ++++++++++++------
|
||||
net/ipv4/proc.c | 3 +++
|
||||
net/ipv4/route.c | 3 +++
|
||||
20 files changed, 105 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/fs/locks.c
|
||||
+++ b/fs/locks.c
|
||||
@@ -2885,6 +2885,8 @@ static const struct seq_operations locks
|
||||
|
||||
static int __init proc_locks_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
proc_create_seq_private("locks", 0, NULL, &locks_seq_operations,
|
||||
sizeof(struct locks_iterator), NULL);
|
||||
return 0;
|
||||
--- a/fs/proc/Kconfig
|
||||
+++ b/fs/proc/Kconfig
|
||||
@@ -101,6 +101,11 @@ config PROC_CHILDREN
|
||||
Say Y if you are running any user-space software which takes benefit from
|
||||
this interface. For example, rkt is such a piece of software.
|
||||
|
||||
+config PROC_STRIPPED
|
||||
+ default n
|
||||
+ depends on EXPERT
|
||||
+ bool "Strip non-essential /proc functionality to reduce code size"
|
||||
+
|
||||
config PROC_PID_ARCH_STATUS
|
||||
def_bool n
|
||||
depends on PROC_FS
|
||||
--- a/fs/proc/consoles.c
|
||||
+++ b/fs/proc/consoles.c
|
||||
@@ -92,6 +92,9 @@ static const struct seq_operations conso
|
||||
|
||||
static int __init proc_consoles_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
+
|
||||
proc_create_seq("consoles", 0, NULL, &consoles_op);
|
||||
return 0;
|
||||
}
|
||||
--- a/fs/proc/proc_tty.c
|
||||
+++ b/fs/proc/proc_tty.c
|
||||
@@ -131,7 +131,10 @@ static const struct seq_operations tty_d
|
||||
void proc_tty_register_driver(struct tty_driver *driver)
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
-
|
||||
+
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return;
|
||||
+
|
||||
if (!driver->driver_name || driver->proc_entry ||
|
||||
!driver->ops->proc_show)
|
||||
return;
|
||||
@@ -148,6 +151,9 @@ void proc_tty_unregister_driver(struct t
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return;
|
||||
+
|
||||
ent = driver->proc_entry;
|
||||
if (!ent)
|
||||
return;
|
||||
@@ -162,6 +168,9 @@ void proc_tty_unregister_driver(struct t
|
||||
*/
|
||||
void __init proc_tty_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return;
|
||||
+
|
||||
if (!proc_mkdir("tty", NULL))
|
||||
return;
|
||||
proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */
|
||||
--- a/include/net/snmp.h
|
||||
+++ b/include/net/snmp.h
|
||||
@@ -124,6 +124,21 @@ struct linux_tls_mib {
|
||||
#define DECLARE_SNMP_STAT(type, name) \
|
||||
extern __typeof__(type) __percpu *name
|
||||
|
||||
+#ifdef CONFIG_PROC_STRIPPED
|
||||
+#define __SNMP_STATS_DUMMY(mib) \
|
||||
+ do { (void) mib->mibs[0]; } while(0)
|
||||
+
|
||||
+#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
|
||||
+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib)
|
||||
+#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
|
||||
+#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
|
||||
+#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
|
||||
+#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
|
||||
+#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
|
||||
+#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
#define __SNMP_INC_STATS(mib, field) \
|
||||
__this_cpu_inc(mib->mibs[field])
|
||||
|
||||
@@ -154,8 +169,9 @@ struct linux_tls_mib {
|
||||
__this_cpu_add(ptr[basefield##OCTETS], addend); \
|
||||
} while (0)
|
||||
|
||||
+#endif
|
||||
|
||||
-#if BITS_PER_LONG==32
|
||||
+#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED)
|
||||
|
||||
#define __SNMP_ADD_STATS64(mib, field, addend) \
|
||||
do { \
|
||||
--- a/ipc/msg.c
|
||||
+++ b/ipc/msg.c
|
||||
@@ -1370,6 +1370,9 @@ void __init msg_init(void)
|
||||
{
|
||||
msg_init_ns(&init_ipc_ns);
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return;
|
||||
+
|
||||
ipc_init_proc_interface("sysvipc/msg",
|
||||
" key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
|
||||
IPC_MSG_IDS, sysvipc_msg_proc_show);
|
||||
--- a/ipc/sem.c
|
||||
+++ b/ipc/sem.c
|
||||
@@ -268,6 +268,8 @@ void sem_exit_ns(struct ipc_namespace *n
|
||||
void __init sem_init(void)
|
||||
{
|
||||
sem_init_ns(&init_ipc_ns);
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return;
|
||||
ipc_init_proc_interface("sysvipc/sem",
|
||||
" key semid perms nsems uid gid cuid cgid otime ctime\n",
|
||||
IPC_SEM_IDS, sysvipc_sem_proc_show);
|
||||
--- a/ipc/shm.c
|
||||
+++ b/ipc/shm.c
|
||||
@@ -154,6 +154,8 @@ pure_initcall(ipc_ns_init);
|
||||
|
||||
void __init shm_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return;
|
||||
ipc_init_proc_interface("sysvipc/shm",
|
||||
#if BITS_PER_LONG <= 32
|
||||
" key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
|
||||
--- a/ipc/util.c
|
||||
+++ b/ipc/util.c
|
||||
@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons
|
||||
struct proc_dir_entry *pde;
|
||||
struct ipc_proc_iface *iface;
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return;
|
||||
+
|
||||
iface = kmalloc(sizeof(*iface), GFP_KERNEL);
|
||||
if (!iface)
|
||||
return;
|
||||
--- a/kernel/exec_domain.c
|
||||
+++ b/kernel/exec_domain.c
|
||||
@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct
|
||||
|
||||
static int __init proc_execdomains_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
proc_create_single("execdomains", 0, NULL, execdomains_proc_show);
|
||||
return 0;
|
||||
}
|
||||
--- a/kernel/irq/proc.c
|
||||
+++ b/kernel/irq/proc.c
|
||||
@@ -341,6 +341,9 @@ void register_irq_proc(unsigned int irq,
|
||||
void __maybe_unused *irqp = (void *)(unsigned long) irq;
|
||||
char name [MAX_NAMELEN];
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
|
||||
+ return;
|
||||
+
|
||||
if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
|
||||
return;
|
||||
|
||||
@@ -394,6 +397,9 @@ void unregister_irq_proc(unsigned int ir
|
||||
{
|
||||
char name [MAX_NAMELEN];
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
|
||||
+ return;
|
||||
+
|
||||
if (!root_irq_dir || !desc->dir)
|
||||
return;
|
||||
#ifdef CONFIG_SMP
|
||||
@@ -432,6 +438,9 @@ void init_irq_proc(void)
|
||||
unsigned int irq;
|
||||
struct irq_desc *desc;
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
|
||||
+ return;
|
||||
+
|
||||
/* create /proc/irq */
|
||||
root_irq_dir = proc_mkdir("irq", NULL);
|
||||
if (!root_irq_dir)
|
||||
--- a/kernel/time/timer_list.c
|
||||
+++ b/kernel/time/timer_list.c
|
||||
@@ -350,6 +350,8 @@ static int __init init_timer_list_procfs
|
||||
{
|
||||
struct proc_dir_entry *pe;
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops,
|
||||
sizeof(struct timer_list_iter), NULL);
|
||||
if (!pe)
|
||||
--- a/mm/vmalloc.c
|
||||
+++ b/mm/vmalloc.c
|
||||
@@ -4177,6 +4177,8 @@ static const struct seq_operations vmall
|
||||
|
||||
static int __init proc_vmalloc_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
if (IS_ENABLED(CONFIG_NUMA))
|
||||
proc_create_seq_private("vmallocinfo", 0400, NULL,
|
||||
&vmalloc_op,
|
||||
--- a/mm/vmstat.c
|
||||
+++ b/mm/vmstat.c
|
||||
@@ -2109,10 +2109,12 @@ void __init init_mm_internals(void)
|
||||
start_shepherd_timer();
|
||||
#endif
|
||||
#ifdef CONFIG_PROC_FS
|
||||
- proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
|
||||
- proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
|
||||
+ proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
|
||||
+ proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
|
||||
+ proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
|
||||
+ }
|
||||
proc_create_seq("vmstat", 0444, NULL, &vmstat_op);
|
||||
- proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
|
||||
#endif
|
||||
}
|
||||
|
||||
--- a/net/8021q/vlanproc.c
|
||||
+++ b/net/8021q/vlanproc.c
|
||||
@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net)
|
||||
{
|
||||
struct vlan_net *vn = net_generic(net, vlan_net_id);
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return;
|
||||
+
|
||||
if (vn->proc_vlan_conf)
|
||||
remove_proc_entry(name_conf, vn->proc_vlan_dir);
|
||||
|
||||
@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net
|
||||
{
|
||||
struct vlan_net *vn = net_generic(net, vlan_net_id);
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
+
|
||||
vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
|
||||
if (!vn->proc_vlan_dir)
|
||||
goto err;
|
||||
--- a/net/core/net-procfs.c
|
||||
+++ b/net/core/net-procfs.c
|
||||
@@ -319,10 +319,12 @@ static int __net_init dev_proc_net_init(
|
||||
if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops,
|
||||
sizeof(struct seq_net_private)))
|
||||
goto out;
|
||||
- if (!proc_create_seq("softnet_stat", 0444, net->proc_net,
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
|
||||
+ !proc_create_seq("softnet_stat", 0444, net->proc_net,
|
||||
&softnet_seq_ops))
|
||||
goto out_dev;
|
||||
- if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
|
||||
+ !proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
|
||||
sizeof(struct seq_net_private)))
|
||||
goto out_softnet;
|
||||
|
||||
@@ -332,9 +334,11 @@ static int __net_init dev_proc_net_init(
|
||||
out:
|
||||
return rc;
|
||||
out_ptype:
|
||||
- remove_proc_entry("ptype", net->proc_net);
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ remove_proc_entry("ptype", net->proc_net);
|
||||
out_softnet:
|
||||
- remove_proc_entry("softnet_stat", net->proc_net);
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ remove_proc_entry("softnet_stat", net->proc_net);
|
||||
out_dev:
|
||||
remove_proc_entry("dev", net->proc_net);
|
||||
goto out;
|
||||
@@ -344,8 +348,10 @@ static void __net_exit dev_proc_net_exit
|
||||
{
|
||||
wext_proc_exit(net);
|
||||
|
||||
- remove_proc_entry("ptype", net->proc_net);
|
||||
- remove_proc_entry("softnet_stat", net->proc_net);
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
|
||||
+ remove_proc_entry("ptype", net->proc_net);
|
||||
+ remove_proc_entry("softnet_stat", net->proc_net);
|
||||
+ }
|
||||
remove_proc_entry("dev", net->proc_net);
|
||||
}
|
||||
|
||||
--- a/net/core/sock.c
|
||||
+++ b/net/core/sock.c
|
||||
@@ -4077,6 +4077,8 @@ static __net_initdata struct pernet_oper
|
||||
|
||||
static int __init proto_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
return register_pernet_subsys(&proto_net_ops);
|
||||
}
|
||||
|
||||
--- a/net/ipv4/fib_trie.c
|
||||
+++ b/net/ipv4/fib_trie.c
|
||||
@@ -3031,11 +3031,13 @@ static const struct seq_operations fib_r
|
||||
|
||||
int __net_init fib_proc_init(struct net *net)
|
||||
{
|
||||
- if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
|
||||
+ !proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
|
||||
sizeof(struct fib_trie_iter)))
|
||||
goto out1;
|
||||
|
||||
- if (!proc_create_net_single("fib_triestat", 0444, net->proc_net,
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
|
||||
+ !proc_create_net_single("fib_triestat", 0444, net->proc_net,
|
||||
fib_triestat_seq_show, NULL))
|
||||
goto out2;
|
||||
|
||||
@@ -3046,17 +3048,21 @@ int __net_init fib_proc_init(struct net
|
||||
return 0;
|
||||
|
||||
out3:
|
||||
- remove_proc_entry("fib_triestat", net->proc_net);
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ remove_proc_entry("fib_triestat", net->proc_net);
|
||||
out2:
|
||||
- remove_proc_entry("fib_trie", net->proc_net);
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ remove_proc_entry("fib_trie", net->proc_net);
|
||||
out1:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void __net_exit fib_proc_exit(struct net *net)
|
||||
{
|
||||
- remove_proc_entry("fib_trie", net->proc_net);
|
||||
- remove_proc_entry("fib_triestat", net->proc_net);
|
||||
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
|
||||
+ remove_proc_entry("fib_trie", net->proc_net);
|
||||
+ remove_proc_entry("fib_triestat", net->proc_net);
|
||||
+ }
|
||||
remove_proc_entry("route", net->proc_net);
|
||||
}
|
||||
|
||||
--- a/net/ipv4/proc.c
|
||||
+++ b/net/ipv4/proc.c
|
||||
@@ -553,5 +553,8 @@ static __net_initdata struct pernet_oper
|
||||
|
||||
int __init ip_misc_proc_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
+
|
||||
return register_pernet_subsys(&ip_proc_ops);
|
||||
}
|
||||
--- a/net/ipv4/route.c
|
||||
+++ b/net/ipv4/route.c
|
||||
@@ -380,6 +380,9 @@ static struct pernet_operations ip_rt_pr
|
||||
|
||||
static int __init ip_rt_proc_init(void)
|
||||
{
|
||||
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||
+ return 0;
|
||||
+
|
||||
return register_pernet_subsys(&ip_rt_proc_ops);
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 8 Jul 2017 08:20:43 +0200
|
||||
Subject: debloat: dmabuf
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
drivers/base/Kconfig | 2 +-
|
||||
drivers/dma-buf/Makefile | 10 +++++++---
|
||||
drivers/dma-buf/dma-buf.c | 4 +++-
|
||||
kernel/sched/core.c | 1 +
|
||||
4 files changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/base/Kconfig
|
||||
+++ b/drivers/base/Kconfig
|
||||
@@ -198,7 +198,7 @@ config SOC_BUS
|
||||
source "drivers/base/regmap/Kconfig"
|
||||
|
||||
config DMA_SHARED_BUFFER
|
||||
- bool
|
||||
+ tristate
|
||||
default n
|
||||
select IRQ_WORK
|
||||
help
|
||||
--- a/drivers/dma-buf/heaps/Makefile
|
||||
+++ b/drivers/dma-buf/heaps/Makefile
|
||||
@@ -1,3 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
-obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
|
||||
-obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
|
||||
+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
|
||||
+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
|
||||
--- a/drivers/dma-buf/Makefile
|
||||
+++ b/drivers/dma-buf/Makefile
|
||||
@@ -1,12 +1,14 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
-obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
|
||||
+obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o
|
||||
+
|
||||
+dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
|
||||
dma-fence-unwrap.o dma-resv.o
|
||||
-obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
|
||||
-obj-$(CONFIG_DMABUF_HEAPS) += heaps/
|
||||
-obj-$(CONFIG_SYNC_FILE) += sync_file.o
|
||||
-obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o
|
||||
-obj-$(CONFIG_UDMABUF) += udmabuf.o
|
||||
-obj-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o
|
||||
+dma-buf-objs-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
|
||||
+obj-$(CONFIG_DMABUF_HEAPS) += heaps/
|
||||
+dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o
|
||||
+dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o
|
||||
+dma-buf-objs-$(CONFIG_UDMABUF) += udmabuf.o
|
||||
+dma-buf-objs-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o
|
||||
|
||||
dmabuf_selftests-y := \
|
||||
selftest.o \
|
||||
@@ -15,4 +17,6 @@ dmabuf_selftests-y := \
|
||||
st-dma-fence-unwrap.o \
|
||||
st-dma-resv.o
|
||||
|
||||
-obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
|
||||
+dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
|
||||
+
|
||||
+dma-shared-buffer-objs := $(dma-buf-objs-y)
|
||||
--- a/drivers/dma-buf/dma-buf.c
|
||||
+++ b/drivers/dma-buf/dma-buf.c
|
||||
@@ -1589,4 +1589,5 @@ static void __exit dma_buf_deinit(void)
|
||||
kern_unmount(dma_buf_mnt);
|
||||
dma_buf_uninit_sysfs_statistics();
|
||||
}
|
||||
-__exitcall(dma_buf_deinit);
|
||||
+module_exit(dma_buf_deinit);
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/kernel/sched/core.c
|
||||
+++ b/kernel/sched/core.c
|
||||
@@ -4331,6 +4331,7 @@ int wake_up_state(struct task_struct *p,
|
||||
{
|
||||
return try_to_wake_up(p, state, 0);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(wake_up_state);
|
||||
|
||||
/*
|
||||
* Perform scheduler related setup for a newly forked process p.
|
||||
--- a/fs/d_path.c
|
||||
+++ b/fs/d_path.c
|
||||
@@ -313,6 +313,7 @@ char *dynamic_dname(char *buffer, int bu
|
||||
buffer += buflen - sz;
|
||||
return memcpy(buffer, temp, sz);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(dynamic_dname);
|
||||
|
||||
char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
|
||||
{
|
|
@ -1,32 +0,0 @@
|
|||
From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sun, 16 Jul 2017 16:56:10 +0200
|
||||
Subject: lib: add uevent_next_seqnum()
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
include/linux/kobject.h | 5 +++++
|
||||
lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 42 insertions(+)
|
||||
|
||||
--- a/lib/kobject_uevent.c
|
||||
+++ b/lib/kobject_uevent.c
|
||||
@@ -179,6 +179,18 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
+u64 uevent_next_seqnum(void)
|
||||
+{
|
||||
+ u64 seq;
|
||||
+
|
||||
+ mutex_lock(&uevent_sock_mutex);
|
||||
+ seq = ++uevent_seqnum;
|
||||
+ mutex_unlock(&uevent_sock_mutex);
|
||||
+
|
||||
+ return seq;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(uevent_next_seqnum);
|
||||
+
|
||||
/**
|
||||
* kobject_synth_uevent - send synthetic uevent with arguments
|
||||
*
|
|
@ -1,76 +0,0 @@
|
|||
From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sun, 16 Jul 2017 16:56:10 +0200
|
||||
Subject: lib: add uevent_next_seqnum()
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
include/linux/kobject.h | 5 +++++
|
||||
lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 42 insertions(+)
|
||||
|
||||
--- a/include/linux/kobject.h
|
||||
+++ b/include/linux/kobject.h
|
||||
@@ -32,6 +32,8 @@
|
||||
#define UEVENT_NUM_ENVP 64 /* number of env pointers */
|
||||
#define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
|
||||
|
||||
+struct sk_buff;
|
||||
+
|
||||
#ifdef CONFIG_UEVENT_HELPER
|
||||
/* path to the userspace helper executed on an event */
|
||||
extern char uevent_helper[];
|
||||
@@ -224,4 +226,7 @@ int kobject_synth_uevent(struct kobject
|
||||
__printf(2, 3)
|
||||
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
|
||||
|
||||
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||
+ gfp_t allocation);
|
||||
+
|
||||
#endif /* _KOBJECT_H_ */
|
||||
--- a/lib/kobject_uevent.c
|
||||
+++ b/lib/kobject_uevent.c
|
||||
@@ -691,6 +691,43 @@ int add_uevent_var(struct kobj_uevent_en
|
||||
EXPORT_SYMBOL_GPL(add_uevent_var);
|
||||
|
||||
#if defined(CONFIG_NET)
|
||||
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||
+ gfp_t allocation)
|
||||
+{
|
||||
+ struct uevent_sock *ue_sk;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ /* send netlink message */
|
||||
+ mutex_lock(&uevent_sock_mutex);
|
||||
+ list_for_each_entry(ue_sk, &uevent_sock_list, list) {
|
||||
+ struct sock *uevent_sock = ue_sk->sk;
|
||||
+ struct sk_buff *skb2;
|
||||
+
|
||||
+ skb2 = skb_clone(skb, allocation);
|
||||
+ if (!skb2)
|
||||
+ break;
|
||||
+
|
||||
+ err = netlink_broadcast(uevent_sock, skb2, pid, group,
|
||||
+ allocation);
|
||||
+ if (err)
|
||||
+ break;
|
||||
+ }
|
||||
+ mutex_unlock(&uevent_sock_mutex);
|
||||
+
|
||||
+ kfree_skb(skb);
|
||||
+ return err;
|
||||
+}
|
||||
+#else
|
||||
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||
+ gfp_t allocation)
|
||||
+{
|
||||
+ kfree_skb(skb);
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+EXPORT_SYMBOL_GPL(broadcast_uevent);
|
||||
+
|
||||
+#if defined(CONFIG_NET)
|
||||
static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
|
@ -1,21 +0,0 @@
|
|||
From e08bcbbaa52fcc41f02743fd2e62a33255ce52da Mon Sep 17 00:00:00 2001
|
||||
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||
Date: Wed, 13 Jul 2022 13:52:28 +0200
|
||||
Subject: [PATCH] of/ftd: add device tree cmdline
|
||||
|
||||
---
|
||||
drivers/of/fdt.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/of/fdt.c
|
||||
+++ b/drivers/of/fdt.c
|
||||
@@ -1187,6 +1187,9 @@ int __init early_init_dt_scan_chosen(cha
|
||||
p = of_get_flat_dt_prop(node, "bootargs", &l);
|
||||
if (p != NULL && l > 0)
|
||||
strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE));
|
||||
+ p = of_get_flat_dt_prop(node, "bootargs-append", &l);
|
||||
+ if (p != NULL && l > 0)
|
||||
+ strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE));
|
||||
|
||||
handle_cmdline:
|
||||
/*
|
|
@ -1,30 +0,0 @@
|
|||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Tue, 19 Jul 2022 06:17:48 +0200
|
||||
Subject: [PATCH] Revert "Revert "Revert "driver core: Set fw_devlink=on by
|
||||
default"""
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This reverts commit ea718c699055c8566eb64432388a04974c43b2ea.
|
||||
|
||||
With of_platform_populate() called for MTD partitions that commit breaks
|
||||
probing devices which reference MTD in device tree.
|
||||
|
||||
Link: https://lore.kernel.org/all/696cb2da-20b9-b3dd-46d9-de4bf91a1506@gmail.com/T/#u
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
---
|
||||
drivers/base/core.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/base/core.c
|
||||
+++ b/drivers/base/core.c
|
||||
@@ -1606,7 +1606,7 @@ static void device_links_purge(struct de
|
||||
#define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \
|
||||
DL_FLAG_PM_RUNTIME)
|
||||
|
||||
-static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_ON;
|
||||
+static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_PERMISSIVE;
|
||||
static int __init fw_devlink_setup(char *arg)
|
||||
{
|
||||
if (!arg)
|
|
@ -1,352 +0,0 @@
|
|||
From 42824d4b753f84ccf885eca602c5037338b546c8 Mon Sep 17 00:00:00 2001
|
||||
From: Zhi Chen <zhichen@codeaurora.org>
|
||||
Date: Tue, 13 Jan 2015 14:28:18 -0800
|
||||
Subject: [PATCH 3/3] net: conntrack events, support multiple registrant
|
||||
|
||||
Merging this patch from kernel 3.4:
|
||||
This was supported by old (.28) kernel versions but removed
|
||||
because of it's overhead.
|
||||
But we need this feature for NA connection manager. Both ipv4
|
||||
and ipv6 modules needs to register themselves to ct events.
|
||||
|
||||
Change-Id: Iebfb254590fb594f5baf232f849d1b7ae45ef757
|
||||
Signed-off-by: Zhi Chen <zhichen@codeaurora.org>
|
||||
---
|
||||
include/net/netfilter/nf_conntrack_ecache.h | 15 ++-
|
||||
include/net/netns/conntrack.h | 3 +
|
||||
net/netfilter/Kconfig | 8 ++
|
||||
net/netfilter/nf_conntrack_core.c | 4 +
|
||||
net/netfilter/nf_conntrack_ecache.c | 103 +++++++++++++++++++-
|
||||
net/netfilter/nf_conntrack_netlink.c | 17 ++++
|
||||
6 files changed, 146 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/include/net/netfilter/nf_conntrack_ecache.h
|
||||
+++ b/include/net/netfilter/nf_conntrack_ecache.h
|
||||
@@ -65,9 +65,14 @@ struct nf_ct_event_notifier {
|
||||
int (*exp_event)(unsigned int events, const struct nf_exp_event *item);
|
||||
};
|
||||
|
||||
-void nf_conntrack_register_notifier(struct net *net,
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
|
||||
+extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
|
||||
+#else
|
||||
+int nf_conntrack_register_notifier(struct net *net,
|
||||
const struct nf_ct_event_notifier *nb);
|
||||
void nf_conntrack_unregister_notifier(struct net *net);
|
||||
+#endif
|
||||
|
||||
void nf_ct_deliver_cached_events(struct nf_conn *ct);
|
||||
int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
@@ -98,11 +103,13 @@ static inline void
|
||||
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
|
||||
{
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
- struct net *net = nf_ct_net(ct);
|
||||
struct nf_conntrack_ecache *e;
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ struct net *net = nf_ct_net(ct);
|
||||
|
||||
if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
|
||||
return;
|
||||
+#endif
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
@@ -117,20 +124,34 @@ nf_conntrack_event_report(enum ip_conntr
|
||||
u32 portid, int report)
|
||||
{
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
- if (nf_ct_ecache_exist(ct))
|
||||
- return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ const struct net *net = nf_ct_net(ct);
|
||||
+
|
||||
+ if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
|
||||
+ return 0;
|
||||
#endif
|
||||
+
|
||||
+ return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
|
||||
+#else
|
||||
return 0;
|
||||
+#endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
|
||||
{
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
- if (nf_ct_ecache_exist(ct))
|
||||
- return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ const struct net *net = nf_ct_net(ct);
|
||||
+
|
||||
+ if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
|
||||
+ return 0;
|
||||
#endif
|
||||
+
|
||||
+ return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
|
||||
+#else
|
||||
return 0;
|
||||
+#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
--- a/include/net/netns/conntrack.h
|
||||
+++ b/include/net/netns/conntrack.h
|
||||
@@ -106,6 +106,9 @@ struct netns_ct {
|
||||
u8 sysctl_checksum;
|
||||
|
||||
struct ip_conntrack_stat __percpu *stat;
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ struct atomic_notifier_head nf_conntrack_chain;
|
||||
+#endif
|
||||
struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
|
||||
struct nf_ip_net nf_ct_proto;
|
||||
#if defined(CONFIG_NF_CONNTRACK_LABELS)
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -161,6 +161,14 @@ config NF_CONNTRACK_EVENTS
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
+config NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ bool "Register multiple callbacks to ct events"
|
||||
+ depends on NF_CONNTRACK_EVENTS
|
||||
+ help
|
||||
+ Support multiple registrations.
|
||||
+
|
||||
+ If unsure, say `N'.
|
||||
+
|
||||
config NF_CONNTRACK_TIMEOUT
|
||||
bool 'Connection tracking timeout'
|
||||
depends on NETFILTER_ADVANCED
|
||||
--- a/net/netfilter/nf_conntrack_core.c
|
||||
+++ b/net/netfilter/nf_conntrack_core.c
|
||||
@@ -2804,6 +2804,10 @@ int nf_conntrack_init_net(struct net *ne
|
||||
nf_conntrack_ecache_pernet_init(net);
|
||||
nf_conntrack_proto_pernet_init(net);
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain);
|
||||
+#endif
|
||||
+
|
||||
return 0;
|
||||
|
||||
err_expect:
|
||||
--- a/net/netfilter/nf_conntrack_ecache.c
|
||||
+++ b/net/netfilter/nf_conntrack_ecache.c
|
||||
@@ -17,6 +17,9 @@
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+#include <linux/notifier.h>
|
||||
+#endif
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/export.h>
|
||||
@@ -162,6 +165,35 @@ static int __nf_conntrack_eventmask_repo
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
+ u32 portid, int report)
|
||||
+{
|
||||
+ struct nf_conntrack_ecache *e;
|
||||
+ struct net *net = nf_ct_net(ct);
|
||||
+
|
||||
+ e = nf_ct_ecache_find(ct);
|
||||
+ if (e == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (nf_ct_is_confirmed(ct)) {
|
||||
+ struct nf_ct_event item = {
|
||||
+ .ct = ct,
|
||||
+ .portid = e->portid ? e->portid : portid,
|
||||
+ .report = report
|
||||
+ };
|
||||
+ /* This is a resent of a destroy event? If so, skip missed */
|
||||
+ unsigned long missed = e->portid ? 0 : e->missed;
|
||||
+
|
||||
+ if (!((eventmask | missed) & e->ctmask))
|
||||
+ return 0;
|
||||
+
|
||||
+ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
int nf_conntrack_eventmask_report(unsigned int events, struct nf_conn *ct,
|
||||
u32 portid, int report)
|
||||
{
|
||||
@@ -197,10 +229,52 @@ int nf_conntrack_eventmask_report(unsign
|
||||
|
||||
return ret;
|
||||
}
|
||||
+#endif
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report);
|
||||
|
||||
/* deliver cached events and clear cache entry - must be called with locally
|
||||
* disabled softirqs */
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+void nf_ct_deliver_cached_events(struct nf_conn *ct)
|
||||
+{
|
||||
+ unsigned long events, missed;
|
||||
+ struct nf_conntrack_ecache *e;
|
||||
+ struct nf_ct_event item;
|
||||
+ struct net *net = nf_ct_net(ct);
|
||||
+
|
||||
+ e = nf_ct_ecache_find(ct);
|
||||
+ if (e == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ events = xchg(&e->cache, 0);
|
||||
+
|
||||
+ if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events)
|
||||
+ return;
|
||||
+
|
||||
+ /* We make a copy of the missed event cache without taking
|
||||
+ * the lock, thus we may send missed events twice. However,
|
||||
+ * this does not harm and it happens very rarely. */
|
||||
+ missed = e->missed;
|
||||
+
|
||||
+ if (!((events | missed) & e->ctmask))
|
||||
+ return;
|
||||
+
|
||||
+ item.ct = ct;
|
||||
+ item.portid = 0;
|
||||
+ item.report = 0;
|
||||
+
|
||||
+ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ events | missed,
|
||||
+ &item);
|
||||
+
|
||||
+ if (likely(!missed))
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock_bh(&ct->lock);
|
||||
+ e->missed &= ~missed;
|
||||
+ spin_unlock_bh(&ct->lock);
|
||||
+}
|
||||
+#else
|
||||
void nf_ct_deliver_cached_events(struct nf_conn *ct)
|
||||
{
|
||||
struct nf_conntrack_ecache *e;
|
||||
@@ -226,6 +300,7 @@ void nf_ct_deliver_cached_events(struct
|
||||
*/
|
||||
__nf_conntrack_eventmask_report(e, events, e->missed, &item);
|
||||
}
|
||||
+#endif
|
||||
EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
|
||||
|
||||
void nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
|
||||
@@ -258,20 +333,43 @@ out_unlock:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
-void nf_conntrack_register_notifier(struct net *net,
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+int nf_conntrack_register_notifier(struct net *net,
|
||||
+ struct notifier_block *nb)
|
||||
+{
|
||||
+ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
|
||||
+}
|
||||
+#else
|
||||
+int nf_conntrack_register_notifier(struct net *net,
|
||||
const struct nf_ct_event_notifier *new)
|
||||
{
|
||||
+ int ret;
|
||||
struct nf_ct_event_notifier *notify;
|
||||
|
||||
mutex_lock(&nf_ct_ecache_mutex);
|
||||
notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
|
||||
lockdep_is_held(&nf_ct_ecache_mutex));
|
||||
WARN_ON_ONCE(notify);
|
||||
+ if (notify != NULL) {
|
||||
+ ret = -EBUSY;
|
||||
+ goto out_unlock;
|
||||
+ }
|
||||
+
|
||||
rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new);
|
||||
- mutex_unlock(&nf_ct_ecache_mutex);
|
||||
+ ret = 0;
|
||||
+out_unlock:
|
||||
+ mutex_unlock(&nf_ct_ecache_mutex);
|
||||
+ return ret;
|
||||
}
|
||||
+#endif
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
|
||||
+{
|
||||
+ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
|
||||
+}
|
||||
+#else
|
||||
void nf_conntrack_unregister_notifier(struct net *net)
|
||||
{
|
||||
mutex_lock(&nf_ct_ecache_mutex);
|
||||
@@ -279,6 +377,7 @@ void nf_conntrack_unregister_notifier(st
|
||||
mutex_unlock(&nf_ct_ecache_mutex);
|
||||
/* synchronize_rcu() is called after netns pre_exit */
|
||||
}
|
||||
+#endif
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
|
||||
|
||||
void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state)
|
||||
--- a/net/netfilter/nf_conntrack_netlink.c
|
||||
+++ b/net/netfilter/nf_conntrack_netlink.c
|
||||
@@ -717,12 +717,19 @@ static size_t ctnetlink_nlmsg_size(const
|
||||
}
|
||||
|
||||
static int
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ctnetlink_conntrack_event(struct notifier_block *this, unsigned long events, void *ptr)
|
||||
+#else
|
||||
ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
|
||||
+#endif
|
||||
{
|
||||
const struct nf_conntrack_zone *zone;
|
||||
struct net *net;
|
||||
struct nlmsghdr *nlh;
|
||||
struct nlattr *nest_parms;
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ struct nf_ct_event *item = (struct nf_ct_event *)ptr;
|
||||
+#endif
|
||||
struct nf_conn *ct = item->ct;
|
||||
struct sk_buff *skb;
|
||||
unsigned int type;
|
||||
@@ -3750,11 +3757,17 @@ static int ctnetlink_stat_exp_cpu(struct
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+static struct notifier_block ctnl_notifier = {
|
||||
+ .notifier_call = ctnetlink_conntrack_event
|
||||
+};
|
||||
+#else
|
||||
static struct nf_ct_event_notifier ctnl_notifier = {
|
||||
.ct_event = ctnetlink_conntrack_event,
|
||||
.exp_event = ctnetlink_expect_event,
|
||||
};
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
|
||||
[IPCTNL_MSG_CT_NEW] = {
|
||||
@@ -3853,8 +3866,12 @@ static int __net_init ctnetlink_net_init
|
||||
static void ctnetlink_net_pre_exit(struct net *net)
|
||||
{
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ nf_conntrack_unregister_notifier(net,&ctnl_notifier);
|
||||
+#else
|
||||
nf_conntrack_unregister_notifier(net);
|
||||
#endif
|
||||
+#endif
|
||||
}
|
||||
|
||||
static struct pernet_operations ctnetlink_net_ops = {
|
|
@ -1,204 +0,0 @@
|
|||
--- a/include/linux/if_bridge.h
|
||||
+++ b/include/linux/if_bridge.h
|
||||
@@ -71,6 +71,9 @@ void brioctl_set(int (*hook)(struct net
|
||||
int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
|
||||
struct ifreq *ifr, void __user *uarg);
|
||||
|
||||
+extern void br_dev_update_stats(struct net_device *dev,
|
||||
+ struct rtnl_link_stats64 *nlstats);
|
||||
+
|
||||
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
|
||||
int br_multicast_list_adjacent(struct net_device *dev,
|
||||
struct list_head *br_ip_list);
|
||||
--- a/include/linux/skbuff.h
|
||||
+++ b/include/linux/skbuff.h
|
||||
@@ -986,6 +986,10 @@ struct sk_buff {
|
||||
__u8 csum_not_inet:1;
|
||||
__u8 scm_io_uring:1;
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ __u8 fast_forwarded:1;
|
||||
+#endif
|
||||
+
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
__u16 tc_index; /* traffic control index */
|
||||
#endif
|
||||
--- a/include/linux/timer.h
|
||||
+++ b/include/linux/timer.h
|
||||
@@ -18,6 +18,10 @@ struct timer_list {
|
||||
void (*function)(struct timer_list *);
|
||||
u32 flags;
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ unsigned long cust_data;
|
||||
+#endif
|
||||
+
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
struct lockdep_map lockdep_map;
|
||||
#endif
|
||||
--- a/include/net/netfilter/nf_conntrack_ecache.h
|
||||
+++ b/include/net/netfilter/nf_conntrack_ecache.h
|
||||
@@ -68,6 +68,8 @@ struct nf_ct_event_notifier {
|
||||
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
|
||||
extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
|
||||
+extern int nf_conntrack_register_chain_notifier(struct net *net, struct notifier_block *nb);
|
||||
+extern int nf_conntrack_unregister_chain_notifier(struct net *net, struct notifier_block *nb);
|
||||
#else
|
||||
int nf_conntrack_register_notifier(struct net *net,
|
||||
const struct nf_ct_event_notifier *nb);
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -467,6 +467,9 @@ config FAILOVER
|
||||
migration of VMs with direct attached VFs by failing over to the
|
||||
paravirtual datapath when the VF is unplugged.
|
||||
|
||||
+config SHORTCUT_FE
|
||||
+ bool "Enables kernel network stack path for Shortcut Forwarding Engine"
|
||||
+
|
||||
config ETHTOOL_NETLINK
|
||||
bool "Netlink interface for ethtool"
|
||||
default y
|
||||
--- a/net/bridge/br_if.c
|
||||
+++ b/net/bridge/br_if.c
|
||||
@@ -767,6 +767,28 @@ void br_port_flags_change(struct net_bri
|
||||
br_offload_port_state(p);
|
||||
}
|
||||
|
||||
+void br_dev_update_stats(struct net_device *dev,
|
||||
+ struct rtnl_link_stats64 *nlstats)
|
||||
+{
|
||||
+
|
||||
+ struct pcpu_sw_netstats *stats;
|
||||
+
|
||||
+ /* Is this a bridge? */
|
||||
+ if (!(dev->priv_flags & IFF_EBRIDGE))
|
||||
+ return;
|
||||
+
|
||||
+
|
||||
+ stats = this_cpu_ptr(dev->tstats);
|
||||
+
|
||||
+ u64_stats_update_begin(&stats->syncp);
|
||||
+ u64_stats_add(&stats->rx_packets, nlstats->rx_packets);
|
||||
+ u64_stats_add(&stats->rx_bytes, nlstats->rx_bytes);
|
||||
+ u64_stats_add(&stats->tx_packets, nlstats->tx_packets);
|
||||
+ u64_stats_add(&stats->tx_bytes, nlstats->tx_bytes);
|
||||
+ u64_stats_update_end(&stats->syncp);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(br_dev_update_stats);
|
||||
+
|
||||
bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag)
|
||||
{
|
||||
struct net_bridge_port *p;
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -3581,9 +3581,17 @@ static int xmit_one(struct sk_buff *skb,
|
||||
{
|
||||
unsigned int len;
|
||||
int rc;
|
||||
-
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ /* If this skb has been fast forwarded then we don't want it to
|
||||
+ * go to any taps (by definition we're trying to bypass them).
|
||||
+ */
|
||||
+ if (!skb->fast_forwarded) {
|
||||
+#endif
|
||||
if (dev_nit_active(dev))
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb)))
|
||||
@@ -5242,6 +5250,11 @@ void netdev_rx_handler_unregister(struct
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+int (*athrs_fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
|
||||
+EXPORT_SYMBOL_GPL(athrs_fast_nat_recv);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Limit the use of PFMEMALLOC reserves to those protocols that implement
|
||||
* the special handling of PFMEMALLOC skbs.
|
||||
@@ -5290,6 +5303,10 @@ static int __netif_receive_skb_core(stru
|
||||
int ret = NET_RX_DROP;
|
||||
__be16 type;
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ int (*fast_recv)(struct sk_buff *skb);
|
||||
+#endif
|
||||
+
|
||||
net_timestamp_check(!READ_ONCE(netdev_tstamp_prequeue), skb);
|
||||
|
||||
trace_netif_receive_skb(skb);
|
||||
@@ -5327,6 +5344,15 @@ another_round:
|
||||
goto out;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ fast_recv = rcu_dereference(athrs_fast_nat_recv);
|
||||
+ if (fast_recv) {
|
||||
+ if (fast_recv(skb)) {
|
||||
+ ret = NET_RX_SUCCESS;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
if (skb_skip_tc_classify(skb))
|
||||
goto skip_classify;
|
||||
|
||||
--- a/net/netfilter/nf_conntrack_ecache.c
|
||||
+++ b/net/netfilter/nf_conntrack_ecache.c
|
||||
@@ -143,12 +143,23 @@ static int __nf_conntrack_eventmask_repo
|
||||
rcu_read_lock();
|
||||
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
- if (!notify) {
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ if (!notify && !rcu_dereference_raw(net->ct.nf_conntrack_chain.head))
|
||||
+#else
|
||||
+ if (!notify)
|
||||
+#endif
|
||||
+ {
|
||||
rcu_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ events | missed, &item);
|
||||
+ if (notify)
|
||||
+ ret = notify->ct_event(events | missed, item);
|
||||
+#else
|
||||
ret = notify->ct_event(events | missed, item);
|
||||
+#endif
|
||||
rcu_read_unlock();
|
||||
|
||||
if (likely(ret >= 0 && missed == 0))
|
||||
@@ -339,6 +350,11 @@ int nf_conntrack_register_notifier(struc
|
||||
{
|
||||
return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
|
||||
}
|
||||
+int nf_conntrack_register_chain_notifier(struct net *net, struct notifier_block *nb)
|
||||
+{
|
||||
+ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nf_conntrack_register_chain_notifier);
|
||||
#else
|
||||
int nf_conntrack_register_notifier(struct net *net,
|
||||
const struct nf_ct_event_notifier *new)
|
||||
@@ -369,6 +385,11 @@ int nf_conntrack_unregister_notifier(str
|
||||
{
|
||||
return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
|
||||
}
|
||||
+int nf_conntrack_unregister_chain_notifier(struct net *net, struct notifier_block *nb)
|
||||
+{
|
||||
+ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nf_conntrack_unregister_chain_notifier);
|
||||
#else
|
||||
void nf_conntrack_unregister_notifier(struct net *net)
|
||||
{
|
|
@ -1,235 +0,0 @@
|
|||
--- a/net/netfilter/nf_nat_masquerade.c
|
||||
+++ b/net/netfilter/nf_nat_masquerade.c
|
||||
@@ -8,6 +8,9 @@
|
||||
#include <linux/netfilter_ipv6.h>
|
||||
|
||||
#include <net/netfilter/nf_nat_masquerade.h>
|
||||
+#include <net/netfilter/nf_conntrack_zones.h>
|
||||
+#include <net/netfilter/nf_conntrack_helper.h>
|
||||
+#include <net/netfilter/nf_conntrack_core.h>
|
||||
|
||||
struct masq_dev_work {
|
||||
struct work_struct work;
|
||||
@@ -24,6 +27,129 @@ static DEFINE_MUTEX(masq_mutex);
|
||||
static unsigned int masq_refcnt __read_mostly;
|
||||
static atomic_t masq_worker_count __read_mostly;
|
||||
|
||||
+static void bcm_nat_expect(struct nf_conn *ct,
|
||||
+ struct nf_conntrack_expect *exp)
|
||||
+{
|
||||
+ struct nf_nat_range2 range;
|
||||
+
|
||||
+ /* This must be a fresh one. */
|
||||
+ BUG_ON(ct->status & IPS_NAT_DONE_MASK);
|
||||
+
|
||||
+ /* Change src to where new ct comes from */
|
||||
+ range.flags = NF_NAT_RANGE_MAP_IPS;
|
||||
+ range.min_addr = range.max_addr =
|
||||
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3;
|
||||
+ nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
|
||||
+
|
||||
+ /* For DST manip, map port here to where it's expected. */
|
||||
+ range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
|
||||
+ range.min_proto = range.max_proto = exp->saved_proto;
|
||||
+ range.min_addr = range.max_addr = exp->saved_addr;
|
||||
+ nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
|
||||
+}
|
||||
+
|
||||
+/****************************************************************************/
|
||||
+static int bcm_nat_help(struct sk_buff *skb, unsigned int protoff,
|
||||
+ struct nf_conn *ct, enum ip_conntrack_info ctinfo)
|
||||
+{
|
||||
+ int dir = CTINFO2DIR(ctinfo);
|
||||
+ struct nf_conn_help *help = nfct_help(ct);
|
||||
+ struct nf_conntrack_expect *exp;
|
||||
+
|
||||
+ if (dir != IP_CT_DIR_ORIGINAL ||
|
||||
+ help->expecting[NF_CT_EXPECT_CLASS_DEFAULT])
|
||||
+ return NF_ACCEPT;
|
||||
+
|
||||
+ pr_debug("bcm_nat: packet[%d bytes] ", skb->len);
|
||||
+ nf_ct_dump_tuple(&ct->tuplehash[dir].tuple);
|
||||
+ pr_debug("reply: ");
|
||||
+ nf_ct_dump_tuple(&ct->tuplehash[!dir].tuple);
|
||||
+
|
||||
+ /* Create expect */
|
||||
+ if ((exp = nf_ct_expect_alloc(ct)) == NULL)
|
||||
+ return NF_ACCEPT;
|
||||
+
|
||||
+ nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, AF_INET, NULL,
|
||||
+ &ct->tuplehash[!dir].tuple.dst.u3, IPPROTO_UDP,
|
||||
+ NULL, &ct->tuplehash[!dir].tuple.dst.u.udp.port);
|
||||
+ exp->flags = NF_CT_EXPECT_PERMANENT;
|
||||
+ exp->saved_addr = ct->tuplehash[dir].tuple.src.u3;
|
||||
+ exp->saved_proto.udp.port = ct->tuplehash[dir].tuple.src.u.udp.port;
|
||||
+ exp->dir = !dir;
|
||||
+ exp->expectfn = bcm_nat_expect;
|
||||
+
|
||||
+ /* Setup expect */
|
||||
+ nf_ct_expect_related(exp, 0);
|
||||
+ nf_ct_expect_put(exp);
|
||||
+ pr_debug("bcm_nat: expect setup\n");
|
||||
+
|
||||
+ return NF_ACCEPT;
|
||||
+}
|
||||
+
|
||||
+/****************************************************************************/
|
||||
+static struct nf_conntrack_expect_policy bcm_nat_exp_policy __read_mostly = {
|
||||
+ .max_expected = 1000,
|
||||
+ .timeout = 240,
|
||||
+};
|
||||
+
|
||||
+/****************************************************************************/
|
||||
+static struct nf_conntrack_helper nf_conntrack_helper_bcm_nat __read_mostly = {
|
||||
+ .name = "BCM-NAT",
|
||||
+ .me = THIS_MODULE,
|
||||
+ .tuple.src.l3num = AF_INET,
|
||||
+ .tuple.dst.protonum = IPPROTO_UDP,
|
||||
+ .expect_policy = &bcm_nat_exp_policy,
|
||||
+ .expect_class_max = 1,
|
||||
+ .help = bcm_nat_help,
|
||||
+};
|
||||
+
|
||||
+/****************************************************************************/
|
||||
+static inline int find_exp(__be32 ip, __be16 port, struct nf_conn *ct)
|
||||
+{
|
||||
+ struct nf_conntrack_tuple tuple;
|
||||
+ struct nf_conntrack_expect *i = NULL;
|
||||
+
|
||||
+
|
||||
+ memset(&tuple, 0, sizeof(tuple));
|
||||
+ tuple.src.l3num = AF_INET;
|
||||
+ tuple.dst.protonum = IPPROTO_UDP;
|
||||
+ tuple.dst.u3.ip = ip;
|
||||
+ tuple.dst.u.udp.port = port;
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ i = __nf_ct_expect_find(nf_ct_net(ct), nf_ct_zone(ct), &tuple);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return i != NULL;
|
||||
+}
|
||||
+
|
||||
+/****************************************************************************/
|
||||
+static inline struct nf_conntrack_expect *find_fullcone_exp(struct nf_conn *ct)
|
||||
+{
|
||||
+ struct nf_conntrack_tuple * tp =
|
||||
+ &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
|
||||
+ struct nf_conntrack_expect * exp = NULL;
|
||||
+ struct nf_conntrack_expect * i;
|
||||
+ unsigned int h;
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ for (h = 0; h < nf_ct_expect_hsize; h++) {
|
||||
+ hlist_for_each_entry_rcu(i, &nf_ct_expect_hash[h], hnode) {
|
||||
+ if (nf_inet_addr_cmp(&i->saved_addr, &tp->src.u3) &&
|
||||
+ i->saved_proto.all == tp->src.u.all &&
|
||||
+ i->tuple.dst.protonum == tp->dst.protonum &&
|
||||
+ i->tuple.src.u3.ip == 0 &&
|
||||
+ i->tuple.src.u.udp.port == 0) {
|
||||
+ exp = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return exp;
|
||||
+}
|
||||
+
|
||||
unsigned int
|
||||
nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
|
||||
const struct nf_nat_range2 *range,
|
||||
@@ -61,6 +187,72 @@ nf_nat_masquerade_ipv4(struct sk_buff *s
|
||||
if (nat)
|
||||
nat->masq_index = out->ifindex;
|
||||
|
||||
+/* RFC 4787 - 4.2.2. Port Parity
|
||||
+ i.e., an even port will be mapped to an even port, and an odd port will be mapped to an odd port.
|
||||
+*/
|
||||
+#define CHECK_PORT_PARITY(a, b) ((a%2)==(b%2))
|
||||
+ if (range->min_addr.ip != 0 /* nat_mode == full cone */
|
||||
+ && (nfct_help(ct) == NULL || nfct_help(ct)->helper == NULL)
|
||||
+ && nf_ct_protonum(ct) == IPPROTO_UDP) {
|
||||
+ unsigned int ret;
|
||||
+ u_int16_t minport;
|
||||
+ u_int16_t maxport;
|
||||
+ struct nf_conntrack_expect *exp;
|
||||
+
|
||||
+ pr_debug("bcm_nat: need full cone NAT\n");
|
||||
+
|
||||
+ /* Choose port */
|
||||
+ spin_lock_bh(&nf_conntrack_expect_lock);
|
||||
+ /* Look for existing expectation */
|
||||
+ exp = find_fullcone_exp(ct);
|
||||
+ if (exp) {
|
||||
+ minport = maxport = exp->tuple.dst.u.udp.port;
|
||||
+ pr_debug("bcm_nat: existing mapped port = %hu\n",
|
||||
+ ntohs(minport));
|
||||
+ } else { /* no previous expect */
|
||||
+ u_int16_t newport, tmpport, orgport;
|
||||
+
|
||||
+ minport = range->min_proto.all == 0?
|
||||
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.
|
||||
+ u.udp.port : range->min_proto.all;
|
||||
+ maxport = range->max_proto.all == 0?
|
||||
+ htons(65535) : range->max_proto.all;
|
||||
+ orgport = ntohs(minport);
|
||||
+ for (newport = ntohs(minport),tmpport = ntohs(maxport);
|
||||
+ newport <= tmpport; newport++) {
|
||||
+ if (CHECK_PORT_PARITY(orgport, newport) && !find_exp(newsrc, htons(newport), ct)) {
|
||||
+ pr_debug("bcm_nat: new mapped port = "
|
||||
+ "%hu\n", newport);
|
||||
+ minport = maxport = htons(newport);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ spin_unlock_bh(&nf_conntrack_expect_lock);
|
||||
+
|
||||
+
|
||||
+ memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
|
||||
+ memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
|
||||
+
|
||||
+ newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS |
|
||||
+ NF_NAT_RANGE_PROTO_SPECIFIED;
|
||||
+ newrange.max_addr.ip = newrange.min_addr.ip = newsrc;
|
||||
+ newrange.min_proto.udp.port = newrange.max_proto.udp.port = minport;
|
||||
+
|
||||
+ /* Set ct helper */
|
||||
+ ret = nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
|
||||
+ if (ret == NF_ACCEPT) {
|
||||
+ struct nf_conn_help *help = nfct_help(ct);
|
||||
+ if (help == NULL)
|
||||
+ help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
|
||||
+ if (help != NULL) {
|
||||
+ help->helper = &nf_conntrack_helper_bcm_nat;
|
||||
+ pr_debug("bcm_nat: helper set\n");
|
||||
+ }
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
/* Transfer from original range. */
|
||||
memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
|
||||
memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
|
||||
@@ -352,6 +544,7 @@ EXPORT_SYMBOL_GPL(nf_nat_masquerade_inet
|
||||
|
||||
void nf_nat_masquerade_inet_unregister_notifiers(void)
|
||||
{
|
||||
+ nf_conntrack_helper_unregister(&nf_conntrack_helper_bcm_nat);
|
||||
mutex_lock(&masq_mutex);
|
||||
/* check if the notifiers still have clients */
|
||||
if (--masq_refcnt > 0)
|
||||
--- a/net/netfilter/xt_MASQUERADE.c
|
||||
+++ b/net/netfilter/xt_MASQUERADE.c
|
||||
@@ -42,6 +42,9 @@ masquerade_tg(struct sk_buff *skb, const
|
||||
range.min_proto = mr->range[0].min;
|
||||
range.max_proto = mr->range[0].max;
|
||||
|
||||
+ range.min_addr.ip = mr->range[0].min_ip;
|
||||
+ range.max_addr.ip = mr->range[0].max_ip;
|
||||
+
|
||||
return nf_nat_masquerade_ipv4(skb, xt_hooknum(par), &range,
|
||||
xt_out(par));
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
--- a/net/wireless/wext-core.c
|
||||
+++ b/net/wireless/wext-core.c
|
||||
@@ -959,6 +959,9 @@ static int wireless_process_ioctl(struct
|
||||
else if (private)
|
||||
return private(dev, iwr, cmd, info, handler);
|
||||
}
|
||||
+ /* Old driver API : call driver ioctl handler */
|
||||
+ if (dev->netdev_ops->ndo_do_ioctl)
|
||||
+ return dev->netdev_ops->ndo_do_ioctl(dev, (struct ifreq *) iwr, cmd);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
--- a/drivers/net/phy/ar8216.c 2022-12-16 09:52:12.560547743 +0100
|
||||
+++ b/drivers/net/phy/ar8216.c 2022-12-16 09:54:48.161592238 +0100
|
||||
@@ -2467,7 +2467,7 @@
|
||||
/* VID fixup only needed on ar8216 */
|
||||
if (chip_is_ar8216(priv)) {
|
||||
dev->phy_ptr = priv;
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,15,0)
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0)
|
||||
dev->extra_priv_flags |= IFF_NO_IP_ALIGN;
|
||||
#else
|
||||
dev->priv_flags |= IFF_NO_IP_ALIGN;
|
||||
@@ -2706,7 +2706,7 @@
|
||||
|
||||
#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
dev->phy_ptr = NULL;
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,15,0)
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0)
|
||||
dev->extra_priv_flags &= ~IFF_NO_IP_ALIGN;
|
||||
#else
|
||||
dev->priv_flags &= ~IFF_NO_IP_ALIGN;
|
Loading…
Add table
Add a link
Reference in a new issue