mirror of
https://github.com/Ysurac/openmptcprouter-feeds.git
synced 2025-02-12 10:31:51 +00:00
Update shortcut-fe
This commit is contained in:
parent
cf871353f8
commit
89c7a3c206
17 changed files with 369 additions and 702 deletions
|
@ -1,43 +1,60 @@
|
|||
#
|
||||
# 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.
|
||||
# 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.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=fast-classifier
|
||||
PKG_RELEASE:=1
|
||||
PKG_CONFIG_DEPENDS := CONFIG_IPV6
|
||||
PKG_RELEASE:=6
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/$(PKG_NAME)/Default
|
||||
define KernelPackage/fast-classifier/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)
|
||||
KCONFIG:= \
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y \
|
||||
CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y \
|
||||
CONFIG_NF_CONNTRACK_MARK=y \
|
||||
CONFIG_XFRM=y
|
||||
CONFLICTS:=kmod-shortcut-fe-drv kmod-shortcut-fe-cm
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)
|
||||
$(call KernelPackage/$(PKG_NAME)/Default)
|
||||
define KernelPackage/fast-classifier
|
||||
$(call KernelPackage/fast-classifier/Default)
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)-noload
|
||||
$(call KernelPackage/$(PKG_NAME)/Default)
|
||||
define KernelPackage/fast-classifier-noload
|
||||
$(call KernelPackage/fast-classifier/Default)
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)/Default/description
|
||||
define KernelPackage/fast-classifier/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)
|
||||
define KernelPackage/fast-classifier/description
|
||||
$(call KernelPackage/fast-classifier/Default/description)
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)-noload/description
|
||||
$(call KernelPackage/$(PKG_NAME)/Default/description)
|
||||
define KernelPackage/fast-classifier-noload/description
|
||||
$(call KernelPackage/fast-classifier/Default/description)
|
||||
|
||||
This package does not load $(PKG_NAME) at boot by default
|
||||
This package does not load fast-classifier at boot by default
|
||||
endef
|
||||
|
||||
define Package/fast-classifier-example
|
||||
|
@ -50,15 +67,16 @@ Example user space program that communicates with fast
|
|||
classifier kernel module
|
||||
endef
|
||||
|
||||
SFE_MAKE_OPTS:=SFE_SUPPORT_IPV6=$(if $(CONFIG_IPV6),y,n)
|
||||
HAVE_ECM:=$(CONFIG_PACKAGE_kmod-qca-nss-ecm-premium)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-noload)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-premium-noload)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-standard)
|
||||
|
||||
define Build/Compile/kmod
|
||||
+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(SFE_MAKE_OPTS) \
|
||||
+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
$(PKG_MAKE_FLAGS) \
|
||||
M="$(PKG_BUILD_DIR)" \
|
||||
CONFIG_FAST_CLASSIFIER=m \
|
||||
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
|
||||
EXTRA_CFLAGS+="-DSFE_SUPPORT_IPV6" \
|
||||
$(if $(HAVE_ECM),EXTRA_CFLAGS+="-DCONFIG_SFE_ECM" CONFIG_SFE_ECM=y,) \
|
||||
modules
|
||||
endef
|
||||
|
||||
|
@ -81,12 +99,11 @@ define Build/InstallDev
|
|||
$(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 KernelPackage,fast-classifier))
|
||||
#$(eval $(call KernelPackage,fast-classifier-noload))
|
||||
#$(eval $(call BuildPackage,fast-classifier-example))
|
||||
|
|
|
@ -36,9 +36,9 @@
|
|||
#include <linux/hashtable.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "sfe_backport.h"
|
||||
#include "sfe.h"
|
||||
#include "sfe_cm.h"
|
||||
#include <sfe_backport.h>
|
||||
#include <sfe.h>
|
||||
#include <sfe_cm.h>
|
||||
#include "fast-classifier.h"
|
||||
|
||||
typedef enum fast_classifier_exception {
|
||||
|
@ -451,6 +451,10 @@ static u32 fc_conn_hash(sfe_ip_addr_t *saddr, sfe_ip_addr_t *daddr,
|
|||
*/
|
||||
static int fast_classifier_update_protocol(struct sfe_connection_create *p_sic, struct nf_conn *ct)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
||||
struct net *net=NULL ;
|
||||
struct nf_tcp_net *tn=NULL;
|
||||
#endif
|
||||
switch (p_sic->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
p_sic->src_td_window_scale = ct->proto.tcp.seen[0].td_scale;
|
||||
|
@ -461,8 +465,14 @@ static int fast_classifier_update_protocol(struct sfe_connection_create *p_sic,
|
|||
p_sic->dest_td_max_window = ct->proto.tcp.seen[1].td_maxwin;
|
||||
p_sic->dest_td_end = ct->proto.tcp.seen[1].td_end;
|
||||
p_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)) {
|
||||
p_sic->flags |= SFE_CREATE_FLAG_NO_SEQ_CHECK;
|
||||
|
@ -1744,8 +1754,11 @@ static int __init fast_classifier_init(void)
|
|||
{
|
||||
struct fast_classifier *sc = &__sc;
|
||||
int result = -1;
|
||||
#ifdef CONFIG_SFE_ECM
|
||||
int (*fast_recv)(struct sk_buff *skb);
|
||||
#endif
|
||||
|
||||
printk(KERN_ALERT "fast-classifier (PBR safe v2.1.4a): starting up\n");
|
||||
printk(KERN_ALERT "fast-classifier: starting up\n");
|
||||
DEBUG_INFO("SFE CM init\n");
|
||||
|
||||
hash_init(fc_conn_ht);
|
||||
|
@ -1810,6 +1823,7 @@ static int __init fast_classifier_init(void)
|
|||
goto exit3;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
/*
|
||||
* Register a notifier hook to get fast notifications of expired connections.
|
||||
*/
|
||||
|
@ -1817,12 +1831,14 @@ static int __init fast_classifier_init(void)
|
|||
result = nf_conntrack_register_chain_notifier(&init_net, &fast_classifier_conntrack_notifier);
|
||||
#else
|
||||
result = nf_conntrack_register_notifier(&init_net, &fast_classifier_conntrack_notifier);
|
||||
#endif
|
||||
if (result < 0) {
|
||||
DEBUG_ERROR("can't register nf notifier hook: %d\n", result);
|
||||
goto exit4;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
|
||||
result = genl_register_family(&fast_classifier_gnl_family);
|
||||
if (result) {
|
||||
|
@ -1865,7 +1881,16 @@ static int __init fast_classifier_init(void)
|
|||
/*
|
||||
* 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, fast_classifier_recv);
|
||||
|
||||
/*
|
||||
|
@ -1974,3 +1999,4 @@ module_exit(fast_classifier_exit)
|
|||
|
||||
MODULE_DESCRIPTION("Shortcut Forwarding Engine - Connection Manager");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
* sfe.h
|
||||
* Shortcut forwarding engine.
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* 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 2
|
||||
|
||||
#if (DEBUG_LEVEL < 1)
|
||||
#define DEBUG_ASSERT(s, ...)
|
||||
#define DEBUG_ERROR(s, ...)
|
||||
#else
|
||||
#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, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL < 3)
|
||||
#define DEBUG_INFO(s, ...)
|
||||
#else
|
||||
#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, ...) 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*/
|
|
@ -1,195 +0,0 @@
|
|||
/*
|
||||
* sfe_backport.h
|
||||
* Shortcut forwarding engine compatible header file.
|
||||
*
|
||||
* Copyright (c) 2014-2016 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.
|
||||
*/
|
||||
|
||||
#include <linux/version.h>
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
|
||||
#include <net/netfilter/nf_conntrack_timeout.h>
|
||||
#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, \
|
||||
struct sk_buff *SKB, \
|
||||
const struct nf_hook_state *state)
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
|
||||
#define sfe_define_post_routing_hook(FN_NAME, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
|
||||
static unsigned int FN_NAME(const struct nf_hook_ops *OPS, \
|
||||
struct sk_buff *SKB, \
|
||||
const struct net_device *UNUSED, \
|
||||
const struct net_device *OUT, \
|
||||
int (*OKFN)(struct sk_buff *))
|
||||
#else
|
||||
#define sfe_define_post_routing_hook(FN_NAME, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
|
||||
static unsigned int FN_NAME(unsigned int HOOKNUM, \
|
||||
struct sk_buff *SKB, \
|
||||
const struct net_device *UNUSED, \
|
||||
const struct net_device *OUT, \
|
||||
int (*OKFN)(struct sk_buff *))
|
||||
#endif
|
||||
|
||||
#define sfe_cm_ipv4_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
|
||||
sfe_define_post_routing_hook(__sfe_cm_ipv4_post_routing_hook, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN)
|
||||
#define sfe_cm_ipv6_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
|
||||
sfe_define_post_routing_hook(__sfe_cm_ipv6_post_routing_hook, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN)
|
||||
#define fast_classifier_ipv4_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
|
||||
sfe_define_post_routing_hook(__fast_classifier_ipv4_post_routing_hook, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN)
|
||||
#define fast_classifier_ipv6_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
|
||||
sfe_define_post_routing_hook(__fast_classifier_ipv6_post_routing_hook, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN)
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
#define SFE_IPV4_NF_POST_ROUTING_HOOK(fn) \
|
||||
{ \
|
||||
.hook = fn, \
|
||||
.pf = NFPROTO_IPV4, \
|
||||
.hooknum = NF_INET_POST_ROUTING, \
|
||||
.priority = NF_IP_PRI_NAT_SRC + 1, \
|
||||
}
|
||||
#else
|
||||
#define SFE_IPV4_NF_POST_ROUTING_HOOK(fn) \
|
||||
{ \
|
||||
.hook = fn, \
|
||||
.owner = THIS_MODULE, \
|
||||
.pf = NFPROTO_IPV4, \
|
||||
.hooknum = NF_INET_POST_ROUTING, \
|
||||
.priority = NF_IP_PRI_NAT_SRC + 1, \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
#define SFE_IPV6_NF_POST_ROUTING_HOOK(fn) \
|
||||
{ \
|
||||
.hook = fn, \
|
||||
.pf = NFPROTO_IPV6, \
|
||||
.hooknum = NF_INET_POST_ROUTING, \
|
||||
.priority = NF_IP_PRI_NAT_SRC + 1, \
|
||||
}
|
||||
#else
|
||||
#define SFE_IPV6_NF_POST_ROUTING_HOOK(fn) \
|
||||
{ \
|
||||
.hook = fn, \
|
||||
.owner = THIS_MODULE, \
|
||||
.pf = NFPROTO_IPV6, \
|
||||
.hooknum = NF_INET_POST_ROUTING, \
|
||||
.priority = NF_IP6_PRI_NAT_SRC + 1, \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))
|
||||
#define SFE_NF_CT_DEFAULT_ZONE (&nf_ct_zone_dflt)
|
||||
#else
|
||||
#define SFE_NF_CT_DEFAULT_ZONE NF_CT_DEFAULT_ZONE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sfe_dev_get_master
|
||||
* get master of bridge port, and hold it
|
||||
*/
|
||||
static inline struct net_device *sfe_dev_get_master(struct net_device *dev)
|
||||
{
|
||||
struct net_device *master;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
|
||||
rcu_read_lock();
|
||||
master = netdev_master_upper_dev_get_rcu(dev);
|
||||
if (master)
|
||||
dev_hold(master);
|
||||
|
||||
rcu_read_unlock();
|
||||
#else
|
||||
master = dev->master;
|
||||
if (master)
|
||||
dev_hold(master);
|
||||
#endif
|
||||
return master;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
|
||||
#define SFE_DEV_EVENT_PTR(PTR) netdev_notifier_info_to_dev(PTR)
|
||||
#else
|
||||
#define SFE_DEV_EVENT_PTR(PTR) (struct net_device *)(PTR)
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
|
||||
#define SFE_NF_CONN_ACCT(NM) struct nf_conn_acct *NM
|
||||
#else
|
||||
#define SFE_NF_CONN_ACCT(NM) struct nf_conn_counter *NM
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
|
||||
#define SFE_ACCT_COUNTER(NM) ((NM)->counter)
|
||||
#else
|
||||
#define SFE_ACCT_COUNTER(NM) (NM)
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
#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
|
|
@ -1,259 +0,0 @@
|
|||
/*
|
||||
* sfe_cm.h
|
||||
* Shortcut forwarding engine.
|
||||
*
|
||||
* Copyright (c) 2013-2016 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* connection flags.
|
||||
*/
|
||||
#define SFE_CREATE_FLAG_NO_SEQ_CHECK BIT(0)
|
||||
/* Indicates that we should not check sequence numbers */
|
||||
#define SFE_CREATE_FLAG_REMARK_PRIORITY BIT(1)
|
||||
/* Indicates that we should remark priority of skb */
|
||||
#define SFE_CREATE_FLAG_REMARK_DSCP BIT(2)
|
||||
/* Indicates that we should remark DSCP of packet */
|
||||
|
||||
/*
|
||||
* IPv6 address structure
|
||||
*/
|
||||
struct sfe_ipv6_addr {
|
||||
__be32 addr[4];
|
||||
};
|
||||
|
||||
typedef union {
|
||||
__be32 ip;
|
||||
struct sfe_ipv6_addr ip6[1];
|
||||
} sfe_ip_addr_t;
|
||||
|
||||
/*
|
||||
* connection creation structure.
|
||||
*/
|
||||
struct sfe_connection_create {
|
||||
int protocol;
|
||||
struct net_device *src_dev;
|
||||
struct net_device *dest_dev;
|
||||
u32 flags;
|
||||
u32 src_mtu;
|
||||
u32 dest_mtu;
|
||||
sfe_ip_addr_t src_ip;
|
||||
sfe_ip_addr_t src_ip_xlate;
|
||||
sfe_ip_addr_t dest_ip;
|
||||
sfe_ip_addr_t dest_ip_xlate;
|
||||
__be16 src_port;
|
||||
__be16 src_port_xlate;
|
||||
__be16 dest_port;
|
||||
__be16 dest_port_xlate;
|
||||
u8 src_mac[ETH_ALEN];
|
||||
u8 src_mac_xlate[ETH_ALEN];
|
||||
u8 dest_mac[ETH_ALEN];
|
||||
u8 dest_mac_xlate[ETH_ALEN];
|
||||
u8 src_td_window_scale;
|
||||
u32 src_td_max_window;
|
||||
u32 src_td_end;
|
||||
u32 src_td_max_end;
|
||||
u8 dest_td_window_scale;
|
||||
u32 dest_td_max_window;
|
||||
u32 dest_td_end;
|
||||
u32 dest_td_max_end;
|
||||
u32 mark;
|
||||
#ifdef CONFIG_XFRM
|
||||
u32 original_accel;
|
||||
u32 reply_accel;
|
||||
#endif
|
||||
u32 src_priority;
|
||||
u32 dest_priority;
|
||||
u32 src_dscp;
|
||||
u32 dest_dscp;
|
||||
};
|
||||
|
||||
/*
|
||||
* connection destruction structure.
|
||||
*/
|
||||
struct sfe_connection_destroy {
|
||||
int protocol;
|
||||
sfe_ip_addr_t src_ip;
|
||||
sfe_ip_addr_t dest_ip;
|
||||
__be16 src_port;
|
||||
__be16 dest_port;
|
||||
};
|
||||
|
||||
typedef enum sfe_sync_reason {
|
||||
SFE_SYNC_REASON_STATS, /* Sync is to synchronize stats */
|
||||
SFE_SYNC_REASON_FLUSH, /* Sync is to flush a entry */
|
||||
SFE_SYNC_REASON_DESTROY /* Sync is to destroy a entry(requested by connection manager) */
|
||||
} sfe_sync_reason_t;
|
||||
|
||||
/*
|
||||
* Structure used to sync connection stats/state back within the system.
|
||||
*
|
||||
* NOTE: The addresses here are NON-NAT addresses, i.e. the true endpoint addressing.
|
||||
* 'src' is the creator of the connection.
|
||||
*/
|
||||
struct sfe_connection_sync {
|
||||
struct net_device *src_dev;
|
||||
struct net_device *dest_dev;
|
||||
int is_v6; /* Is it for ipv6? */
|
||||
int protocol; /* IP protocol number (IPPROTO_...) */
|
||||
sfe_ip_addr_t src_ip; /* Non-NAT source address, i.e. the creator of the connection */
|
||||
sfe_ip_addr_t src_ip_xlate; /* NATed source address */
|
||||
__be16 src_port; /* Non-NAT source port */
|
||||
__be16 src_port_xlate; /* NATed source port */
|
||||
sfe_ip_addr_t dest_ip; /* Non-NAT destination address, i.e. to whom the connection was created */
|
||||
sfe_ip_addr_t dest_ip_xlate; /* NATed destination address */
|
||||
__be16 dest_port; /* Non-NAT destination port */
|
||||
__be16 dest_port_xlate; /* NATed destination port */
|
||||
u32 src_td_max_window;
|
||||
u32 src_td_end;
|
||||
u32 src_td_max_end;
|
||||
u64 src_packet_count;
|
||||
u64 src_byte_count;
|
||||
u32 src_new_packet_count;
|
||||
u32 src_new_byte_count;
|
||||
u32 dest_td_max_window;
|
||||
u32 dest_td_end;
|
||||
u32 dest_td_max_end;
|
||||
u64 dest_packet_count;
|
||||
u64 dest_byte_count;
|
||||
u32 dest_new_packet_count;
|
||||
u32 dest_new_byte_count;
|
||||
u32 reason; /* reason for stats sync message, i.e. destroy, flush, period sync */
|
||||
u64 delta_jiffies; /* Time to be added to the current timeout to keep the connection alive */
|
||||
};
|
||||
|
||||
/*
|
||||
* connection mark structure
|
||||
*/
|
||||
struct sfe_connection_mark {
|
||||
int protocol;
|
||||
sfe_ip_addr_t src_ip;
|
||||
sfe_ip_addr_t dest_ip;
|
||||
__be16 src_port;
|
||||
__be16 dest_port;
|
||||
u32 mark;
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose the hook for the receive processing.
|
||||
*/
|
||||
extern int (*athrs_fast_nat_recv)(struct sk_buff *skb);
|
||||
|
||||
/*
|
||||
* Expose what should be a static flag in the TCP connection tracker.
|
||||
*/
|
||||
extern int nf_ct_tcp_no_window_check;
|
||||
|
||||
/*
|
||||
* This callback will be called in a timer
|
||||
* at 100 times per second to sync stats back to
|
||||
* Linux connection track.
|
||||
*
|
||||
* A RCU lock is taken to prevent this callback
|
||||
* from unregistering.
|
||||
*/
|
||||
typedef void (*sfe_sync_rule_callback_t)(struct sfe_connection_sync *);
|
||||
|
||||
/*
|
||||
* IPv4 APIs used by connection manager
|
||||
*/
|
||||
int sfe_ipv4_recv(struct net_device *dev, struct sk_buff *skb);
|
||||
int sfe_ipv4_create_rule(struct sfe_connection_create *sic);
|
||||
void sfe_ipv4_destroy_rule(struct sfe_connection_destroy *sid);
|
||||
void sfe_ipv4_destroy_all_rules_for_dev(struct net_device *dev);
|
||||
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
|
||||
*/
|
||||
int sfe_ipv6_recv(struct net_device *dev, struct sk_buff *skb);
|
||||
int sfe_ipv6_create_rule(struct sfe_connection_create *sic);
|
||||
void sfe_ipv6_destroy_rule(struct sfe_connection_destroy *sid);
|
||||
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()
|
||||
* compare ipv6 address
|
||||
*
|
||||
* return: 1, equal; 0, no equal
|
||||
*/
|
||||
static inline int sfe_ipv6_addr_equal(struct sfe_ipv6_addr *a,
|
||||
struct sfe_ipv6_addr *b)
|
||||
{
|
||||
return a->addr[0] == b->addr[0] &&
|
||||
a->addr[1] == b->addr[1] &&
|
||||
a->addr[2] == b->addr[2] &&
|
||||
a->addr[3] == b->addr[3];
|
||||
}
|
||||
|
||||
/*
|
||||
* sfe_ipv4_addr_equal()
|
||||
* compare ipv4 address
|
||||
*
|
||||
* return: 1, equal; 0, no equal
|
||||
*/
|
||||
#define sfe_ipv4_addr_equal(a, b) ((u32)(a) == (u32)(b))
|
||||
|
||||
/*
|
||||
* sfe_addr_equal()
|
||||
* compare ipv4 or ipv6 address
|
||||
*
|
||||
* return: 1, equal; 0, no equal
|
||||
*/
|
||||
static inline int sfe_addr_equal(sfe_ip_addr_t *a,
|
||||
sfe_ip_addr_t *b, int is_v4)
|
||||
{
|
||||
return is_v4 ? sfe_ipv4_addr_equal(a->ip, b->ip) : sfe_ipv6_addr_equal(a->ip6, b->ip6);
|
||||
}
|
|
@ -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,12 +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:=2
|
||||
PKG_CONFIG_DEPENDS := CONFIG_IPV6
|
||||
PKG_RELEASE:=8
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
@ -24,13 +24,17 @@ 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 $(if $(CONFIG_IPV6),$(PKG_BUILD_DIR)/shortcut-fe-ipv6.ko,)
|
||||
KCONFIG:=CONFIG_NF_CONNTRACK_EVENTS=y \
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/shortcut-fe.ko \
|
||||
$(PKG_BUILD_DIR)/shortcut-fe-ipv6.ko
|
||||
KCONFIG:= \
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y \
|
||||
CONFIG_NF_CONNTRACK_TIMEOUT=y \
|
||||
CONFIG_SHORTCUT_FE=y \
|
||||
CONFIG_XFRM=y
|
||||
PROVIDES:=$(PKG_NAME)
|
||||
AUTOLOAD:=$(call AutoLoad,09,shortcut-fe shortcut-fe-ipv6)
|
||||
endef
|
||||
|
||||
|
@ -43,6 +47,8 @@ define KernelPackage/shortcut-fe/install
|
|||
$(INSTALL_BIN) ./files/usr/bin/sfe_dump $(1)/usr/bin
|
||||
endef
|
||||
|
||||
HAVE_ECM:=$(CONFIG_PACKAGE_kmod-qca-nss-ecm-premium)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-noload)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-premium-noload)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-standard)
|
||||
|
||||
define KernelPackage/shortcut-fe-cm
|
||||
SECTION:=kernel
|
||||
CATEGORY:=Kernel modules
|
||||
|
@ -50,7 +56,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
|
||||
CONFLICTS:=kmod-shortcut-fe-drv
|
||||
endef
|
||||
|
||||
define KernelPackage/shortcut-fe-cm/Description
|
||||
|
@ -58,20 +68,21 @@ Simple connection manager for the Shortcut forwarding engine.
|
|||
endef
|
||||
|
||||
define Build/Compile
|
||||
+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
|
||||
$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
$(PKG_MAKE_FLAGS) \
|
||||
M="$(PKG_BUILD_DIR)" \
|
||||
modules \
|
||||
$(if $(CONFIG_IPV6),EXTRA_CFLAGS="-DSFE_SUPPORT_IPV6" SFE_SUPPORT_IPV6=y,)
|
||||
EXTRA_CFLAGS+="-DSFE_SUPPORT_IPV6" SFE_SUPPORT_IPV6=y \
|
||||
$(if $(HAVE_ECM),EXTRA_CFLAGS+="-DCONFIG_SFE_ECM" CONFIG_SFE_ECM=y,) \
|
||||
modules
|
||||
endef
|
||||
|
||||
#ifneq ($(CONFIG_PACKAGE_kmod-shortcut-fe)$(CONFIG_PACKAGE_kmod-shortcut-fe-cm),)
|
||||
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
|
||||
endef
|
||||
#endif
|
||||
endif
|
||||
|
||||
$(eval $(call KernelPackage,shortcut-fe))
|
||||
$(eval $(call KernelPackage,shortcut-fe-cm))
|
||||
|
|
51
shortcut-fe/files/etc/init.d/shortcut-fe
Executable file
51
shortcut-fe/files/etc/init.d/shortcut-fe
Executable file
|
@ -0,0 +1,51 @@
|
|||
#!/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=70
|
||||
|
||||
have_cm() {
|
||||
[ -d "/sys/kernel/debug/ecm" ] && echo 1 && return
|
||||
|
||||
echo 0
|
||||
}
|
||||
|
||||
#load shortcut-fe and connection manager
|
||||
load_sfe() {
|
||||
local kernel_version=$(uname -r)
|
||||
|
||||
[ -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
|
||||
}
|
||||
[ -e "/lib/modules/$kernel_version/fast-classifier.ko" ] && {
|
||||
[ -d /sys/module/fast_classifier ] || insmod /lib/modules/$kernel_version/fast-classifier.ko
|
||||
}
|
||||
}
|
||||
|
||||
start() {
|
||||
[ "$(have_cm)" = "0" ] && load_sfe
|
||||
}
|
||||
|
||||
stop() {
|
||||
[ -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
|
||||
}
|
0
shortcut-fe/files/usr/bin/sfe_dump
Normal file → Executable file
0
shortcut-fe/files/usr/bin/sfe_dump
Normal file → Executable file
|
@ -5,8 +5,7 @@
|
|||
config SHORTCUT_FE
|
||||
tristate "Shortcut Forwarding Engine"
|
||||
depends on NF_CONNTRACK
|
||||
default n
|
||||
help
|
||||
---help---
|
||||
Shortcut is a fast in-kernel packet forwarding engine.
|
||||
|
||||
To compile this code as a module, choose M here: the module will be
|
||||
|
|
|
@ -21,3 +21,4 @@ endif
|
|||
shortcut-fe-cm-objs := \
|
||||
sfe_cm.o
|
||||
|
||||
ccflags-y += -Werror -Wall
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
60
simulated-driver/Makefile
Normal file
60
simulated-driver/Makefile
Normal file
|
@ -0,0 +1,60 @@
|
|||
#
|
||||
# Copyright (c) 2015,2016 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.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=shortcut-fe-simulated-driver
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/shortcut-fe
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2021-03-17
|
||||
PKG_SOURCE_VERSION:=697977d8d0ccf0ab596e5692d08608a75dd7f33d
|
||||
PKG_MIRROR_HASH:=659fa82a431e15af797a6c7069faeee02810453ad8b576c51c29f95a1761a045
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/shortcut-fe-drv
|
||||
SECTION:=kernel
|
||||
CATEGORY:=Kernel modules
|
||||
SUBMENU:=Network Support
|
||||
DEPENDS:=@TARGET_ipq806x||TARGET_ipq807x +kmod-shortcut-fe
|
||||
KCONFIG:= \
|
||||
CONFIG_NET_CLS_ACT=y \
|
||||
CONFIG_XFRM=y
|
||||
TITLE:=Simulated sfe driver for ECM
|
||||
FILES:=$(PKG_BUILD_DIR)/simulated-driver/shortcut-fe-drv.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/shortcut-fe-drv/Description
|
||||
Simulated sfe driver which act as an adapter to convert message
|
||||
between a connection manager and the SFE core engine.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
$(PKG_MAKE_FLAGS) \
|
||||
M="$(PKG_BUILD_DIR)/simulated-driver" \
|
||||
EXTRA_CFLAGS="-DSFE_SUPPORT_IPV6" \
|
||||
modules
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include/shortcut-fe
|
||||
$(CP) -rf $(PKG_BUILD_DIR)/simulated-driver/sfe_drv.h $(1)/usr/include/shortcut-fe
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,shortcut-fe-drv))
|
11
simulated-driver/patches/200-nss-qdisc-support.patch
Normal file
11
simulated-driver/patches/200-nss-qdisc-support.patch
Normal file
|
@ -0,0 +1,11 @@
|
|||
--- ./simulated-driver/sfe_drv.c.orig 2020-06-16 12:49:47.680153371 +0800
|
||||
+++ ./simulated-driver/sfe_drv.c 2020-06-16 12:50:18.540153371 +0800
|
||||
@@ -1167,7 +1167,7 @@ int sfe_drv_recv(struct sk_buff *skb)
|
||||
* If ingress Qdisc configured, and packet not processed by ingress Qdisc yet
|
||||
* We can not accelerate this packet.
|
||||
*/
|
||||
- if (dev->ingress_queue && !(skb->tc_verd & TC_NCLS)) {
|
||||
+ if (dev->ingress_queue && !(skb->tc_verd_qca_nss & TC_NCLS)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
Loading…
Reference in a new issue