shortcut-fe: sync changes form coolsnowwolf

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2022-11-24 02:22:08 +08:00
parent 6df69462c8
commit 8fb32e9a33
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
17 changed files with 186 additions and 126 deletions

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -21,3 +21,4 @@ endif
shortcut-fe-cm-objs := \
sfe_cm.o
ccflags-y += -Werror -Wall

View File

@ -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)

View File

@ -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,10 +241,12 @@ 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();
if (likely(!skb))
dst_release(dst);
goto ret_fail;
}
@ -243,6 +254,7 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device
if (unlikely(!(neigh->nud_state & NUD_VALID))) {
rcu_read_unlock();
neigh_release(neigh);
if (likely(!skb))
dst_release(dst);
goto ret_fail;
}
@ -251,6 +263,7 @@ 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);
if (likely(!skb))
dst_release(dst);
goto ret_fail;
}
@ -261,6 +274,7 @@ 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);
if (likely(!skb))
dst_release(dst);
return true;
@ -295,8 +309,14 @@ 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 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);

View File

@ -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

View File

@ -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);

View File

@ -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);