1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-03-09 15:40:03 +00:00

Revert "fix shortcut"

This reverts commit 2096997ef7.
This commit is contained in:
suyuan 2021-09-25 17:31:25 +08:00
parent 2096997ef7
commit b28cad97f6
31 changed files with 673 additions and 1015 deletions

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2013-2018, 2020 The Linux Foundation. All rights reserved.
# Copyright (c) 2014 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.
@ -16,6 +16,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=shortcut-fe
PKG_RELEASE:=2
PKG_CONFIG_DEPENDS := CONFIG_IPV6
include $(INCLUDE_DIR)/package.mk
@ -23,14 +24,13 @@ define KernelPackage/shortcut-fe
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Support
DEPENDS:=@IPV6
DEPENDS:=
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 \
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
@ -39,14 +39,10 @@ Shortcut is an in-Linux-kernel IP packet forwarding engine.
endef
define KernelPackage/shortcut-fe/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/shortcut-fe $(1)/etc/init.d
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) ./files/usr/bin/sfe_dump $(1)/usr/bin
endef
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
@ -54,10 +50,7 @@ define KernelPackage/shortcut-fe-cm
DEPENDS:=+kmod-ipt-conntrack +kmod-shortcut-fe
TITLE:=Kernel driver for SFE
FILES:=$(PKG_BUILD_DIR)/shortcut-fe-cm.ko
KCONFIG:=CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y \
CONFIG_NF_CONNTRACK_EVENTS=y \
CONFIG_XFRM=y
CONFLICTS:=kmod-shortcut-fe-drv
KCONFIG:=CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y
endef
define KernelPackage/shortcut-fe-cm/Description
@ -65,21 +58,20 @@ 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)" \
$(if $(CONFIG_IPV6),EXTRA_CFLAGS+="-DSFE_SUPPORT_IPV6" SFE_SUPPORT_IPV6=y,) \
$(if $(HAVE_ECM),EXTRA_CFLAGS+="-DCONFIG_SFE_ECM" CONFIG_SFE_ECM=y,) \
modules
modules \
$(if $(CONFIG_IPV6),EXTRA_CFLAGS="-DSFE_SUPPORT_IPV6" SFE_SUPPORT_IPV6=y,)
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))

View file

