diff --git a/package/kernel/fast-classifier/Makefile b/package/network/utils/fast-classifier/Makefile similarity index 80% rename from package/kernel/fast-classifier/Makefile rename to package/network/utils/fast-classifier/Makefile index e04601696c..34ecfd73ce 100644 --- a/package/kernel/fast-classifier/Makefile +++ b/package/network/utils/fast-classifier/Makefile @@ -16,7 +16,6 @@ define KernelPackage/fast-classifier CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y \ CONFIG_NF_CONNTRACK_MARK=y DEPENDS:=+kmod-ipt-conntrack +kmod-shortcut-fe - PROVIDES:=fast-classifier endef define KernelPackage/fast-classifier/description @@ -35,25 +34,22 @@ define Package/fast-classifier-example/description classifier kernel module. endef -SFE_MAKE_OPTS:=SFE_SUPPORT_IPV6=y -EXTRA_CFLAGS+=-I$(STAGING_DIR)/usr/include/shortcut-fe +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/shortcut-fe define Build/Compile - +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(SFE_MAKE_OPTS)) \ - $(KERNEL_MAKE_FLAGS) \ - $(PKG_MAKE_FLAGS) \ - M="$(PKG_BUILD_DIR)" \ + +$(KERNEL_MAKE) $(PKG_JOBS) M="$(PKG_BUILD_DIR)" \ CONFIG_FAST_CLASSIFIER=m \ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + SFE_SUPPORT_IPV6=y \ modules ifneq ($(CONFIG_PACKAGE_fast-classifier-example),) - $(TARGET_CC) -o $(PKG_BUILD_DIR)/userspace_fast_classifier \ - -I $(PKG_BUILD_DIR) \ + $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \ -I$(STAGING_DIR)/usr/include/libnl \ -I$(STAGING_DIR)/usr/include/libnl3 \ -lnl-genl-3 -lnl-3 \ - $(PKG_BUILD_DIR)/nl_classifier_test.c + $(PKG_BUILD_DIR)/nl_classifier_test.c \ + -o $(PKG_BUILD_DIR)/userspace_fast_classifier endif endef diff --git a/package/kernel/fast-classifier/src/Makefile b/package/network/utils/fast-classifier/src/Makefile similarity index 100% rename from package/kernel/fast-classifier/src/Makefile rename to package/network/utils/fast-classifier/src/Makefile diff --git a/package/kernel/fast-classifier/src/fast-classifier.c b/package/network/utils/fast-classifier/src/fast-classifier.c similarity index 100% rename from package/kernel/fast-classifier/src/fast-classifier.c rename to package/network/utils/fast-classifier/src/fast-classifier.c diff --git a/package/kernel/fast-classifier/src/fast-classifier.h b/package/network/utils/fast-classifier/src/fast-classifier.h similarity index 100% rename from package/kernel/fast-classifier/src/fast-classifier.h rename to package/network/utils/fast-classifier/src/fast-classifier.h diff --git a/package/kernel/fast-classifier/src/nl_classifier_test.c b/package/network/utils/fast-classifier/src/nl_classifier_test.c similarity index 100% rename from package/kernel/fast-classifier/src/nl_classifier_test.c rename to package/network/utils/fast-classifier/src/nl_classifier_test.c diff --git a/package/kernel/fast-classifier/src/userspace_example.c b/package/network/utils/fast-classifier/src/userspace_example.c similarity index 100% rename from package/kernel/fast-classifier/src/userspace_example.c rename to package/network/utils/fast-classifier/src/userspace_example.c diff --git a/package/kernel/shortcut-fe/Makefile b/package/network/utils/shortcut-fe/Makefile similarity index 82% rename from package/kernel/shortcut-fe/Makefile rename to package/network/utils/shortcut-fe/Makefile index d9b9c72197..e8762ccb7b 100644 --- a/package/kernel/shortcut-fe/Makefile +++ b/package/network/utils/shortcut-fe/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014 The Linux Foundation. All rights reserved. +# Copyright (c) 2013-2018, 2020 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. @@ -11,11 +11,12 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # + include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=shortcut-fe -PKG_RELEASE:=3 +PKG_RELEASE:=8 include $(INCLUDE_DIR)/package.mk @@ -23,7 +24,7 @@ define KernelPackage/shortcut-fe SECTION:=kernel CATEGORY:=Kernel modules SUBMENU:=Network Support - DEPENDS:= + DEPENDS:=@IPV6 +kmod-nf-conntrack TITLE:=Kernel driver for SFE FILES:= \ $(PKG_BUILD_DIR)/shortcut-fe.ko \ @@ -33,7 +34,7 @@ define KernelPackage/shortcut-fe CONFIG_NF_CONNTRACK_TIMEOUT=y \ CONFIG_SHORTCUT_FE=y \ CONFIG_XFRM=y - AUTOLOAD:=$(call AutoLoad,09,shortcut-fe shortcut-fe-ipv6) + # AUTOLOAD:=$(call AutoLoad,09,shortcut-fe shortcut-fe-ipv6) endef define KernelPackage/shortcut-fe/Description @@ -47,7 +48,11 @@ 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 + KCONFIG:= \ + CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y \ + CONFIG_NF_CONNTRACK_EVENTS=y \ + CONFIG_XFRM=y + # AUTOLOAD:=$(call AutoLoad,10,shortcut-fe-cm) endef define KernelPackage/shortcut-fe-cm/Description @@ -57,18 +62,15 @@ endef EXTRA_CFLAGS+= -DSFE_SUPPORT_IPV6 define Build/Compile - +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ - $(KERNEL_MAKE_FLAGS) \ - $(PKG_MAKE_FLAGS) \ + +$(KERNEL_MAKE) $(PKG_JOBS) \ M="$(PKG_BUILD_DIR)" \ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ - SFE_SUPPORT_IPV6=1 \ modules endef define Build/InstallDev $(INSTALL_DIR) $(1)/usr/include/shortcut-fe - $(CP) -rf $(PKG_BUILD_DIR)/*.h $(1)/usr/include/shortcut-fe + $(CP) $(PKG_BUILD_DIR)/sfe.h $(1)/usr/include/shortcut-fe endef define KernelPackage/shortcut-fe/install diff --git a/package/kernel/shortcut-fe/files/etc/init.d/shortcut-fe b/package/network/utils/shortcut-fe/files/etc/init.d/shortcut-fe similarity index 71% rename from package/kernel/shortcut-fe/files/etc/init.d/shortcut-fe rename to package/network/utils/shortcut-fe/files/etc/init.d/shortcut-fe index 8c0d3a27ac..ee2da820e4 100755 --- a/package/kernel/shortcut-fe/files/etc/init.d/shortcut-fe +++ b/package/network/utils/shortcut-fe/files/etc/init.d/shortcut-fe @@ -15,7 +15,7 @@ #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 +START=70 have_cm() { [ -d "/sys/kernel/debug/ecm" ] && echo 1 && return @@ -23,27 +23,29 @@ have_cm() { echo 0 } -#load shortcut-fe connection manager -load_sfe_cm() { +#load shortcut-fe and connection manager +load_sfe() { 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/fast-classifier.ko" ] && { - [ -d /sys/module/fast_classifier ] || insmod /lib/modules/$kernel_version/fast-classifier.ko && return - } + [ -d "/sys/module/shortcut_fe" ] || insmod /lib/modules/$kernel_version/shortcut-fe.ko + [ -d "/sys/module/shortcut_fe_ipv6" ] || insmod /lib/modules/$kernel_version/shortcut-fe-ipv6.ko [ -e "/lib/modules/$kernel_version/shortcut-fe-cm.ko" ] && { - [ -d /sys/module/shortcut_fe_cm ] || insmod /lib/modules/$kernel_version/shortcut-fe-cm.ko && return + [ -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 + [ "$(have_cm)" = "0" ] && load_sfe } stop() { - [ -d /sys/module/shortcut_fe_cm ] && rmmod shortcut_fe_cm - [ -d /sys/module/fast_classifier ] && rmmod fast_classifier + [ -d "/sys/module/shortcut_fe_cm" ] && rmmod shortcut_fe_cm + [ -d "/sys/module/shortcut_fe_ipv6" ] && rmmod shortcut_fe_ipv6 + [ -d "/sys/module/shortcut_fe" ] && rmmod shortcut_fe + [ -d "/sys/module/shortcut_fe_drv" ] && rmmod shortcut_fe_drv + [ -d "/sys/module/fast_classifier" ] && rmmod fast_classifier } diff --git a/package/kernel/shortcut-fe/files/usr/bin/sfe_dump b/package/network/utils/shortcut-fe/files/usr/bin/sfe_dump similarity index 100% rename from package/kernel/shortcut-fe/files/usr/bin/sfe_dump rename to package/network/utils/shortcut-fe/files/usr/bin/sfe_dump diff --git a/package/kernel/shortcut-fe/src/Kconfig b/package/network/utils/shortcut-fe/src/Kconfig similarity index 100% rename from package/kernel/shortcut-fe/src/Kconfig rename to package/network/utils/shortcut-fe/src/Kconfig diff --git a/package/kernel/shortcut-fe/src/Makefile b/package/network/utils/shortcut-fe/src/Makefile similarity index 91% rename from package/kernel/shortcut-fe/src/Makefile rename to package/network/utils/shortcut-fe/src/Makefile index 3b1ceaa44e..991a20ec63 100644 --- a/package/kernel/shortcut-fe/src/Makefile +++ b/package/network/utils/shortcut-fe/src/Makefile @@ -21,3 +21,4 @@ endif shortcut-fe-cm-objs := \ sfe_cm.o +ccflags-y += -Werror -Wall diff --git a/package/kernel/shortcut-fe/src/sfe.h b/package/network/utils/shortcut-fe/src/sfe.h similarity index 100% rename from package/kernel/shortcut-fe/src/sfe.h rename to package/network/utils/shortcut-fe/src/sfe.h diff --git a/package/kernel/shortcut-fe/src/sfe_backport.h b/package/network/utils/shortcut-fe/src/sfe_backport.h similarity index 99% rename from package/kernel/shortcut-fe/src/sfe_backport.h rename to package/network/utils/shortcut-fe/src/sfe_backport.h index 2f8c8ca3c1..d2d60c73c9 100644 --- a/package/kernel/shortcut-fe/src/sfe_backport.h +++ b/package/network/utils/shortcut-fe/src/sfe_backport.h @@ -180,7 +180,7 @@ static inline struct net_device *sfe_dev_get_master(struct net_device *dev) #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) -#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, daddr) +#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, addr) #else static inline struct neighbour * sfe_dst_get_neighbour(struct dst_entry *dst, void *daddr) diff --git a/package/kernel/shortcut-fe/src/sfe_cm.c b/package/network/utils/shortcut-fe/src/sfe_cm.c similarity index 89% rename from package/kernel/shortcut-fe/src/sfe_cm.c rename to package/network/utils/shortcut-fe/src/sfe_cm.c index 18f3475e5b..2d3f79a048 100644 --- a/package/kernel/shortcut-fe/src/sfe_cm.c +++ b/package/network/utils/shortcut-fe/src/sfe_cm.c @@ -2,7 +2,7 @@ * sfe-cm.c * Shortcut forwarding engine connection manager. * - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, 2020 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. @@ -199,7 +199,7 @@ int sfe_cm_recv(struct sk_buff *skb) * structure, obtain the hardware address. This means this function also * works if the neighbours are routers too. */ -static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device **dev, u8 *mac_addr, int is_v4) +static bool sfe_cm_find_dev_and_mac_addr(struct sk_buff *skb, sfe_ip_addr_t *addr, struct net_device **dev, u8 *mac_addr, int is_v4) { struct neighbour *neigh; struct rtable *rt; @@ -207,6 +207,15 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device 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 work when the @@ -220,11 +229,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 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)) rt6 = rt6_lookup(&init_net, (struct in6_addr *)addr->ip6, 0, 0, 0); -#endif /*KERNEL_VERSION(4, 17, 0)*/ +#else + rt6 = rt6_lookup(&init_net, (struct in6_addr *)addr->ip6, 0, 0, NULL, 0); +#endif if (!rt6) { goto ret_fail; } @@ -232,18 +241,21 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device dst = (struct dst_entry *)rt6; } +skip_dst_lookup: rcu_read_lock(); 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; } @@ -251,7 +263,8 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device if (!mac_dev) { rcu_read_unlock(); neigh_release(neigh); - dst_release(dst); + if (likely(!skb)) + dst_release(dst); goto ret_fail; } @@ -261,7 +274,8 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device *dev = mac_dev; rcu_read_unlock(); neigh_release(neigh); - dst_release(dst); + if (likely(!skb)) + dst_release(dst); return true; @@ -295,7 +309,13 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) struct net_device *dest_br_dev = NULL; struct nf_conntrack_tuple orig_tuple; struct nf_conntrack_tuple reply_tuple; + struct sk_buff *tmp_skb = NULL; SFE_NF_CONN_ACCT(acct); + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + struct net *net=NULL; + struct nf_tcp_net *tn=NULL; + #endif /* * Don't process broadcast or multicast packets. @@ -352,16 +372,18 @@ 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. */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) if (unlikely(nf_ct_is_untracked(ct))) { +#else + if (unlikely(ctinfo == IP_CT_UNTRACKED)) { +#endif sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_CT_NO_TRACK); 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, @@ -479,8 +501,13 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) sic.dest_td_max_window = ct->proto.tcp.seen[1].td_maxwin; sic.dest_td_end = ct->proto.tcp.seen[1].td_end; sic.dest_td_max_end = ct->proto.tcp.seen[1].td_maxend; - - if (nf_ct_tcp_no_window_check +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + net = nf_ct_net(ct); + tn = nf_tcp_pernet(net); + if ((tn&&tn->tcp_no_window_check) +#else + if (nf_ct_tcp_no_window_check +#endif || (ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_BE_LIBERAL) || (ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { sic.flags |= SFE_CREATE_FLAG_NO_SEQ_CHECK; @@ -510,6 +537,21 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4) return NF_ACCEPT; } spin_unlock_bh(&ct->lock); + + /* + * 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("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("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; case IPPROTO_UDP: @@ -533,10 +575,10 @@ 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 (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) if (unlikely(skb->sp)) { +#else + if (unlikely(secpath_exists(skb))) { #endif if (sic.protocol == IPPROTO_TCP && !(sic.flags & SFE_CREATE_FLAG_NO_SEQ_CHECK)) { @@ -564,25 +606,27 @@ 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_tmp, sic.src_mac, is_v4)) { + if (!sfe_cm_find_dev_and_mac_addr(NULL, &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)) { + if (!sfe_cm_find_dev_and_mac_addr(NULL, &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)) { + /* Somehow, for IPv6, we need this workaround as well */ + if (unlikely(!is_v4)) + tmp_skb = skb; + if (!sfe_cm_find_dev_and_mac_addr(tmp_skb, &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_tmp, sic.dest_mac_xlate, is_v4)) { + if (!sfe_cm_find_dev_and_mac_addr(skb, &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; } @@ -688,14 +732,11 @@ static int sfe_cm_conntrack_event(unsigned int events, struct nf_ct_event *item) } #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) - /* - * If this is an untracked connection then we can't have any state either. - */ if (unlikely(nf_ct_is_untracked(ct))) { DEBUG_TRACE("ignoring untracked conn\n"); return NOTIFY_DONE; } -#endif /*KERNEL_VERSION(4, 12, 0)*/ +#endif /* * We're only interested in destroy events. @@ -825,18 +866,17 @@ 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)*/ - +#endif /* * 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)) - ct->timeout += sis->delta_jiffies; -#else +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) ct->timeout.expires += sis->delta_jiffies; -#endif /*KERNEL_VERSION(4, 9, 0)*/ +#else + ct->timeout += sis->delta_jiffies; +#endif spin_unlock_bh(&ct->lock); } @@ -891,26 +931,26 @@ static void sfe_cm_sync_rule(struct sfe_connection_sync *sis) if (reply_pkts != 0) { unsigned int *timeouts; - + struct nf_conntrack_l4proto *l4proto __maybe_unused; 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; - +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) 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); + ct->timeout.expires = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); +#else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { + timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts; + } spin_lock_bh(&ct->lock); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; -#else - ct->timeout.expires = jiffies + timeouts[UDP_CT_REPLIED]; -#endif /*KERNEL_VERSION(4, 9, 0)*/ spin_unlock_bh(&ct->lock); +#endif } } break; @@ -1001,6 +1041,9 @@ static int __init sfe_cm_init(void) { struct sfe_cm *sc = &__sc; int result = -1; +#ifdef CONFIG_SFE_ECM + int (*fast_recv)(struct sk_buff *skb); +#endif DEBUG_INFO("SFE CM init\n"); @@ -1036,7 +1079,11 @@ static int __init sfe_cm_init(void) /* * Register our netfilter hooks. */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)) + result = nf_register_hooks(sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); +#else result = nf_register_net_hooks(&init_net, sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); +#endif if (result < 0) { DEBUG_ERROR("can't register nf post routing hook: %d\n", result); goto exit3; @@ -1049,22 +1096,30 @@ static int __init sfe_cm_init(void) */ #ifdef CONFIG_NF_CONNTRACK_EVENTS #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS - (void)nf_conntrack_register_chain_notifier(&init_net, &sfe_cm_conntrack_notifier); + result = nf_conntrack_register_chain_notifier(&init_net, &sfe_cm_conntrack_notifier); #else result = nf_conntrack_register_notifier(&init_net, &sfe_cm_conntrack_notifier); +#endif if (result < 0) { DEBUG_ERROR("can't register nf notifier hook: %d\n", result); goto exit4; } #endif -#endif - spin_lock_init(&sc->lock); /* * Hook the receive path in the network stack. */ +#ifdef CONFIG_SFE_ECM + rcu_read_lock(); + fast_recv = rcu_dereference(athrs_fast_nat_recv); + rcu_read_unlock(); + if (!fast_recv) { + BUG_ON(athrs_fast_nat_recv); + } +#else BUG_ON(athrs_fast_nat_recv); +#endif RCU_INIT_POINTER(athrs_fast_nat_recv, sfe_cm_recv); /* @@ -1075,10 +1130,15 @@ static int __init sfe_cm_init(void) return 0; #ifdef CONFIG_NF_CONNTRACK_EVENTS -#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS exit4: +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)) + nf_unregister_hooks(sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); +#else nf_unregister_net_hooks(&init_net, sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); #endif + +#endif #endif exit3: unregister_inet6addr_notifier(&sc->inet6_notifier); @@ -1129,8 +1189,12 @@ static void __exit sfe_cm_exit(void) nf_conntrack_unregister_notifier(&init_net, &sfe_cm_conntrack_notifier); #endif #endif - nf_unregister_net_hooks(&init_net, sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)) + nf_unregister_hooks(sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); +#else + nf_unregister_net_hooks(&init_net, sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing)); +#endif unregister_inet6addr_notifier(&sc->inet6_notifier); unregister_inetaddr_notifier(&sc->inet_notifier); unregister_netdevice_notifier(&sc->dev_notifier); diff --git a/package/kernel/shortcut-fe/src/sfe_cm.h b/package/network/utils/shortcut-fe/src/sfe_cm.h similarity index 99% rename from package/kernel/shortcut-fe/src/sfe_cm.h rename to package/network/utils/shortcut-fe/src/sfe_cm.h index 23cbde859b..124c86f47d 100644 --- a/package/kernel/shortcut-fe/src/sfe_cm.h +++ b/package/network/utils/shortcut-fe/src/sfe_cm.h @@ -152,8 +152,9 @@ extern int (*athrs_fast_nat_recv)(struct sk_buff *skb); /* * Expose what should be a static flag in the TCP connection tracker. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) extern int nf_ct_tcp_no_window_check; - +#endif /* * This callback will be called in a timer * at 100 times per second to sync stats back to diff --git a/package/kernel/shortcut-fe/src/sfe_ipv4.c b/package/network/utils/shortcut-fe/src/sfe_ipv4.c similarity index 99% rename from package/kernel/shortcut-fe/src/sfe_ipv4.c rename to package/network/utils/shortcut-fe/src/sfe_ipv4.c index 531456c05f..cdcdd66dd6 100644 --- a/package/kernel/shortcut-fe/src/sfe_ipv4.c +++ b/package/network/utils/shortcut-fe/src/sfe_ipv4.c @@ -2,7 +2,7 @@ * sfe_ipv4.c * Shortcut forwarding engine - IPv4 edition. * - * Copyright (c) 2013-2016, 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 2019-2020 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. @@ -1311,14 +1311,13 @@ static int sfe_ipv4_recv_udp(struct sfe_ipv4 *si, struct sk_buff *skb, struct ne * change the cloned skb's data section. */ if (unlikely(skb_cloned(skb))) { - DEBUG_TRACE("%p: skb is a cloned skb\n", skb); + DEBUG_TRACE("%px: 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; } @@ -1891,14 +1890,13 @@ static int sfe_ipv4_recv_tcp(struct sfe_ipv4 *si, struct sk_buff *skb, struct ne * change the cloned skb's data section. */ if (unlikely(skb_cloned(skb))) { - DEBUG_TRACE("%p: skb is a cloned skb\n", skb); + DEBUG_TRACE("%px: 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; } @@ -2512,7 +2510,7 @@ int sfe_ipv4_create_rule(struct sfe_connection_create *sic) spin_unlock_bh(&si->lock); DEBUG_TRACE("connection already exists - mark: %08x, p: %d\n" - " s: %s:%pM:%pI4:%u, d: %s:%pM:%pI4:%u\n", + " s: %s:%pxM:%pI4:%u, d: %s:%pxM:%pI4:%u\n", sic->mark, sic->protocol, sic->src_dev->name, sic->src_mac, &sic->src_ip.ip, ntohs(sic->src_port), sic->dest_dev->name, sic->dest_mac, &sic->dest_ip.ip, ntohs(sic->dest_port)); @@ -2728,8 +2726,8 @@ int sfe_ipv4_create_rule(struct sfe_connection_create *sic) * We have everything we need! */ DEBUG_INFO("new connection - mark: %08x, p: %d\n" - " s: %s:%pM(%pM):%pI4(%pI4):%u(%u)\n" - " d: %s:%pM(%pM):%pI4(%pI4):%u(%u)\n", + " s: %s:%pxM(%pxM):%pI4(%pI4):%u(%u)\n" + " d: %s:%pxM(%pxM):%pI4(%pI4):%u(%u)\n", sic->mark, sic->protocol, sic->src_dev->name, sic->src_mac, sic->src_mac_xlate, &sic->src_ip.ip, &sic->src_ip_xlate.ip, ntohs(sic->src_port), ntohs(sic->src_port_xlate), @@ -2858,17 +2856,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 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) 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 +static void sfe_ipv4_periodic_sync(struct timer_list *tl) +#endif +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) struct sfe_ipv4 *si = (struct sfe_ipv4 *)arg; -#endif /*KERNEL_VERSION(4, 15, 0)*/ +#else + struct sfe_ipv4 *si = from_timer(si, tl, timer); +#endif u64 now_jiffies; int quota; sfe_sync_rule_callback_t sync_rule_callback; @@ -3547,12 +3545,11 @@ 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 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) setup_timer(&si->timer, sfe_ipv4_periodic_sync, (unsigned long)si); -#endif /*KERNEL_VERSION(4, 15, 0)*/ +#else + timer_setup(&si->timer, sfe_ipv4_periodic_sync, 0); +#endif mod_timer(&si->timer, jiffies + ((HZ + 99) / 100)); spin_lock_init(&si->lock); diff --git a/package/kernel/shortcut-fe/src/sfe_ipv6.c b/package/network/utils/shortcut-fe/src/sfe_ipv6.c similarity index 99% rename from package/kernel/shortcut-fe/src/sfe_ipv6.c rename to package/network/utils/shortcut-fe/src/sfe_ipv6.c index 3c5ef12630..ae3306693c 100644 --- a/package/kernel/shortcut-fe/src/sfe_ipv6.c +++ b/package/network/utils/shortcut-fe/src/sfe_ipv6.c @@ -2,7 +2,7 @@ * sfe_ipv6.c * Shortcut forwarding engine - IPv6 support. * - * Copyright (c) 2015-2016, 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, 2019-2020 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. @@ -1369,14 +1369,13 @@ static int sfe_ipv6_recv_udp(struct sfe_ipv6 *si, struct sk_buff *skb, struct ne * change the cloned skb's data section. */ if (unlikely(skb_cloned(skb))) { - DEBUG_TRACE("%p: skb is a cloned skb\n", skb); + DEBUG_TRACE("%px: 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; } @@ -1929,14 +1928,13 @@ static int sfe_ipv6_recv_tcp(struct sfe_ipv6 *si, struct sk_buff *skb, struct ne * change the cloned skb's data section. */ if (unlikely(skb_cloned(skb))) { - DEBUG_TRACE("%p: skb is a cloned skb\n", skb); + DEBUG_TRACE("%px: 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; } @@ -2328,7 +2326,7 @@ int sfe_ipv6_recv(struct net_device *dev, struct sk_buff *skb) si->packets_not_forwarded++; spin_unlock_bh(&si->lock); - DEBUG_TRACE("payload_len: %u, exceeds len: %u\n", payload_len, (len - sizeof(struct sfe_ipv6_ip_hdr))); + DEBUG_TRACE("payload_len: %u, exceeds len: %u\n", payload_len, (len - (unsigned int)sizeof(struct sfe_ipv6_ip_hdr))); return 0; } @@ -2526,7 +2524,7 @@ int sfe_ipv6_create_rule(struct sfe_connection_create *sic) spin_unlock_bh(&si->lock); DEBUG_TRACE("connection already exists - mark: %08x, p: %d\n" - " s: %s:%pM:%pI6:%u, d: %s:%pM:%pI6:%u\n", + " s: %s:%pxM:%pI6:%u, d: %s:%pxM:%pI6:%u\n", sic->mark, sic->protocol, sic->src_dev->name, sic->src_mac, sic->src_ip.ip6, ntohs(sic->src_port), sic->dest_dev->name, sic->dest_mac, sic->dest_ip.ip6, ntohs(sic->dest_port)); @@ -2742,8 +2740,8 @@ int sfe_ipv6_create_rule(struct sfe_connection_create *sic) * We have everything we need! */ DEBUG_INFO("new connection - mark: %08x, p: %d\n" - " s: %s:%pM(%pM):%pI6(%pI6):%u(%u)\n" - " d: %s:%pM(%pM):%pI6(%pI6):%u(%u)\n", + " s: %s:%pxM(%pxM):%pI6(%pI6):%u(%u)\n" + " d: %s:%pxM(%pxM):%pI6(%pI6):%u(%u)\n", sic->mark, sic->protocol, sic->src_dev->name, sic->src_mac, sic->src_mac_xlate, sic->src_ip.ip6, sic->src_ip_xlate.ip6, ntohs(sic->src_port), ntohs(sic->src_port_xlate), @@ -2866,17 +2864,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 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) 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 +static void sfe_ipv6_periodic_sync(struct timer_list *tl) +#endif +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) struct sfe_ipv6 *si = (struct sfe_ipv6 *)arg; -#endif /*KERNEL_VERSION(4, 15, 0)*/ +#else + struct sfe_ipv6 *si = from_timer(si, tl, timer); +#endif u64 now_jiffies; int quota; sfe_sync_rule_callback_t sync_rule_callback; @@ -3555,12 +3553,11 @@ 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 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) setup_timer(&si->timer, sfe_ipv6_periodic_sync, (unsigned long)si); -#endif /*KERNEL_VERSION(4, 15, 0)*/ +#else + timer_setup(&si->timer, sfe_ipv6_periodic_sync, 0); +#endif mod_timer(&si->timer, jiffies + ((HZ + 99) / 100)); spin_lock_init(&si->lock);