diff --git a/include/kernel-version.mk b/include/kernel-version.mk index 2811d4eea2..6465e25359 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -6,13 +6,13 @@ ifdef CONFIG_TESTING_KERNEL KERNEL_PATCHVER:=$(KERNEL_TESTING_PATCHVER) endif -LINUX_VERSION-4.9 = .228 -LINUX_VERSION-4.14 = .186 +LINUX_VERSION-4.9 = .229 +LINUX_VERSION-4.14 = .187 LINUX_VERSION-4.19 = .130 LINUX_VERSION-5.4 = .48 -LINUX_KERNEL_HASH-4.9.228 = 8fbff429c6453036a0f79a55b4d85c1885c16999751198ddefdca7a3ff17fc34 -LINUX_KERNEL_HASH-4.14.186 = 445b426181005b157a0cd33d663ed61a73c32c669772e066bb30291c6775a260 +LINUX_KERNEL_HASH-4.9.229 = 3256c2835fd95a1a739603e78b02d363eac2ce73a39fa19b13b32da4fc370fdc +LINUX_KERNEL_HASH-4.14.187 = 5b223475eaeea196aa7e127d3f253bca5c35d8afdc72ca75230ce1ecdd1454bd LINUX_KERNEL_HASH-4.19.130 = a692c0e61dc885b4d6e66ae7bf202dadf7d5538fbf92766ce7cf8e227fd4f00f LINUX_KERNEL_HASH-5.4.48 = bf20ddafcd04c114d34654bb10d1eb74f1864f3d14b676c6f0d42d60bbcf1d53 diff --git a/package/ctcgfw/openwrt-v2ray-plugin/Makefile b/package/ctcgfw/openwrt-v2ray-plugin/Makefile index 4609b1b1fc..5c293f68af 100644 --- a/package/ctcgfw/openwrt-v2ray-plugin/Makefile +++ b/package/ctcgfw/openwrt-v2ray-plugin/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=v2ray-plugin -PKG_VERSION:=1.3.1 +PKG_VERSION:=1.3.2 PKG_RELEASE:=2 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://codeload.github.com/shadowsocks/v2ray-plugin/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=86d37a8ecef82457b4750a1af9e8d093b25ae0d32ea7dcc2ad5c0068fe2d3d74 +PKG_SOURCE_URL:=https://codeload.github.com/teddysun/v2ray-plugin/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=1cc9ed8e79347da044fa2f577bc5371dcdf0b03e131f61137b5c1d2a2be11509 PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE diff --git a/package/firmware/linux-firmware/Makefile b/package/firmware/linux-firmware/Makefile index 01dee59171..b50a025409 100644 --- a/package/firmware/linux-firmware/Makefile +++ b/package/firmware/linux-firmware/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=linux-firmware -PKG_VERSION:=20200122 +PKG_VERSION:=20200619 PKG_RELEASE:=1 PKG_SOURCE_URL:=@KERNEL/linux/kernel/firmware PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_HASH:=a30e811b3736a72b874ac27e10662f5e5409b1cadf8aab7ba88e8f8bc8083986 +PKG_HASH:=962d3ae197d226c8259f9cc7746f7ef12a9d23787cd56bd27302021ba6339722 PKG_MAINTAINER:=Felix Fietkau diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk index 3906bf34d8..bdfe44eb75 100644 --- a/package/kernel/linux/modules/fs.mk +++ b/package/kernel/linux/modules/fs.mk @@ -163,7 +163,7 @@ endef $(eval $(call KernelPackage,fs-efivarfs)) -define KernelPackage/fs-exfat-kernel +define KernelPackage/fs-exfat SUBMENU:=$(FS_MENU) TITLE:=exFAT filesystem support KCONFIG:= \ @@ -177,14 +177,14 @@ define KernelPackage/fs-exfat-kernel CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" FILES:=$(LINUX_DIR)/drivers/staging/exfat/exfat.ko AUTOLOAD:=$(call AutoLoad,30,exfat,1) - DEPENDS:=@!(LINUX_4_9||LINUX_4_14||LINUX_4_19) +kmod-nls-base + DEPENDS:=@LINUX_5_4 +kmod-nls-base endef -define KernelPackage/fs-exfat-kernel/description +define KernelPackage/fs-exfat/description Kernel module for exFAT filesystem support endef -$(eval $(call KernelPackage,fs-exfat-kernel)) +$(eval $(call KernelPackage,fs-exfat)) define KernelPackage/fs-exportfs diff --git a/package/kernel/linux/modules/video.mk b/package/kernel/linux/modules/video.mk index f7fad10de1..d433e9f205 100644 --- a/package/kernel/linux/modules/video.mk +++ b/package/kernel/linux/modules/video.mk @@ -282,6 +282,7 @@ define KernelPackage/drm-amdgpu CONFIG_DRM_AMDGPU_SI=y \ CONFIG_DRM_AMDGPU_CIK=y \ CONFIG_DRM_AMD_DC=y \ + CONFIG_HSA_AMD=y \ CONFIG_DEBUG_KERNEL_DC=n FILES:=$(LINUX_DIR)/drivers/gpu/drm/amd/amdgpu/amdgpu.ko \ $(LINUX_DIR)/drivers/gpu/drm/scheduler/gpu-sched.ko@ge4.15 \ diff --git a/package/lean/UnblockNeteaseMusic-Go/Makefile b/package/lean/UnblockNeteaseMusic-Go/Makefile index 983ab1ff1d..b2ed6833b6 100644 --- a/package/lean/UnblockNeteaseMusic-Go/Makefile +++ b/package/lean/UnblockNeteaseMusic-Go/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=UnblockNeteaseMusic-Go -PKG_VERSION:=0.2.0 -PKG_RELEASE:=3 +PKG_VERSION:=0.2.1 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/cnsilvan/UnblockNeteaseMusic.git -PKG_SOURCE_VERSION:=0c1c2f7ed9ae6277a10b1b1bba81101f552af509 +PKG_SOURCE_VERSION:=7664b2b5c5dbe8e1ff7fde0c0051b4feabc0e0ba PKG_MAINTAINER:=Silvan PKG_SOURCE_SUBDIR:=$(PKG_NAME) @@ -27,6 +27,19 @@ GO_PKG_LDFLAGS+= \ include $(INCLUDE_DIR)/package.mk include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk +define Package/$(PKG_NAME)/config +config $(PKG_NAME)_INCLUDE_GOPROXY + bool "Compiling with GOPROXY proxy" + default n + +endef + +ifeq ($(CONFIG_$(PKG_NAME)_INCLUDE_GOPROXY),y) +export GO111MODULE=on +export GOPROXY=https://goproxy.io +#export GOPROXY=https://mirrors.aliyun.com/goproxy/ +endif + define Package/$(PKG_NAME) SECTION:=multimedia CATEGORY:=Multimedia @@ -44,7 +57,6 @@ define Build/Prepare endef define Build/Configure - patch -p1 -d $(BUILD_DIR)/$(PKG_NAME) <./patches/01-fix-endpoint.patch endef define Build/Compile diff --git a/package/lean/UnblockNeteaseMusic-Go/patches/01-fix-endpoint.patch b/package/lean/UnblockNeteaseMusic-Go/patches/01-fix-endpoint.patch deleted file mode 100644 index c67f83ef2c..0000000000 --- a/package/lean/UnblockNeteaseMusic-Go/patches/01-fix-endpoint.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/processor/processor.go b/processor/processor.go -index a35f8df..a7e3015 100644 ---- a/processor/processor.go -+++ b/processor/processor.go -@@ -393,7 +393,7 @@ - //data["url"] = uri.Scheme + "://" + uri.Host + uri.EscapedPath() - //data["url"] = uri.String() - if *config.EndPoint { -- data["url"] = "http://music.163.com/unblockmusic/" + uri.String() -+ data["url"] = "https://music.163.com/unblockmusic/" + uri.String() - } else { - data["url"] = uri.String() - } diff --git a/package/lean/automount/Makefile b/package/lean/automount/Makefile index 1639af7a5f..2066168784 100644 --- a/package/lean/automount/Makefile +++ b/package/lean/automount/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=automount PKG_VERSION:=1 -PKG_RELEASE:=31 +PKG_RELEASE:=32 PKG_ARCH:=all include $(INCLUDE_DIR)/package.mk @@ -17,7 +17,7 @@ include $(INCLUDE_DIR)/package.mk define Package/automount TITLE:=Mount autoconfig hotplug script. MAINTAINER:=Lean - DEPENDS:=+block-mount +kmod-usb-storage +kmod-usb-storage-extras +!TARGET_ramips:kmod-usb-storage-uas +kmod-fs-vfat +kmod-fs-ext4 +ntfs-3g +(LINUX_4_9||LINUX_4_14||LINUX_4_19):kmod-fs-exfat +LINUX_5_4:kmod-fs-exfat-kernel + DEPENDS:=+block-mount +kmod-usb-storage +kmod-usb-storage-extras +!TARGET_ramips:kmod-usb-storage-uas +kmod-fs-vfat +kmod-fs-ext4 +!LINUX_5_4:kmod-fs-exfat0 +LINUX_5_4:kmod-fs-exfat +ntfs-3g endef define Package/automount/description diff --git a/package/lean/baidupcs-web/Makefile b/package/lean/baidupcs-web/Makefile index a0fe471825..0540b060d8 100644 --- a/package/lean/baidupcs-web/Makefile +++ b/package/lean/baidupcs-web/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=baidupcs-web PKG_VERSION:=3.7.1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 include $(INCLUDE_DIR)/package.mk @@ -62,7 +62,7 @@ endif PKG_SOURCE:=BaiduPCS-Go-v$(PKG_VERSION)-linux-$(PKG_ARCH_BAIDUPCS-WEB).zip -PKG_SOURCE_URL:=https://github.com/Erope/baidupcs-web/releases/download/$(PKG_VERSION)/ +PKG_SOURCE_URL:=https://github.com/coolsnowwolf/baidupcs-web/raw/master/ UNZIP_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/$(PKG_NAME)-unzip diff --git a/package/lean/default-settings/Makefile b/package/lean/default-settings/Makefile index e4b1903cbb..e42ca7dbfc 100644 --- a/package/lean/default-settings/Makefile +++ b/package/lean/default-settings/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=default-settings PKG_VERSION:=1.1 -PKG_RELEASE:=60 +PKG_RELEASE:=61 PKG_LICENSE:=GPLv3 PKG_LICENSE_FILES:=LICENSE diff --git a/package/lean/default-settings/files/openwrt_banner b/package/lean/default-settings/files/openwrt_banner index 1b4961d2d7..06b8a2206e 100644 --- a/package/lean/default-settings/files/openwrt_banner +++ b/package/lean/default-settings/files/openwrt_banner @@ -8,5 +8,5 @@ │ # │ │ " │ │─────────────────────────────────────────────────│ -│ OpenWrt 18.06 by Lean | Mod 20.06 By CTCGFW │ +│ OpenWrt 18.06 by Lean | Mod 20.07 By CTCGFW │ └─────────────────────────────────────────────────┘ diff --git a/package/lean/default-settings/files/zzz-default-settings b/package/lean/default-settings/files/zzz-default-settings index 5194e74142..1e8792e266 100755 --- a/package/lean/default-settings/files/zzz-default-settings +++ b/package/lean/default-settings/files/zzz-default-settings @@ -45,13 +45,13 @@ sed -i '/option disabled/d' /etc/config/wireless sed -i '/set wireless.radio${devidx}.disabled/d' /lib/wifi/mac80211.sh sed -i '/DISTRIB_REVISION/d' /etc/openwrt_release -echo "DISTRIB_REVISION='| Mod20.06 by CTCGFW'" >> /etc/openwrt_release +echo "DISTRIB_REVISION='| Mod20.07 by CTCGFW'" >> /etc/openwrt_release sed -i '/DISTRIB_DESCRIPTION/d' /etc/openwrt_release echo "DISTRIB_DESCRIPTION='OpenWrt 18.06 by Lean '" >> /etc/openwrt_release sed -i 's/LuCI openwrt-18.06 branch/LuCI 18.06 by Lean/g' /usr/lib/lua/luci/version.lua sed -i '/luciversion/d' /usr/lib/lua/luci/version.lua -echo 'luciversion = "Mod20.05 by CTCGFW"' >> /usr/lib/lua/luci/version.lua +echo 'luciversion = "Mod20.06 by CTCGFW"' >> /usr/lib/lua/luci/version.lua sed -i '/log-facility/d' /etc/dnsmasq.conf echo "log-facility=/dev/null" >> /etc/dnsmasq.conf diff --git a/package/lean/fast-classifier/Makefile b/package/lean/fast-classifier/Makefile new file mode 100644 index 0000000000..2e29898b46 --- /dev/null +++ b/package/lean/fast-classifier/Makefile @@ -0,0 +1,91 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=fast-classifier +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/$(PKG_NAME)/Default + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + DEPENDS:=+kmod-ipt-conntrack +kmod-shortcut-fe + TITLE:=Kernel driver for FAST Classifier + FILES:=$(PKG_BUILD_DIR)/fast-classifier.ko + KCONFIG:=CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y CONFIG_NF_CONNTRACK_MARK=y + PROVIDES:=$(PKG_NAME) +endef + +define KernelPackage/$(PKG_NAME) + $(call KernelPackage/$(PKG_NAME)/Default) +endef + +define KernelPackage/$(PKG_NAME)-noload + $(call KernelPackage/$(PKG_NAME)/Default) +endef + +define KernelPackage/$(PKG_NAME)/Default/description +FAST Classifier talks to SFE to make decisions about offloading connections +endef + +define KernelPackage/$(PKG_NAME)/description +$(call KernelPackage/$(PKG_NAME)/Default/description) +endef + +define KernelPackage/$(PKG_NAME)-noload/description +$(call KernelPackage/$(PKG_NAME)/Default/description) + +This package does not load $(PKG_NAME) at boot by default +endef + +define Package/fast-classifier-example + TITLE:=Example user space program for fast-classifier + DEPENDS:=+libnl +kmod-fast-classifier +endef + +define Package/fast-classifier-example/description +Example user space program that communicates with fast +classifier kernel module +endef + +SFE_MAKE_OPTS:=SFE_SUPPORT_IPV6=y + +define Build/Compile/kmod + +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(SFE_MAKE_OPTS)) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + SUBDIRS="$(PKG_BUILD_DIR)" \ + CONFIG_FAST_CLASSIFIER=m \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + modules +endef + +define Build/Compile/example + $(TARGET_CC) -o $(PKG_BUILD_DIR)/userspace_fast_classifier \ + -I $(PKG_BUILD_DIR) \ + -I$(STAGING_DIR)/usr/include/libnl \ + -I$(STAGING_DIR)/usr/include/libnl3 \ + -lnl-genl-3 -lnl-3 \ + $(PKG_BUILD_DIR)/nl_classifier_test.c +endef + +define Build/Compile + $(Build/Compile/kmod) + $(if $(CONFIG_PACKAGE_fast-classifier-example),$(Build/Compile/example)) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/fast-classifier.h $(1)/usr/include/ +endef + + +define Package/fast-classifier-example/install + $(INSTALL_DIR) $(1)/sbin + $(CP) $(PKG_BUILD_DIR)/userspace_fast_classifier $(1)/sbin/ +endef + +$(eval $(call KernelPackage,$(PKG_NAME))) +$(eval $(call KernelPackage,$(PKG_NAME)-noload)) +$(eval $(call BuildPackage,fast-classifier-example)) diff --git a/package/lean/fast-classifier/src/Makefile b/package/lean/fast-classifier/src/Makefile new file mode 100644 index 0000000000..58dd06e018 --- /dev/null +++ b/package/lean/fast-classifier/src/Makefile @@ -0,0 +1,10 @@ +obj-$(CONFIG_FAST_CLASSIFIER) += fast-classifier.o + +ifeq ($(SFE_SUPPORT_IPV6),) +SFE_SUPPORT_IPV6=y +endif +ccflags-$(SFE_SUPPORT_IPV6) += -DSFE_SUPPORT_IPV6 + +ccflags-y += -I$(obj)/../shortcut-fe + +obj ?= . diff --git a/package/lean/shortcut-fe/src/fast-classifier.c b/package/lean/fast-classifier/src/fast-classifier.c similarity index 83% rename from package/lean/shortcut-fe/src/fast-classifier.c rename to package/lean/fast-classifier/src/fast-classifier.c index 48a2d27f4d..e9f3d0eb4e 100644 --- a/package/lean/shortcut-fe/src/fast-classifier.c +++ b/package/lean/fast-classifier/src/fast-classifier.c @@ -3,7 +3,7 @@ * Shortcut forwarding engine connection manager. * fast-classifier * - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. @@ -29,17 +29,16 @@ #include #include #include -#include #include #include #include #include #include -#include +#include -#include "sfe_backport.h" -#include "sfe.h" -#include "sfe_cm.h" +#include +#include +#include #include "fast-classifier.h" typedef enum fast_classifier_exception { @@ -111,14 +110,16 @@ struct fast_classifier { u32 exceptions[FAST_CL_EXCEPTION_MAX]; }; -static struct fast_classifier __fsc; +static struct fast_classifier __sc; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) static struct nla_policy fast_classifier_genl_policy[FAST_CLASSIFIER_A_MAX + 1] = { [FAST_CLASSIFIER_A_TUPLE] = { .type = NLA_UNSPEC, .len = sizeof(struct fast_classifier_tuple) }, }; +#endif /*KERNEL_VERSION(5, 2, 0)*/ static struct genl_multicast_group fast_classifier_genl_mcgrp[] = { { @@ -126,14 +127,6 @@ static struct genl_multicast_group fast_classifier_genl_mcgrp[] = { }, }; -static struct genl_family fast_classifier_gnl_family = { - .id = GENL_ID_GENERATE, - .hdrsize = FAST_CLASSIFIER_GENL_HDRSIZE, - .name = FAST_CLASSIFIER_GENL_NAME, - .version = FAST_CLASSIFIER_GENL_VERSION, - .maxattr = FAST_CLASSIFIER_A_MAX, -}; - static int fast_classifier_offload_genl_msg(struct sk_buff *skb, struct genl_info *info); static int fast_classifier_nl_genl_msg_DUMP(struct sk_buff *skb, struct netlink_callback *cb); @@ -141,26 +134,48 @@ static struct genl_ops fast_classifier_gnl_ops[] = { { .cmd = FAST_CLASSIFIER_C_OFFLOAD, .flags = 0, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) .policy = fast_classifier_genl_policy, +#endif /*KERNEL_VERSION(5, 2, 0)*/ .doit = fast_classifier_offload_genl_msg, .dumpit = NULL, }, { .cmd = FAST_CLASSIFIER_C_OFFLOADED, .flags = 0, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) .policy = fast_classifier_genl_policy, +#endif /*KERNEL_VERSION(5, 2, 0)*/ .doit = NULL, .dumpit = fast_classifier_nl_genl_msg_DUMP, }, { .cmd = FAST_CLASSIFIER_C_DONE, .flags = 0, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) .policy = fast_classifier_genl_policy, +#endif /*KERNEL_VERSION(5, 2, 0)*/ .doit = NULL, .dumpit = fast_classifier_nl_genl_msg_DUMP, }, }; +static struct genl_family fast_classifier_gnl_family = { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) + .id = GENL_ID_GENERATE, +#endif /*KERNEL_VERSION(4, 10, 0)*/ + .hdrsize = FAST_CLASSIFIER_GENL_HDRSIZE, + .name = FAST_CLASSIFIER_GENL_NAME, + .version = FAST_CLASSIFIER_GENL_VERSION, + .maxattr = FAST_CLASSIFIER_A_MAX, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) + .ops = fast_classifier_gnl_ops, + .n_ops = ARRAY_SIZE(fast_classifier_gnl_ops), + .mcgrps = fast_classifier_genl_mcgrp, + .n_mcgrps = ARRAY_SIZE(fast_classifier_genl_mcgrp), +#endif /*KERNEL_VERSION(4, 10, 0)*/ +}; + static atomic_t offload_msgs = ATOMIC_INIT(0); static atomic_t offload_no_match_msgs = ATOMIC_INIT(0); static atomic_t offloaded_msgs = ATOMIC_INIT(0); @@ -189,7 +204,7 @@ static bool skip_to_bridge_ingress; */ static inline void fast_classifier_incr_exceptions(fast_classifier_exception_t except) { - struct fast_classifier *sc = &__fsc; + struct fast_classifier *sc = &__sc; spin_lock_bh(&sc->lock); sc->exceptions[except]++; @@ -202,7 +217,7 @@ static inline void fast_classifier_incr_exceptions(fast_classifier_exception_t e * * Returns 1 if the packet is forwarded or 0 if it isn't. */ -static int fast_classifier_recv(struct sk_buff *skb) +int fast_classifier_recv(struct sk_buff *skb) { struct net_device *dev; struct net_device *master_dev = NULL; @@ -224,22 +239,12 @@ static int fast_classifier_recv(struct sk_buff *skb) (dev->priv_flags & IFF_BRIDGE_PORT)) { master_dev = sfe_dev_get_master(dev); if (!master_dev) { - DEBUG_WARN("master dev is NULL %s\n"); + DEBUG_WARN("master dev is NULL %s\n", dev->name); goto rx_exit; } dev = master_dev; } -#ifdef CONFIG_NET_CLS_ACT - /* - * If ingress Qdisc configured, and packet not processed by ingress Qdisc yet - * We cannot accelerate this packet. - */ - if (dev->ingress_queue && !(skb->tc_verd & TC_NCLS)) { - goto rx_exit; - } -#endif - /* * We're only interested in IPv4 and IPv6 packets. */ @@ -311,7 +316,7 @@ rx_exit: * structure, obtain the hardware address. This means this function also * works if the neighbours are routers too. */ -static bool fast_classifier_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device **dev, u8 *mac_addr, bool is_v4) +static bool fast_classifier_find_dev_and_mac_addr(struct sk_buff *skb, sfe_ip_addr_t *addr, struct net_device **dev, u8 *mac_addr, bool is_v4) { struct neighbour *neigh; struct rtable *rt; @@ -319,12 +324,21 @@ static bool fast_classifier_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct ne struct dst_entry *dst; struct net_device *mac_dev; + /* + * If we have skb provided, use it as the original code is unable + * to lookup routes that are policy routed. + */ + if (unlikely(skb)) { + dst = skb_dst(skb); + goto skip_dst_lookup; + } + /* * Look up the rtable entry for the IP address then get the hardware * address from its neighbour structure. This means this works when the * neighbours are routers too. */ - if (is_v4) { + if (likely(is_v4)) { rt = ip_route_output(&init_net, addr->ip, 0, 0, 0); if (unlikely(IS_ERR(rt))) { goto ret_fail; @@ -332,7 +346,11 @@ static bool fast_classifier_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct ne dst = (struct dst_entry *)rt; } else { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) + rt6 = rt6_lookup(&init_net, (struct in6_addr *)addr->ip6, 0, 0, NULL, 0); +#else rt6 = rt6_lookup(&init_net, (struct in6_addr *)addr->ip6, 0, 0, 0); +#endif /*KERNEL_VERSION(4, 17, 0)*/ if (!rt6) { goto ret_fail; } @@ -340,18 +358,23 @@ static bool fast_classifier_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct ne dst = (struct dst_entry *)rt6; } +skip_dst_lookup: rcu_read_lock(); - neigh = dst_neigh_lookup(dst, addr); + neigh = sfe_dst_get_neighbour(dst, addr); if (unlikely(!neigh)) { rcu_read_unlock(); - dst_release(dst); + if (likely(!skb)) + dst_release(dst); + goto ret_fail; } if (unlikely(!(neigh->nud_state & NUD_VALID))) { rcu_read_unlock(); neigh_release(neigh); - dst_release(dst); + if (likely(!skb)) + dst_release(dst); + goto ret_fail; } @@ -359,7 +382,9 @@ static bool fast_classifier_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct ne if (!mac_dev) { rcu_read_unlock(); neigh_release(neigh); - dst_release(dst); + if (likely(!skb)) + dst_release(dst); + goto ret_fail; } @@ -369,12 +394,18 @@ static bool fast_classifier_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct ne *dev = mac_dev; rcu_read_unlock(); neigh_release(neigh); - dst_release(dst); + if (likely(!skb)) + dst_release(dst); return true; ret_fail: - DEBUG_TRACE("failed to find MAC address for IP: %pIS\n", addr); + if (is_v4) { + DEBUG_TRACE("failed to find MAC address for IP: %pI4\n", addr); + + } else { + DEBUG_TRACE("failed to find MAC address for IP: %pI6\n", addr); + } return false; } @@ -439,16 +470,16 @@ static int fast_classifier_update_protocol(struct sfe_connection_create *p_sic, * state can not be SYN_SENT, SYN_RECV because connection is assured * Not managed states: FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE. */ - spin_lock_bh(&ct->lock); + spin_lock(&ct->lock); if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) { - spin_unlock_bh(&ct->lock); + spin_unlock(&ct->lock); fast_classifier_incr_exceptions(FAST_CL_EXCEPTION_TCP_NOT_ESTABLISHED); DEBUG_TRACE("connection in termination state: %#x, s: %pI4:%u, d: %pI4:%u\n", ct->proto.tcp.state, &p_sic->src_ip, ntohs(p_sic->src_port), &p_sic->dest_ip, ntohs(p_sic->dest_port)); return 0; } - spin_unlock_bh(&ct->lock); + spin_unlock(&ct->lock); break; case IPPROTO_UDP: @@ -511,12 +542,17 @@ static void fast_classifier_send_genl_msg(int msg, struct fast_classifier_tuple return; } - genlmsg_end(skb, msg_head); +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19 , 0)) + rc = genlmsg_end(skb, msg_head); if (rc < 0) { genlmsg_cancel(skb, msg_head); nlmsg_free(skb); return; } +#else + genlmsg_end(skb, msg_head); + +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) rc = genlmsg_multicast(&fast_classifier_gnl_family, skb, 0, 0, GFP_ATOMIC); @@ -525,14 +561,18 @@ static void fast_classifier_send_genl_msg(int msg, struct fast_classifier_tuple #endif switch (msg) { case FAST_CLASSIFIER_C_OFFLOADED: - atomic_inc(&offloaded_msgs); - if (rc != 0) + if (rc == 0) { + atomic_inc(&offloaded_msgs); + } else { atomic_inc(&offloaded_fail_msgs); + } break; case FAST_CLASSIFIER_C_DONE: - atomic_inc(&done_msgs); - if (rc != 0) + if (rc == 0) { + atomic_inc(&done_msgs); + } else { atomic_inc(&done_fail_msgs); + } break; default: DEBUG_ERROR("fast-classifer: Unknown message type sent!\n"); @@ -540,7 +580,11 @@ static void fast_classifier_send_genl_msg(int msg, struct fast_classifier_tuple } DEBUG_TRACE("Notify NL message %d ", msg); - DEBUG_TRACE("sip=%pIS dip=%pIS ", &fc_msg->src_saddr, &fc_msg->dst_saddr); + if (fc_msg->ethertype == AF_INET) { + DEBUG_TRACE("sip=%pI4 dip=%pI4 ", &fc_msg->src_saddr, &fc_msg->dst_saddr); + } else { + DEBUG_TRACE("sip=%pI6 dip=%pI6 ", &fc_msg->src_saddr, &fc_msg->dst_saddr); + } DEBUG_TRACE("protocol=%d sport=%d dport=%d smac=%pM dmac=%pM\n", fc_msg->proto, fc_msg->sport, fc_msg->dport, fc_msg->smac, fc_msg->dmac); } @@ -558,10 +602,13 @@ fast_classifier_find_conn(sfe_ip_addr_t *saddr, sfe_ip_addr_t *daddr, struct sfe_connection_create *p_sic; struct sfe_connection *conn; u32 key; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) + struct hlist_node *node; +#endif key = fc_conn_hash(saddr, daddr, sport, dport, is_v4); - sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) { + sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) { if (conn->is_v4 != is_v4) { continue; } @@ -595,10 +642,13 @@ fast_classifier_sb_find_conn(sfe_ip_addr_t *saddr, sfe_ip_addr_t *daddr, struct sfe_connection_create *p_sic; struct sfe_connection *conn; u32 key; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) + struct hlist_node *node; +#endif key = fc_conn_hash(saddr, daddr, sport, dport, is_v4); - sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) { + sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) { if (conn->is_v4 != is_v4) { continue; } @@ -619,7 +669,7 @@ fast_classifier_sb_find_conn(sfe_ip_addr_t *saddr, sfe_ip_addr_t *daddr, */ key = fc_conn_hash(daddr, saddr, dport, sport, is_v4); - sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) { + sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) { if (conn->is_v4 != is_v4) { continue; } @@ -667,8 +717,13 @@ fast_classifier_add_conn(struct sfe_connection *conn) DEBUG_TRACE(" -> adding item to sfe_connections, new size: %d\n", sfe_connections_size); - DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n", - key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port); + if (conn->is_v4) { + DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n", + key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port); + } else { + DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n", + key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port); + } return conn; } @@ -687,15 +742,27 @@ fast_classifier_offload_genl_msg(struct sk_buff *skb, struct genl_info *info) na = info->attrs[FAST_CLASSIFIER_A_TUPLE]; fc_msg = nla_data(na); - DEBUG_TRACE("want to offload: %d-%d, %pIS, %pIS, %d, %d SMAC=%pM DMAC=%pM\n", - fc_msg->ethertype, - fc_msg->proto, - &fc_msg->src_saddr, - &fc_msg->dst_saddr, - fc_msg->sport, - fc_msg->dport, - fc_msg->smac, - fc_msg->dmac); + if (fc_msg->ethertype == AF_INET) { + DEBUG_TRACE("want to offload: %d-%d, %pI4, %pI4, %d, %d SMAC=%pM DMAC=%pM\n", + fc_msg->ethertype, + fc_msg->proto, + &fc_msg->src_saddr, + &fc_msg->dst_saddr, + fc_msg->sport, + fc_msg->dport, + fc_msg->smac, + fc_msg->dmac); + } else { + DEBUG_TRACE("want to offload: %d-%d, %pI6, %pI6, %d, %d SMAC=%pM DMAC=%pM\n", + fc_msg->ethertype, + fc_msg->proto, + &fc_msg->src_saddr, + &fc_msg->dst_saddr, + fc_msg->sport, + fc_msg->dport, + fc_msg->smac, + fc_msg->dmac); + } spin_lock_bh(&sfe_connections_lock); conn = fast_classifier_sb_find_conn((sfe_ip_addr_t *)&fc_msg->src_saddr, @@ -747,12 +814,14 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 struct net_device *dev; struct net_device *src_dev; struct net_device *dest_dev; + struct net_device *src_dev_tmp; + struct net_device *dest_dev_tmp; struct net_device *src_br_dev = NULL; struct net_device *dest_br_dev = NULL; struct nf_conntrack_tuple orig_tuple; struct nf_conntrack_tuple reply_tuple; struct sfe_connection *conn; - SFE_NF_CONN_ACCT(acct); + struct sk_buff *tmp_skb = NULL; /* * Don't process broadcast or multicast packets. @@ -790,6 +859,7 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 return NF_ACCEPT; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) /* * Don't process untracked connections. */ @@ -798,6 +868,7 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 DEBUG_TRACE("untracked connection\n"); return NF_ACCEPT; } +#endif /*KERNEL_VERSION(4, 12, 0)*/ /* * Unconfirmed connection may be dropped by Linux at the final step, @@ -818,21 +889,6 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 return NF_ACCEPT; } - /* - * Check if the acceleration of a flow could be rejected quickly. - */ - acct = nf_conn_acct_find(ct); - if (acct) { - long long packets = atomic64_read(&SFE_ACCT_COUNTER(acct)[CTINFO2DIR(ctinfo)].packets); - if ((packets > 0xff) && (packets & 0xff)) { - /* - * Connection hits slow path at least 256 times, so it must be not able to accelerate. - * But we also give it a chance to walk through ECM every 256 packets - */ - return NF_ACCEPT; - } - } - memset(&sic, 0, sizeof(sic)); /* @@ -850,7 +906,7 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 /* * Get addressing information, non-NAT first */ - if (is_v4) { + if (likely(is_v4)) { u32 dscp; sic.src_ip.ip = (__be32)orig_tuple.src.u3.ip; @@ -926,6 +982,21 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 sic.dest_port = orig_tuple.dst.u.udp.port; sic.src_port_xlate = reply_tuple.dst.u.udp.port; sic.dest_port_xlate = reply_tuple.src.u.udp.port; + + /* + * Somehow, SFE is not playing nice with IPSec traffic. + * Do not accelerate for now. + */ + if (ntohs(sic.dest_port) == 4500 || ntohs(sic.dest_port) == 500) { + if (likely(is_v4)) + DEBUG_TRACE("quarkysg:: IPsec bypass: %pI4:%d(%pI4:%d) to %pI4:%d(%pI4:%d)\n", + &sic.src_ip.ip, ntohs(sic.src_port), &sic.src_ip_xlate.ip, ntohs(sic.src_port_xlate), + &sic.dest_ip.ip, ntohs(sic.dest_port), &sic.dest_ip_xlate.ip, ntohs(sic.dest_port_xlate)); + else + DEBUG_TRACE("quarkysg:: IPsec bypass: %pI6:%d to %pI6:%d\n", + &sic.src_ip.ip6, ntohs(sic.src_port), &sic.dest_ip.ip6, ntohs(sic.dest_port)); + return NF_ACCEPT; + } break; default: @@ -948,8 +1019,13 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 sic.flags |= SFE_CREATE_FLAG_REMARK_PRIORITY; } - DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n", - sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port); + if (is_v4) { + DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n", + sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port); + } else { + DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n", + sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port); + } /* * If we already have this connection in our list, skip it @@ -1018,32 +1094,35 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 * Get the net device and MAC addresses that correspond to the various source and * destination host addresses. */ - if (!fast_classifier_find_dev_and_mac_addr(&sic.src_ip, &src_dev, sic.src_mac, is_v4)) { + if (!fast_classifier_find_dev_and_mac_addr(NULL, &sic.src_ip, &src_dev_tmp, sic.src_mac, is_v4)) { fast_classifier_incr_exceptions(FAST_CL_EXCEPTION_NO_SRC_DEV); return NF_ACCEPT; } + src_dev = src_dev_tmp; - if (!fast_classifier_find_dev_and_mac_addr(&sic.src_ip_xlate, &dev, sic.src_mac_xlate, is_v4)) { + if (!fast_classifier_find_dev_and_mac_addr(NULL, &sic.src_ip_xlate, &dev, sic.src_mac_xlate, is_v4)) { fast_classifier_incr_exceptions(FAST_CL_EXCEPTION_NO_SRC_XLATE_DEV); goto done1; } - dev_put(dev); - if (!fast_classifier_find_dev_and_mac_addr(&sic.dest_ip, &dev, sic.dest_mac, is_v4)) { + if (unlikely(!is_v4)) + tmp_skb = skb; + + if (!fast_classifier_find_dev_and_mac_addr(tmp_skb, &sic.dest_ip, &dev, sic.dest_mac, is_v4)) { fast_classifier_incr_exceptions(FAST_CL_EXCEPTION_NO_DEST_DEV); goto done1; } - dev_put(dev); - if (!fast_classifier_find_dev_and_mac_addr(&sic.dest_ip_xlate, &dest_dev, sic.dest_mac_xlate, is_v4)) { + if (!fast_classifier_find_dev_and_mac_addr(skb, &sic.dest_ip_xlate, &dest_dev_tmp, sic.dest_mac_xlate, is_v4)) { fast_classifier_incr_exceptions(FAST_CL_EXCEPTION_NO_DEST_XLATE_DEV); goto done1; } + dest_dev = dest_dev_tmp; /* - * Our devices may actually be part of a bridge interface. If that's + * Our devices may actually be part of a bridge interface. If that's * the case then find the bridge interface instead. */ if (src_dev->priv_flags & IFF_BRIDGE_PORT) { @@ -1053,7 +1132,6 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 DEBUG_TRACE("no bridge found for: %s\n", src_dev->name); goto done2; } - src_dev = src_br_dev; } @@ -1064,7 +1142,6 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 DEBUG_TRACE("no bridge found for: %s\n", dest_dev->name); goto done3; } - dest_dev = dest_br_dev; } @@ -1082,7 +1159,7 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 conn = kmalloc(sizeof(*conn), GFP_ATOMIC); if (!conn) { printk(KERN_CRIT "ERROR: no memory for sfe\n"); - goto done3; + goto done4; } conn->hits = 0; conn->offload_permit = 0; @@ -1096,7 +1173,7 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 if (!p_sic) { printk(KERN_CRIT "ERROR: no memory for sfe\n"); kfree(conn); - goto done3; + goto done4; } memcpy(p_sic, &sic, sizeof(sic)); @@ -1111,20 +1188,18 @@ static unsigned int fast_classifier_post_routing(struct sk_buff *skb, bool is_v4 /* * If we had bridge ports then release them too. */ +done4: if (dest_br_dev) { dev_put(dest_br_dev); } - done3: if (src_br_dev) { dev_put(src_br_dev); } - done2: - dev_put(dest_dev); - + dev_put(dest_dev_tmp); done1: - dev_put(src_dev); + dev_put(src_dev_tmp); return NF_ACCEPT; } @@ -1198,6 +1273,7 @@ static int fast_classifier_conntrack_event(unsigned int events, struct nf_ct_eve return NOTIFY_DONE; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) /* * If this is an untracked connection then we can't have any state either. */ @@ -1205,6 +1281,7 @@ static int fast_classifier_conntrack_event(unsigned int events, struct nf_ct_eve DEBUG_TRACE("ignoring untracked conn\n"); return NOTIFY_DONE; } +#endif /*KERNEL_VERSION(4, 12, 0)*/ orig_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; sid.protocol = (s32)orig_tuple.dst.protonum; @@ -1267,8 +1344,13 @@ static int fast_classifier_conntrack_event(unsigned int events, struct nf_ct_eve return NOTIFY_DONE; } - DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n", - sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port); + if (is_v4) { + DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n", + sid.protocol, &sid.src_ip, &sid.dest_ip, ntohs(sid.src_port), ntohs(sid.dest_port)); + } else { + DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n", + sid.protocol, &sid.src_ip, &sid.dest_ip, ntohs(sid.src_port), ntohs(sid.dest_port)); + } spin_lock_bh(&sfe_connections_lock); @@ -1416,7 +1498,9 @@ static void fast_classifier_sync_rule(struct sfe_connection_sync *sis) } ct = nf_ct_tuplehash_to_ctrack(h); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct); +#endif /*KERNEL_VERSION(4, 9, 0)*/ /* * Only update if this is not a fixed timeout @@ -1427,7 +1511,7 @@ static void fast_classifier_sync_rule(struct sfe_connection_sync *sis) ct->timeout += sis->delta_jiffies; #else ct->timeout.expires += sis->delta_jiffies; -#endif +#endif /*KERNEL_VERSION(4, 9, 0)*/ spin_unlock_bh(&ct->lock); } @@ -1456,7 +1540,7 @@ static void fast_classifier_sync_rule(struct sfe_connection_sync *sis) if (ct->proto.tcp.seen[1].td_maxwin < sis->dest_td_max_window) { ct->proto.tcp.seen[1].td_maxwin = sis->dest_td_max_window; } - if ((s32)(ct->proto.tcp.seen[1].td_end - sis->dest_td_end) < 0) { + if ((s32)(ct->proto.tcp.seen[1].td_end - sis->dest_td_end) < 0) { ct->proto.tcp.seen[1].td_end = sis->dest_td_end; } if ((s32)(ct->proto.tcp.seen[1].td_maxend - sis->dest_td_max_end) < 0) { @@ -1464,42 +1548,6 @@ static void fast_classifier_sync_rule(struct sfe_connection_sync *sis) } spin_unlock_bh(&ct->lock); break; - - case IPPROTO_UDP: - /* - * In Linux connection track, UDP flow has two timeout values: - * /proc/sys/net/netfilter/nf_conntrack_udp_timeout: - * this is for uni-direction UDP flow, normally its value is 60 seconds - * /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream: - * this is for bi-direction UDP flow, normally its value is 180 seconds - * - * Linux will update timer of UDP flow to stream timeout once it seen packets - * in reply direction. But if flow is accelerated by NSS or SFE, Linux won't - * see any packets. So we have to do the same thing in our stats sync message. - */ - if (!test_bit(IPS_ASSURED_BIT, &ct->status) && acct) { - u_int64_t reply_pkts = atomic64_read(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets); - - if (reply_pkts != 0) { - struct nf_conntrack_l4proto *l4proto; - unsigned int *timeouts; - - set_bit(IPS_SEEN_REPLY_BIT, &ct->status); - set_bit(IPS_ASSURED_BIT, &ct->status); - - l4proto = __nf_ct_l4proto_find((sis->is_v6 ? AF_INET6 : AF_INET), IPPROTO_UDP); - timeouts = nf_ct_timeout_lookup(&init_net, ct, l4proto); - - spin_lock_bh(&ct->lock); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) - ct->timeout = nfct_time_stamp + timeouts[UDP_CT_REPLIED]; -#else - ct->timeout.expires = jiffies + timeouts[UDP_CT_REPLIED]; -#endif - spin_unlock_bh(&ct->lock); - } - } - break; } /* @@ -1590,10 +1638,13 @@ static ssize_t fast_classifier_get_debug_info(struct device *dev, size_t len = 0; struct sfe_connection *conn; u32 i; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) + struct hlist_node *node; +#endif spin_lock_bh(&sfe_connections_lock); len += scnprintf(buf, PAGE_SIZE - len, "size=%d offload=%d offload_no_match=%d" - " offloaded=%d done=%d offl_dbg_msg_fail=%d done_dbg_msg_fail=%d\n", + " offloaded=%d done=%d offloaded_fail=%d done_fail=%d\n", sfe_connections_size, atomic_read(&offload_msgs), atomic_read(&offload_no_match_msgs), @@ -1601,16 +1652,16 @@ static ssize_t fast_classifier_get_debug_info(struct device *dev, atomic_read(&done_msgs), atomic_read(&offloaded_fail_msgs), atomic_read(&done_fail_msgs)); - sfe_hash_for_each(fc_conn_ht, i, conn, hl) { + sfe_hash_for_each(fc_conn_ht, i, node, conn, hl) { len += scnprintf(buf + len, PAGE_SIZE - len, (conn->is_v4 ? "o=%d, p=%d [%pM]:%pI4:%u %pI4:%u:[%pM] m=%08x h=%d\n" : "o=%d, p=%d [%pM]:%pI6:%u %pI6:%u:[%pM] m=%08x h=%d\n"), conn->offloaded, conn->sic->protocol, conn->sic->src_mac, &conn->sic->src_ip, - conn->sic->src_port, + ntohs(conn->sic->src_port), &conn->sic->dest_ip, - conn->sic->dest_port, + ntohs(conn->sic->dest_port), conn->sic->dest_mac_xlate, conn->sic->mark, conn->hits); @@ -1658,7 +1709,7 @@ static ssize_t fast_classifier_get_exceptions(struct device *dev, char *buf) { int idx, len; - struct fast_classifier *sc = &__fsc; + struct fast_classifier *sc = &__sc; spin_lock_bh(&sc->lock); for (len = 0, idx = 0; idx < FAST_CL_EXCEPTION_MAX; idx++) { @@ -1674,23 +1725,24 @@ static ssize_t fast_classifier_get_exceptions(struct device *dev, /* * sysfs attributes. */ -static const struct device_attribute fast_classifier_attrs[] = { - __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts), - __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL), - __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress), - __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL), -}; +static const struct device_attribute fast_classifier_offload_at_pkts_attr = + __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts); +static const struct device_attribute fast_classifier_debug_info_attr = + __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL); +static const struct device_attribute fast_classifier_skip_bridge_ingress = + __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress); +static const struct device_attribute fast_classifier_exceptions_attr = + __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL); /* * fast_classifier_init() */ static int __init fast_classifier_init(void) { - struct fast_classifier *sc = &__fsc; + struct fast_classifier *sc = &__sc; int result = -1; - size_t i, j; - printk(KERN_ALERT "fast-classifier: starting up\n"); + printk(KERN_ALERT "fast-classifier (PBR safe v2.1.4a): starting up\n"); DEBUG_INFO("SFE CM init\n"); hash_init(fc_conn_ht); @@ -1704,13 +1756,34 @@ static int __init fast_classifier_init(void) goto exit1; } - for (i = 0; i < ARRAY_SIZE(fast_classifier_attrs); i++) { - result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_attrs[i].attr); - if (result) { - DEBUG_ERROR("failed to register %s : %d\n", - fast_classifier_attrs[i].attr.name, result); - goto exit2; - } + result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr); + if (result) { + DEBUG_ERROR("failed to register offload at pkgs: %d\n", result); + goto exit2; + } + + result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr); + if (result) { + DEBUG_ERROR("failed to register debug dev: %d\n", result); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr); + goto exit2; + } + + result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr); + if (result) { + DEBUG_ERROR("failed to register skip bridge on ingress: %d\n", result); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr); + goto exit2; + } + + result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr); + if (result) { + DEBUG_ERROR("failed to register exceptions file: %d\n", result); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr); + goto exit2; } sc->dev_notifier.notifier_call = fast_classifier_device_event; @@ -1728,7 +1801,7 @@ static int __init fast_classifier_init(void) /* * Register our netfilter hooks. */ - result = nf_register_hooks(fast_classifier_ops_post_routing, ARRAY_SIZE(fast_classifier_ops_post_routing)); + result = nf_register_net_hooks(&init_net, fast_classifier_ops_post_routing, ARRAY_SIZE(fast_classifier_ops_post_routing)); if (result < 0) { DEBUG_ERROR("can't register nf post routing hook: %d\n", result); goto exit3; @@ -1737,22 +1810,21 @@ static int __init fast_classifier_init(void) #ifdef CONFIG_NF_CONNTRACK_EVENTS /* * Register a notifier hook to get fast notifications of expired connections. - * Note: In CONFIG_NF_CONNTRACK_CHAIN_EVENTS enabled case, nf_conntrack_register_notifier() - * function always returns 0. */ - -#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS - (void)nf_conntrack_register_notifier(&init_net, &fast_classifier_conntrack_notifier); -#else result = nf_conntrack_register_notifier(&init_net, &fast_classifier_conntrack_notifier); if (result < 0) { DEBUG_ERROR("can't register nf notifier hook: %d\n", result); goto exit4; } #endif -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) + result = genl_register_family(&fast_classifier_gnl_family); + if (result) { + DEBUG_ERROR("failed to register genl family: %d\n", result); + goto exit5; + } +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) result = genl_register_family_with_ops_groups(&fast_classifier_gnl_family, fast_classifier_gnl_ops, fast_classifier_genl_mcgrp); @@ -1788,8 +1860,8 @@ static int __init fast_classifier_init(void) /* * Hook the receive path in the network stack. */ - BUG_ON(fast_nat_recv); - RCU_INIT_POINTER(fast_nat_recv, fast_classifier_recv); + BUG_ON(athrs_fast_nat_recv); + RCU_INIT_POINTER(athrs_fast_nat_recv, fast_classifier_recv); /* * Hook the shortcut sync callback. @@ -1809,17 +1881,18 @@ exit5: exit4: #endif - nf_unregister_hooks(fast_classifier_ops_post_routing, ARRAY_SIZE(fast_classifier_ops_post_routing)); + nf_unregister_net_hooks(&init_net, fast_classifier_ops_post_routing, ARRAY_SIZE(fast_classifier_ops_post_routing)); exit3: unregister_inetaddr_notifier(&sc->inet_notifier); unregister_inet6addr_notifier(&sc->inet6_notifier); unregister_netdevice_notifier(&sc->dev_notifier); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr); + sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr); exit2: - for (j = 0; j < i; j++) { - sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_attrs[j].attr); - } kobject_put(sc->sys_fast_classifier); exit1: @@ -1831,7 +1904,7 @@ exit1: */ static void __exit fast_classifier_exit(void) { - struct fast_classifier *sc = &__fsc; + struct fast_classifier *sc = &__sc; int result = -1; DEBUG_INFO("SFE CM exit\n"); @@ -1846,7 +1919,7 @@ static void __exit fast_classifier_exit(void) /* * Unregister our receive callback. */ - RCU_INIT_POINTER(fast_nat_recv, NULL); + RCU_INIT_POINTER(athrs_fast_nat_recv, NULL); /* * Wait for all callbacks to complete. @@ -1868,14 +1941,14 @@ static void __exit fast_classifier_exit(void) result = genl_unregister_family(&fast_classifier_gnl_family); if (result != 0) { - printk(KERN_CRIT "Unable to unreigster genl_family\n"); + printk(KERN_CRIT "Unable to unregister genl_family\n"); } #ifdef CONFIG_NF_CONNTRACK_EVENTS nf_conntrack_unregister_notifier(&init_net, &fast_classifier_conntrack_notifier); #endif - nf_unregister_hooks(fast_classifier_ops_post_routing, ARRAY_SIZE(fast_classifier_ops_post_routing)); + nf_unregister_net_hooks(&init_net, fast_classifier_ops_post_routing, ARRAY_SIZE(fast_classifier_ops_post_routing)); unregister_inet6addr_notifier(&sc->inet6_notifier); unregister_inetaddr_notifier(&sc->inet_notifier); diff --git a/package/lean/shortcut-fe/src/fast-classifier.h b/package/lean/fast-classifier/src/fast-classifier.h similarity index 100% rename from package/lean/shortcut-fe/src/fast-classifier.h rename to package/lean/fast-classifier/src/fast-classifier.h diff --git a/package/lean/shortcut-fe/src/nl_classifier_test.c b/package/lean/fast-classifier/src/nl_classifier_test.c similarity index 100% rename from package/lean/shortcut-fe/src/nl_classifier_test.c rename to package/lean/fast-classifier/src/nl_classifier_test.c diff --git a/package/lean/shortcut-fe/src/userspace_example.c b/package/lean/fast-classifier/src/userspace_example.c similarity index 99% rename from package/lean/shortcut-fe/src/userspace_example.c rename to package/lean/fast-classifier/src/userspace_example.c index 8bdd4670cd..4f4113d991 100644 --- a/package/lean/shortcut-fe/src/userspace_example.c +++ b/package/lean/fast-classifier/src/userspace_example.c @@ -18,7 +18,7 @@ #include #include -#include "fast-classifier.h" +#include static struct nl_sock *sock; static struct nl_sock *sock_event; diff --git a/package/lean/luci-app-flowoffload/Makefile b/package/lean/luci-app-flowoffload/Makefile index 76d03a284a..a58f5c106a 100644 --- a/package/lean/luci-app-flowoffload/Makefile +++ b/package/lean/luci-app-flowoffload/Makefile @@ -6,10 +6,10 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI support for Flow Offload -LUCI_DEPENDS:=+kmod-ipt-offload +pdnsd-alt +kmod-tcp-bbr @!LINUX_4_9 +LUCI_DEPENDS:=+kmod-ipt-offload +pdnsd-alt +kmod-tcp-bbr @LINUX_5_4 LUCI_PKGARCH:=all PKG_VERSION:=1.0 -PKG_RELEASE:=15 +PKG_RELEASE:=19 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/package/lean/luci-app-flowoffload/root/etc/config/flowoffload b/package/lean/luci-app-flowoffload/root/etc/config/flowoffload index 2724309b3f..10009d70b1 100644 --- a/package/lean/luci-app-flowoffload/root/etc/config/flowoffload +++ b/package/lean/luci-app-flowoffload/root/etc/config/flowoffload @@ -6,6 +6,6 @@ config flow option dns '0' option dnscache_enable '1' option dns_server '114.114.114.114,114.114.115.115,223.5.5.5,223.6.6.6,180.76.76.76,119.29.29.29,119.28.28.28,1.2.4.8,210.2.4.8' - option ipv6dns_server '240c::6666,240c::6644,2400:da00::6666,2001:da8::666' + option ipv6dns_server '240c::6666,240c::6644,2001:da8::666,2001:da8:202:10::36,2001:da8:8000:1:202:120:2:100' diff --git a/package/lean/luci-app-flowoffload/root/etc/init.d/flowoffload b/package/lean/luci-app-flowoffload/root/etc/init.d/flowoffload index a2320b12af..b1fdc21d1f 100755 --- a/package/lean/luci-app-flowoffload/root/etc/init.d/flowoffload +++ b/package/lean/luci-app-flowoffload/root/etc/init.d/flowoffload @@ -7,7 +7,7 @@ USE_PROCD=1 DNSMASQ_RESTART=N DNS_SERVER="114.114.114.114,114.114.115.115,223.5.5.5,223.6.6.6,180.76.76.76,119.29.29.29,119.28.28.28,1.2.4.8,210.2.4.8" -IPV6DNS_SERVER="2001:4860:4860::8888,2001:4860:4860::8844,2001:2001::1111,2001:2001::1001,2400:da00::6666,240C::6666,240C::6644" +IPV6DNS_SERVER="240c::6666,240c::6644,2001:da8::666,2001:da8:202:10::36,2001:da8:8000:1:202:120:2:100" start_pdnsd() { DNS_SERVER=$(uci get flowoffload.@flow[0].dns_server 2>/dev/null) diff --git a/package/lean/luci-app-sfe/Makefile b/package/lean/luci-app-sfe/Makefile index 25ed29e713..7320a83664 100644 --- a/package/lean/luci-app-sfe/Makefile +++ b/package/lean/luci-app-sfe/Makefile @@ -6,10 +6,10 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI support for Turbo ACC (SFE) -LUCI_DEPENDS:=+kmod-fast-classifier +pdnsd-alt +kmod-tcp-bbr @LINUX_4_9 +LUCI_DEPENDS:=+kmod-fast-classifier +pdnsd-alt +kmod-tcp-bbr LUCI_PKGARCH:=all PKG_VERSION:=1.0 -PKG_RELEASE:=38 +PKG_RELEASE:=13 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/package/lean/luci-app-unblockmusic/Makefile b/package/lean/luci-app-unblockmusic/Makefile index 58c1cecd8a..e8120ed28a 100644 --- a/package/lean/luci-app-unblockmusic/Makefile +++ b/package/lean/luci-app-unblockmusic/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-unblockmusic PKG_VERSION:=2.3.5 -PKG_RELEASE:=7 +PKG_RELEASE:=8 PKG_CONFIG_DEPENDS := \ CONFIG_UnblockNeteaseMusic_Go \ diff --git a/package/lean/luci-app-unblockmusic/root/etc/init.d/unblockmusic b/package/lean/luci-app-unblockmusic/root/etc/init.d/unblockmusic index 1020406812..b0d2fe987e 100755 --- a/package/lean/luci-app-unblockmusic/root/etc/init.d/unblockmusic +++ b/package/lean/luci-app-unblockmusic/root/etc/init.d/unblockmusic @@ -184,9 +184,8 @@ start() add_cron echo "$(date -R) # UnblockNeteaseMusic Nodejs Version (http:5200, https:5201)" >>/tmp/unblockmusic.log elif [ "$APPTYPE" == "go" ]; then - UnblockNeteaseMusic -p 5200 -sp 5202 -m 0 -c /usr/share/UnblockNeteaseMusicGo/server.crt -k /usr/share/UnblockNeteaseMusicGo/server.key -m 0 >>/tmp/unblockmusic.log 2>&1 & + UnblockNeteaseMusic -p 5200 -sp 5201 -m 0 -c /usr/share/UnblockNeteaseMusicGo/server.crt -k /usr/share/UnblockNeteaseMusicGo/server.key -m 0 -e >>/tmp/unblockmusic.log 2>&1 & echo "$(date -R) # UnblockNeteaseMusic Golang Version (http:5200, https:5201)" >>/tmp/unblockmusic.log - UnblockNeteaseMusic -p 5203 -sp 5201 -m 0 -c /usr/share/UnblockNeteaseMusicGo/server.crt -k /usr/share/UnblockNeteaseMusicGo/server.key -m 0 -e >>/tmp/unblockmusic.log 2>&1 & else kill -9 $(busybox ps -w | grep 'sleep 60m' | grep -v grep | awk '{print $1}') >/dev/null 2>&1 /usr/bin/UnblockNeteaseMusicCloud >/dev/null 2>&1 & diff --git a/package/lean/mt-drivers/mt_wifi/files/firmware.sh b/package/lean/mt-drivers/mt_wifi/files/firmware.sh index abdade9c79..bcc8240ea9 100644 --- a/package/lean/mt-drivers/mt_wifi/files/firmware.sh +++ b/package/lean/mt-drivers/mt_wifi/files/firmware.sh @@ -1,5 +1,5 @@ #!/bin/sh /etc/rc.common -chmod 777 /sbin/mtkwifi +chmod 0755 /sbin/mtkwifi START=15 STOP=15 diff --git a/package/lean/qBittorrent-Enhanced-Edition/Makefile b/package/lean/qBittorrent-Enhanced-Edition/Makefile index fdc23aabf4..cc7e5a5ed4 100644 --- a/package/lean/qBittorrent-Enhanced-Edition/Makefile +++ b/package/lean/qBittorrent-Enhanced-Edition/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qBittorrent-Enhanced-Edition -PKG_VERSION:=4.2.5.10 +PKG_VERSION:=4.2.5.12 PKG_RELEASE=1 PKG_SOURCE:=$(PKG_NAME)-release-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/c0re100/qBittorrent-Enhanced-Edition/tar.gz/release-$(PKG_VERSION)? -PKG_HASH:=d3c98f3beec064af5c95efa075fda2bb8aa5a9dec4219ff9bd003f27c8a24d36 +PKG_HASH:=1317cf11bc7f9cef418c177aee29d3a0d36c21cb7c06319d86bb49e5d3d8fa97 PKG_BUILD_DIR:=$(BUILD_DIR)/qBittorrent-Enhanced-Edition-release-$(PKG_VERSION) diff --git a/package/lean/shortcut-fe/Makefile b/package/lean/shortcut-fe/Makefile index 9f49cb90c5..a0111cfe25 100644 --- a/package/lean/shortcut-fe/Makefile +++ b/package/lean/shortcut-fe/Makefile @@ -15,7 +15,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=shortcut-fe -PKG_RELEASE:=9 +PKG_RELEASE:=1 include $(INCLUDE_DIR)/package.mk @@ -23,17 +23,27 @@ define KernelPackage/shortcut-fe SECTION:=kernel CATEGORY:=Kernel modules SUBMENU:=Network Support - DEPENDS:=@IPV6 @LINUX_4_9 + DEPENDS:= TITLE:=Kernel driver for SFE FILES:=$(PKG_BUILD_DIR)/shortcut-fe.ko $(PKG_BUILD_DIR)/shortcut-fe-ipv6.ko - KCONFIG:=CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_SHORTCUT_FE=y - AUTOLOAD:=$(call AutoProbe,shortcut-fe shortcut-fe-ipv6) + KCONFIG:=CONFIG_NF_CONNTRACK_EVENTS=y \ + CONFIG_NF_CONNTRACK_TIMEOUT=y \ + CONFIG_SHORTCUT_FE=y \ + CONFIG_XFRM=y + AUTOLOAD:=$(call AutoLoad,09,shortcut-fe shortcut-fe-ipv6) endef define KernelPackage/shortcut-fe/Description Shortcut is an in-Linux-kernel IP packet forwarding engine. endef +define KernelPackage/shortcut-fe/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/etc/init.d/shortcut-fe $(1)/etc/init.d + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) ./files/usr/bin/sfe_dump $(1)/usr/bin +endef + define KernelPackage/shortcut-fe-cm SECTION:=kernel CATEGORY:=Kernel modules @@ -41,81 +51,31 @@ define KernelPackage/shortcut-fe-cm DEPENDS:=+kmod-ipt-conntrack +kmod-shortcut-fe TITLE:=Kernel driver for SFE FILES:=$(PKG_BUILD_DIR)/shortcut-fe-cm.ko - KCONFIG:=CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y CONFIG_NF_CONNTRACK_MARK=y - AUTOLOAD:=$(call AutoProbe,shortcut-fe-cm) + KCONFIG:=CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y endef define KernelPackage/shortcut-fe-cm/Description Simple connection manager for the Shortcut forwarding engine. endef -define KernelPackage/fast-classifier - SECTION:=kernel - CATEGORY:=Kernel modules - SUBMENU:=Network Support - DEPENDS:=+kmod-ipt-conntrack +kmod-shortcut-fe - TITLE:=Kernel driver for FAST Classifier - FILES:=$(PKG_BUILD_DIR)/fast-classifier.ko - KCONFIG:=CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y CONFIG_NF_CONNTRACK_MARK=y - AUTOLOAD:=$(call AutoLoad,z,fast-classifier) - PROVIDES:=$(PKG_NAME) -endef - -define KernelPackage/fast-classifier/description -FAST Classifier connection manager for Shortcut forwarding engine. -It talks to SFE to make decisions about offloading connections. -endef - -define Package/fast-classifier-example - TITLE:=Example user space program for fast-classifier - DEPENDS:=+libnl +kmod-fast-classifier -endef - -define Package/fast-classifier-example/description -Example user space program that communicates with fast -classifier kernel module -endef - -MAKE_OPTS:= \ - ARCH="$(LINUX_KARCH)" \ - CROSS_COMPILE="$(TARGET_CROSS)" \ - SUBDIRS="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="$(EXTRA_CFLAGS)" +EXTRA_CFLAGS+=-DSFE_SUPPORT_IPV6 define Build/Compile - $(MAKE) -C "$(LINUX_DIR)" \ - $(MAKE_OPTS) \ + +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + SUBDIRS="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + SFE_SUPPORT_IPV6=1 \ modules - $(if $(CONFIG_PACKAGE_fast-classifier-example),$(Build/Compile/fast-classifier-example)) endef -define Build/Compile/fast-classifier-example - $(TARGET_CC) -o $(PKG_BUILD_DIR)/userspace_fast_classifier \ - -I $(PKG_BUILD_DIR) \ - -I$(STAGING_DIR)/usr/include/libnl \ - -I$(STAGING_DIR)/usr/include/libnl3 \ - -lnl-genl-3 -lnl-3 \ - $(PKG_BUILD_DIR)/nl_classifier_test.c -endef - -ifneq ($(CONFIG_PACKAGE_kmod-shortcut-fe)$(CONFIG_PACKAGE_kmod-shortcut-fe-cm)$(CONFIG_PACKAGE_kmod-fast-classifier),) +ifneq ($(CONFIG_PACKAGE_kmod-shortcut-fe)$(CONFIG_PACKAGE_kmod-shortcut-fe-cm),) define Build/InstallDev $(INSTALL_DIR) $(1)/usr/include/shortcut-fe $(CP) -rf $(PKG_BUILD_DIR)/sfe.h $(1)/usr/include/shortcut-fe -ifneq ($(CONFIG_PACKAGE_kmod-fast-classifier),) - $(INSTALL_DIR) $(1)/usr/include - $(CP) $(PKG_BUILD_DIR)/fast-classifier.h $(1)/usr/include/ -endif endef endif -define Package/fast-classifier-example/install - $(INSTALL_DIR) $(1)/sbin - $(CP) $(PKG_BUILD_DIR)/userspace_fast_classifier $(1)/sbin/ -endef - $(eval $(call KernelPackage,shortcut-fe)) $(eval $(call KernelPackage,shortcut-fe-cm)) -$(eval $(call KernelPackage,fast-classifier)) -#$(eval $(call BuildPackage,fast-classifier-example)) - diff --git a/package/lean/shortcut-fe/files/etc/init.d/shortcut-fe b/package/lean/shortcut-fe/files/etc/init.d/shortcut-fe new file mode 100755 index 0000000000..16ca758764 --- /dev/null +++ b/package/lean/shortcut-fe/files/etc/init.d/shortcut-fe @@ -0,0 +1,48 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +#SFE connection manager has a lower priority, it should be started after other connection manager +#to detect the existence of connection manager with higher priority +START=72 + +have_cm() { + [ -d "/sys/kernel/debug/ecm" ] && echo 1 && return + + echo 0 +} + +#load shortcut-fe connection manager +load_sfe_cm() { + local kernel_version=$(uname -r) + + #shortcut-fe-drv.ko is not needed because other connection manager is not enabled + [ -d "/sys/module/shortcut_fe_drv" ] && rmmod shortcut_fe_drv + + [ -e "/lib/modules/$kernel_version/shortcut-fe-cm.ko" ] && { + [ -d /sys/module/shortcut_fe_cm ] || insmod /lib/modules/$kernel_version/shortcut-fe-cm.ko + } + [ -e "/lib/modules/$kernel_version/fast-classifier.ko" ] && { + [ -d /sys/module/fast_classifier ] || insmod /lib/modules/$kernel_version/fast-classifier.ko + } +} + +start() { + [ "$(have_cm)" = "1" ] || load_sfe_cm +} + +stop() { + [ -d /sys/module/shortcut_fe_cm ] && rmmod shortcut_fe_cm + [ -d /sys/module/fast_classifier ] && rmmod fast_classifier +} diff --git a/package/lean/shortcut-fe/files/usr/bin/sfe_dump b/package/lean/shortcut-fe/files/usr/bin/sfe_dump new file mode 100644 index 0000000000..2a224e0ca1 --- /dev/null +++ b/package/lean/shortcut-fe/files/usr/bin/sfe_dump @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Copyright (c) 2015 The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +#@sfe_dump +#@example : sfe_dump (ipv4|ipv6) +sfe_dump(){ + [ -e "/dev/sfe_ipv4" ] || { + dev_num=$(cat /sys/sfe_ipv4/debug_dev) + mknod /dev/sfe_ipv4 c $dev_num 0 + } + [ -e "/dev/sfe_ipv6" ] || { + dev_num=$(cat /sys/sfe_ipv6/debug_dev) + mknod /dev/sfe_ipv6 c $dev_num 0 + } + cat /dev/sfe_$1 +} + +if [ -z "$1" ]; then + sfe_dump ipv4 + sfe_dump ipv6 +else + sfe_dump $1 +fi diff --git a/package/lean/shortcut-fe/src/Makefile b/package/lean/shortcut-fe/src/Makefile index 88d95d232e..3b1ceaa44e 100644 --- a/package/lean/shortcut-fe/src/Makefile +++ b/package/lean/shortcut-fe/src/Makefile @@ -2,13 +2,22 @@ # Makefile for Shortcut FE. # -obj-m += shortcut-fe.o shortcut-fe-ipv6.o shortcut-fe-cm.o fast-classifier.o +obj-m += shortcut-fe.o + +ifdef SFE_SUPPORT_IPV6 +obj-m += shortcut-fe-ipv6.o +endif + +obj-m += shortcut-fe-cm.o shortcut-fe-objs := \ sfe_ipv4.o +ifdef SFE_SUPPORT_IPV6 shortcut-fe-ipv6-objs := \ sfe_ipv6.o +endif shortcut-fe-cm-objs := \ sfe_cm.o + diff --git a/package/lean/shortcut-fe/src/README b/package/lean/shortcut-fe/src/README deleted file mode 100644 index 1bf1cc2555..0000000000 --- a/package/lean/shortcut-fe/src/README +++ /dev/null @@ -1,122 +0,0 @@ -Shortcut Forwarding Engine --------------------------- - -Welcome to "Shortcut" :-) - -Here's a quick FAQ: - - -Q) What is Shortcut? - -A) Shortcut is an in-Linux-kernel IP packet forwarding engine. It's designed -to offer very high speed IP packet forwarding based on IP connection tracking. -It's dramatically faster than the standard netfilter-based NAT forwarding path -but is designed to synchronise state back to netfilter/conntrack so that it -doesn't need to deal with all of the complexities of special cases. - - -Q) What versions of IP does it support? - -A) The current version only supports IPv4 but will be extended to support IPv6 in -the future. - - -Q) What transport protocols does it support? - -A) TCP and UDP. It also knows enough about ICMP to spot ICMP error messages -related to TCP and UDP and handle things accordingly. - - -Q) Is there a design spec for this software? - -A) Not at the moment. I'll write one when I get more time. The code is -intended to be a good tutorial though - it's very heavily commented. If you -find yourself reading something and not understanding it then I take that to -mean I've probably not done a sufficently good job of explaining what it's -doing in the comments. Let me know - I will try to fix it :-) - - -Q) Why was it written? - -A) It was written as a demonstration of what can be done to provide high -performance forwarding inside the kernel. There were two initial motivations: - -1) To provide a platform to enable research into how QoS analysis systems can -offload work and avoid huge Linux overheads. - -2) To provide a tool to investigate the behaviour of various processors, SoCs -and software sets so that we can characterize and design new network processor -SoCs. - - -Q) How much faster is it than the Linux kernel forwarding path? - -A) At the time of pushing this to github it's been tested on a QCA AP135. -This has a Scorpion (QCA Scopion, not the QMC one :-)) SoC, QCA9550. The -SoC's processor is a MIPS74K running at 720 MHz and with a DDR2 memory -subsystem that offers a peak of 600 MT/s (16-bit transfers). - -Running IPv4 NAT forwarding of UDP between the board's 2 GMAC ports and -using a SmartBits 200 as a traffic generator Linux is able to forward 70k PPS. -Once the SFE code is invoked this will increase to 350k PPS! - -There's also a slightly hacky mode which causes SFE to bypass the Linux -bridge layer, but this isn't really ready for use because it doesn't have -sufficient MAC address checks or integration of statistics back to the -Ethernet bridge, but that runs at 436k PPS. - - -Q) Are there any diagnostics? - -A) Yes, this is a research tool after all! There's a complex way to do this -that's more general purpose and a simple one - here's the simple one: - - mknod /dev/sfe c 253 0 - -The file /dev/sfe is an XML-ish output and provides details of all the -network connections currently being offloaded. It also reports the numbers -of packets that took various "exception" paths within the code. In addition -it provides a summary of the number of connections, attempts to accelerate -connections, cancel accelerations, etc. It also reports the numbers of -packets that were forwarded and not forwarded by the engine and has some -stats on the effectiveness of the hashing algorithm it uses. - - -Q) How does the code interact with Linux? - -A) There are four minor patches required to make this software run with -Linux. These are currently against a 3.3.8 or 3.4.0 kernel: - -* (net/core/dev.c) adds a hook to allow packets to be extracted out. - -* (net/netfilter/nf_conntrack_proto_tcp.c) exposes a state variable inside - netfilter that's necessary to enable TCP sequence and ACK checking within - the offload path. Note that this specific patch is against the QCA QSDK - patched version of 3.3.8 - there's a slightly braindead "performance" - patch in that kernel, courtesy of the OpenWrt community that makes the - Linux forwarding path slightly faster at the expense of losing - functionality :-( - -* (net/Kconfig) adds the shortcut-fe option. - -* (net/Makefile) adds the shortcut-fe build support. - -Once these are applied and the module is loaded then everything else -is automatic :-) The patches are in this git repo. - - -Q) Are any of the pieces reused from other projects? - -A) Yes! Some of the forwarding concepts are reused from the Ubicom Network -Accelerator that morphed into part of the Akronite NSS. This code has all -been substantially changed though to accomodate Linux's needs. - -There are also some pieces that I borrowed from the QCA "FastNAT" software -written by Xiaoping Fan . Xiaoping's code was the -first actual demonstration within QCA that this in-kernel concept could yield -signficant performance gains. - - -Enjoy! -Dave Hudson - diff --git a/package/lean/shortcut-fe/src/sfe.h b/package/lean/shortcut-fe/src/sfe.h index 21a1275560..279e7b3dca 100644 --- a/package/lean/shortcut-fe/src/sfe.h +++ b/package/lean/shortcut-fe/src/sfe.h @@ -2,7 +2,7 @@ * sfe.h * Shortcut forwarding engine. * - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. @@ -15,47 +15,100 @@ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + /* - * Debug output verbosity level. + * The following are debug macros used throughout the SFE. + * + * The DEBUG_LEVEL enables the followings based on its value, + * when dynamic debug option is disabled. + * + * 0 = OFF + * 1 = ASSERTS / ERRORS + * 2 = 1 + WARN + * 3 = 2 + INFO + * 4 = 3 + TRACE */ -#define DEBUG_LEVEL 0 +#define DEBUG_LEVEL 2 #if (DEBUG_LEVEL < 1) +#define DEBUG_ASSERT(s, ...) #define DEBUG_ERROR(s, ...) #else -#define DEBUG_ERROR(s, ...) \ -do { \ - printk("%s[%u]: ERROR:", __FILE__, __LINE__); \ - printk(s, ##__VA_ARGS__); \ -} while (0) +#define DEBUG_ASSERT(c, s, ...) if (!(c)) { pr_emerg("ASSERT: %s:%d:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__); BUG(); } +#define DEBUG_ERROR(s, ...) pr_err("%s:%d:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) #endif +#if defined(CONFIG_DYNAMIC_DEBUG) +/* + * Compile messages for dynamic enable/disable + */ +#define DEBUG_WARN(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define DEBUG_INFO(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define DEBUG_TRACE(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#else + +/* + * Statically compile messages at different levels + */ #if (DEBUG_LEVEL < 2) #define DEBUG_WARN(s, ...) #else -#define DEBUG_WARN(s, ...) \ -do { \ - printk("%s[%u]: WARN:", __FILE__, __LINE__); \ - printk(s, ##__VA_ARGS__); \ -} while (0) +#define DEBUG_WARN(s, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) #endif #if (DEBUG_LEVEL < 3) #define DEBUG_INFO(s, ...) #else -#define DEBUG_INFO(s, ...) \ -do { \ - printk("%s[%u]: INFO:", __FILE__, __LINE__); \ - printk(s, ##__VA_ARGS__); \ -} while (0) +#define DEBUG_INFO(s, ...) pr_notice("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) #endif #if (DEBUG_LEVEL < 4) #define DEBUG_TRACE(s, ...) #else -#define DEBUG_TRACE(s, ...) \ -do { \ - printk("%s[%u]: TRACE:", __FILE__, __LINE__); \ - printk(s, ##__VA_ARGS__); \ -} while (0) +#define DEBUG_TRACE(s, ...) pr_info("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) #endif +#endif + +#ifdef CONFIG_NF_FLOW_COOKIE +typedef int (*flow_cookie_set_func_t)(u32 protocol, __be32 src_ip, __be16 src_port, + __be32 dst_ip, __be16 dst_port, u16 flow_cookie); +/* + * sfe_register_flow_cookie_cb + * register a function in SFE to let SFE use this function to configure flow cookie for a flow + * + * Hardware driver which support flow cookie should register a callback function in SFE. Then SFE + * can use this function to configure flow cookie for a flow. + * return: 0, success; !=0, fail + */ +int sfe_register_flow_cookie_cb(flow_cookie_set_func_t cb); + +/* + * sfe_unregister_flow_cookie_cb + * unregister function which is used to configure flow cookie for a flow + * + * return: 0, success; !=0, fail + */ +int sfe_unregister_flow_cookie_cb(flow_cookie_set_func_t cb); + +typedef int (*sfe_ipv6_flow_cookie_set_func_t)(u32 protocol, __be32 src_ip[4], __be16 src_port, + __be32 dst_ip[4], __be16 dst_port, u16 flow_cookie); + +/* + * sfe_ipv6_register_flow_cookie_cb + * register a function in SFE to let SFE use this function to configure flow cookie for a flow + * + * Hardware driver which support flow cookie should register a callback function in SFE. Then SFE + * can use this function to configure flow cookie for a flow. + * return: 0, success; !=0, fail + */ +int sfe_ipv6_register_flow_cookie_cb(sfe_ipv6_flow_cookie_set_func_t cb); + +/* + * sfe_ipv6_unregister_flow_cookie_cb + * unregister function which is used to configure flow cookie for a flow + * + * return: 0, success; !=0, fail + */ +int sfe_ipv6_unregister_flow_cookie_cb(sfe_ipv6_flow_cookie_set_func_t cb); + +#endif /*CONFIG_NF_FLOW_COOKIE*/ diff --git a/package/lean/shortcut-fe/src/sfe_backport.h b/package/lean/shortcut-fe/src/sfe_backport.h index b24f6e67e6..2f8c8ca3c1 100644 --- a/package/lean/shortcut-fe/src/sfe_backport.h +++ b/package/lean/shortcut-fe/src/sfe_backport.h @@ -17,6 +17,38 @@ #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) +#include +#else +enum udp_conntrack { + UDP_CT_UNREPLIED, + UDP_CT_REPLIED, + UDP_CT_MAX +}; + +static inline unsigned int * +nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct, + struct nf_conntrack_l4proto *l4proto) +{ +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + struct nf_conn_timeout *timeout_ext; + unsigned int *timeouts; + + timeout_ext = nf_ct_timeout_find(ct); + if (timeout_ext) + timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext); + else + timeouts = l4proto->get_timeouts(net); + + return timeouts; +#else + return l4proto->get_timeouts(net); +#endif /*CONFIG_NF_CONNTRACK_TIMEOUT*/ +} +#endif /*KERNEL_VERSION(3, 7, 0)*/ +#endif /*KERNEL_VERSION(3, 4, 0)*/ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) #define sfe_define_post_routing_hook(FN_NAME, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \ static unsigned int FN_NAME(void *priv, \ @@ -131,8 +163,33 @@ static inline struct net_device *sfe_dev_get_master(struct net_device *dev) #define SFE_ACCT_COUNTER(NM) (NM) #endif -#define sfe_hash_for_each_possible(name, obj, member, key) \ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) +#define sfe_hash_for_each_possible(name, obj, node, member, key) \ hash_for_each_possible(name, obj, member, key) +#else +#define sfe_hash_for_each_possible(name, obj, node, member, key) \ + hash_for_each_possible(name, obj, node, member, key) +#endif -#define sfe_hash_for_each(name, bkt, obj, member) \ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) +#define sfe_hash_for_each(name, bkt, node, obj, member) \ hash_for_each(name, bkt, obj, member) +#else +#define sfe_hash_for_each(name, bkt, node, obj, member) \ + hash_for_each(name, bkt, node, obj, member) +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) +#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, daddr) +#else +static inline struct neighbour * +sfe_dst_get_neighbour(struct dst_entry *dst, void *daddr) +{ + struct neighbour *neigh = dst_get_neighbour_noref(dst); + + if (neigh) + neigh_hold(neigh); + + return neigh; +} +#endif diff --git a/package/lean/shortcut-fe/src/sfe_cm.c b/package/lean/shortcut-fe/src/sfe_cm.c index 6d3e21085a..4e5a0c1841 100644 --- a/package/lean/shortcut-fe/src/sfe_cm.c +++ b/package/lean/shortcut-fe/src/sfe_cm.c @@ -2,7 +2,7 @@ * sfe-cm.c * Shortcut forwarding engine connection manager. * - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. @@ -29,10 +29,9 @@ #include #include #include -#include #include #include -#include +#include #include "sfe.h" #include "sfe_cm.h" @@ -103,7 +102,6 @@ struct sfe_cm { static struct sfe_cm __sc; - /* * sfe_cm_incr_exceptions() * increase an exception counter. @@ -123,7 +121,7 @@ static inline void sfe_cm_incr_exceptions(sfe_cm_exception_t except) * * Returns 1 if the packet is forwarded or 0 if it isn't. */ -static int sfe_cm_recv(struct sk_buff *skb) +int sfe_cm_recv(struct sk_buff *skb) { struct net_device *dev; @@ -136,16 +134,6 @@ static int sfe_cm_recv(struct sk_buff *skb) dev = skb->dev; -#ifdef CONFIG_NET_CLS_ACT - /* - * If ingress Qdisc configured, and packet not processed by ingress Qdisc yet - * We cannot accelerate this packet. - */ - if (dev->ingress_queue && !(skb->tc_verd & TC_NCLS)) { - return 0; - } -#endif - /* * We're only interested in IPv4 and IPv6 packets. */ @@ -232,7 +220,11 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device dst = (struct dst_entry *)rt; } else { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) + rt6 = rt6_lookup(&init_net, (struct in6_addr *)addr->ip6, 0, 0, NULL, 0); +#else rt6 = rt6_lookup(&init_net, (struct in6_addr *)addr->ip6, 0, 0, 0); +#endif /*KERNEL_VERSION(4, 17, 0)*/ if (!rt6) { goto ret_fail; } @@ -241,7 +233,7 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device } rcu_read_lock(); - neigh = dst_neigh_lookup(dst, addr); + neigh = sfe_dst_get_neighbour(dst, addr); if (unlikely(!neigh)) { rcu_read_unlock(); dst_release(dst); @@ -297,6 +289,8 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) struct net_device *dev; struct net_device *src_dev; struct net_device *dest_dev; + struct net_device *src_dev_tmp; + struct net_device *dest_dev_tmp; struct net_device *src_br_dev = NULL; struct net_device *dest_br_dev = NULL; struct nf_conntrack_tuple orig_tuple; @@ -358,6 +352,7 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) return NF_ACCEPT; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) /* * Don't process untracked connections. */ @@ -366,6 +361,7 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) DEBUG_TRACE("untracked connection\n"); return NF_ACCEPT; } +#endif /*KERNEL_VERSION(4, 12, 0)*/ /* * Unconfirmed connection may be dropped by Linux at the final step, @@ -537,7 +533,11 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) * For packets de-capsulated from xfrm, we still can accelerate it * on the direction we just received the packet. */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) + if (unlikely(skb_ext_exist(skb, SKB_EXT_SEC_PATH))) { +#else if (unlikely(skb->sp)) { +#endif if (sic.protocol == IPPROTO_TCP && !(sic.flags & SFE_CREATE_FLAG_NO_SEQ_CHECK)) { return NF_ACCEPT; @@ -564,29 +564,29 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) * Get the net device and MAC addresses that correspond to the various source and * destination host addresses. */ - if (!sfe_cm_find_dev_and_mac_addr(&sic.src_ip, &src_dev, sic.src_mac, is_v4)) { + if (!sfe_cm_find_dev_and_mac_addr(&sic.src_ip, &src_dev_tmp, sic.src_mac, is_v4)) { sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_SRC_DEV); return NF_ACCEPT; } + src_dev = src_dev_tmp; if (!sfe_cm_find_dev_and_mac_addr(&sic.src_ip_xlate, &dev, sic.src_mac_xlate, is_v4)) { sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_SRC_XLATE_DEV); goto done1; } - dev_put(dev); if (!sfe_cm_find_dev_and_mac_addr(&sic.dest_ip, &dev, sic.dest_mac, is_v4)) { sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_DEST_DEV); goto done1; } - dev_put(dev); - if (!sfe_cm_find_dev_and_mac_addr(&sic.dest_ip_xlate, &dest_dev, sic.dest_mac_xlate, is_v4)) { + if (!sfe_cm_find_dev_and_mac_addr(&sic.dest_ip_xlate, &dest_dev_tmp, sic.dest_mac_xlate, is_v4)) { sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_DEST_XLATE_DEV); goto done1; } + dest_dev = dest_dev_tmp; /* * Our devices may actually be part of a bridge interface. If that's @@ -599,7 +599,6 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) DEBUG_TRACE("no bridge found for: %s\n", src_dev->name); goto done2; } - src_dev = src_br_dev; } @@ -610,7 +609,6 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) DEBUG_TRACE("no bridge found for: %s\n", dest_dev->name); goto done3; } - dest_dev = dest_br_dev; } @@ -619,7 +617,7 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) sic.src_mtu = src_dev->mtu; sic.dest_mtu = dest_dev->mtu; - sic.mark = skb->mark; + if (likely(is_v4)) { sfe_ipv4_create_rule(&sic); } else { @@ -632,17 +630,14 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) if (dest_br_dev) { dev_put(dest_br_dev); } - done3: if (src_br_dev) { dev_put(src_br_dev); } - done2: - dev_put(dest_dev); - + dev_put(dest_dev_tmp); done1: - dev_put(src_dev); + dev_put(src_dev_tmp); return NF_ACCEPT; } @@ -692,6 +687,7 @@ static int sfe_cm_conntrack_event(unsigned int events, struct nf_ct_event *item) return NOTIFY_DONE; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) /* * If this is an untracked connection then we can't have any state either. */ @@ -699,6 +695,7 @@ static int sfe_cm_conntrack_event(unsigned int events, struct nf_ct_event *item) DEBUG_TRACE("ignoring untracked conn\n"); return NOTIFY_DONE; } +#endif /*KERNEL_VERSION(4, 12, 0)*/ /* * We're only interested in destroy events. @@ -771,7 +768,9 @@ static struct nf_ct_event_notifier sfe_cm_conntrack_notifier = { */ static struct nf_hook_ops sfe_cm_ops_post_routing[] __read_mostly = { SFE_IPV4_NF_POST_ROUTING_HOOK(__sfe_cm_ipv4_post_routing_hook), +#ifdef SFE_SUPPORT_IPV6 SFE_IPV6_NF_POST_ROUTING_HOOK(__sfe_cm_ipv6_post_routing_hook), +#endif }; /* @@ -824,18 +823,20 @@ static void sfe_cm_sync_rule(struct sfe_connection_sync *sis) } ct = nf_ct_tuplehash_to_ctrack(h); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct); +#endif /*KERNEL_VERSION(4, 9, 0)*/ /* * Only update if this is not a fixed timeout */ if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) { spin_lock_bh(&ct->lock); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) ct->timeout += sis->delta_jiffies; #else ct->timeout.expires += sis->delta_jiffies; -#endif +#endif /*KERNEL_VERSION(4, 9, 0)*/ spin_unlock_bh(&ct->lock); } @@ -872,6 +873,7 @@ static void sfe_cm_sync_rule(struct sfe_connection_sync *sis) } spin_unlock_bh(&ct->lock); break; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) case IPPROTO_UDP: /* * In Linux connection track, UDP flow has two timeout values: @@ -888,25 +890,31 @@ static void sfe_cm_sync_rule(struct sfe_connection_sync *sis) u_int64_t reply_pkts = atomic64_read(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets); if (reply_pkts != 0) { - struct nf_conntrack_l4proto *l4proto; unsigned int *timeouts; set_bit(IPS_SEEN_REPLY_BIT, &ct->status); set_bit(IPS_ASSURED_BIT, &ct->status); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) + timeouts = nf_ct_timeout_lookup(ct); +#else + struct nf_conntrack_l4proto *l4proto; + l4proto = __nf_ct_l4proto_find((sis->is_v6 ? AF_INET6 : AF_INET), IPPROTO_UDP); timeouts = nf_ct_timeout_lookup(&init_net, ct, l4proto); +#endif /*KERNEL_VERSION(4, 19, 0)*/ spin_lock_bh(&ct->lock); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) - ct->timeout = nfct_time_stamp + timeouts[UDP_CT_REPLIED]; + ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; #else ct->timeout.expires = jiffies + timeouts[UDP_CT_REPLIED]; -#endif +#endif /*KERNEL_VERSION(4, 9, 0)*/ spin_unlock_bh(&ct->lock); } } break; +#endif /*KERNEL_VERSION(3, 4, 0)*/ } /* @@ -918,7 +926,7 @@ static void sfe_cm_sync_rule(struct sfe_connection_sync *sis) /* * sfe_cm_device_event() */ -static int sfe_cm_device_event(struct notifier_block *this, unsigned long event, void *ptr) +int sfe_cm_device_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = SFE_DEV_EVENT_PTR(ptr); @@ -980,80 +988,11 @@ static ssize_t sfe_cm_get_exceptions(struct device *dev, return len; } -/* - * sfe_cm_get_stop - * dump stop - */ -static ssize_t sfe_cm_get_stop(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int (*fast_recv)(struct sk_buff *skb); - rcu_read_lock(); - fast_recv = rcu_dereference(fast_nat_recv); - rcu_read_unlock(); - return snprintf(buf, (ssize_t)PAGE_SIZE, "%d\n", fast_recv ? 0 : 1); -} - -static ssize_t sfe_cm_set_stop(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int ret; - u32 num; - int (*fast_recv)(struct sk_buff *skb); - - ret = kstrtou32(buf, 0, &num); - if (ret) - return ret; - - /* - * Hook/Unhook the receive path in the network stack. - */ - if (num) { - RCU_INIT_POINTER(fast_nat_recv, NULL); - } else { - rcu_read_lock(); - fast_recv = rcu_dereference(fast_nat_recv); - rcu_read_unlock(); - if (!fast_recv) { - BUG_ON(fast_nat_recv); - RCU_INIT_POINTER(fast_nat_recv, sfe_cm_recv); - } - } - - DEBUG_TRACE("sfe_cm_stop = %d\n", num); - return count; -} - -/* - * sfe_cm_get_defunct_all - * dump state of SFE - */ -static ssize_t sfe_cm_get_defunct_all(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, (ssize_t)PAGE_SIZE, "%d\n", 0); -} - -static ssize_t sfe_cm_set_defunct_all(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - sfe_ipv4_destroy_all_rules_for_dev(NULL); - sfe_ipv6_destroy_all_rules_for_dev(NULL); - return count; -} - /* * sysfs attributes. */ -static const struct device_attribute sfe_attrs[] = { - __ATTR(exceptions, S_IRUGO, sfe_cm_get_exceptions, NULL), - __ATTR(stop, S_IWUSR | S_IRUGO, sfe_cm_get_stop, sfe_cm_set_stop), - __ATTR(defunct_all, S_IWUSR | S_IRUGO, sfe_cm_get_defunct_all, sfe_cm_set_defunct_all), -}; +static const struct device_attribute sfe_cm_exceptions_attr = + __ATTR(exceptions, S_IRUGO, sfe_cm_get_exceptions, NULL); /* * sfe_cm_init() @@ -1062,7 +1001,6 @@ static int __init sfe_cm_init(void) { struct sfe_cm *sc = &__sc; int result = -1; - size_t i, j; DEBUG_INFO("SFE CM init\n"); @@ -1075,13 +1013,13 @@ static int __init sfe_cm_init(void) goto exit1; } - for (i = 0; i < ARRAY_SIZE(sfe_attrs); i++) { - result = sysfs_create_file(sc->sys_sfe_cm, &sfe_attrs[i].attr); - if (result) { - DEBUG_ERROR("failed to register %s : %d\n", - sfe_attrs[i].attr.name, result); - goto exit2; - } + /* + * Create sys/sfe_cm/exceptions + */ + result = sysfs_create_file(sc->sys_sfe_cm, &sfe_cm_exceptions_attr.attr); + if (result) { + DEBUG_ERROR("failed to register exceptions file: %d\n", result); + goto exit2; } sc->dev_notifier.notifier_call = sfe_cm_device_event; @@ -1098,19 +1036,18 @@ static int __init sfe_cm_init(void) /* * Register our netfilter hooks. */ - result = nf_register_hooks(sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); + result = nf_register_net_hooks(&init_net, sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); if (result < 0) { DEBUG_ERROR("can't register nf post routing hook: %d\n", result); goto exit3; } -#ifdef CONFIG_NF_CONNTRACK_EVENTS /* * Register a notifier hook to get fast notifications of expired connections. * Note: In CONFIG_NF_CONNTRACK_CHAIN_EVENTS enabled case, nf_conntrack_register_notifier() * function always returns 0. */ - +#ifdef CONFIG_NF_CONNTRACK_EVENTS #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS (void)nf_conntrack_register_notifier(&init_net, &sfe_cm_conntrack_notifier); #else @@ -1124,6 +1061,12 @@ static int __init sfe_cm_init(void) spin_lock_init(&sc->lock); + /* + * Hook the receive path in the network stack. + */ + BUG_ON(athrs_fast_nat_recv); + RCU_INIT_POINTER(athrs_fast_nat_recv, sfe_cm_recv); + /* * Hook the shortcut sync callback. */ @@ -1134,7 +1077,7 @@ static int __init sfe_cm_init(void) #ifdef CONFIG_NF_CONNTRACK_EVENTS #ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS exit4: - nf_unregister_hooks(sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); + nf_unregister_net_hooks(&init_net, sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); #endif #endif exit3: @@ -1142,9 +1085,6 @@ exit3: unregister_inetaddr_notifier(&sc->inet_notifier); unregister_netdevice_notifier(&sc->dev_notifier); exit2: - for (j = 0; j < i; j++) { - sysfs_remove_file(sc->sys_sfe_cm, &sfe_attrs[j].attr); - } kobject_put(sc->sys_sfe_cm); exit1: @@ -1169,7 +1109,7 @@ static void __exit sfe_cm_exit(void) /* * Unregister our receive callback. */ - RCU_INIT_POINTER(fast_nat_recv, NULL); + RCU_INIT_POINTER(athrs_fast_nat_recv, NULL); /* * Wait for all callbacks to complete. @@ -1186,7 +1126,7 @@ static void __exit sfe_cm_exit(void) nf_conntrack_unregister_notifier(&init_net, &sfe_cm_conntrack_notifier); #endif - nf_unregister_hooks(sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); + nf_unregister_net_hooks(&init_net, sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); unregister_inet6addr_notifier(&sc->inet6_notifier); unregister_inetaddr_notifier(&sc->inet_notifier); diff --git a/package/lean/shortcut-fe/src/sfe_cm.h b/package/lean/shortcut-fe/src/sfe_cm.h index 6f2a819d12..23cbde859b 100644 --- a/package/lean/shortcut-fe/src/sfe_cm.h +++ b/package/lean/shortcut-fe/src/sfe_cm.h @@ -147,7 +147,7 @@ struct sfe_connection_mark { /* * Expose the hook for the receive processing. */ -extern int (*fast_nat_recv)(struct sk_buff *skb); +extern int (*athrs_fast_nat_recv)(struct sk_buff *skb); /* * Expose what should be a static flag in the TCP connection tracker. @@ -175,6 +175,7 @@ void sfe_ipv4_register_sync_rule_callback(sfe_sync_rule_callback_t callback); void sfe_ipv4_update_rule(struct sfe_connection_create *sic); void sfe_ipv4_mark_rule(struct sfe_connection_mark *mark); +#ifdef SFE_SUPPORT_IPV6 /* * IPv6 APIs used by connection manager */ @@ -185,6 +186,42 @@ void sfe_ipv6_destroy_all_rules_for_dev(struct net_device *dev); void sfe_ipv6_register_sync_rule_callback(sfe_sync_rule_callback_t callback); void sfe_ipv6_update_rule(struct sfe_connection_create *sic); void sfe_ipv6_mark_rule(struct sfe_connection_mark *mark); +#else +static inline int sfe_ipv6_recv(struct net_device *dev, struct sk_buff *skb) +{ + return 0; +} + +static inline int sfe_ipv6_create_rule(struct sfe_connection_create *sic) +{ + return 0; +} + +static inline void sfe_ipv6_destroy_rule(struct sfe_connection_destroy *sid) +{ + return; +} + +static inline void sfe_ipv6_destroy_all_rules_for_dev(struct net_device *dev) +{ + return; +} + +static inline void sfe_ipv6_register_sync_rule_callback(sfe_sync_rule_callback_t callback) +{ + return; +} + +static inline void sfe_ipv6_update_rule(struct sfe_connection_create *sic) +{ + return; +} + +static inline void sfe_ipv6_mark_rule(struct sfe_connection_mark *mark) +{ + return; +} +#endif /* * sfe_ipv6_addr_equal() diff --git a/package/lean/shortcut-fe/src/sfe_ipv4.c b/package/lean/shortcut-fe/src/sfe_ipv4.c index 34ed09b58a..531456c05f 100644 --- a/package/lean/shortcut-fe/src/sfe_ipv4.c +++ b/package/lean/shortcut-fe/src/sfe_ipv4.c @@ -2,7 +2,7 @@ * sfe_ipv4.c * Shortcut forwarding engine - IPv4 edition. * - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 2019, The Linux Foundation. All rights reserved. * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include "sfe.h" #include "sfe_cm.h" @@ -38,7 +38,7 @@ */ #define SFE_IPV4_UNALIGNED_IP_HEADER 1 #if SFE_IPV4_UNALIGNED_IP_HEADER -#define SFE_IPV4_UNALIGNED_STRUCT __attribute__((aligned(4))) +#define SFE_IPV4_UNALIGNED_STRUCT __attribute__((packed)) #else #define SFE_IPV4_UNALIGNED_STRUCT #endif @@ -202,6 +202,9 @@ struct sfe_ipv4_connection_match { * Control the operations of the match. */ u32 flags; /* Bit flags */ +#ifdef CONFIG_NF_FLOW_COOKIE + u32 flow_cookie; /* used flow cookie, for debug */ +#endif #ifdef CONFIG_XFRM u32 flow_accel; /* The flow accelerated or not */ #endif @@ -300,6 +303,16 @@ struct sfe_ipv4_connection { #define SFE_IPV4_CONNECTION_HASH_SIZE (1 << SFE_IPV4_CONNECTION_HASH_SHIFT) #define SFE_IPV4_CONNECTION_HASH_MASK (SFE_IPV4_CONNECTION_HASH_SIZE - 1) +#ifdef CONFIG_NF_FLOW_COOKIE +#define SFE_FLOW_COOKIE_SIZE 2048 +#define SFE_FLOW_COOKIE_MASK 0x7ff + +struct sfe_flow_cookie_entry { + struct sfe_ipv4_connection_match *match; + unsigned long last_clean_time; +}; +#endif + enum sfe_ipv4_exception_events { SFE_IPV4_EXCEPTION_EVENT_UDP_HEADER_INCOMPLETE, SFE_IPV4_EXCEPTION_EVENT_UDP_NO_CONNECTION, @@ -337,7 +350,7 @@ enum sfe_ipv4_exception_events { SFE_IPV4_EXCEPTION_EVENT_DATAGRAM_INCOMPLETE, SFE_IPV4_EXCEPTION_EVENT_IP_OPTIONS_INCOMPLETE, SFE_IPV4_EXCEPTION_EVENT_UNHANDLED_PROTOCOL, - SFE_IPV4_EXCEPTION_EVENT_CSUM_ERROR, + SFE_IPV4_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR, SFE_IPV4_EXCEPTION_EVENT_LAST }; @@ -378,7 +391,7 @@ static char *sfe_ipv4_exception_events_string[SFE_IPV4_EXCEPTION_EVENT_LAST] = { "DATAGRAM_INCOMPLETE", "IP_OPTIONS_INCOMPLETE", "UNHANDLED_PROTOCOL", - "CSUM_ERROR" + "CLONED_SKB_UNSHARE_ERROR" }; /* @@ -402,6 +415,14 @@ struct sfe_ipv4 { /* Connection hash table */ struct sfe_ipv4_connection_match *conn_match_hash[SFE_IPV4_CONNECTION_HASH_SIZE]; /* Connection match hash table */ +#ifdef CONFIG_NF_FLOW_COOKIE + struct sfe_flow_cookie_entry sfe_flow_cookie_table[SFE_FLOW_COOKIE_SIZE]; + /* flow cookie table*/ + flow_cookie_set_func_t flow_cookie_set_func; + /* function used to configure flow cookie in hardware*/ + int flow_cookie_enable; + /* Enable/disable flow cookie at runtime */ +#endif /* * Stats recorded in a sync period. These stats will be added to @@ -759,6 +780,36 @@ static inline void sfe_ipv4_insert_sfe_ipv4_connection_match(struct sfe_ipv4 *si cm->next = prev_head; *hash_head = cm; + +#ifdef CONFIG_NF_FLOW_COOKIE + if (!si->flow_cookie_enable) + return; + + /* + * Configure hardware to put a flow cookie in packet of this flow, + * then we can accelerate the lookup process when we received this packet. + */ + for (conn_match_idx = 1; conn_match_idx < SFE_FLOW_COOKIE_SIZE; conn_match_idx++) { + struct sfe_flow_cookie_entry *entry = &si->sfe_flow_cookie_table[conn_match_idx]; + + if ((NULL == entry->match) && time_is_before_jiffies(entry->last_clean_time + HZ)) { + flow_cookie_set_func_t func; + + rcu_read_lock(); + func = rcu_dereference(si->flow_cookie_set_func); + if (func) { + if (!func(cm->match_protocol, cm->match_src_ip, cm->match_src_port, + cm->match_dest_ip, cm->match_dest_port, conn_match_idx)) { + entry->match = cm; + cm->flow_cookie = conn_match_idx; + } + } + rcu_read_unlock(); + + break; + } + } +#endif } /* @@ -769,6 +820,36 @@ static inline void sfe_ipv4_insert_sfe_ipv4_connection_match(struct sfe_ipv4 *si */ static inline void sfe_ipv4_remove_sfe_ipv4_connection_match(struct sfe_ipv4 *si, struct sfe_ipv4_connection_match *cm) { +#ifdef CONFIG_NF_FLOW_COOKIE + if (si->flow_cookie_enable) { + /* + * Tell hardware that we no longer need a flow cookie in packet of this flow + */ + unsigned int conn_match_idx; + + for (conn_match_idx = 1; conn_match_idx < SFE_FLOW_COOKIE_SIZE; conn_match_idx++) { + struct sfe_flow_cookie_entry *entry = &si->sfe_flow_cookie_table[conn_match_idx]; + + if (cm == entry->match) { + flow_cookie_set_func_t func; + + rcu_read_lock(); + func = rcu_dereference(si->flow_cookie_set_func); + if (func) { + func(cm->match_protocol, cm->match_src_ip, cm->match_src_port, + cm->match_dest_ip, cm->match_dest_port, 0); + } + rcu_read_unlock(); + + cm->flow_cookie = 0; + entry->match = NULL; + entry->last_clean_time = jiffies; + break; + } + } + } +#endif + /* * Unlink the connection match entry from the hash. */ @@ -1142,7 +1223,14 @@ static int sfe_ipv4_recv_udp(struct sfe_ipv4 *si, struct sk_buff *skb, struct ne /* * Look for a connection match. */ +#ifdef CONFIG_NF_FLOW_COOKIE + cm = si->sfe_flow_cookie_table[skb->flow_cookie & SFE_FLOW_COOKIE_MASK].match; + if (unlikely(!cm)) { + cm = sfe_ipv4_find_sfe_ipv4_connection_match(si, dev, IPPROTO_UDP, src_ip, src_port, dest_ip, dest_port); + } +#else cm = sfe_ipv4_find_sfe_ipv4_connection_match(si, dev, IPPROTO_UDP, src_ip, src_port, dest_ip, dest_port); +#endif if (unlikely(!cm)) { si->exception_events[SFE_IPV4_EXCEPTION_EVENT_UDP_NO_CONNECTION]++; si->packets_not_forwarded++; @@ -1217,6 +1305,30 @@ static int sfe_ipv4_recv_udp(struct sfe_ipv4 *si, struct sk_buff *skb, struct ne * From this point on we're good to modify the packet. */ + /* + * Check if skb was cloned. If it was, unshare it. Because + * the data area is going to be written in this path and we don't want to + * change the cloned skb's data section. + */ + if (unlikely(skb_cloned(skb))) { + DEBUG_TRACE("%p: skb is a cloned skb\n", skb); + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) { + DEBUG_WARN("Failed to unshare the cloned skb\n"); + si->exception_events[SFE_IPV4_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR]++; + si->packets_not_forwarded++; + spin_unlock_bh(&si->lock); + + return 0; + } + + /* + * Update the iph and udph pointers with the unshared skb's data area. + */ + iph = (struct sfe_ipv4_ip_hdr *)skb->data; + udph = (struct sfe_ipv4_udp_hdr *)(skb->data + ihl); + } + /* * Update DSCP */ @@ -1502,7 +1614,14 @@ static int sfe_ipv4_recv_tcp(struct sfe_ipv4 *si, struct sk_buff *skb, struct ne /* * Look for a connection match. */ +#ifdef CONFIG_NF_FLOW_COOKIE + cm = si->sfe_flow_cookie_table[skb->flow_cookie & SFE_FLOW_COOKIE_MASK].match; + if (unlikely(!cm)) { + cm = sfe_ipv4_find_sfe_ipv4_connection_match(si, dev, IPPROTO_TCP, src_ip, src_port, dest_ip, dest_port); + } +#else cm = sfe_ipv4_find_sfe_ipv4_connection_match(si, dev, IPPROTO_TCP, src_ip, src_port, dest_ip, dest_port); +#endif if (unlikely(!cm)) { /* * We didn't get a connection but as TCP is connection-oriented that @@ -1766,6 +1885,30 @@ static int sfe_ipv4_recv_tcp(struct sfe_ipv4 *si, struct sk_buff *skb, struct ne * From this point on we're good to modify the packet. */ + /* + * Check if skb was cloned. If it was, unshare it. Because + * the data area is going to be written in this path and we don't want to + * change the cloned skb's data section. + */ + if (unlikely(skb_cloned(skb))) { + DEBUG_TRACE("%p: skb is a cloned skb\n", skb); + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) { + DEBUG_WARN("Failed to unshare the cloned skb\n"); + si->exception_events[SFE_IPV4_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR]++; + si->packets_not_forwarded++; + spin_unlock_bh(&si->lock); + + return 0; + } + + /* + * Update the iph and tcph pointers with the unshared skb's data area. + */ + iph = (struct sfe_ipv4_ip_hdr *)skb->data; + tcph = (struct sfe_ipv4_tcp_hdr *)(skb->data + ihl); + } + /* * Update DSCP */ @@ -2225,16 +2368,6 @@ int sfe_ipv4_recv(struct net_device *dev, struct sk_buff *skb) flush_on_find = true; } - if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) { - spin_lock_bh(&si->lock); - si->exception_events[SFE_IPV4_EXCEPTION_EVENT_CSUM_ERROR]++; - si->packets_not_forwarded++; - spin_unlock_bh(&si->lock); - - DEBUG_TRACE("checksum of ipv4 header is invalid\n"); - return 0; - } - protocol = iph->protocol; if (IPPROTO_UDP == protocol) { return sfe_ipv4_recv_udp(si, skb, dev, len, iph, ihl, flush_on_find); @@ -2445,6 +2578,9 @@ int sfe_ipv4_create_rule(struct sfe_connection_create *sic) original_cm->dscp = sic->src_dscp << SFE_IPV4_DSCP_SHIFT; original_cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_DSCP_REMARK; } +#ifdef CONFIG_NF_FLOW_COOKIE + original_cm->flow_cookie = 0; +#endif #ifdef CONFIG_XFRM original_cm->flow_accel = sic->original_accel; #endif @@ -2501,6 +2637,9 @@ int sfe_ipv4_create_rule(struct sfe_connection_create *sic) reply_cm->dscp = sic->dest_dscp << SFE_IPV4_DSCP_SHIFT; reply_cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_DSCP_REMARK; } +#ifdef CONFIG_NF_FLOW_COOKIE + reply_cm->flow_cookie = 0; +#endif #ifdef CONFIG_XFRM reply_cm->flow_accel = sic->reply_accel; #endif @@ -2719,9 +2858,17 @@ another_round: /* * sfe_ipv4_periodic_sync() */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +static void sfe_ipv4_periodic_sync(struct timer_list *arg) +#else static void sfe_ipv4_periodic_sync(unsigned long arg) +#endif /*KERNEL_VERSION(4, 15, 0)*/ { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + struct sfe_ipv4 *si = (struct sfe_ipv4 *)arg->cust_data; +#else struct sfe_ipv4 *si = (struct sfe_ipv4 *)arg; +#endif /*KERNEL_VERSION(4, 15, 0)*/ u64 now_jiffies; int quota; sfe_sync_rule_callback_t sync_rule_callback; @@ -2889,6 +3036,9 @@ static bool sfe_ipv4_debug_dev_read_connections_connection(struct sfe_ipv4 *si, u64 dest_rx_bytes; u64 last_sync_jiffies; u32 mark, src_priority, dest_priority, src_dscp, dest_dscp; +#ifdef CONFIG_NF_FLOW_COOKIE + int src_flow_cookie, dst_flow_cookie; +#endif spin_lock_bh(&si->lock); @@ -2936,7 +3086,10 @@ static bool sfe_ipv4_debug_dev_read_connections_connection(struct sfe_ipv4 *si, dest_rx_bytes = reply_cm->rx_byte_count64; last_sync_jiffies = get_jiffies_64() - c->last_sync_jiffies; mark = c->mark; - +#ifdef CONFIG_NF_FLOW_COOKIE + src_flow_cookie = original_cm->flow_cookie; + dst_flow_cookie = reply_cm->flow_cookie; +#endif spin_unlock_bh(&si->lock); bytes_read = snprintf(msg, CHAR_DEV_MSG_SIZE, "\t\t\n", protocol, @@ -2964,6 +3120,9 @@ static bool sfe_ipv4_debug_dev_read_connections_connection(struct sfe_ipv4 *si, ntohs(dest_port), ntohs(dest_port_xlate), dest_priority, dest_dscp, dest_rx_packets, dest_rx_bytes, +#ifdef CONFIG_NF_FLOW_COOKIE + src_flow_cookie, dst_flow_cookie, +#endif last_sync_jiffies, mark); if (copy_to_user(buffer + *total_read, msg, CHAR_DEV_MSG_SIZE)) { @@ -3270,6 +3429,74 @@ static struct file_operations sfe_ipv4_debug_dev_fops = { .release = sfe_ipv4_debug_dev_release }; +#ifdef CONFIG_NF_FLOW_COOKIE +/* + * sfe_register_flow_cookie_cb + * register a function in SFE to let SFE use this function to configure flow cookie for a flow + * + * Hardware driver which support flow cookie should register a callback function in SFE. Then SFE + * can use this function to configure flow cookie for a flow. + * return: 0, success; !=0, fail + */ +int sfe_register_flow_cookie_cb(flow_cookie_set_func_t cb) +{ + struct sfe_ipv4 *si = &__si; + + BUG_ON(!cb); + + if (si->flow_cookie_set_func) { + return -1; + } + + rcu_assign_pointer(si->flow_cookie_set_func, cb); + return 0; +} + +/* + * sfe_unregister_flow_cookie_cb + * unregister function which is used to configure flow cookie for a flow + * + * return: 0, success; !=0, fail + */ +int sfe_unregister_flow_cookie_cb(flow_cookie_set_func_t cb) +{ + struct sfe_ipv4 *si = &__si; + + RCU_INIT_POINTER(si->flow_cookie_set_func, NULL); + return 0; +} + +/* + * sfe_ipv4_get_flow_cookie() + */ +static ssize_t sfe_ipv4_get_flow_cookie(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sfe_ipv4 *si = &__si; + return snprintf(buf, (ssize_t)PAGE_SIZE, "%d\n", si->flow_cookie_enable); +} + +/* + * sfe_ipv4_set_flow_cookie() + */ +static ssize_t sfe_ipv4_set_flow_cookie(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct sfe_ipv4 *si = &__si; + strict_strtol(buf, 0, (long int *)&si->flow_cookie_enable); + + return size; +} + +/* + * sysfs attributes. + */ +static const struct device_attribute sfe_ipv4_flow_cookie_attr = + __ATTR(flow_cookie_enable, S_IWUSR | S_IRUGO, sfe_ipv4_get_flow_cookie, sfe_ipv4_set_flow_cookie); +#endif /*CONFIG_NF_FLOW_COOKIE*/ + /* * sfe_ipv4_init() */ @@ -3298,13 +3525,21 @@ static int __init sfe_ipv4_init(void) goto exit2; } +#ifdef CONFIG_NF_FLOW_COOKIE + result = sysfs_create_file(si->sys_sfe_ipv4, &sfe_ipv4_flow_cookie_attr.attr); + if (result) { + DEBUG_ERROR("failed to register flow cookie enable file: %d\n", result); + goto exit3; + } +#endif /* CONFIG_NF_FLOW_COOKIE */ + /* * Register our debug char device. */ result = register_chrdev(0, "sfe_ipv4", &sfe_ipv4_debug_dev_fops); if (result < 0) { DEBUG_ERROR("Failed to register chrdev: %d\n", result); - goto exit3; + goto exit4; } si->debug_dev = result; @@ -3312,14 +3547,24 @@ static int __init sfe_ipv4_init(void) /* * Create a timer to handle periodic statistics. */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + timer_setup(&si->timer, sfe_ipv4_periodic_sync, 0); + si->timer.cust_data = (unsigned long)si; +#else setup_timer(&si->timer, sfe_ipv4_periodic_sync, (unsigned long)si); +#endif /*KERNEL_VERSION(4, 15, 0)*/ mod_timer(&si->timer, jiffies + ((HZ + 99) / 100)); spin_lock_init(&si->lock); return 0; +exit4: +#ifdef CONFIG_NF_FLOW_COOKIE + sysfs_remove_file(si->sys_sfe_ipv4, &sfe_ipv4_flow_cookie_attr.attr); + exit3: +#endif /* CONFIG_NF_FLOW_COOKIE */ sysfs_remove_file(si->sys_sfe_ipv4, &sfe_ipv4_debug_dev_attr.attr); exit2: @@ -3347,6 +3592,9 @@ static void __exit sfe_ipv4_exit(void) unregister_chrdev(si->debug_dev, "sfe_ipv4"); +#ifdef CONFIG_NF_FLOW_COOKIE + sysfs_remove_file(si->sys_sfe_ipv4, &sfe_ipv4_flow_cookie_attr.attr); +#endif /* CONFIG_NF_FLOW_COOKIE */ sysfs_remove_file(si->sys_sfe_ipv4, &sfe_ipv4_debug_dev_attr.attr); kobject_put(si->sys_sfe_ipv4); @@ -3363,6 +3611,10 @@ EXPORT_SYMBOL(sfe_ipv4_destroy_all_rules_for_dev); EXPORT_SYMBOL(sfe_ipv4_register_sync_rule_callback); EXPORT_SYMBOL(sfe_ipv4_mark_rule); EXPORT_SYMBOL(sfe_ipv4_update_rule); +#ifdef CONFIG_NF_FLOW_COOKIE +EXPORT_SYMBOL(sfe_register_flow_cookie_cb); +EXPORT_SYMBOL(sfe_unregister_flow_cookie_cb); +#endif MODULE_DESCRIPTION("Shortcut Forwarding Engine - IPv4 edition"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/lean/shortcut-fe/src/sfe_ipv6.c b/package/lean/shortcut-fe/src/sfe_ipv6.c index 16f460723a..3c5ef12630 100644 --- a/package/lean/shortcut-fe/src/sfe_ipv6.c +++ b/package/lean/shortcut-fe/src/sfe_ipv6.c @@ -2,7 +2,7 @@ * sfe_ipv6.c * Shortcut forwarding engine - IPv6 support. * - * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, 2019, The Linux Foundation. All rights reserved. * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. @@ -21,6 +21,7 @@ #include #include #include +#include #include "sfe.h" #include "sfe_cm.h" @@ -37,7 +38,7 @@ */ #define SFE_IPV6_UNALIGNED_IP_HEADER 1 #if SFE_IPV6_UNALIGNED_IP_HEADER -#define SFE_IPV6_UNALIGNED_STRUCT __attribute__((aligned(4))) +#define SFE_IPV6_UNALIGNED_STRUCT __attribute__((packed)) #else #define SFE_IPV6_UNALIGNED_STRUCT #endif @@ -231,6 +232,9 @@ struct sfe_ipv6_connection_match { * Control the operations of the match. */ u32 flags; /* Bit flags */ +#ifdef CONFIG_NF_FLOW_COOKIE + u32 flow_cookie; /* used flow cookie, for debug */ +#endif #ifdef CONFIG_XFRM u32 flow_accel; /* The flow accelerated or not */ #endif @@ -324,6 +328,16 @@ struct sfe_ipv6_connection { #define SFE_IPV6_CONNECTION_HASH_SIZE (1 << SFE_IPV6_CONNECTION_HASH_SHIFT) #define SFE_IPV6_CONNECTION_HASH_MASK (SFE_IPV6_CONNECTION_HASH_SIZE - 1) +#ifdef CONFIG_NF_FLOW_COOKIE +#define SFE_FLOW_COOKIE_SIZE 2048 +#define SFE_FLOW_COOKIE_MASK 0x7ff + +struct sfe_ipv6_flow_cookie_entry { + struct sfe_ipv6_connection_match *match; + unsigned long last_clean_time; +}; +#endif + enum sfe_ipv6_exception_events { SFE_IPV6_EXCEPTION_EVENT_UDP_HEADER_INCOMPLETE, SFE_IPV6_EXCEPTION_EVENT_UDP_NO_CONNECTION, @@ -362,6 +376,7 @@ enum sfe_ipv6_exception_events { SFE_IPV6_EXCEPTION_EVENT_IP_OPTIONS_INCOMPLETE, SFE_IPV6_EXCEPTION_EVENT_UNHANDLED_PROTOCOL, SFE_IPV6_EXCEPTION_EVENT_FLOW_COOKIE_ADD_FAIL, + SFE_IPV6_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR, SFE_IPV6_EXCEPTION_EVENT_LAST }; @@ -402,7 +417,8 @@ static char *sfe_ipv6_exception_events_string[SFE_IPV6_EXCEPTION_EVENT_LAST] = { "DATAGRAM_INCOMPLETE", "IP_OPTIONS_INCOMPLETE", "UNHANDLED_PROTOCOL", - "FLOW_COOKIE_ADD_FAIL" + "FLOW_COOKIE_ADD_FAIL", + "CLONED_SKB_UNSHARE_ERROR" }; /* @@ -426,6 +442,14 @@ struct sfe_ipv6 { /* Connection hash table */ struct sfe_ipv6_connection_match *conn_match_hash[SFE_IPV6_CONNECTION_HASH_SIZE]; /* Connection match hash table */ +#ifdef CONFIG_NF_FLOW_COOKIE + struct sfe_ipv6_flow_cookie_entry sfe_flow_cookie_table[SFE_FLOW_COOKIE_SIZE]; + /* flow cookie table*/ + sfe_ipv6_flow_cookie_set_func_t flow_cookie_set_func; + /* function used to configure flow cookie in hardware*/ + int flow_cookie_enable; + /* Enable/disable flow cookie at runtime */ +#endif /* * Stats recorded in a sync period. These stats will be added to @@ -809,6 +833,38 @@ static inline void sfe_ipv6_insert_connection_match(struct sfe_ipv6 *si, cm->next = prev_head; *hash_head = cm; + +#ifdef CONFIG_NF_FLOW_COOKIE + if (!si->flow_cookie_enable || !(cm->flags & (SFE_IPV6_CONNECTION_MATCH_FLAG_XLATE_SRC | SFE_IPV6_CONNECTION_MATCH_FLAG_XLATE_DEST))) + return; + + /* + * Configure hardware to put a flow cookie in packet of this flow, + * then we can accelerate the lookup process when we received this packet. + */ + for (conn_match_idx = 1; conn_match_idx < SFE_FLOW_COOKIE_SIZE; conn_match_idx++) { + struct sfe_ipv6_flow_cookie_entry *entry = &si->sfe_flow_cookie_table[conn_match_idx]; + + if ((NULL == entry->match) && time_is_before_jiffies(entry->last_clean_time + HZ)) { + sfe_ipv6_flow_cookie_set_func_t func; + + rcu_read_lock(); + func = rcu_dereference(si->flow_cookie_set_func); + if (func) { + if (!func(cm->match_protocol, cm->match_src_ip->addr, cm->match_src_port, + cm->match_dest_ip->addr, cm->match_dest_port, conn_match_idx)) { + entry->match = cm; + cm->flow_cookie = conn_match_idx; + } else { + si->exception_events[SFE_IPV6_EXCEPTION_EVENT_FLOW_COOKIE_ADD_FAIL]++; + } + } + rcu_read_unlock(); + + break; + } + } +#endif } /* @@ -819,6 +875,36 @@ static inline void sfe_ipv6_insert_connection_match(struct sfe_ipv6 *si, */ static inline void sfe_ipv6_remove_connection_match(struct sfe_ipv6 *si, struct sfe_ipv6_connection_match *cm) { +#ifdef CONFIG_NF_FLOW_COOKIE + if (si->flow_cookie_enable) { + /* + * Tell hardware that we no longer need a flow cookie in packet of this flow + */ + unsigned int conn_match_idx; + + for (conn_match_idx = 1; conn_match_idx < SFE_FLOW_COOKIE_SIZE; conn_match_idx++) { + struct sfe_ipv6_flow_cookie_entry *entry = &si->sfe_flow_cookie_table[conn_match_idx]; + + if (cm == entry->match) { + sfe_ipv6_flow_cookie_set_func_t func; + + rcu_read_lock(); + func = rcu_dereference(si->flow_cookie_set_func); + if (func) { + func(cm->match_protocol, cm->match_src_ip->addr, cm->match_src_port, + cm->match_dest_ip->addr, cm->match_dest_port, 0); + } + rcu_read_unlock(); + + cm->flow_cookie = 0; + entry->match = NULL; + entry->last_clean_time = jiffies; + break; + } + } + } +#endif + /* * Unlink the connection match entry from the hash. */ @@ -1196,7 +1282,14 @@ static int sfe_ipv6_recv_udp(struct sfe_ipv6 *si, struct sk_buff *skb, struct ne /* * Look for a connection match. */ +#ifdef CONFIG_NF_FLOW_COOKIE + cm = si->sfe_flow_cookie_table[skb->flow_cookie & SFE_FLOW_COOKIE_MASK].match; + if (unlikely(!cm)) { + cm = sfe_ipv6_find_connection_match(si, dev, IPPROTO_UDP, src_ip, src_port, dest_ip, dest_port); + } +#else cm = sfe_ipv6_find_connection_match(si, dev, IPPROTO_UDP, src_ip, src_port, dest_ip, dest_port); +#endif if (unlikely(!cm)) { si->exception_events[SFE_IPV6_EXCEPTION_EVENT_UDP_NO_CONNECTION]++; si->packets_not_forwarded++; @@ -1270,6 +1363,30 @@ static int sfe_ipv6_recv_udp(struct sfe_ipv6 *si, struct sk_buff *skb, struct ne * From this point on we're good to modify the packet. */ + /* + * Check if skb was cloned. If it was, unshare it. Because + * the data area is going to be written in this path and we don't want to + * change the cloned skb's data section. + */ + if (unlikely(skb_cloned(skb))) { + DEBUG_TRACE("%p: skb is a cloned skb\n", skb); + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) { + DEBUG_WARN("Failed to unshare the cloned skb\n"); + si->exception_events[SFE_IPV6_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR]++; + si->packets_not_forwarded++; + spin_unlock_bh(&si->lock); + + return 0; + } + + /* + * Update the iph and udph pointers with the unshared skb's data area. + */ + iph = (struct sfe_ipv6_ip_hdr *)skb->data; + udph = (struct sfe_ipv6_udp_hdr *)(skb->data + ihl); + } + /* * Update DSCP */ @@ -1535,7 +1652,14 @@ static int sfe_ipv6_recv_tcp(struct sfe_ipv6 *si, struct sk_buff *skb, struct ne /* * Look for a connection match. */ +#ifdef CONFIG_NF_FLOW_COOKIE + cm = si->sfe_flow_cookie_table[skb->flow_cookie & SFE_FLOW_COOKIE_MASK].match; + if (unlikely(!cm)) { + cm = sfe_ipv6_find_connection_match(si, dev, IPPROTO_TCP, src_ip, src_port, dest_ip, dest_port); + } +#else cm = sfe_ipv6_find_connection_match(si, dev, IPPROTO_TCP, src_ip, src_port, dest_ip, dest_port); +#endif if (unlikely(!cm)) { /* * We didn't get a connection but as TCP is connection-oriented that @@ -1799,6 +1923,30 @@ static int sfe_ipv6_recv_tcp(struct sfe_ipv6 *si, struct sk_buff *skb, struct ne * From this point on we're good to modify the packet. */ + /* + * Check if skb was cloned. If it was, unshare it. Because + * the data area is going to be written in this path and we don't want to + * change the cloned skb's data section. + */ + if (unlikely(skb_cloned(skb))) { + DEBUG_TRACE("%p: skb is a cloned skb\n", skb); + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) { + DEBUG_WARN("Failed to unshare the cloned skb\n"); + si->exception_events[SFE_IPV6_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR]++; + si->packets_not_forwarded++; + spin_unlock_bh(&si->lock); + + return 0; + } + + /* + * Update the iph and tcph pointers with the unshared skb's data area. + */ + iph = (struct sfe_ipv6_ip_hdr *)skb->data; + tcph = (struct sfe_ipv6_tcp_hdr *)(skb->data + ihl); + } + /* * Update DSCP */ @@ -2444,6 +2592,9 @@ int sfe_ipv6_create_rule(struct sfe_connection_create *sic) original_cm->dscp = sic->src_dscp << SFE_IPV6_DSCP_SHIFT; original_cm->flags |= SFE_IPV6_CONNECTION_MATCH_FLAG_DSCP_REMARK; } +#ifdef CONFIG_NF_FLOW_COOKIE + original_cm->flow_cookie = 0; +#endif #ifdef CONFIG_XFRM original_cm->flow_accel = sic->original_accel; #endif @@ -2500,6 +2651,9 @@ int sfe_ipv6_create_rule(struct sfe_connection_create *sic) reply_cm->dscp = sic->dest_dscp << SFE_IPV6_DSCP_SHIFT; reply_cm->flags |= SFE_IPV6_CONNECTION_MATCH_FLAG_DSCP_REMARK; } +#ifdef CONFIG_NF_FLOW_COOKIE + reply_cm->flow_cookie = 0; +#endif #ifdef CONFIG_XFRM reply_cm->flow_accel = sic->reply_accel; #endif @@ -2712,9 +2866,17 @@ another_round: /* * sfe_ipv6_periodic_sync() */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +static void sfe_ipv6_periodic_sync(struct timer_list *arg) +#else static void sfe_ipv6_periodic_sync(unsigned long arg) +#endif /*KERNEL_VERSION(4, 15, 0)*/ { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + struct sfe_ipv6 *si = (struct sfe_ipv6 *)arg->cust_data; +#else struct sfe_ipv6 *si = (struct sfe_ipv6 *)arg; +#endif /*KERNEL_VERSION(4, 15, 0)*/ u64 now_jiffies; int quota; sfe_sync_rule_callback_t sync_rule_callback; @@ -2880,6 +3042,9 @@ static bool sfe_ipv6_debug_dev_read_connections_connection(struct sfe_ipv6 *si, u64 dest_rx_bytes; u64 last_sync_jiffies; u32 mark, src_priority, dest_priority, src_dscp, dest_dscp; +#ifdef CONFIG_NF_FLOW_COOKIE + int src_flow_cookie, dst_flow_cookie; +#endif spin_lock_bh(&si->lock); @@ -2927,7 +3092,10 @@ static bool sfe_ipv6_debug_dev_read_connections_connection(struct sfe_ipv6 *si, dest_rx_bytes = reply_cm->rx_byte_count64; last_sync_jiffies = get_jiffies_64() - c->last_sync_jiffies; mark = c->mark; - +#ifdef CONFIG_NF_FLOW_COOKIE + src_flow_cookie = original_cm->flow_cookie; + dst_flow_cookie = reply_cm->flow_cookie; +#endif spin_unlock_bh(&si->lock); bytes_read = snprintf(msg, CHAR_DEV_MSG_SIZE, "\t\t\n", protocol, @@ -2955,6 +3126,9 @@ static bool sfe_ipv6_debug_dev_read_connections_connection(struct sfe_ipv6 *si, ntohs(dest_port), ntohs(dest_port_xlate), dest_priority, dest_dscp, dest_rx_packets, dest_rx_bytes, +#ifdef CONFIG_NF_FLOW_COOKIE + src_flow_cookie, dst_flow_cookie, +#endif last_sync_jiffies, mark); if (copy_to_user(buffer + *total_read, msg, CHAR_DEV_MSG_SIZE)) { @@ -3263,6 +3437,74 @@ static struct file_operations sfe_ipv6_debug_dev_fops = { .release = sfe_ipv6_debug_dev_release }; +#ifdef CONFIG_NF_FLOW_COOKIE +/* + * sfe_ipv6_register_flow_cookie_cb + * register a function in SFE to let SFE use this function to configure flow cookie for a flow + * + * Hardware driver which support flow cookie should register a callback function in SFE. Then SFE + * can use this function to configure flow cookie for a flow. + * return: 0, success; !=0, fail + */ +int sfe_ipv6_register_flow_cookie_cb(sfe_ipv6_flow_cookie_set_func_t cb) +{ + struct sfe_ipv6 *si = &__si6; + + BUG_ON(!cb); + + if (si->flow_cookie_set_func) { + return -1; + } + + rcu_assign_pointer(si->flow_cookie_set_func, cb); + return 0; +} + +/* + * sfe_ipv6_unregister_flow_cookie_cb + * unregister function which is used to configure flow cookie for a flow + * + * return: 0, success; !=0, fail + */ +int sfe_ipv6_unregister_flow_cookie_cb(sfe_ipv6_flow_cookie_set_func_t cb) +{ + struct sfe_ipv6 *si = &__si6; + + RCU_INIT_POINTER(si->flow_cookie_set_func, NULL); + return 0; +} + +/* + * sfe_ipv6_get_flow_cookie() + */ +static ssize_t sfe_ipv6_get_flow_cookie(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sfe_ipv6 *si = &__si6; + return snprintf(buf, (ssize_t)PAGE_SIZE, "%d\n", si->flow_cookie_enable); +} + +/* + * sfe_ipv6_set_flow_cookie() + */ +static ssize_t sfe_ipv6_set_flow_cookie(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct sfe_ipv6 *si = &__si6; + strict_strtol(buf, 0, (long int *)&si->flow_cookie_enable); + + return size; +} + +/* + * sysfs attributes. + */ +static const struct device_attribute sfe_ipv6_flow_cookie_attr = + __ATTR(flow_cookie_enable, S_IWUSR | S_IRUGO, sfe_ipv6_get_flow_cookie, sfe_ipv6_set_flow_cookie); +#endif /*CONFIG_NF_FLOW_COOKIE*/ + /* * sfe_ipv6_init() */ @@ -3291,13 +3533,21 @@ static int __init sfe_ipv6_init(void) goto exit2; } +#ifdef CONFIG_NF_FLOW_COOKIE + result = sysfs_create_file(si->sys_sfe_ipv6, &sfe_ipv6_flow_cookie_attr.attr); + if (result) { + DEBUG_ERROR("failed to register flow cookie enable file: %d\n", result); + goto exit3; + } +#endif /* CONFIG_NF_FLOW_COOKIE */ + /* * Register our debug char device. */ result = register_chrdev(0, "sfe_ipv6", &sfe_ipv6_debug_dev_fops); if (result < 0) { DEBUG_ERROR("Failed to register chrdev: %d\n", result); - goto exit3; + goto exit4; } si->debug_dev = result; @@ -3305,14 +3555,24 @@ static int __init sfe_ipv6_init(void) /* * Create a timer to handle periodic statistics. */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + timer_setup(&si->timer, sfe_ipv6_periodic_sync, 0); + si->timer.cust_data = (unsigned long)si; +#else setup_timer(&si->timer, sfe_ipv6_periodic_sync, (unsigned long)si); +#endif /*KERNEL_VERSION(4, 15, 0)*/ mod_timer(&si->timer, jiffies + ((HZ + 99) / 100)); spin_lock_init(&si->lock); return 0; +exit4: +#ifdef CONFIG_NF_FLOW_COOKIE + sysfs_remove_file(si->sys_sfe_ipv6, &sfe_ipv6_flow_cookie_attr.attr); + exit3: +#endif /* CONFIG_NF_FLOW_COOKIE */ sysfs_remove_file(si->sys_sfe_ipv6, &sfe_ipv6_debug_dev_attr.attr); exit2: @@ -3340,6 +3600,9 @@ static void __exit sfe_ipv6_exit(void) unregister_chrdev(si->debug_dev, "sfe_ipv6"); +#ifdef CONFIG_NF_FLOW_COOKIE + sysfs_remove_file(si->sys_sfe_ipv6, &sfe_ipv6_flow_cookie_attr.attr); +#endif /* CONFIG_NF_FLOW_COOKIE */ sysfs_remove_file(si->sys_sfe_ipv6, &sfe_ipv6_debug_dev_attr.attr); kobject_put(si->sys_sfe_ipv6); @@ -3355,6 +3618,10 @@ EXPORT_SYMBOL(sfe_ipv6_destroy_all_rules_for_dev); EXPORT_SYMBOL(sfe_ipv6_register_sync_rule_callback); EXPORT_SYMBOL(sfe_ipv6_mark_rule); EXPORT_SYMBOL(sfe_ipv6_update_rule); +#ifdef CONFIG_NF_FLOW_COOKIE +EXPORT_SYMBOL(sfe_ipv6_register_flow_cookie_cb); +EXPORT_SYMBOL(sfe_ipv6_unregister_flow_cookie_cb); +#endif MODULE_DESCRIPTION("Shortcut Forwarding Engine - IPv6 support"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/lean/v2ray/Config.in b/package/lean/v2ray/Config.in index 60700ede5b..3f13ba2057 100644 --- a/package/lean/v2ray/Config.in +++ b/package/lean/v2ray/Config.in @@ -3,7 +3,7 @@ menu "V2Ray Configuration" config V2RAY_COMPRESS_GOPROXY bool "Compiling with GOPROXY proxy" - default n + default y choice prompt "JSON Config Support" diff --git a/package/lienol/redsocks2/Makefile b/package/lienol/redsocks2/Makefile index fbede3435f..27e29caad2 100644 --- a/package/lienol/redsocks2/Makefile +++ b/package/lienol/redsocks2/Makefile @@ -10,12 +10,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=redsocks2 PKG_VERSION:=0.67 -PKG_RELEASE:=2 +PKG_RELEASE:=4 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/semigodking/redsocks.git PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=53cad23a14afdd5f61a0542615beb7f4d98be728 +PKG_SOURCE_VERSION:=d94c245ea47859cda5b4b7373308589206b97bdc PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) @@ -37,6 +37,14 @@ The name is changed to be REDSOCKS2 since this release to distinguish with origi This variant is useful for anti-GFW (Great Fire Wall). endef +define Package/redsocks2/conffiles +/etc/config/redsocks2 +endef + +define Build/Compile + $(call Build/Compile/Default,DISABLE_SHADOWSOCKS=true) +endef + define Package/redsocks2/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) $(PKG_BUILD_DIR)/redsocks2 $(1)/usr/sbin diff --git a/package/lienol/redsocks2/patches/000-fix-compatible-with-openssl-1.1.x.patch b/package/lienol/redsocks2/patches/000-fix-compatible-with-openssl-1.1.x.patch deleted file mode 100644 index aefbc21054..0000000000 --- a/package/lienol/redsocks2/patches/000-fix-compatible-with-openssl-1.1.x.patch +++ /dev/null @@ -1,315 +0,0 @@ -diff --git a/encrypt.c b/encrypt.c -index ce04c6f..dc27754 100644 ---- a/encrypt.c -+++ b/encrypt.c -@@ -278,7 +278,7 @@ static void enc_table_init(enc_info * info, const char *pass) - } - } - --int cipher_iv_size(const cipher_kt_t *cipher) -+int cipher_iv_size(const cipher_t *cipher) - { - #if defined(USE_CRYPTO_OPENSSL) - return EVP_CIPHER_iv_length(cipher); -@@ -290,7 +290,7 @@ int cipher_iv_size(const cipher_kt_t *cipher) - #endif - } - --int cipher_key_size(const cipher_kt_t *cipher) -+int cipher_key_size(const cipher_t *cipher) - { - #if defined(USE_CRYPTO_OPENSSL) - return EVP_CIPHER_key_length(cipher); -@@ -307,102 +307,66 @@ int cipher_key_size(const cipher_kt_t *cipher) - #endif - } - --int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, -- const uint8_t *pass, uint8_t *key, uint8_t *iv) -+int bytes_to_key(const cipher_t *cipher, const digest_type_t *md, -+ const uint8_t *pass, uint8_t *key) - { - size_t datal; - datal = strlen((const char *)pass); - #if defined(USE_CRYPTO_OPENSSL) -- return EVP_BytesToKey(cipher, md, NULL, pass, datal, 1, key, iv); -+ MD5_CTX c; -+ unsigned char md_buf[MAX_MD_SIZE]; -+ int nkey; -+ int addmd; -+ unsigned int i, j, mds; -+ -+ mds = 16; -+ if (pass == NULL) return nkey; -+ memset(&c, 0, sizeof(MD5_CTX)); -+ -+ for (j = 0, addmd = 0; j < nkey; addmd++) { -+ MD5_Init(&c); -+ if (addmd) { -+ MD5_Update(&c, md_buf, mds); -+ } -+ MD5_Update(&c, pass, datal); -+ MD5_Final(md_buf, &c); -+ -+ for (i = 0; i < mds; i++, j++) { -+ if (j >= nkey) break; -+ key[j] = md_buf[i]; -+ } -+ } -+ return nkey; - #elif defined(USE_CRYPTO_POLARSSL) - md_context_t c; - unsigned char md_buf[MAX_MD_SIZE]; -- int niv; - int nkey; - int addmd; -- unsigned int mds; -- unsigned int i; -- int rv; -+ unsigned int i, j, mds; - - nkey = cipher_key_size(cipher); -- niv = cipher_iv_size(cipher); -- rv = nkey; -- if (pass == NULL) { -- return nkey; -- } -- -+ mds = md_get_size(md); - memset(&c, 0, sizeof(md_context_t)); -- if (md_init_ctx(&c, md)) { -- return 0; -- } -- addmd = 0; -- mds = md_get_size(md); -- for (;; ) { -- int error; -- do { -- error = 1; -- if (md_starts(&c)) { -- break; -- } -- if (addmd) { -- if (md_update(&c, &(md_buf[0]), mds)) { -- break; -- } -- } else { -- addmd = 1; -- } -- if (md_update(&c, pass, datal)) { -- break; -- } -- if (md_finish(&c, &(md_buf[0]))) { -- break; -- } -- error = 0; -- } while (0); -- if (error) { -- md_free_ctx(&c); -- memset(md_buf, 0, MAX_MD_SIZE); -- return 0; -- } - -- i = 0; -- if (nkey) { -- for (;; ) { -- if (nkey == 0) { -- break; -- } -- if (i == mds) { -- break; -- } -- if (key != NULL) { -- *(key++) = md_buf[i]; -- } -- nkey--; -- i++; -- } -- } -- if (niv && (i != mds)) { -- for (;; ) { -- if (niv == 0) { -- break; -- } -- if (i == mds) { -- break; -- } -- if (iv != NULL) { -- *(iv++) = md_buf[i]; -- } -- niv--; -- i++; -- } -+ if (pass == NULL) return nkey; -+ if (md_init_ctx(&c, md)) return 0; -+ -+ for (j = 0, addmd = 0; j < nkey; addmd++) { -+ md_starts(&c); -+ if (addmd) { -+ md_update(&c, md_buf, mds); - } -- if ((nkey == 0) && (niv == 0)) { -- break; -+ md_update(&c, pass, datal); -+ md_finish(&c, md_buf); -+ -+ for (i = 0; i < mds; i++, j++) { -+ if (j >= nkey) break; -+ key[j] = md_buf[i]; - } - } -+ - md_free_ctx(&c); -- memset(md_buf, 0, MAX_MD_SIZE); -- return rv; -+ return nkey; - #endif - } - -@@ -472,7 +436,7 @@ int rand_bytes(uint8_t *output, int len) - #endif - } - --const cipher_kt_t *get_cipher_type(int method) -+const cipher_t *get_cipher_type(int method) - { - if (method <= TABLE || method >= CIPHER_NUM) { - //LOGE("get_cipher_type(): Illegal method"); -@@ -548,7 +512,7 @@ static int cipher_context_init(const enc_info * info, cipher_ctx_t *ctx, int enc - #endif - - cipher_evp_t *evp = &ctx->evp; -- const cipher_kt_t *cipher = get_cipher_type(method); -+ const cipher_t *cipher = get_cipher_type(method); - #if defined(USE_CRYPTO_OPENSSL) - if (cipher == NULL) { - // Cipher is not found in OpenSSL library -@@ -560,7 +524,7 @@ static int cipher_context_init(const enc_info * info, cipher_ctx_t *ctx, int enc - return -1; - } - if (!EVP_CIPHER_CTX_set_key_length(evp, info->key_len)) { -- EVP_CIPHER_CTX_cleanup(evp); -+ EVP_CIPHER_CTX_free(ctx->evp); - // Invalid key length - return -1; - } -@@ -649,7 +613,7 @@ static void cipher_context_set_iv(const enc_info * info, cipher_ctx_t *ctx, uint - } - #if defined(USE_CRYPTO_OPENSSL) - if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) { -- EVP_CIPHER_CTX_cleanup(evp); -+ EVP_CIPHER_CTX_free(ctx->evp); - //FATAL("Cannot set key and IV"); - } - #elif defined(USE_CRYPTO_POLARSSL) -@@ -698,7 +662,7 @@ static void cipher_context_release(enc_info * info, cipher_ctx_t *ctx) - - cipher_evp_t *evp = &ctx->evp; - #if defined(USE_CRYPTO_OPENSSL) -- EVP_CIPHER_CTX_cleanup(evp); -+ EVP_CIPHER_CTX_free(ctx->evp); - #elif defined(USE_CRYPTO_POLARSSL) - cipher_free_ctx(evp); - #endif -@@ -730,7 +694,7 @@ static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, int *olen, - size_t ss_calc_buffer_size(struct enc_ctx * ctx, size_t ilen) - { - int method = ctx->info->method; -- const cipher_kt_t *cipher = get_cipher_type(method); -+ const cipher_t *cipher = get_cipher_type(method); - #if defined(USE_CRYPTO_OPENSSL) - if (ctx->init) - return ilen + EVP_CIPHER_block_size(cipher); -@@ -913,10 +877,7 @@ static int enc_key_init(enc_info * info, int method, const char *pass) - OpenSSL_add_all_algorithms(); - #endif - -- uint8_t iv[MAX_IV_LENGTH]; -- -- cipher_kt_t *cipher = NULL; -- cipher_kt_t cipher_info; -+ cipher_t *cipher; - - - if (method == SALSA20 || method == CHACHA20) { -@@ -924,11 +885,9 @@ static int enc_key_init(enc_info * info, int method, const char *pass) - if (sodium_init() == -1) { - //FATAL("Failed to initialize sodium"); - } -- // Fake cipher -- cipher = (cipher_kt_t *)&cipher_info; - #if defined(USE_CRYPTO_OPENSSL) -- cipher->key_len = supported_ciphers_key_size[method]; -- cipher->iv_len = supported_ciphers_iv_size[method]; -+ cipher.key_len = supported_ciphers_key_size[method]; -+ cipher.iv_len = supported_ciphers_iv_size[method]; - #endif - #if defined(USE_CRYPTO_POLARSSL) - cipher->base = NULL; -@@ -937,7 +896,7 @@ static int enc_key_init(enc_info * info, int method, const char *pass) - #endif - */ - } else { -- cipher = (cipher_kt_t *)get_cipher_type(method); -+ cipher = (cipher_t *)get_cipher_type(method); - } - - if (cipher == NULL) { -@@ -947,7 +906,7 @@ static int enc_key_init(enc_info * info, int method, const char *pass) - cipher_info.base = NULL; - cipher_info.key_length = supported_ciphers_key_size[method] * 8; - cipher_info.iv_size = supported_ciphers_iv_size[method]; -- cipher = (cipher_kt_t *)&cipher_info; -+ cipher = (cipher_t *)&cipher_info; - break; - } - #endif -@@ -959,7 +918,7 @@ static int enc_key_init(enc_info * info, int method, const char *pass) - if (md == NULL) - return -1; - -- info->key_len = bytes_to_key(cipher, md, (const uint8_t *)pass, info->key, iv); -+ info->key_len = bytes_to_key(&cipher, md, (const uint8_t *)pass, info->key); - if (info->key_len == 0) { - //FATAL("Cannot generate key and IV"); - return -1; -@@ -967,7 +926,7 @@ static int enc_key_init(enc_info * info, int method, const char *pass) - if (method == RC4_MD5) { - info->iv_len = 16; - } else { -- info->iv_len = cipher_iv_size(cipher); -+ info->iv_len = cipher_iv_size(&cipher); - } - info->method = method; - return method; -diff --git a/encrypt.h b/encrypt.h -index 61b3fc7..c3359d0 100644 ---- a/encrypt.h -+++ b/encrypt.h -@@ -45,7 +45,7 @@ - #if defined(USE_CRYPTO_OPENSSL) - - #include --typedef EVP_CIPHER cipher_kt_t; -+typedef EVP_CIPHER cipher_t; - typedef EVP_CIPHER_CTX cipher_evp_t; - typedef EVP_MD digest_type_t; - #define MAX_KEY_LENGTH EVP_MAX_KEY_LENGTH -@@ -56,7 +56,7 @@ typedef EVP_MD digest_type_t; - - #include - #include --typedef cipher_info_t cipher_kt_t; -+typedef cipher_info_t cipher_t; - typedef cipher_context_t cipher_evp_t; - typedef md_info_t digest_type_t; - #define MAX_KEY_LENGTH 64 -@@ -89,7 +89,7 @@ typedef struct { - #endif - - typedef struct { -- cipher_evp_t evp; -+ cipher_evp_t *evp; - #ifdef USE_CRYPTO_APPLECC - cipher_cc_t cc; - #endif diff --git a/package/lienol/redsocks2/patches/001-fix-redudp-failing-to-extract-original-destination-address.patch b/package/lienol/redsocks2/patches/001-fix-redudp-failing-to-extract-original-destination-address.patch deleted file mode 100644 index a55f479346..0000000000 --- a/package/lienol/redsocks2/patches/001-fix-redudp-failing-to-extract-original-destination-address.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/utils.c b/utils.c -index 9fe148e..196a04e 100644 ---- a/utils.c -+++ b/utils.c -@@ -62,7 +62,9 @@ int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inadd - if ( - cmsg->cmsg_level == SOL_IP && - cmsg->cmsg_type == IP_ORIGDSTADDR && -- cmsg->cmsg_len >= CMSG_LEN(sizeof(*toaddr)) -+ (cmsg->cmsg_len == CMSG_LEN(sizeof(struct sockaddr_in)) -+ || cmsg->cmsg_len == CMSG_LEN(sizeof(struct sockaddr_in6))) && -+ cmsg->cmsg_len <= CMSG_LEN(sizeof(*toaddr)) - ) { - struct sockaddr_in* cmsgaddr = (struct sockaddr_in*)CMSG_DATA(cmsg); - memcpy(toaddr, cmsgaddr, sizeof(*toaddr)); diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index 8031a0c62a..0a9b5c0a99 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -8,14 +8,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dropbear -PKG_VERSION:=2020.79 +PKG_VERSION:=2020.80 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ http://matt.ucc.asn.au/dropbear/releases/ \ https://dropbear.nl/mirror/releases/ -PKG_HASH:=084f00546b1610a3422a0773e2c04cbe1a220d984209e033b548b49f379cc441 +PKG_HASH:=d927941b91f2da150b2033f1a88b6a47999bf0afb1493a73e9216cffdb5d7949 PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE libtomcrypt/LICENSE libtommath/LICENSE diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index daf111fadb..ab8e908d8c 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -238,7 +238,7 @@ killclients() while [ "${pid}" -ne 0 ] do # get parent process id - pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"` + pid=$(cut -d ' ' -f 4 "/proc/${pid}/stat") [ "${pid}" -eq 0 ] && break # check if client connection @@ -249,14 +249,14 @@ killclients() done # get all server pids that should be ignored - for server in `cat /var/run/${NAME}.*.pid` + for server in $(cat /var/run/${NAME}.*.pid) do append ignore "${server}" done # get all running pids and kill client connections local skip - for pid in `pidof "${NAME}"` + for pid in $(pidof "${NAME}") do # check if correct program, otherwise process next pid grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" || { diff --git a/package/network/services/dropbear/patches/001-backport_GNU_SOURCE-for-random.patch b/package/network/services/dropbear/patches/001-backport_GNU_SOURCE-for-random.patch deleted file mode 100644 index d9b13d77dd..0000000000 --- a/package/network/services/dropbear/patches/001-backport_GNU_SOURCE-for-random.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3f5c106a880a02b21739f2022746e6aa7672474c Mon Sep 17 00:00:00 2001 -From: Matt Johnston -Date: Tue, 23 Jun 2020 21:38:46 +0800 -Subject: [PATCH] _GNU_SOURCE for random - ---- - includes.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/includes.h b/includes.h -index e8c3e18..2789f23 100644 ---- a/includes.h -+++ b/includes.h -@@ -125,6 +125,8 @@ - #endif - - #ifdef HAVE_SYS_RANDOM_H -+/* uclibc needs _GNU_SOURCE */ -+#define _GNU_SOURCE - #include - #endif - --- -2.25.1 - diff --git a/package/network/services/dropbear/patches/002-backport-move-GNU_SOURCE-earlier.patch b/package/network/services/dropbear/patches/002-backport-move-GNU_SOURCE-earlier.patch deleted file mode 100644 index 26454c2829..0000000000 --- a/package/network/services/dropbear/patches/002-backport-move-GNU_SOURCE-earlier.patch +++ /dev/null @@ -1,34 +0,0 @@ -From a7a67585cbc3fe5df85c641618b347a51a943356 Mon Sep 17 00:00:00 2001 -From: Matt Johnston -Date: Tue, 23 Jun 2020 22:24:58 +0800 -Subject: [PATCH] move GNU_SOURCE earlier - ---- - includes.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/includes.h b/includes.h -index 2789f23..884ebf7 100644 ---- a/includes.h -+++ b/includes.h -@@ -25,6 +25,8 @@ - #ifndef DROPBEAR_INCLUDES_H_ - #define DROPBEAR_INCLUDES_H_ - -+/* uclibc needs _GNU_SOURCE, maybe other things? */ -+#define _GNU_SOURCE - - #include "options.h" - #include "debug.h" -@@ -125,8 +127,6 @@ - #endif - - #ifdef HAVE_SYS_RANDOM_H --/* uclibc needs _GNU_SOURCE */ --#define _GNU_SOURCE - #include - #endif - --- -2.25.1 - diff --git a/package/network/services/dropbear/patches/010-backport-disable-toom-and-karatsuba.patch b/package/network/services/dropbear/patches/010-backport-disable-toom-and-karatsuba.patch deleted file mode 100644 index 9af291eb01..0000000000 --- a/package/network/services/dropbear/patches/010-backport-disable-toom-and-karatsuba.patch +++ /dev/null @@ -1,17 +0,0 @@ -From: Matt Johnston -Date: Thu, 18 Jun 2020 19:12:07 +0800 -Subject: Disable toom and karatsuba for new libtommath - ---- a/libtommath/tommath_class.h -+++ b/libtommath/tommath_class.h -@@ -1312,6 +1312,10 @@ - #undef BN_MP_KARATSUBA_SQR_C - #undef BN_MP_TOOM_MUL_C - #undef BN_MP_TOOM_SQR_C -+#undef BN_S_MP_KARATSUBA_MUL_C -+#undef BN_S_MP_KARATSUBA_SQR_C -+#undef BN_S_MP_TOOM_MUL_C -+#undef BN_S_MP_TOOM_SQR_C - - #include "dbmalloc.h" - #define MP_MALLOC m_malloc diff --git a/package/network/utils/curl/Makefile b/package/network/utils/curl/Makefile index f2a7406164..54ca5d8b6b 100644 --- a/package/network/utils/curl/Makefile +++ b/package/network/utils/curl/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=curl -PKG_VERSION:=7.70.0 +PKG_VERSION:=7.71.0 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz @@ -16,7 +16,7 @@ PKG_SOURCE_URL:=https://dl.uxnr.de/mirror/curl/ \ https://curl.mirror.anstey.ca/ \ https://curl.askapache.com/download/ \ https://curl.haxx.se/download/ -PKG_HASH:=032f43f2674008c761af19bf536374128c16241fb234699a55f9fb603fcfbae7 +PKG_HASH:=cdf18794393d8bead915312708a9e5d819c6e9919de14b20d5c8e7987abd9772 PKG_LICENSE:=MIT PKG_LICENSE_FILES:=COPYING diff --git a/package/network/utils/curl/patches/200-no_docs_tests.patch b/package/network/utils/curl/patches/200-no_docs_tests.patch index 53f8c6c3f6..b5f92b58c8 100644 --- a/package/network/utils/curl/patches/200-no_docs_tests.patch +++ b/package/network/utils/curl/patches/200-no_docs_tests.patch @@ -1,6 +1,6 @@ --- a/Makefile.am +++ b/Makefile.am -@@ -189,7 +189,7 @@ CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) +@@ -192,7 +192,7 @@ CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) bin_SCRIPTS = curl-config SUBDIRS = lib src @@ -9,10 +9,10 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libcurl.pc -@@ -300,8 +300,8 @@ cygwinbin: +@@ -303,8 +303,8 @@ cygwinbin: # We extend the standard install with a custom hook: install-data-hook: - (cd include && $(MAKE) install) + (cd include && $(MAKE) install) - (cd docs && $(MAKE) install) - (cd docs/libcurl && $(MAKE) install) + #(cd docs && $(MAKE) install) diff --git a/package/system/zram-swap/files/zram.init b/package/system/zram-swap/files/zram.init index 9fd4089c6b..584fdc36c9 100755 --- a/package/system/zram-swap/files/zram.init +++ b/package/system/zram-swap/files/zram.init @@ -69,7 +69,7 @@ zram_getdev() local zdev=$( zram_dev ) if [ "$(mount | grep $zdev)" ]; then - local idx=`cat /sys/class/zram-control/hot_add` + local idx=$(cat /sys/class/zram-control/hot_add) zdev="$( zram_dev $idx )" fi @@ -85,7 +85,7 @@ zram_comp_algo() return 0 fi - if [ `grep -c "$zram_comp_algo" /sys/block/$( basename $dev )/comp_algorithm` -ne 0 ]; then + if [ $(grep -c "$zram_comp_algo" /sys/block/$( basename $dev )/comp_algorithm) -ne 0 ]; then logger -s -t zram_comp_algo -p daemon.debug "Set compression algorithm '$zram_comp_algo' for zram '$dev'" echo $zram_comp_algo > "/sys/block/$( basename $dev )/comp_algorithm" else diff --git a/target/linux/ar71xx/Makefile b/target/linux/ar71xx/Makefile index e7ca46c7ac..93832b560e 100644 --- a/target/linux/ar71xx/Makefile +++ b/target/linux/ar71xx/Makefile @@ -13,7 +13,7 @@ FEATURES:=usbgadget CPU_TYPE:=24kc SUBTARGETS:=generic tiny nand mikrotik -KERNEL_PATCHVER:=4.9 +KERNEL_PATCHVER:=4.14 include $(INCLUDE_DIR)/target.mk diff --git a/target/linux/ar71xx/patches-4.14/910-unaligned_access_hacks.patch b/target/linux/ar71xx/patches-4.14/910-unaligned_access_hacks.patch index 83df8d79a0..52f48d0d0e 100644 --- a/target/linux/ar71xx/patches-4.14/910-unaligned_access_hacks.patch +++ b/target/linux/ar71xx/patches-4.14/910-unaligned_access_hacks.patch @@ -276,7 +276,7 @@ case IPV6_2292HOPOPTS: --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c -@@ -397,7 +397,7 @@ static void ip6gre_err(struct sk_buff *s +@@ -400,7 +400,7 @@ static void ip6gre_err(struct sk_buff *s return; ipv6h = (const struct ipv6hdr *)skb->data; greh = (const struct gre_base_hdr *)(skb->data + offset); diff --git a/target/linux/ar71xx/patches-4.9/910-unaligned_access_hacks.patch b/target/linux/ar71xx/patches-4.9/910-unaligned_access_hacks.patch index def45bb2e1..5eb1853451 100644 --- a/target/linux/ar71xx/patches-4.9/910-unaligned_access_hacks.patch +++ b/target/linux/ar71xx/patches-4.9/910-unaligned_access_hacks.patch @@ -267,7 +267,7 @@ case IPV6_2292HOPOPTS: --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c -@@ -397,7 +397,7 @@ static void ip6gre_err(struct sk_buff *s +@@ -400,7 +400,7 @@ static void ip6gre_err(struct sk_buff *s return; ipv6h = (const struct ipv6hdr *)skb->data; greh = (const struct gre_base_hdr *)(skb->data + offset); diff --git a/target/linux/generic/backport-4.14/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch b/target/linux/generic/backport-4.14/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch index 7939ee46b0..a098c4416c 100644 --- a/target/linux/generic/backport-4.14/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch +++ b/target/linux/generic/backport-4.14/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch @@ -55,7 +55,7 @@ Cc: Kir Kolyshkin rwlock_t sk_callback_lock; --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -2748,6 +2748,7 @@ void sock_init_data(struct socket *sock, +@@ -2750,6 +2750,7 @@ void sock_init_data(struct socket *sock, sk->sk_max_pacing_rate = ~0U; sk->sk_pacing_rate = ~0U; diff --git a/target/linux/generic/backport-4.19/395-v5.8-net-sch_cake-Take-advantage-of-skb-hash-where-appropriate.patch b/target/linux/generic/backport-4.19/395-v5.8-net-sch_cake-Take-advantage-of-skb-hash-where-appropriate.patch new file mode 100644 index 0000000000..12962135d0 --- /dev/null +++ b/target/linux/generic/backport-4.19/395-v5.8-net-sch_cake-Take-advantage-of-skb-hash-where-appropriate.patch @@ -0,0 +1,170 @@ +From b0c19ed6088ab41dd2a727b60594b7297c15d6ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Fri, 29 May 2020 14:43:44 +0200 +Subject: [PATCH] sch_cake: Take advantage of skb->hash where appropriate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +While the other fq-based qdiscs take advantage of skb->hash and doesn't +recompute it if it is already set, sch_cake does not. + +This was a deliberate choice because sch_cake hashes various parts of the +packet header to support its advanced flow isolation modes. However, +foregoing the use of skb->hash entirely loses a few important benefits: + +- When skb->hash is set by hardware, a few CPU cycles can be saved by not + hashing again in software. + +- Tunnel encapsulations will generally preserve the value of skb->hash from + before the encapsulation, which allows flow-based qdiscs to distinguish + between flows even though the outer packet header no longer has flow + information. + +It turns out that we can preserve these desirable properties in many cases, +while still supporting the advanced flow isolation properties of sch_cake. +This patch does so by reusing the skb->hash value as the flow_hash part of +the hashing procedure in cake_hash() only in the following conditions: + +- If the skb->hash is marked as covering the flow headers (skb->l4_hash is + set) + +AND + +- NAT header rewriting is either disabled, or did not change any values + used for hashing. The latter is important to match local-origin packets + such as those of a tunnel endpoint. + +The immediate motivation for fixing this was the recent patch to WireGuard +to preserve the skb->hash on encapsulation. As such, this is also what I +tested against; with this patch, added latency under load for competing +flows drops from ~8 ms to sub-1ms on an RRUL test over a WireGuard tunnel +going through a virtual link shaped to 1Gbps using sch_cake. This matches +the results we saw with a similar setup using sch_fq_codel when testing the +WireGuard patch. + +Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc") +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Kevin Darbyshire-Bryant +--- + net/sched/sch_cake.c | 65 ++++++++++++++++++++++++++++++++++---------- + 1 file changed, 51 insertions(+), 14 deletions(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -584,26 +584,48 @@ static bool cobalt_should_drop(struct co + return drop; + } + +-static void cake_update_flowkeys(struct flow_keys *keys, ++static bool cake_update_flowkeys(struct flow_keys *keys, + const struct sk_buff *skb) + { + #if IS_ENABLED(CONFIG_NF_CONNTRACK) + struct nf_conntrack_tuple tuple = {}; +- bool rev = !skb->_nfct; ++ bool rev = !skb->_nfct, upd = false; ++ __be32 ip; + + if (tc_skb_protocol(skb) != htons(ETH_P_IP)) +- return; ++ return false; + + if (!nf_ct_get_tuple_skb(&tuple, skb)) +- return; ++ return false; + +- keys->addrs.v4addrs.src = rev ? tuple.dst.u3.ip : tuple.src.u3.ip; +- keys->addrs.v4addrs.dst = rev ? tuple.src.u3.ip : tuple.dst.u3.ip; ++ ip = rev ? tuple.dst.u3.ip : tuple.src.u3.ip; ++ if (ip != keys->addrs.v4addrs.src) { ++ keys->addrs.v4addrs.src = ip; ++ upd = true; ++ } ++ ip = rev ? tuple.src.u3.ip : tuple.dst.u3.ip; ++ if (ip != keys->addrs.v4addrs.dst) { ++ keys->addrs.v4addrs.dst = ip; ++ upd = true; ++ } + + if (keys->ports.ports) { +- keys->ports.src = rev ? tuple.dst.u.all : tuple.src.u.all; +- keys->ports.dst = rev ? tuple.src.u.all : tuple.dst.u.all; ++ __be16 port; ++ ++ port = rev ? tuple.dst.u.all : tuple.src.u.all; ++ if (port != keys->ports.src) { ++ keys->ports.src = port; ++ upd = true; ++ } ++ port = rev ? tuple.src.u.all : tuple.dst.u.all; ++ if (port != keys->ports.dst) { ++ port = keys->ports.dst; ++ upd = true; ++ } + } ++ return upd; ++#else ++ return false; + #endif + } + +@@ -624,23 +646,36 @@ static bool cake_ddst(int flow_mode) + static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + int flow_mode, u16 flow_override, u16 host_override) + { ++ bool hash_flows = (!flow_override && !!(flow_mode & CAKE_FLOW_FLOWS)); ++ bool hash_hosts = (!host_override && !!(flow_mode & CAKE_FLOW_HOSTS)); ++ bool nat_enabled = !!(flow_mode & CAKE_FLOW_NAT_FLAG); + u32 flow_hash = 0, srchost_hash = 0, dsthost_hash = 0; + u16 reduced_hash, srchost_idx, dsthost_idx; + struct flow_keys keys, host_keys; ++ bool use_skbhash = skb->l4_hash; + + if (unlikely(flow_mode == CAKE_FLOW_NONE)) + return 0; + +- /* If both overrides are set we can skip packet dissection entirely */ +- if ((flow_override || !(flow_mode & CAKE_FLOW_FLOWS)) && +- (host_override || !(flow_mode & CAKE_FLOW_HOSTS))) ++ /* If both overrides are set, or we can use the SKB hash and nat mode is ++ * disabled, we can skip packet dissection entirely. If nat mode is ++ * enabled there's another check below after doing the conntrack lookup. ++ */ ++ if ((!hash_flows || (use_skbhash && !nat_enabled)) && !hash_hosts) + goto skip_hash; + + skb_flow_dissect_flow_keys(skb, &keys, + FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); + +- if (flow_mode & CAKE_FLOW_NAT_FLAG) +- cake_update_flowkeys(&keys, skb); ++ /* Don't use the SKB hash if we change the lookup keys from conntrack */ ++ if (nat_enabled && cake_update_flowkeys(&keys, skb)) ++ use_skbhash = false; ++ ++ /* If we can still use the SKB hash and don't need the host hash, we can ++ * skip the rest of the hashing procedure ++ */ ++ if (use_skbhash && !hash_hosts) ++ goto skip_hash; + + /* flow_hash_from_keys() sorts the addresses by value, so we have + * to preserve their order in a separate data structure to treat +@@ -679,12 +714,14 @@ static u32 cake_hash(struct cake_tin_dat + /* This *must* be after the above switch, since as a + * side-effect it sorts the src and dst addresses. + */ +- if (flow_mode & CAKE_FLOW_FLOWS) ++ if (hash_flows && !use_skbhash) + flow_hash = flow_hash_from_keys(&keys); + + skip_hash: + if (flow_override) + flow_hash = flow_override - 1; ++ else if (use_skbhash) ++ flow_hash = skb->hash; + if (host_override) { + dsthost_hash = host_override - 1; + srchost_hash = host_override - 1; diff --git a/target/linux/generic/backport-4.19/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch b/target/linux/generic/backport-4.19/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch new file mode 100644 index 0000000000..a36095c26c --- /dev/null +++ b/target/linux/generic/backport-4.19/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch @@ -0,0 +1,96 @@ +From 9208d2863ac689a563b92f2161d8d1e7127d0add Mon Sep 17 00:00:00 2001 +From: Ilya Ponetayev +Date: Thu, 25 Jun 2020 22:12:07 +0200 +Subject: [PATCH] sch_cake: don't try to reallocate or unshare skb + unconditionally +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cake_handle_diffserv() tries to linearize mac and network header parts of +skb and to make it writable unconditionally. In some cases it leads to full +skb reallocation, which reduces throughput and increases CPU load. Some +measurements of IPv4 forward + NAPT on MIPS router with 580 MHz single-core +CPU was conducted. It appears that on kernel 4.9 skb_try_make_writable() +reallocates skb, if skb was allocated in ethernet driver via so-called +'build skb' method from page cache (it was discovered by strange increase +of kmalloc-2048 slab at first). + +Obtain DSCP value via read-only skb_header_pointer() call, and leave +linearization only for DSCP bleaching or ECN CE setting. And, as an +additional optimisation, skip diffserv parsing entirely if it is not needed +by the current configuration. + +Fixes: c87b4ecdbe8d ("sch_cake: Make sure we can write the IP header before changing DSCP bits") +Signed-off-by: Ilya Ponetayev +[ fix a few style issues, reflow commit message ] +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Kevin Darbyshire-Bryant +--- + net/sched/sch_cake.c | 41 ++++++++++++++++++++++++++++++----------- + 1 file changed, 30 insertions(+), 11 deletions(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1553,30 +1553,49 @@ static unsigned int cake_drop(struct Qdi + + static u8 cake_handle_diffserv(struct sk_buff *skb, u16 wash) + { +- int wlen = skb_network_offset(skb); ++ const int offset = skb_network_offset(skb); ++ u16 *buf, buf_; + u8 dscp; + + switch (tc_skb_protocol(skb)) { + case htons(ETH_P_IP): +- wlen += sizeof(struct iphdr); +- if (!pskb_may_pull(skb, wlen) || +- skb_try_make_writable(skb, wlen)) ++ buf = skb_header_pointer(skb, offset, sizeof(buf_), &buf_); ++ if (unlikely(!buf)) + return 0; + +- dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2; +- if (wash && dscp) ++ /* ToS is in the second byte of iphdr */ ++ dscp = ipv4_get_dsfield((struct iphdr *)buf) >> 2; ++ ++ if (wash && dscp) { ++ const int wlen = offset + sizeof(struct iphdr); ++ ++ if (!pskb_may_pull(skb, wlen) || ++ skb_try_make_writable(skb, wlen)) ++ return 0; ++ + ipv4_change_dsfield(ip_hdr(skb), INET_ECN_MASK, 0); ++ } ++ + return dscp; + + case htons(ETH_P_IPV6): +- wlen += sizeof(struct ipv6hdr); +- if (!pskb_may_pull(skb, wlen) || +- skb_try_make_writable(skb, wlen)) ++ buf = skb_header_pointer(skb, offset, sizeof(buf_), &buf_); ++ if (unlikely(!buf)) + return 0; + +- dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2; +- if (wash && dscp) ++ /* Traffic class is in the first and second bytes of ipv6hdr */ ++ dscp = ipv6_get_dsfield((struct ipv6hdr *)buf) >> 2; ++ ++ if (wash && dscp) { ++ const int wlen = offset + sizeof(struct ipv6hdr); ++ ++ if (!pskb_may_pull(skb, wlen) || ++ skb_try_make_writable(skb, wlen)) ++ return 0; ++ + ipv6_change_dsfield(ipv6_hdr(skb), INET_ECN_MASK, 0); ++ } ++ + return dscp; + + case htons(ETH_P_ARP): diff --git a/target/linux/generic/backport-4.19/397-5.8-sch_cake-don-t-call-diffserv-parsing-code-when-it-is.patch b/target/linux/generic/backport-4.19/397-5.8-sch_cake-don-t-call-diffserv-parsing-code-when-it-is.patch new file mode 100644 index 0000000000..b40bb36c74 --- /dev/null +++ b/target/linux/generic/backport-4.19/397-5.8-sch_cake-don-t-call-diffserv-parsing-code-when-it-is.patch @@ -0,0 +1,62 @@ +From 8c95eca0bb8c4bd2231a0d581f1ad0d50c90488c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Thu, 25 Jun 2020 22:12:08 +0200 +Subject: [PATCH] sch_cake: don't call diffserv parsing code when it is not + needed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As a further optimisation of the diffserv parsing codepath, we can skip it +entirely if CAKE is configured to neither use diffserv-based +classification, nor to zero out the diffserv bits. + +Fixes: c87b4ecdbe8d ("sch_cake: Make sure we can write the IP header before changing DSCP bits") +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Kevin Darbyshire-Bryant +--- + net/sched/sch_cake.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1551,7 +1551,7 @@ static unsigned int cake_drop(struct Qdi + return idx + (tin << 16); + } + +-static u8 cake_handle_diffserv(struct sk_buff *skb, u16 wash) ++static u8 cake_handle_diffserv(struct sk_buff *skb, bool wash) + { + const int offset = skb_network_offset(skb); + u16 *buf, buf_; +@@ -1612,14 +1612,17 @@ static struct cake_tin_data *cake_select + { + struct cake_sched_data *q = qdisc_priv(sch); + u32 tin, mark; ++ bool wash; + u8 dscp; + + /* Tin selection: Default to diffserv-based selection, allow overriding +- * using firewall marks or skb->priority. ++ * using firewall marks or skb->priority. Call DSCP parsing early if ++ * wash is enabled, otherwise defer to below to skip unneeded parsing. + */ +- dscp = cake_handle_diffserv(skb, +- q->rate_flags & CAKE_FLAG_WASH); + mark = (skb->mark & q->fwmark_mask) >> q->fwmark_shft; ++ wash = !!(q->rate_flags & CAKE_FLAG_WASH); ++ if (wash) ++ dscp = cake_handle_diffserv(skb, wash); + + if (q->tin_mode == CAKE_DIFFSERV_BESTEFFORT) + tin = 0; +@@ -1630,6 +1633,8 @@ static struct cake_tin_data *cake_select + tin = q->tin_order[TC_H_MIN(skb->priority) - 1]; + + else { ++ if (!wash) ++ dscp = cake_handle_diffserv(skb, wash); + tin = q->tin_index[dscp]; + + if (unlikely(tin >= q->tin_cnt)) diff --git a/target/linux/generic/backport-4.19/398-5.8-sch_cake-fix-a-few-style-nits.patch b/target/linux/generic/backport-4.19/398-5.8-sch_cake-fix-a-few-style-nits.patch new file mode 100644 index 0000000000..a1d72113b7 --- /dev/null +++ b/target/linux/generic/backport-4.19/398-5.8-sch_cake-fix-a-few-style-nits.patch @@ -0,0 +1,40 @@ +From 3f608f0c41360b11b04c763f348b712f651c8bac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Thu, 25 Jun 2020 22:12:09 +0200 +Subject: [PATCH] sch_cake: fix a few style nits +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +I spotted a few nits when comparing the in-tree version of sch_cake with +the out-of-tree one: A redundant error variable declaration shadowing an +outer declaration, and an indentation alignment issue. Fix both of these. + +Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc") +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Kevin Darbyshire-Bryant +--- + net/sched/sch_cake.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -2713,7 +2713,7 @@ static int cake_init(struct Qdisc *sch, + qdisc_watchdog_init(&q->watchdog, sch); + + if (opt) { +- int err = cake_change(sch, opt, extack); ++ err = cake_change(sch, opt, extack); + + if (err) + return err; +@@ -3030,7 +3030,7 @@ static int cake_dump_class_stats(struct + PUT_STAT_S32(BLUE_TIMER_US, + ktime_to_us( + ktime_sub(now, +- flow->cvars.blue_timer))); ++ flow->cvars.blue_timer))); + } + if (flow->cvars.dropping) { + PUT_STAT_S32(DROP_NEXT_US, diff --git a/target/linux/generic/backport-4.19/399-5.9-sch_cake-add-RFC-8622-LE-PHB-support-to-CAKE-diffser.patch b/target/linux/generic/backport-4.19/399-5.9-sch_cake-add-RFC-8622-LE-PHB-support-to-CAKE-diffser.patch new file mode 100644 index 0000000000..e171b4cec7 --- /dev/null +++ b/target/linux/generic/backport-4.19/399-5.9-sch_cake-add-RFC-8622-LE-PHB-support-to-CAKE-diffser.patch @@ -0,0 +1,57 @@ +From b8392808eb3fc28e523e28cb258c81ca246deb9b Mon Sep 17 00:00:00 2001 +From: Kevin Darbyshire-Bryant +Date: Thu, 25 Jun 2020 22:18:00 +0200 +Subject: [PATCH] sch_cake: add RFC 8622 LE PHB support to CAKE diffserv + handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Change tin mapping on diffserv3, 4 & 8 for LE PHB support, in essence +making LE a member of the Bulk tin. + +Bulk has the least priority and minimum of 1/16th total bandwidth in the +face of higher priority traffic. + +NB: Diffserv 3 & 4 swap tin 0 & 1 priorities from the default order as +found in diffserv8, in case anyone is wondering why it looks a bit odd. + +Signed-off-by: Kevin Darbyshire-Bryant +[ reword commit message slightly ] +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +--- + net/sched/sch_cake.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -312,8 +312,8 @@ static const u8 precedence[] = { + }; + + static const u8 diffserv8[] = { +- 2, 5, 1, 2, 4, 2, 2, 2, +- 0, 2, 1, 2, 1, 2, 1, 2, ++ 2, 0, 1, 2, 4, 2, 2, 2, ++ 1, 2, 1, 2, 1, 2, 1, 2, + 5, 2, 4, 2, 4, 2, 4, 2, + 3, 2, 3, 2, 3, 2, 3, 2, + 6, 2, 3, 2, 3, 2, 3, 2, +@@ -323,7 +323,7 @@ static const u8 diffserv8[] = { + }; + + static const u8 diffserv4[] = { +- 0, 2, 0, 0, 2, 0, 0, 0, ++ 0, 1, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 2, 0, 2, 0, 2, 0, + 2, 0, 2, 0, 2, 0, 2, 0, +@@ -334,7 +334,7 @@ static const u8 diffserv4[] = { + }; + + static const u8 diffserv3[] = { +- 0, 0, 0, 0, 2, 0, 0, 0, ++ 0, 1, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/target/linux/generic/backport-4.9/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch b/target/linux/generic/backport-4.9/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch index 11f1cd565d..3ba94528ab 100644 --- a/target/linux/generic/backport-4.9/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch +++ b/target/linux/generic/backport-4.9/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch @@ -55,7 +55,7 @@ Cc: Kir Kolyshkin rwlock_t sk_callback_lock; --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -2484,6 +2484,7 @@ void sock_init_data(struct socket *sock, +@@ -2486,6 +2486,7 @@ void sock_init_data(struct socket *sock, sk->sk_max_pacing_rate = ~0U; sk->sk_pacing_rate = ~0U; diff --git a/target/linux/generic/backport-4.9/063-v4.11-0001-mtd-nand-Add-Winbond-manufacturer-id.patch b/target/linux/generic/backport-4.9/063-v4.11-0001-mtd-nand-Add-Winbond-manufacturer-id.patch index cbab378b2b..b6545bb714 100644 --- a/target/linux/generic/backport-4.9/063-v4.11-0001-mtd-nand-Add-Winbond-manufacturer-id.patch +++ b/target/linux/generic/backport-4.9/063-v4.11-0001-mtd-nand-Add-Winbond-manufacturer-id.patch @@ -24,7 +24,7 @@ Signed-off-by: Boris Brezillon --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h -@@ -928,6 +928,7 @@ static inline void nand_set_controller_d +@@ -926,6 +926,7 @@ static inline void nand_set_controller_d #define NAND_MFR_SANDISK 0x45 #define NAND_MFR_INTEL 0x89 #define NAND_MFR_ATO 0x9b diff --git a/target/linux/generic/config-4.14 b/target/linux/generic/config-4.14 index d6520a98a0..76f049808d 100644 --- a/target/linux/generic/config-4.14 +++ b/target/linux/generic/config-4.14 @@ -4367,6 +4367,7 @@ CONFIG_SERIAL_EARLYCON=y # CONFIG_SG_POOL is not set # CONFIG_SG_SPLIT is not set CONFIG_SHMEM=y +# CONFIG_SHORTCUT_FE is not set # CONFIG_SH_ETH is not set # CONFIG_SH_TIMER_CMT is not set # CONFIG_SH_TIMER_MTU2 is not set diff --git a/target/linux/generic/config-4.19 b/target/linux/generic/config-4.19 index 5d0d0742ce..69c943b236 100644 --- a/target/linux/generic/config-4.19 +++ b/target/linux/generic/config-4.19 @@ -4592,6 +4592,7 @@ CONFIG_SERIAL_EARLYCON=y # CONFIG_SG_POOL is not set # CONFIG_SG_SPLIT is not set CONFIG_SHMEM=y +# CONFIG_SHORTCUT_FE is not set # CONFIG_SH_ETH is not set # CONFIG_SH_TIMER_CMT is not set # CONFIG_SH_TIMER_MTU2 is not set diff --git a/target/linux/generic/hack-4.14/661-use_fq_codel_by_default.patch b/target/linux/generic/hack-4.14/661-use_fq_codel_by_default.patch index e4943fbaa3..352572c7b1 100644 --- a/target/linux/generic/hack-4.14/661-use_fq_codel_by_default.patch +++ b/target/linux/generic/hack-4.14/661-use_fq_codel_by_default.patch @@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau EXPORT_SYMBOL(default_qdisc_ops); /* Main transmission queue. */ -@@ -772,7 +772,7 @@ static void attach_one_default_qdisc(str +@@ -773,7 +773,7 @@ static void attach_one_default_qdisc(str void *_unused) { struct Qdisc *qdisc; diff --git a/target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch b/target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch index 86feb04a49..03bdb2443b 100644 --- a/target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch +++ b/target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c -@@ -461,146 +461,6 @@ struct Qdisc_ops noqueue_qdisc_ops __rea +@@ -462,146 +462,6 @@ struct Qdisc_ops noqueue_qdisc_ops __rea .owner = THIS_MODULE, }; diff --git a/target/linux/generic/hack-4.14/901-debloat_sock_diag.patch b/target/linux/generic/hack-4.14/901-debloat_sock_diag.patch index a4ca573569..2f2b8eb705 100644 --- a/target/linux/generic/hack-4.14/901-debloat_sock_diag.patch +++ b/target/linux/generic/hack-4.14/901-debloat_sock_diag.patch @@ -61,7 +61,7 @@ Signed-off-by: Felix Fietkau struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) { struct dst_entry *dst = __sk_dst_get(sk); -@@ -1598,9 +1610,11 @@ void sk_destruct(struct sock *sk) +@@ -1599,9 +1611,11 @@ void sk_destruct(struct sock *sk) static void __sk_free(struct sock *sk) { diff --git a/target/linux/generic/hack-4.14/902-debloat_proc.patch b/target/linux/generic/hack-4.14/902-debloat_proc.patch index 54c6b4d265..3cf89b7421 100644 --- a/target/linux/generic/hack-4.14/902-debloat_proc.patch +++ b/target/linux/generic/hack-4.14/902-debloat_proc.patch @@ -327,7 +327,7 @@ Signed-off-by: Felix Fietkau --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -3387,6 +3387,8 @@ static __net_initdata struct pernet_oper +@@ -3389,6 +3389,8 @@ static __net_initdata struct pernet_oper static int __init proto_init(void) { diff --git a/target/linux/generic/hack-4.14/999-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-4.14/999-net-patch-linux-kernel-to-support-shortcut-fe.patch new file mode 100644 index 0000000000..05f64b2869 --- /dev/null +++ b/target/linux/generic/hack-4.14/999-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -0,0 +1,236 @@ +--- a/include/linux/skbuff.h 2019-01-16 20:16:08.325745306 +0800 ++++ b/include/linux/skbuff.h 2019-01-16 20:31:47.288028493 +0800 +@@ -783,6 +783,9 @@ struct sk_buff { + __u8 tc_from_ingress:1; + #endif + __u8 gro_skip:1; ++#ifdef CONFIG_SHORTCUT_FE ++ __u8 fast_forwarded:1; ++#endif + + #ifdef CONFIG_NET_SCHED + __u16 tc_index; /* traffic control index */ +--- a/include/linux/if_bridge.h 2019-01-16 20:51:47.871445535 +0800 ++++ b/include/linux/if_bridge.h 2019-01-16 20:52:26.220269649 +0800 +@@ -54,6 +54,8 @@ struct br_ip_list { + #define BR_DEFAULT_AGEING_TIME (300 * HZ) + + extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); ++extern void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats); + + typedef int br_should_route_hook_t(struct sk_buff *skb); + extern br_should_route_hook_t __rcu *br_should_route_hook; +--- a/include/linux/timer.h ++++ b/include/linux/timer.h +@@ -20,6 +20,9 @@ struct timer_list { + void (*function)(unsigned long); + unsigned long data; + u32 flags; ++#ifdef CONFIG_SHORTCUT_FE ++ unsigned long cust_data; ++#endif + + #ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; +--- a/net/Kconfig 2019-01-16 20:36:30.266465286 +0800 ++++ b/net/Kconfig 2019-01-16 20:36:41.980609067 +0800 +@@ -463,3 +463,6 @@ config HAVE_CBPF_JIT + # Extended BPF JIT (eBPF) + config HAVE_EBPF_JIT + bool ++ ++config SHORTCUT_FE ++ bool "Enables kernel network stack path for Shortcut Forwarding Engine +--- a/net/core/dev.c 2019-01-16 20:38:37.274933833 +0800 ++++ b/net/core/dev.c 2019-01-16 20:44:07.773594898 +0800 +@@ -3001,8 +3001,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 (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) + dev_queue_xmit_nit(skb, dev); ++#ifdef CONFIG_SHORTCUT_FE ++ } ++#endif + + #ifdef CONFIG_ETHERNET_PACKET_MANGLE + if (!dev->eth_mangle_tx || +@@ -4315,6 +4324,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. +@@ -4362,6 +4376,9 @@ static int __netif_receive_skb_core(stru + bool deliver_exact = false; + int ret = NET_RX_DROP; + __be16 type; ++#ifdef CONFIG_SHORTCUT_FE ++ int (*fast_recv)(struct sk_buff *skb); ++#endif + + net_timestamp_check(!netdev_tstamp_prequeue, skb); + +@@ -4388,6 +4405,16 @@ 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_proto_tcp.c 2019-01-16 20:47:40.886993297 +0800 ++++ b/net/netfilter/nf_conntrack_proto_tcp.c 2019-01-16 20:48:57.700570104 +0800 +@@ -35,11 +35,17 @@ + + /* Do not check the TCP window for incoming packets */ + static int nf_ct_tcp_no_window_check __read_mostly = 1; ++#ifdef CONFIG_SHORTCUT_FE ++EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check); ++#endif + + /* "Be conservative in what you do, + be liberal in what you accept from others." + If it's non-zero, we mark only out of window RST segments as INVALID. */ + static int nf_ct_tcp_be_liberal __read_mostly = 0; ++#ifdef CONFIG_SHORTCUT_FE ++EXPORT_SYMBOL_GPL(nf_ct_tcp_be_liberal); ++#endif + + /* If it is set to zero, we disable picking up already established + connections. */ +--- a/net/bridge/br_if.c 2019-01-16 20:54:51.919367044 +0800 ++++ b/net/bridge/br_if.c 2019-01-16 20:55:53.812401263 +0800 +@@ -653,3 +653,26 @@ void br_port_flags_change(struct net_bri + if (mask & BR_AUTO_MASK) + nbp_update_port_count(br); + } ++ ++/* Update bridge statistics for bridge packets processed by offload engines */ ++void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct net_bridge *br; ++ struct pcpu_sw_netstats *stats; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return; ++ ++ br = netdev_priv(dev); ++ stats = this_cpu_ptr(br->stats); ++ ++ u64_stats_update_begin(&stats->syncp); ++ stats->rx_packets += nlstats->rx_packets; ++ stats->rx_bytes += nlstats->rx_bytes; ++ stats->tx_packets += nlstats->tx_packets; ++ stats->tx_bytes += nlstats->tx_bytes; ++ u64_stats_update_end(&stats->syncp); ++} ++EXPORT_SYMBOL_GPL(br_dev_update_stats); +--- a/net/netfilter/Kconfig 2019-01-16 21:07:34.543460920 +0800 ++++ b/net/netfilter/Kconfig 2019-01-16 21:08:14.739465937 +0800 +@@ -146,6 +146,14 @@ config NF_CONNTRACK_TIMEOUT + + 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_TIMESTAMP + bool 'Connection tracking timestamping' + depends on NETFILTER_ADVANCED +--- a/net/netfilter/nf_conntrack_ecache.c 2019-01-16 21:12:22.183462975 +0800 ++++ b/net/netfilter/nf_conntrack_ecache.c 2019-01-16 21:26:10.379462031 +0800 +@@ -122,13 +125,17 @@ int nf_conntrack_eventmask_report(unsign + { + int ret = 0; + struct net *net = nf_ct_net(ct); ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + struct nf_ct_event_notifier *notify; ++#endif + struct nf_conntrack_ecache *e; + + rcu_read_lock(); ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + notify = rcu_dereference(net->ct.nf_conntrack_event_cb); + if (!notify) + goto out_unlock; ++#endif + + e = nf_ct_ecache_find(ct); + if (!e) +@@ -146,7 +153,12 @@ int nf_conntrack_eventmask_report(unsign + if (!((eventmask | missed) & e->ctmask)) + goto out_unlock; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, ++ eventmask | missed, &item); ++#else + ret = notify->fcn(eventmask | missed, &item); ++#endif + if (unlikely(ret < 0 || missed)) { + spin_lock_bh(&ct->lock); + if (ret < 0) { +@@ -179,15 +191,19 @@ void nf_ct_deliver_cached_events(struct + { + struct net *net = nf_ct_net(ct); + unsigned long events, missed; ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + struct nf_ct_event_notifier *notify; ++#endif + struct nf_conntrack_ecache *e; + struct nf_ct_event item; + int ret; + + rcu_read_lock(); ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + notify = rcu_dereference(net->ct.nf_conntrack_event_cb); + if (notify == NULL) + goto out_unlock; ++#endif + + e = nf_ct_ecache_find(ct); + if (e == NULL) +@@ -210,7 +226,13 @@ void nf_ct_deliver_cached_events(struct + item.portid = 0; + item.report = 0; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, ++ events | missed, ++ &item); ++#else + ret = notify->fcn(events | missed, &item); ++#endif + + if (likely(ret == 0 && !missed)) + goto out_unlock; \ No newline at end of file diff --git a/target/linux/generic/hack-4.19/641-sch_cake-fix-IP-protocol-handling-in-the-presence-of.patch b/target/linux/generic/hack-4.19/641-sch_cake-fix-IP-protocol-handling-in-the-presence-of.patch new file mode 100644 index 0000000000..e651743c1d --- /dev/null +++ b/target/linux/generic/hack-4.19/641-sch_cake-fix-IP-protocol-handling-in-the-presence-of.patch @@ -0,0 +1,114 @@ +From a00590d570212c3c633bd463cef8ec7377cc7993 Mon Sep 17 00:00:00 2001 +From: Kevin Darbyshire-Bryant +Date: Tue, 30 Jun 2020 12:07:44 +0100 +Subject: [PATCH] sch_cake: fix IP protocol handling in the presence of VLAN + tags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilya Ponetayev + +CAKE was using the return value of tc_skb_protocol() and expecting it to be +the IP protocol type. This can fail in the presence of QinQ VLAN tags, +making CAKE unable to handle ECN marking and diffserv parsing in this case. +Fix this by implementing our own version of tc_skb_protocol(), which will +use skb->protocol directly, but also parse and skip over any VLAN tags and +return the inner protocol number instead. + +Also fix CE marking by implementing a version of INET_ECN_set_ce() that +uses the same parsing routine. + +Fixes: ea82511518f4 ("sch_cake: Add NAT awareness to packet classifier") +Fixes: b2100cc56fca ("sch_cake: Use tc_skb_protocol() helper for getting packet protocol") +Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc") +Signed-off-by: Ilya Ponetayev +[ squash original two patches, rewrite commit message ] +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: Kevin Darbyshire-Bryant +--- + net/sched/sch_cake.c | 52 +++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 49 insertions(+), 3 deletions(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -497,6 +497,52 @@ static bool cobalt_queue_empty(struct co + return down; + } + ++static __be16 cake_skb_proto(const struct sk_buff *skb) ++{ ++ unsigned int offset = skb_mac_offset(skb) + sizeof(struct ethhdr); ++ __be16 proto = skb->protocol; ++ struct vlan_hdr vhdr, *vh; ++ ++ while (proto == htons(ETH_P_8021Q) || proto == htons(ETH_P_8021AD)) { ++ vh = skb_header_pointer(skb, offset, sizeof(vhdr), &vhdr); ++ if (!vh) ++ break; ++ ++ proto = vh->h_vlan_encapsulated_proto; ++ offset += sizeof(vhdr); ++ } ++ ++ return proto; ++} ++ ++static int cake_set_ce(struct sk_buff *skb) ++{ ++ int wlen = skb_network_offset(skb); ++ ++ switch (cake_skb_proto(skb)) { ++ case htons(ETH_P_IP): ++ wlen += sizeof(struct iphdr); ++ if (!pskb_may_pull(skb, wlen) || ++ skb_try_make_writable(skb, wlen)) ++ return 0; ++ ++ return IP_ECN_set_ce(ip_hdr(skb)); ++ ++ case htons(ETH_P_IPV6): ++ wlen += sizeof(struct ipv6hdr); ++ if (!pskb_may_pull(skb, wlen) || ++ skb_try_make_writable(skb, wlen)) ++ return 0; ++ ++ return IP6_ECN_set_ce(skb, ipv6_hdr(skb)); ++ ++ default: ++ return 0; ++ } ++ ++ return 0; ++} ++ + /* Call this with a freshly dequeued packet for possible congestion marking. + * Returns true as an instruction to drop the packet, false for delivery. + */ +@@ -549,7 +595,7 @@ static bool cobalt_should_drop(struct co + + if (next_due && vars->dropping) { + /* Use ECN mark if possible, otherwise drop */ +- drop = !(vars->ecn_marked = INET_ECN_set_ce(skb)); ++ drop = !(vars->ecn_marked = cake_set_ce(skb)); + + vars->count++; + if (!vars->count) +@@ -592,7 +638,7 @@ static bool cake_update_flowkeys(struct + bool rev = !skb->_nfct, upd = false; + __be32 ip; + +- if (tc_skb_protocol(skb) != htons(ETH_P_IP)) ++ if (cake_skb_proto(skb) != htons(ETH_P_IP)) + return false; + + if (!nf_ct_get_tuple_skb(&tuple, skb)) +@@ -1557,7 +1603,7 @@ static u8 cake_handle_diffserv(struct sk + u16 *buf, buf_; + u8 dscp; + +- switch (tc_skb_protocol(skb)) { ++ switch (cake_skb_proto(skb)) { + case htons(ETH_P_IP): + buf = skb_header_pointer(skb, offset, sizeof(buf_), &buf_); + if (unlikely(!buf)) diff --git a/target/linux/generic/hack-4.19/999-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-4.19/999-net-patch-linux-kernel-to-support-shortcut-fe.patch new file mode 100644 index 0000000000..05f64b2869 --- /dev/null +++ b/target/linux/generic/hack-4.19/999-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -0,0 +1,236 @@ +--- a/include/linux/skbuff.h 2019-01-16 20:16:08.325745306 +0800 ++++ b/include/linux/skbuff.h 2019-01-16 20:31:47.288028493 +0800 +@@ -783,6 +783,9 @@ struct sk_buff { + __u8 tc_from_ingress:1; + #endif + __u8 gro_skip:1; ++#ifdef CONFIG_SHORTCUT_FE ++ __u8 fast_forwarded:1; ++#endif + + #ifdef CONFIG_NET_SCHED + __u16 tc_index; /* traffic control index */ +--- a/include/linux/if_bridge.h 2019-01-16 20:51:47.871445535 +0800 ++++ b/include/linux/if_bridge.h 2019-01-16 20:52:26.220269649 +0800 +@@ -54,6 +54,8 @@ struct br_ip_list { + #define BR_DEFAULT_AGEING_TIME (300 * HZ) + + extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); ++extern void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats); + + typedef int br_should_route_hook_t(struct sk_buff *skb); + extern br_should_route_hook_t __rcu *br_should_route_hook; +--- a/include/linux/timer.h ++++ b/include/linux/timer.h +@@ -20,6 +20,9 @@ struct timer_list { + void (*function)(unsigned long); + unsigned long data; + u32 flags; ++#ifdef CONFIG_SHORTCUT_FE ++ unsigned long cust_data; ++#endif + + #ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; +--- a/net/Kconfig 2019-01-16 20:36:30.266465286 +0800 ++++ b/net/Kconfig 2019-01-16 20:36:41.980609067 +0800 +@@ -463,3 +463,6 @@ config HAVE_CBPF_JIT + # Extended BPF JIT (eBPF) + config HAVE_EBPF_JIT + bool ++ ++config SHORTCUT_FE ++ bool "Enables kernel network stack path for Shortcut Forwarding Engine +--- a/net/core/dev.c 2019-01-16 20:38:37.274933833 +0800 ++++ b/net/core/dev.c 2019-01-16 20:44:07.773594898 +0800 +@@ -3001,8 +3001,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 (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) + dev_queue_xmit_nit(skb, dev); ++#ifdef CONFIG_SHORTCUT_FE ++ } ++#endif + + #ifdef CONFIG_ETHERNET_PACKET_MANGLE + if (!dev->eth_mangle_tx || +@@ -4315,6 +4324,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. +@@ -4362,6 +4376,9 @@ static int __netif_receive_skb_core(stru + bool deliver_exact = false; + int ret = NET_RX_DROP; + __be16 type; ++#ifdef CONFIG_SHORTCUT_FE ++ int (*fast_recv)(struct sk_buff *skb); ++#endif + + net_timestamp_check(!netdev_tstamp_prequeue, skb); + +@@ -4388,6 +4405,16 @@ 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_proto_tcp.c 2019-01-16 20:47:40.886993297 +0800 ++++ b/net/netfilter/nf_conntrack_proto_tcp.c 2019-01-16 20:48:57.700570104 +0800 +@@ -35,11 +35,17 @@ + + /* Do not check the TCP window for incoming packets */ + static int nf_ct_tcp_no_window_check __read_mostly = 1; ++#ifdef CONFIG_SHORTCUT_FE ++EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check); ++#endif + + /* "Be conservative in what you do, + be liberal in what you accept from others." + If it's non-zero, we mark only out of window RST segments as INVALID. */ + static int nf_ct_tcp_be_liberal __read_mostly = 0; ++#ifdef CONFIG_SHORTCUT_FE ++EXPORT_SYMBOL_GPL(nf_ct_tcp_be_liberal); ++#endif + + /* If it is set to zero, we disable picking up already established + connections. */ +--- a/net/bridge/br_if.c 2019-01-16 20:54:51.919367044 +0800 ++++ b/net/bridge/br_if.c 2019-01-16 20:55:53.812401263 +0800 +@@ -653,3 +653,26 @@ void br_port_flags_change(struct net_bri + if (mask & BR_AUTO_MASK) + nbp_update_port_count(br); + } ++ ++/* Update bridge statistics for bridge packets processed by offload engines */ ++void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct net_bridge *br; ++ struct pcpu_sw_netstats *stats; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return; ++ ++ br = netdev_priv(dev); ++ stats = this_cpu_ptr(br->stats); ++ ++ u64_stats_update_begin(&stats->syncp); ++ stats->rx_packets += nlstats->rx_packets; ++ stats->rx_bytes += nlstats->rx_bytes; ++ stats->tx_packets += nlstats->tx_packets; ++ stats->tx_bytes += nlstats->tx_bytes; ++ u64_stats_update_end(&stats->syncp); ++} ++EXPORT_SYMBOL_GPL(br_dev_update_stats); +--- a/net/netfilter/Kconfig 2019-01-16 21:07:34.543460920 +0800 ++++ b/net/netfilter/Kconfig 2019-01-16 21:08:14.739465937 +0800 +@@ -146,6 +146,14 @@ config NF_CONNTRACK_TIMEOUT + + 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_TIMESTAMP + bool 'Connection tracking timestamping' + depends on NETFILTER_ADVANCED +--- a/net/netfilter/nf_conntrack_ecache.c 2019-01-16 21:12:22.183462975 +0800 ++++ b/net/netfilter/nf_conntrack_ecache.c 2019-01-16 21:26:10.379462031 +0800 +@@ -122,13 +125,17 @@ int nf_conntrack_eventmask_report(unsign + { + int ret = 0; + struct net *net = nf_ct_net(ct); ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + struct nf_ct_event_notifier *notify; ++#endif + struct nf_conntrack_ecache *e; + + rcu_read_lock(); ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + notify = rcu_dereference(net->ct.nf_conntrack_event_cb); + if (!notify) + goto out_unlock; ++#endif + + e = nf_ct_ecache_find(ct); + if (!e) +@@ -146,7 +153,12 @@ int nf_conntrack_eventmask_report(unsign + if (!((eventmask | missed) & e->ctmask)) + goto out_unlock; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, ++ eventmask | missed, &item); ++#else + ret = notify->fcn(eventmask | missed, &item); ++#endif + if (unlikely(ret < 0 || missed)) { + spin_lock_bh(&ct->lock); + if (ret < 0) { +@@ -179,15 +191,19 @@ void nf_ct_deliver_cached_events(struct + { + struct net *net = nf_ct_net(ct); + unsigned long events, missed; ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + struct nf_ct_event_notifier *notify; ++#endif + struct nf_conntrack_ecache *e; + struct nf_ct_event item; + int ret; + + rcu_read_lock(); ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + notify = rcu_dereference(net->ct.nf_conntrack_event_cb); + if (notify == NULL) + goto out_unlock; ++#endif + + e = nf_ct_ecache_find(ct); + if (e == NULL) +@@ -210,7 +226,13 @@ void nf_ct_deliver_cached_events(struct + item.portid = 0; + item.report = 0; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, ++ events | missed, ++ &item); ++#else + ret = notify->fcn(events | missed, &item); ++#endif + + if (likely(ret == 0 && !missed)) + goto out_unlock; \ No newline at end of file diff --git a/target/linux/generic/hack-4.9/260-crypto_test_dependencies.patch b/target/linux/generic/hack-4.9/260-crypto_test_dependencies.patch index f2570f5988..bd406552dc 100644 --- a/target/linux/generic/hack-4.9/260-crypto_test_dependencies.patch +++ b/target/linux/generic/hack-4.9/260-crypto_test_dependencies.patch @@ -43,7 +43,7 @@ Signed-off-by: Felix Fietkau algorithm registration. --- a/crypto/algboss.c +++ b/crypto/algboss.c -@@ -248,12 +248,16 @@ static int cryptomgr_schedule_test(struc +@@ -246,12 +246,16 @@ static int cryptomgr_schedule_test(struc type = alg->cra_flags; /* This piece of crap needs to disappear into per-type test hooks. */ diff --git a/target/linux/generic/hack-4.9/661-use_fq_codel_by_default.patch b/target/linux/generic/hack-4.9/661-use_fq_codel_by_default.patch index ad8bb9e278..63735025ff 100644 --- a/target/linux/generic/hack-4.9/661-use_fq_codel_by_default.patch +++ b/target/linux/generic/hack-4.9/661-use_fq_codel_by_default.patch @@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau EXPORT_SYMBOL(default_qdisc_ops); /* Main transmission queue. */ -@@ -772,7 +772,7 @@ static void attach_one_default_qdisc(str +@@ -773,7 +773,7 @@ static void attach_one_default_qdisc(str void *_unused) { struct Qdisc *qdisc; diff --git a/target/linux/generic/hack-4.9/662-remove_pfifo_fast.patch b/target/linux/generic/hack-4.9/662-remove_pfifo_fast.patch index 03de751bbc..bcf9dfadbe 100644 --- a/target/linux/generic/hack-4.9/662-remove_pfifo_fast.patch +++ b/target/linux/generic/hack-4.9/662-remove_pfifo_fast.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c -@@ -457,146 +457,6 @@ struct Qdisc_ops noqueue_qdisc_ops __rea +@@ -458,146 +458,6 @@ struct Qdisc_ops noqueue_qdisc_ops __rea .owner = THIS_MODULE, }; diff --git a/target/linux/generic/hack-4.9/721-phy_packets.patch b/target/linux/generic/hack-4.9/721-phy_packets.patch index db4c06733c..9c088b7d37 100644 --- a/target/linux/generic/hack-4.9/721-phy_packets.patch +++ b/target/linux/generic/hack-4.9/721-phy_packets.patch @@ -101,7 +101,7 @@ Signed-off-by: Felix Fietkau help --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -2980,10 +2980,20 @@ static int xmit_one(struct sk_buff *skb, +@@ -2976,10 +2976,20 @@ static int xmit_one(struct sk_buff *skb, #endif dev_queue_xmit_nit(skb, dev); diff --git a/target/linux/generic/hack-4.9/901-debloat_sock_diag.patch b/target/linux/generic/hack-4.9/901-debloat_sock_diag.patch index a78bb0f8a4..fd7233f8cc 100644 --- a/target/linux/generic/hack-4.9/901-debloat_sock_diag.patch +++ b/target/linux/generic/hack-4.9/901-debloat_sock_diag.patch @@ -41,7 +41,7 @@ Signed-off-by: Felix Fietkau obj-$(CONFIG_PROC_FS) += net-procfs.o --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -1463,9 +1463,11 @@ void sk_destruct(struct sock *sk) +@@ -1464,9 +1464,11 @@ void sk_destruct(struct sock *sk) static void __sk_free(struct sock *sk) { diff --git a/target/linux/generic/hack-4.9/902-debloat_proc.patch b/target/linux/generic/hack-4.9/902-debloat_proc.patch index 338bbea553..22bba555bf 100644 --- a/target/linux/generic/hack-4.9/902-debloat_proc.patch +++ b/target/linux/generic/hack-4.9/902-debloat_proc.patch @@ -328,7 +328,7 @@ Signed-off-by: Felix Fietkau --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -3093,6 +3093,8 @@ static __net_initdata struct pernet_oper +@@ -3095,6 +3095,8 @@ static __net_initdata struct pernet_oper static int __init proto_init(void) { diff --git a/target/linux/generic/pending-4.9/601-add-kernel-imq-support.patch b/target/linux/generic/pending-4.9/601-add-kernel-imq-support.patch index 3982e2c78c..0841b87a17 100644 --- a/target/linux/generic/pending-4.9/601-add-kernel-imq-support.patch +++ b/target/linux/generic/pending-4.9/601-add-kernel-imq-support.patch @@ -1592,7 +1592,7 @@ * number or errno values. Not nice, but better than additional function --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -141,6 +141,9 @@ +@@ -142,6 +142,9 @@ #include #include #include @@ -1602,7 +1602,7 @@ #include "net-sysfs.h" -@@ -2969,7 +2972,12 @@ static int xmit_one(struct sk_buff *skb, +@@ -2965,7 +2968,12 @@ static int xmit_one(struct sk_buff *skb, unsigned int len; int rc; @@ -1615,7 +1615,7 @@ dev_queue_xmit_nit(skb, dev); len = skb->len; -@@ -3008,6 +3016,8 @@ out: +@@ -3004,6 +3012,8 @@ out: return skb; } diff --git a/target/linux/generic/pending-4.9/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-4.9/680-NET-skip-GRO-for-foreign-MAC-addresses.patch index 53e93e6fdc..d0d2d15b4c 100644 --- a/target/linux/generic/pending-4.9/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ b/target/linux/generic/pending-4.9/680-NET-skip-GRO-for-foreign-MAC-addresses.patch @@ -34,7 +34,7 @@ Signed-off-by: Felix Fietkau __u8 imq_flags:IMQ_F_BITS; --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -4582,6 +4582,9 @@ static enum gro_result dev_gro_receive(s +@@ -4578,6 +4578,9 @@ static enum gro_result dev_gro_receive(s enum gro_result ret; int grow; @@ -44,7 +44,7 @@ Signed-off-by: Felix Fietkau if (!(skb->dev->features & NETIF_F_GRO)) goto normal; -@@ -5877,6 +5880,48 @@ static void __netdev_adjacent_dev_unlink +@@ -5873,6 +5876,48 @@ static void __netdev_adjacent_dev_unlink &upper_dev->adj_list.lower); } @@ -93,7 +93,7 @@ Signed-off-by: Felix Fietkau static int __netdev_upper_dev_link(struct net_device *dev, struct net_device *upper_dev, bool master, void *upper_priv, void *upper_info) -@@ -5949,6 +5994,7 @@ static int __netdev_upper_dev_link(struc +@@ -5945,6 +5990,7 @@ static int __netdev_upper_dev_link(struc goto rollback_lower_mesh; } @@ -101,7 +101,7 @@ Signed-off-by: Felix Fietkau ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev, &changeupper_info.info); ret = notifier_to_errno(ret); -@@ -6075,6 +6121,7 @@ void netdev_upper_dev_unlink(struct net_ +@@ -6071,6 +6117,7 @@ void netdev_upper_dev_unlink(struct net_ list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr); @@ -109,7 +109,7 @@ Signed-off-by: Felix Fietkau call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev, &changeupper_info.info); } -@@ -6678,6 +6725,7 @@ int dev_set_mac_address(struct net_devic +@@ -6674,6 +6721,7 @@ int dev_set_mac_address(struct net_devic if (err) return err; dev->addr_assign_type = NET_ADDR_SET; diff --git a/target/linux/generic/pending-4.9/834-ledtrig-libata.patch b/target/linux/generic/pending-4.9/834-ledtrig-libata.patch index 0913f3ebff..a369c7166e 100644 --- a/target/linux/generic/pending-4.9/834-ledtrig-libata.patch +++ b/target/linux/generic/pending-4.9/834-ledtrig-libata.patch @@ -45,7 +45,7 @@ Signed-off-by: Daniel Golle depends on ACPI --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c -@@ -731,6 +731,19 @@ u64 ata_tf_read_block(const struct ata_t +@@ -730,6 +730,19 @@ u64 ata_tf_read_block(const struct ata_t return block; } @@ -65,7 +65,7 @@ Signed-off-by: Daniel Golle /** * ata_build_rw_tf - Build ATA taskfile for given read/write request * @tf: Target ATA taskfile -@@ -4998,6 +5011,9 @@ struct ata_queued_cmd *ata_qc_new_init(s +@@ -4997,6 +5010,9 @@ struct ata_queued_cmd *ata_qc_new_init(s if (tag < 0) return NULL; } @@ -75,7 +75,7 @@ Signed-off-by: Daniel Golle qc = __ata_qc_from_tag(ap, tag); qc->tag = tag; -@@ -5899,6 +5915,9 @@ struct ata_port *ata_port_alloc(struct a +@@ -5898,6 +5914,9 @@ struct ata_port *ata_port_alloc(struct a ap->stats.unhandled_irq = 1; ap->stats.idle_irq = 1; #endif @@ -85,7 +85,7 @@ Signed-off-by: Daniel Golle ata_sff_port_init(ap); return ap; -@@ -5920,6 +5939,12 @@ static void ata_host_release(struct devi +@@ -5919,6 +5938,12 @@ static void ata_host_release(struct devi kfree(ap->pmp_link); kfree(ap->slave_link); @@ -98,7 +98,7 @@ Signed-off-by: Daniel Golle kfree(ap); host->ports[i] = NULL; } -@@ -6366,7 +6391,23 @@ int ata_host_register(struct ata_host *h +@@ -6365,7 +6390,23 @@ int ata_host_register(struct ata_host *h host->ports[i]->print_id = atomic_inc_return(&ata_print_id); host->ports[i]->local_port_no = i + 1; } @@ -124,17 +124,17 @@ Signed-off-by: Daniel Golle rc = ata_tport_add(host->dev,host->ports[i]); --- a/include/linux/libata.h +++ b/include/linux/libata.h -@@ -38,6 +38,9 @@ - #include +@@ -39,6 +39,9 @@ #include #include + #include +#ifdef CONFIG_ATA_LEDS +#include +#endif /* * Define if arch has non-standard setup. This is a _PCI_ standard -@@ -884,6 +887,12 @@ struct ata_port { +@@ -887,6 +890,12 @@ struct ata_port { #ifdef CONFIG_ATA_ACPI struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ #endif diff --git a/target/linux/ipq40xx/Makefile b/target/linux/ipq40xx/Makefile index ac8e6de739..8a8470ac26 100644 --- a/target/linux/ipq40xx/Makefile +++ b/target/linux/ipq40xx/Makefile @@ -20,6 +20,6 @@ DEFAULT_PACKAGES += \ kmod-usb3 kmod-usb-dwc3 ath10k-firmware-qca4019 \ automount autosamba luci-app-ipsec-vpnd v2ray shadowsocks-libev-ss-redir shadowsocksr-libev-server \ luci-app-unblockmusic luci-app-cpufreq luci-app-zerotier ca-certificates \ - htop fdisk e2fsprogs + htop fdisk e2fsprogs ethtool $(eval $(call BuildTarget)) diff --git a/target/linux/mediatek/patches-4.14/0190-usb-xhci-mtk-supports-remote-wakeup-for-mt2712-with-.patch b/target/linux/mediatek/patches-4.14/0190-usb-xhci-mtk-supports-remote-wakeup-for-mt2712-with-.patch index c49efcbd38..2742915c4a 100644 --- a/target/linux/mediatek/patches-4.14/0190-usb-xhci-mtk-supports-remote-wakeup-for-mt2712-with-.patch +++ b/target/linux/mediatek/patches-4.14/0190-usb-xhci-mtk-supports-remote-wakeup-for-mt2712-with-.patch @@ -229,7 +229,7 @@ Signed-off-by: Greg Kroah-Hartman mtk->num_phys = of_count_phandle_with_args(node, "phys", "#phy-cells"); -@@ -782,7 +725,7 @@ static int __maybe_unused xhci_mtk_suspe +@@ -783,7 +726,7 @@ static int __maybe_unused xhci_mtk_suspe xhci_mtk_host_disable(mtk); xhci_mtk_phy_power_off(mtk); xhci_mtk_clks_disable(mtk); @@ -238,7 +238,7 @@ Signed-off-by: Greg Kroah-Hartman return 0; } -@@ -792,7 +735,7 @@ static int __maybe_unused xhci_mtk_resum +@@ -793,7 +736,7 @@ static int __maybe_unused xhci_mtk_resum struct usb_hcd *hcd = mtk->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); diff --git a/target/linux/x86/Makefile b/target/linux/x86/Makefile index 2ff78df339..b113f2cae6 100644 --- a/target/linux/x86/Makefile +++ b/target/linux/x86/Makefile @@ -21,9 +21,8 @@ include $(INCLUDE_DIR)/target.mk DEFAULT_PACKAGES += partx-utils mkf2fs fdisk e2fsprogs wpad kmod-usb-hid kmod-ath5k kmod-ath9k kmod-ath9k-htc kmod-ath10k \ kmod-rt2800-usb kmod-e1000e kmod-igb kmod-igbvf kmod-ixgbe kmod-pcnet32 kmod-tulip kmod-vmxnet3 kmod-i40e kmod-i40evf kmod-r8125 kmod-r8168 kmod-8139cp kmod-8139too kmod-fs-f2fs \ -htop lm-sensors autocore-x86 automount autosamba luci-app-ipsec-vpnd luci-proto-bonding luci-app-xlnetacc luci-app-zerotier ca-certificates ddns-scripts_aliyun ddns-scripts_dnspod \ -luci-app-airplay2 luci-app-music-remote-center luci-app-qbittorrent luci-app-amule luci-app-openvpn-server luci-app-unblockmusic \ -ath10k-firmware-qca988x ath10k-firmware-qca9888 ath10k-firmware-qca9984 brcmfmac-firmware-43602a1-pcie \ +htop lm-sensors autocore-x86 automount autosamba luci-app-ipsec-vpnd luci-proto-bonding luci-app-xlnetacc luci-app-unblockmusic luci-app-zerotier \ +ath10k-firmware-qca988x ath10k-firmware-qca9888 ath10k-firmware-qca9984 brcmfmac-firmware-43602a1-pcie ca-certificates ddns-scripts_aliyun ddns-scripts_dnspod \ kmod-sound-hda-core kmod-sound-hda-codec-realtek kmod-sound-hda-codec-via kmod-sound-via82xx kmod-sound-hda-intel kmod-sound-hda-codec-hdmi kmod-sound-i8x0 kmod-usb-audio \ kmod-usb-net kmod-usb-net-asix kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8150 kmod-usb-net-rtl8152 kmod-mlx4-core kmod-mlx5-core diff --git a/target/linux/x86/config-4.19 b/target/linux/x86/config-4.19 index f910fb945f..db792ca5a1 100644 --- a/target/linux/x86/config-4.19 +++ b/target/linux/x86/config-4.19 @@ -151,6 +151,7 @@ CONFIG_DECOMPRESS_BZIP2=y CONFIG_DECOMPRESS_GZIP=y CONFIG_DEFAULT_IO_DELAY_TYPE=0 # CONFIG_DELL_RBU is not set +CONFIG_DMADEVICES=y CONFIG_DMA_DIRECT_OPS=y CONFIG_DMI=y CONFIG_DMIID=y diff --git a/target/linux/x86/patches-4.9/200-pcengines-apu2-reboot.patch b/target/linux/x86/patches-4.9/200-pcengines-apu2-reboot.patch index 0eaf1ed70c..0a312fbe3f 100644 --- a/target/linux/x86/patches-4.9/200-pcengines-apu2-reboot.patch +++ b/target/linux/x86/patches-4.9/200-pcengines-apu2-reboot.patch @@ -1,6 +1,6 @@ --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c -@@ -470,6 +470,16 @@ static struct dmi_system_id __initdata r +@@ -478,6 +478,16 @@ static struct dmi_system_id __initdata r }, },