@ -1,112 +0,0 @@
#
# 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
include $(INCLUDE_DIR)/package.mk
define KernelPackage/$(PKG_NAME)/Default
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Support
DEPENDS:=+kmod-ipt-conntrack +kmod-shortcut-fe
TITLE:=Kernel driver for FAST Classifier
FILES:=$(PKG_BUILD_DIR)/fast-classifier.ko
KCONFIG:=CONFIG_NF_CONNTRACK_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)
endef
define KernelPackage/$(PKG_NAME)-noload
$(call KernelPackage/$(PKG_NAME)/Default)
endef
define KernelPackage/$(PKG_NAME)/Default/description
FAST Classifier talks to SFE to make decisions about offloading connections
endef
define KernelPackage/$(PKG_NAME)/description
$(call KernelPackage/$(PKG_NAME)/Default/description)
endef
define KernelPackage/$(PKG_NAME)-noload/description
$(call KernelPackage/$(PKG_NAME)/Default/description)
This package does not load $(PKG_NAME) at boot by default
endef
define Package/fast-classifier-example
TITLE:=Example user space program for fast-classifier
DEPENDS:=+libnl +kmod-fast-classifier
endef
define Package/fast-classifier-example/description
Example user space program that communicates with fast
classifier kernel module
endef
SFE_MAKE_OPTS:=SFE_SUPPORT_IPV6=$(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) \
$(KERNEL_MAKE_FLAGS) \
$(PKG_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
CONFIG_FAST_CLASSIFIER=m \
$(if $(HAVE_ECM),EXTRA_CFLAGS+="-DCONFIG_SFE_ECM" CONFIG_SFE_ECM=y,) \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
modules
endef
define Build/Compile/example
$(TARGET_CC) -o $(PKG_BUILD_DIR)/userspace_fast_classifier \
-I $(PKG_BUILD_DIR) \
-I$(STAGING_DIR)/usr/include/libnl \
-I$(STAGING_DIR)/usr/include/libnl3 \
-lnl-genl-3 -lnl-3 \
$(PKG_BUILD_DIR)/nl_classifier_test.c
endef
define Build/Compile
$(Build/Compile/kmod)
$(if $(CONFIG_PACKAGE_fast-classifier-example),$(Build/Compile/example))
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(CP) $(PKG_BUILD_DIR)/fast-classifier.h $(1)/usr/include/
endef
define Package/fast-classifier-example/install
$(INSTALL_DIR) $(1)/sbin
$(CP) $(PKG_BUILD_DIR)/userspace_fast_classifier $(1)/sbin/
endef
$(eval $(call KernelPackage,$(PKG_NAME)))
$(eval $(call KernelPackage,$(PKG_NAME)-noload))
#$(eval $(call BuildPackage,fast-classifier-example))

View file

@ -1,10 +0,0 @@
obj-$(CONFIG_FAST_CLASSIFIER) += fast-classifier.o
ifeq ($(SFE_SUPPORT_IPV6),)
SFE_SUPPORT_IPV6=y
endif
ccflags-$(SFE_SUPPORT_IPV6) += -DSFE_SUPPORT_IPV6
ccflags-y += -I$(obj)/../shortcut-fe
obj ?= .

File diff suppressed because it is too large Load diff

View file

@ -1,57 +0,0 @@
/*
* User space header to send message to the fast classifier
*
* 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.
*/
#include <linux/if_ether.h>
#define FAST_CLASSIFIER_GENL_VERSION (1)
#define FAST_CLASSIFIER_GENL_NAME "FC"
#define FAST_CLASSIFIER_GENL_MCGRP "FC_MCGRP"
#define FAST_CLASSIFIER_GENL_HDRSIZE (0)
enum {
FAST_CLASSIFIER_A_UNSPEC,
FAST_CLASSIFIER_A_TUPLE,
__FAST_CLASSIFIER_A_MAX,
};
#define FAST_CLASSIFIER_A_MAX (__FAST_CLASSIFIER_A_MAX - 1)
enum {
FAST_CLASSIFIER_C_UNSPEC,
FAST_CLASSIFIER_C_OFFLOAD,
FAST_CLASSIFIER_C_OFFLOADED,
FAST_CLASSIFIER_C_DONE,
__FAST_CLASSIFIER_C_MAX,
};
#define FAST_CLASSIFIER_C_MAX (__FAST_CLASSIFIER_C_MAX - 1)
struct fast_classifier_tuple {
unsigned short ethertype;
unsigned char proto;
union {
struct in_addr in;
struct in6_addr in6;
} src_saddr;
union {
struct in_addr in;
struct in6_addr in6;
} dst_saddr;
unsigned short sport;
unsigned short dport;
unsigned char smac[ETH_ALEN];
unsigned char dmac[ETH_ALEN];
};

View file

@ -1,281 +0,0 @@
/*
* Copyright (c) 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 <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <arpa/inet.h>
#define NL_CLASSIFIER_GENL_VERSION 1
#define NL_CLASSIFIER_GENL_FAMILY "FC"
#define NL_CLASSIFIER_GENL_GROUP "FC_MCGRP"
#define NL_CLASSIFIER_GENL_HDRSIZE 0
enum NL_CLASSIFIER_CMD {
NL_CLASSIFIER_CMD_UNSPEC,
NL_CLASSIFIER_CMD_ACCEL,
NL_CLASSIFIER_CMD_ACCEL_OK,
NL_CLASSIFIER_CMD_CONNECTION_CLOSED,
NL_CLASSIFIER_CMD_MAX,
};
enum NL_CLASSIFIER_ATTR {
NL_CLASSIFIER_ATTR_UNSPEC,
NL_CLASSIFIER_ATTR_TUPLE,
NL_CLASSIFIER_ATTR_MAX,
};
union nl_classifier_tuple_ip {
struct in_addr in;
struct in6_addr in6;
};
struct nl_classifier_tuple {
unsigned short af;
unsigned char proto;
union nl_classifier_tuple_ip src_ip;
union nl_classifier_tuple_ip dst_ip;
unsigned short sport;
unsigned short dport;
unsigned char smac[6];
unsigned char dmac[6];
};
struct nl_classifier_instance {
struct nl_sock *sock;
int family_id;
int group_id;
int stop;
};
struct nl_classifier_instance nl_cls_inst;
static struct nla_policy nl_classifier_genl_policy[(NL_CLASSIFIER_ATTR_MAX+1)] = {
[NL_CLASSIFIER_ATTR_TUPLE] = { .type = NLA_UNSPEC },
};
void nl_classifier_dump_nl_tuple(struct nl_classifier_tuple *tuple)
{
char ip_str[64];
printf("protocol = %s\n", (tuple->proto == IPPROTO_UDP) ? "udp" : ((tuple->proto == IPPROTO_TCP) ? "tcp" : "unknown"));
printf("source ip = %s\n", inet_ntop(tuple->af, &tuple->src_ip, ip_str, sizeof(ip_str)));
printf("destination ip = %s\n", inet_ntop(tuple->af, &tuple->dst_ip, ip_str, sizeof(ip_str)));
printf("source port = %d\n", ntohs(tuple->sport));
printf("destination port = %d\n", ntohs(tuple->dport));
}
int nl_classifier_msg_recv(struct nl_msg *msg, void *arg)
{
struct nlmsghdr *nlh = nlmsg_hdr(msg);
struct genlmsghdr *gnlh = nlmsg_data(nlh);
struct nlattr *attrs[(NL_CLASSIFIER_ATTR_MAX+1)];
genlmsg_parse(nlh, NL_CLASSIFIER_GENL_HDRSIZE, attrs, NL_CLASSIFIER_ATTR_MAX, nl_classifier_genl_policy);
switch (gnlh->cmd) {
case NL_CLASSIFIER_CMD_ACCEL_OK:
printf("Acceleration successful:\n");
nl_classifier_dump_nl_tuple(nla_data(attrs[NL_CLASSIFIER_ATTR_TUPLE]));
return NL_OK;
case NL_CLASSIFIER_CMD_CONNECTION_CLOSED:
printf("Connection is closed:\n");
nl_classifier_dump_nl_tuple(nla_data(attrs[NL_CLASSIFIER_ATTR_TUPLE]));
return NL_OK;
default:
printf("nl classifier received unknow message %d\n", gnlh->cmd);
}
return NL_SKIP;
}
void nl_classifier_offload(struct nl_classifier_instance *inst,
unsigned char proto, unsigned long *src_saddr,
unsigned long *dst_saddr, unsigned short sport,
unsigned short dport, int af)
{
struct nl_msg *msg;
int ret;
struct nl_classifier_tuple classifier_msg;
memset(&classifier_msg, 0, sizeof(classifier_msg));
classifier_msg.af = af;
classifier_msg.proto = proto;
memcpy(&classifier_msg.src_ip, src_saddr, (af == AF_INET ? 4 : 16));
memcpy(&classifier_msg.dst_ip, dst_saddr, (af == AF_INET ? 4 : 16));
classifier_msg.sport = sport;
classifier_msg.dport = dport;
msg = nlmsg_alloc();
if (!msg) {
printf("Unable to allocate message\n");
return;
}
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, inst->family_id,
NL_CLASSIFIER_GENL_HDRSIZE, NLM_F_REQUEST,
NL_CLASSIFIER_CMD_ACCEL, NL_CLASSIFIER_GENL_VERSION);
nla_put(msg, NL_CLASSIFIER_ATTR_TUPLE, sizeof(classifier_msg), &classifier_msg);
ret = nl_send_auto(inst->sock, msg);
if (ret < 0) {
printf("send netlink message failed.\n");
nlmsg_free(msg);
return;
}
nlmsg_free(msg);
printf("nl classifier offload connection successful\n");
}
int nl_classifier_init(struct nl_classifier_instance *inst)
{
int ret;
inst->sock = nl_socket_alloc();
if (!inst->sock) {
printf("Unable to allocation socket.\n");
return -1;
}
genl_connect(inst->sock);
inst->family_id = genl_ctrl_resolve(inst->sock, NL_CLASSIFIER_GENL_FAMILY);
if (inst->family_id < 0) {
printf("Unable to resolve family %s\n", NL_CLASSIFIER_GENL_FAMILY);
goto init_failed;
}
inst->group_id = genl_ctrl_resolve_grp(inst->sock, NL_CLASSIFIER_GENL_FAMILY, NL_CLASSIFIER_GENL_GROUP);
if (inst->group_id < 0) {
printf("Unable to resolve mcast group %s\n", NL_CLASSIFIER_GENL_GROUP);
goto init_failed;
}
ret = nl_socket_add_membership(inst->sock, inst->group_id);
if (ret < 0) {
printf("Unable to add membership\n");
goto init_failed;
}
nl_socket_disable_seq_check(inst->sock);
nl_socket_modify_cb(inst->sock, NL_CB_VALID, NL_CB_CUSTOM, nl_classifier_msg_recv, NULL);
printf("nl classifier init successful\n");
return 0;
init_failed:
if (inst->sock) {
nl_close(inst->sock);
nl_socket_free(inst->sock);
inst->sock = NULL;
}
return -1;
}
void nl_classifier_exit(struct nl_classifier_instance *inst)
{
if (inst->sock) {
nl_close(inst->sock);
nl_socket_free(inst->sock);
inst->sock = NULL;
}
printf("nl classifier exit successful\n");
}
int nl_classifier_parse_arg(int argc, char *argv[], unsigned char *proto, unsigned long *src_saddr,
unsigned long *dst_saddr, unsigned short *sport, unsigned short *dport, int *af)
{
int ret;
unsigned short port;
if (argc < 7) {
printf("help: nl_classifier <v4|v6> <udp|tcp> <source ip> <destination ip> <source port> <destination port>\n");
return -1;
}
if (0 == strncmp(argv[1], "v4", 2)) {
*af = AF_INET;
} else if (0 == strncmp(argv[1], "v6", 2)) {
*af = AF_INET6;
} else {
printf("Address family is not supported");
return -1;
}
if (0 == strncmp(argv[2], "udp", 3)) {
*proto = IPPROTO_UDP;
} else if (0 == strncmp(argv[2], "tcp", 3)) {
*proto = IPPROTO_TCP;
} else {
printf("Protocol is not supported");
return -1;
}
ret = inet_pton(*af, argv[3], src_saddr);
if (ret <= 0) {
printf("source ip has wrong format\n");
return -1;
}
ret = inet_pton(*af, argv[4], dst_saddr);
if (ret <= 0) {
printf("destination ip has wrong format\n");
return -1;
}
port = strtol(argv[5], NULL, 0);
*sport = htons(port);
port = strtol(argv[6], NULL, 0);
*dport = htons(port);
printf("nl classifier parse arguments successful\n");
return 0;
}
int main(int argc, char *argv[])
{
struct nl_classifier_instance *inst = &nl_cls_inst;
unsigned char proto;
unsigned long src_addr[4];
unsigned long dst_addr[4];
unsigned short sport;
unsigned short dport;
int af;
int ret;
ret = nl_classifier_parse_arg(argc, argv, &proto, src_addr, dst_addr, &sport, &dport, &af);
if (ret < 0) {
printf("Failed to parse arguments\n");
return ret;
}
ret = nl_classifier_init(inst);
if (ret < 0) {
printf("Unable to init generic netlink\n");
return ret;
}
nl_classifier_offload(inst, proto, src_addr, dst_addr, sport, dport, af);
/* main loop to listen on message */
while (!inst->stop) {
nl_recvmsgs_default(inst->sock);
}
nl_classifier_exit(inst);
return 0;
}

View file

@ -1,232 +0,0 @@
/*
* 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.
*/
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <errno.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <fast-classifier.h>
static struct nl_sock *sock;
static struct nl_sock *sock_event;
static int family;
static int grp_id;
static struct nla_policy fast_classifier_genl_policy[FAST_CLASSIFIER_A_MAX + 1] = {
[FAST_CLASSIFIER_A_TUPLE] = { .type = NLA_UNSPEC },
};
void dump_fc_tuple(struct fast_classifier_tuple *fc_msg)
{
char src_str[INET_ADDRSTRLEN];
char dst_str[INET_ADDRSTRLEN];
printf("TUPLE: %d, %s, %s, %d, %d"
" SMAC=%02x:%02x:%02x:%02x:%02x:%02x",
" DMAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
fc_msg->proto,
inet_ntop(AF_INET,
&fc_msg->src_saddr.in.s_addr,
src_str,
INET_ADDRSTRLEN),
inet_ntop(AF_INET,
&fc_msg->dst_saddr.in.s_addr,
dst_str,
INET_ADDRSTRLEN),
fc_msg->sport, fc_msg->dport,
fc_msg->smac[0], fc_msg->smac[1], fc_msg->smac[2],
fc_msg->smac[3], fc_msg->smac[4], fc_msg->smac[5],
fc_msg->dmac[0], fc_msg->dmac[1], fc_msg->dmac[2],
fc_msg->dmac[3], fc_msg->dmac[4], fc_msg->dmac[5]);
}
static int parse_cb(struct nl_msg *msg, void *arg)
{
struct nlmsghdr *nlh = nlmsg_hdr(msg);
struct genlmsghdr *gnlh = nlmsg_data(nlh);
struct nlattr *attrs[FAST_CLASSIFIER_A_MAX];
genlmsg_parse(nlh, 0, attrs, FAST_CLASSIFIER_A_MAX, fast_classifier_genl_policy);
switch (gnlh->cmd) {
case FAST_CLASSIFIER_C_OFFLOADED:
printf("Got a offloaded message\n");
dump_fc_tuple(nla_data(attrs[FAST_CLASSIFIER_A_TUPLE]));
return NL_OK;
case FAST_CLASSIFIER_C_DONE:
printf("Got a done message\n");
dump_fc_tuple(nla_data(attrs[FAST_CLASSIFIER_A_TUPLE]));
return NL_OK;
}
return NL_SKIP;
}
int fast_classifier_init(void)
{
int err;
sock = nl_socket_alloc();
if (!sock) {
printf("Unable to allocation socket.\n");
return -1;
}
genl_connect(sock);
sock_event = nl_socket_alloc();
if (!sock_event) {
nl_close(sock);
nl_socket_free(sock);
printf("Unable to allocation socket.\n");
return -1;
}
genl_connect(sock_event);
family = genl_ctrl_resolve(sock, FAST_CLASSIFIER_GENL_NAME);
if (family < 0) {
nl_close(sock_event);
nl_close(sock);
nl_socket_free(sock);
nl_socket_free(sock_event);
printf("Unable to resolve family\n");
return -1;
}
grp_id = genl_ctrl_resolve_grp(sock, FAST_CLASSIFIER_GENL_NAME,
FAST_CLASSIFIER_GENL_MCGRP);
if (grp_id < 0) {
printf("Unable to resolve mcast group\n");
return -1;
}
err = nl_socket_add_membership(sock_event, grp_id);
if (err < 0) {
printf("Unable to add membership\n");
return -1;
}
nl_socket_disable_seq_check(sock_event);
nl_socket_modify_cb(sock_event, NL_CB_VALID, NL_CB_CUSTOM, parse_cb, NULL);
return 0;
}
void fast_classifier_close(void)
{
nl_close(sock_event);
nl_close(sock);
nl_socket_free(sock_event);
nl_socket_free(sock);
}
void fast_classifier_ipv4_offload(unsigned char proto, unsigned long src_saddr,
unsigned long dst_saddr, unsigned short sport,
unsigned short dport)
{
struct nl_msg *msg;
int ret;
#ifdef DEBUG
char src_str[INET_ADDRSTRLEN];
char dst_str[INET_ADDRSTRLEN];
#endif
struct fast_classifier_tuple fc_msg;
#ifdef DEBUG
printf("DEBUG: would offload: %d, %s, %s, %d, %d\n", proto,
inet_ntop(AF_INET, &src_saddr, src_str, INET_ADDRSTRLEN),
inet_ntop(AF_INET, &dst_saddr, dst_str, INET_ADDRSTRLEN),
sport, dport);
#endif
fc_msg.proto = proto;
fc_msg.src_saddr.in.s_addr = src_saddr;
fc_msg.dst_saddr.in.s_addr = dst_saddr;
fc_msg.sport = sport;
fc_msg.dport = dport;
fc_msg.smac[0] = 'a';
fc_msg.smac[1] = 'b';
fc_msg.smac[2] = 'c';
fc_msg.smac[3] = 'd';
fc_msg.smac[4] = 'e';
fc_msg.smac[5] = 'f';
fc_msg.dmac[0] = 'f';
fc_msg.dmac[1] = 'e';
fc_msg.dmac[2] = 'd';
fc_msg.dmac[3] = 'c';
fc_msg.dmac[4] = 'b';
fc_msg.dmac[5] = 'a';
if (fast_classifier_init() < 0) {
printf("Unable to init generic netlink\n");
exit(1);
}
msg = nlmsg_alloc();
if (!msg) {
nl_socket_free(sock);
printf("Unable to allocate message\n");
return;
}
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family,
FAST_CLASSIFIER_GENL_HDRSIZE, NLM_F_REQUEST,
FAST_CLASSIFIER_C_OFFLOAD, FAST_CLASSIFIER_GENL_VERSION);
nla_put(msg, 1, sizeof(fc_msg), &fc_msg);
ret = nl_send_auto_complete(sock, msg);
nlmsg_free(msg);
if (ret < 0) {
printf("nlmsg_free failed");
nl_close(sock);
nl_socket_free(sock);
return;
}
ret = nl_wait_for_ack(sock);
if (ret < 0) {
printf("wait for ack failed");
nl_close(sock);
nl_socket_free(sock);
return;
}
}
void fast_classifier_listen_for_messages(void)
{
printf("waiting for netlink events\n");
while (1) {
nl_recvmsgs_default(sock_event);
}
}
int main(int argc, char *argv[])
{
if (fast_classifier_init() < 0) {
printf("Unable to init generic netlink\n");
exit(1);
}
fast_classifier_ipv4_offload('a', 0, 0, 0, 0);
/* this never returns */
fast_classifier_listen_for_messages();
fast_classifier_close();
return 0;
}

View file

@ -1,51 +0,0 @@
#!/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=99
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_drv" ] && rmmod shortcut_fe_drv
[ -d "/sys/module/shortcut_fe_cm" ] && rmmod shortcut_fe_cm
[ -d "/sys/module/fast_classifier" ] && rmmod fast_classifier
[ -d "/sys/module/shortcut_fe_ipv6" ] && rmmod shortcut-fe-ipv6
[ -d "/sys/module/shortcut_fe" ] && rmmod shortcut-fe
}

View file

@ -1,60 +0,0 @@
#
# 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_CONFIG_DEPENDS := CONFIG_IPV6
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" \
$(if $(CONFIG_IPV6),EXTRA_CFLAGS+="-DSFE_SUPPORT_IPV6" SFE_SUPPORT_IPV6=y,) \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
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))

View file

@ -1,11 +0,0 @@
--- ./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

View file

@ -21,4 +21,3 @@ 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, addr)
#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)

View file

@ -2,7 +2,7 @@
* sfe-cm.c
* Shortcut forwarding engine connection manager.
*
* Copyright (c) 2013-2018, 2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@ -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(struct sk_buff *skb, sfe_ip_addr_t *addr, struct net_device **dev, u8 *mac_addr, int is_v4)
static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device **dev, u8 *mac_addr, int is_v4)
{
struct neighbour *neigh;
struct rtable *rt;
@ -207,15 +207,6 @@ static bool sfe_cm_find_dev_and_mac_addr(struct sk_buff *skb, sfe_ip_addr_t *add
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
@ -229,11 +220,11 @@ static bool sfe_cm_find_dev_and_mac_addr(struct sk_buff *skb, sfe_ip_addr_t *add
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, 0);
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0))
rt6 = rt6_lookup(&init_net, (struct in6_addr *)addr->ip6, 0, 0, NULL, 0);
#endif
#else
rt6 = rt6_lookup(&init_net, (struct in6_addr *)addr->ip6, 0, 0, 0);
#endif /*KERNEL_VERSION(4, 17, 0)*/
if (!rt6) {
goto ret_fail;
}
@ -241,21 +232,18 @@ static bool sfe_cm_find_dev_and_mac_addr(struct sk_buff *skb, sfe_ip_addr_t *add
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);
dst_release(dst);
goto ret_fail;
}
if (unlikely(!(neigh->nud_state & NUD_VALID))) {
rcu_read_unlock();
neigh_release(neigh);
if (likely(!skb))
dst_release(dst);
dst_release(dst);
goto ret_fail;
}
@ -263,8 +251,7 @@ skip_dst_lookup:
if (!mac_dev) {
rcu_read_unlock();
neigh_release(neigh);
if (likely(!skb))
dst_release(dst);
dst_release(dst);
goto ret_fail;
}
@ -274,8 +261,7 @@ skip_dst_lookup:
*dev = mac_dev;
rcu_read_unlock();
neigh_release(neigh);
if (likely(!skb))
dst_release(dst);
dst_release(dst);
return true;
@ -305,7 +291,6 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4)
struct net_device *dest_dev;
struct net_device *src_dev_tmp;
struct net_device *dest_dev_tmp;
struct sk_buff *tmp_skb = NULL;
struct net_device *src_br_dev = NULL;
struct net_device *dest_br_dev = NULL;
struct nf_conntrack_tuple orig_tuple;
@ -367,18 +352,16 @@ 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,
@ -527,21 +510,6 @@ 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:
@ -565,10 +533,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->sp)) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
if (unlikely(skb_ext_exist(skb, SKB_EXT_SEC_PATH))) {
#else
if (unlikely(secpath_exists(skb))) {
if (unlikely(skb->sp)) {
#endif
if (sic.protocol == IPPROTO_TCP &&
!(sic.flags & SFE_CREATE_FLAG_NO_SEQ_CHECK)) {
@ -596,27 +564,25 @@ 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(NULL, &sic.src_ip, &src_dev_tmp, sic.src_mac, is_v4)) {
if (!sfe_cm_find_dev_and_mac_addr(&sic.src_ip, &src_dev_tmp, sic.src_mac, is_v4)) {
sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_SRC_DEV);
return NF_ACCEPT;
}
src_dev = src_dev_tmp;
if (!sfe_cm_find_dev_and_mac_addr(NULL, &sic.src_ip_xlate, &dev, sic.src_mac_xlate, is_v4)) {
if (!sfe_cm_find_dev_and_mac_addr(&sic.src_ip_xlate, &dev, sic.src_mac_xlate, is_v4)) {
sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_SRC_XLATE_DEV);
goto done1;
}
dev_put(dev);
/* 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)) {
if (!sfe_cm_find_dev_and_mac_addr(&sic.dest_ip, &dev, sic.dest_mac, is_v4)) {
sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_DEST_DEV);
goto done1;
}
dev_put(dev);
if (!sfe_cm_find_dev_and_mac_addr(skb, &sic.dest_ip_xlate, &dest_dev_tmp, sic.dest_mac_xlate, is_v4)) {
if (!sfe_cm_find_dev_and_mac_addr(&sic.dest_ip_xlate, &dest_dev_tmp, sic.dest_mac_xlate, is_v4)) {
sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_DEST_XLATE_DEV);
goto done1;
}
@ -722,11 +688,14 @@ 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
#endif /*KERNEL_VERSION(4, 12, 0)*/
/*
* We're only interested in destroy events.
@ -856,17 +825,18 @@ 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
#endif /*KERNEL_VERSION(4, 9, 0)*/
/*
* Only update if this is not a fixed timeout
*/
if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) {
spin_lock_bh(&ct->lock);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0))
ct->timeout.expires += sis->delta_jiffies;
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
ct->timeout += sis->delta_jiffies;
#endif
#else
ct->timeout.expires += sis->delta_jiffies;
#endif /*KERNEL_VERSION(4, 9, 0)*/
spin_unlock_bh(&ct->lock);
}
@ -921,26 +891,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))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
timeouts = nf_ct_timeout_lookup(ct);
#else
struct nf_conntrack_l4proto *l4proto;
l4proto = __nf_ct_l4proto_find((sis->is_v6 ? AF_INET6 : AF_INET), IPPROTO_UDP);
timeouts = nf_ct_timeout_lookup(&init_net, ct, l4proto);
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 = udp_get_timeouts(nf_ct_net(ct));
}
#endif /*KERNEL_VERSION(4, 19, 0)*/
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;
@ -1031,9 +1001,6 @@ 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");
@ -1069,11 +1036,7 @@ 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;
@ -1086,30 +1049,22 @@ static int __init sfe_cm_init(void)
*/
#ifdef CONFIG_NF_CONNTRACK_EVENTS
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
result = nf_conntrack_register_chain_notifier(&init_net, &sfe_cm_conntrack_notifier);
(void)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);
/*
@ -1120,15 +1075,10 @@ 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);
@ -1179,12 +1129,8 @@ static void __exit sfe_cm_exit(void)
nf_conntrack_unregister_notifier(&init_net, &sfe_cm_conntrack_notifier);
#endif
#endif
#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

@ -2,7 +2,7 @@
* sfe_ipv4.c
* Shortcut forwarding engine - IPv4 edition.
*
* Copyright (c) 2013-2016, 2019-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2016, 2019, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@ -1311,13 +1311,14 @@ 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("%px: skb is a cloned skb\n", skb);
DEBUG_TRACE("%p: skb is a cloned skb\n", skb);
skb = skb_unshare(skb, GFP_ATOMIC);
if (!skb) {
DEBUG_WARN("Failed to unshare the cloned skb\n");
si->exception_events[SFE_IPV4_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR]++;
si->packets_not_forwarded++;
spin_unlock_bh(&si->lock);
return 0;
}
@ -1890,13 +1891,14 @@ 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("%px: skb is a cloned skb\n", skb);
DEBUG_TRACE("%p: skb is a cloned skb\n", skb);
skb = skb_unshare(skb, GFP_ATOMIC);
if (!skb) {
DEBUG_WARN("Failed to unshare the cloned skb\n");
si->exception_events[SFE_IPV4_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR]++;
si->packets_not_forwarded++;
spin_unlock_bh(&si->lock);
return 0;
}
@ -2510,7 +2512,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:%pxM:%pI4:%u, d: %s:%pxM:%pI4:%u\n",
" s: %s:%pM:%pI4:%u, d: %s:%pM:%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));
@ -2726,8 +2728,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:%pxM(%pxM):%pI4(%pI4):%u(%u)\n"
" d: %s:%pxM(%pxM):%pI4(%pI4):%u(%u)\n",
" s: %s:%pM(%pM):%pI4(%pI4):%u(%u)\n"
" d: %s:%pM(%pM):%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),
@ -2856,17 +2858,17 @@ another_round:
/*
* sfe_ipv4_periodic_sync()
*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
static void sfe_ipv4_periodic_sync(struct timer_list *arg)
#else
static void sfe_ipv4_periodic_sync(unsigned long arg)
#else
static void sfe_ipv4_periodic_sync(struct timer_list *tl)
#endif
#endif /*KERNEL_VERSION(4, 15, 0)*/
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
struct sfe_ipv4 *si = (struct sfe_ipv4 *)arg;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
struct sfe_ipv4 *si = (struct sfe_ipv4 *)arg->cust_data;
#else
struct sfe_ipv4 *si = from_timer(si, tl, timer);
#endif
struct sfe_ipv4 *si = (struct sfe_ipv4 *)arg;
#endif /*KERNEL_VERSION(4, 15, 0)*/
u64 now_jiffies;
int quota;
sfe_sync_rule_callback_t sync_rule_callback;
@ -3545,11 +3547,12 @@ static int __init sfe_ipv4_init(void)
/*
* Create a timer to handle periodic statistics.
*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
setup_timer(&si->timer, sfe_ipv4_periodic_sync, (unsigned long)si);
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
timer_setup(&si->timer, sfe_ipv4_periodic_sync, 0);
#endif
si->timer.cust_data = (unsigned long)si;
#else
setup_timer(&si->timer, sfe_ipv4_periodic_sync, (unsigned long)si);
#endif /*KERNEL_VERSION(4, 15, 0)*/
mod_timer(&si->timer, jiffies + ((HZ + 99) / 100));
spin_lock_init(&si->lock);

View file

@ -2,7 +2,7 @@
* sfe_ipv6.c
* Shortcut forwarding engine - IPv6 support.
*
* Copyright (c) 2015-2016, 2019-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2016, 2019, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@ -1369,13 +1369,14 @@ 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("%px: skb is a cloned skb\n", skb);
DEBUG_TRACE("%p: skb is a cloned skb\n", skb);
skb = skb_unshare(skb, GFP_ATOMIC);
if (!skb) {
DEBUG_WARN("Failed to unshare the cloned skb\n");
si->exception_events[SFE_IPV6_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR]++;
si->packets_not_forwarded++;
spin_unlock_bh(&si->lock);
return 0;
}
@ -1928,13 +1929,14 @@ 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("%px: skb is a cloned skb\n", skb);
DEBUG_TRACE("%p: skb is a cloned skb\n", skb);
skb = skb_unshare(skb, GFP_ATOMIC);
if (!skb) {
DEBUG_WARN("Failed to unshare the cloned skb\n");
si->exception_events[SFE_IPV6_EXCEPTION_EVENT_CLONED_SKB_UNSHARE_ERROR]++;
si->packets_not_forwarded++;
spin_unlock_bh(&si->lock);
return 0;
}
@ -2326,7 +2328,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 - (unsigned int)sizeof(struct sfe_ipv6_ip_hdr)));
DEBUG_TRACE("payload_len: %u, exceeds len: %u\n", payload_len, (len - sizeof(struct sfe_ipv6_ip_hdr)));
return 0;
}
@ -2524,7 +2526,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:%pxM:%pI6:%u, d: %s:%pxM:%pI6:%u\n",
" s: %s:%pM:%pI6:%u, d: %s:%pM:%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));
@ -2740,8 +2742,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:%pxM(%pxM):%pI6(%pI6):%u(%u)\n"
" d: %s:%pxM(%pxM):%pI6(%pI6):%u(%u)\n",
" s: %s:%pM(%pM):%pI6(%pI6):%u(%u)\n"
" d: %s:%pM(%pM):%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),
@ -2864,17 +2866,17 @@ another_round:
/*
* sfe_ipv6_periodic_sync()
*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
static void sfe_ipv6_periodic_sync(struct timer_list *arg)
#else
static void sfe_ipv6_periodic_sync(unsigned long arg)
#else
static void sfe_ipv6_periodic_sync(struct timer_list *tl)
#endif
#endif /*KERNEL_VERSION(4, 15, 0)*/
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
struct sfe_ipv6 *si = (struct sfe_ipv6 *)arg;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
struct sfe_ipv6 *si = (struct sfe_ipv6 *)arg->cust_data;
#else
struct sfe_ipv6 *si = from_timer(si, tl, timer);
#endif
struct sfe_ipv6 *si = (struct sfe_ipv6 *)arg;
#endif /*KERNEL_VERSION(4, 15, 0)*/
u64 now_jiffies;
int quota;
sfe_sync_rule_callback_t sync_rule_callback;
@ -3553,11 +3555,12 @@ static int __init sfe_ipv6_init(void)
/*
* Create a timer to handle periodic statistics.
*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
setup_timer(&si->timer, sfe_ipv6_periodic_sync, (unsigned long)si);
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
timer_setup(&si->timer, sfe_ipv6_periodic_sync, 0);
#endif
si->timer.cust_data = (unsigned long)si;
#else
setup_timer(&si->timer, sfe_ipv6_periodic_sync, (unsigned long)si);
#endif /*KERNEL_VERSION(4, 15, 0)*/
mod_timer(&si->timer, jiffies + ((HZ + 99) / 100));
spin_lock_init(&si->lock);