kernel: add shortcut-fe support
This commit is contained in:
parent
9c8a3a44e0
commit
6e64d8c6c3
91
package/lean/fast-classifier/Makefile
Normal file
91
package/lean/fast-classifier/Makefile
Normal file
@ -0,0 +1,91 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=fast-classifier
|
||||
PKG_RELEASE:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/$(PKG_NAME)/Default
|
||||
SECTION:=kernel
|
||||
CATEGORY:=Kernel modules
|
||||
SUBMENU:=Network Support
|
||||
DEPENDS:=+kmod-ipt-conntrack +kmod-shortcut-fe
|
||||
TITLE:=Kernel driver for FAST Classifier
|
||||
FILES:=$(PKG_BUILD_DIR)/fast-classifier.ko
|
||||
KCONFIG:=CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y CONFIG_NF_CONNTRACK_MARK=y
|
||||
PROVIDES:=$(PKG_NAME)
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)
|
||||
$(call KernelPackage/$(PKG_NAME)/Default)
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)-noload
|
||||
$(call KernelPackage/$(PKG_NAME)/Default)
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)/Default/description
|
||||
FAST Classifier talks to SFE to make decisions about offloading connections
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)/description
|
||||
$(call KernelPackage/$(PKG_NAME)/Default/description)
|
||||
endef
|
||||
|
||||
define KernelPackage/$(PKG_NAME)-noload/description
|
||||
$(call KernelPackage/$(PKG_NAME)/Default/description)
|
||||
|
||||
This package does not load $(PKG_NAME) at boot by default
|
||||
endef
|
||||
|
||||
define Package/fast-classifier-example
|
||||
TITLE:=Example user space program for fast-classifier
|
||||
DEPENDS:=+libnl +kmod-fast-classifier
|
||||
endef
|
||||
|
||||
define Package/fast-classifier-example/description
|
||||
Example user space program that communicates with fast
|
||||
classifier kernel module
|
||||
endef
|
||||
|
||||
SFE_MAKE_OPTS:=SFE_SUPPORT_IPV6=y
|
||||
|
||||
define Build/Compile/kmod
|
||||
+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(SFE_MAKE_OPTS)) \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
$(PKG_MAKE_FLAGS) \
|
||||
M="$(PKG_BUILD_DIR)" \
|
||||
CONFIG_FAST_CLASSIFIER=m \
|
||||
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
|
||||
modules
|
||||
endef
|
||||
|
||||
define Build/Compile/example
|
||||
$(TARGET_CC) -o $(PKG_BUILD_DIR)/userspace_fast_classifier \
|
||||
-I $(PKG_BUILD_DIR) \
|
||||
-I$(STAGING_DIR)/usr/include/libnl \
|
||||
-I$(STAGING_DIR)/usr/include/libnl3 \
|
||||
-lnl-genl-3 -lnl-3 \
|
||||
$(PKG_BUILD_DIR)/nl_classifier_test.c
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(Build/Compile/kmod)
|
||||
$(if $(CONFIG_PACKAGE_fast-classifier-example),$(Build/Compile/example))
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(CP) $(PKG_BUILD_DIR)/fast-classifier.h $(1)/usr/include/
|
||||
endef
|
||||
|
||||
|
||||
define Package/fast-classifier-example/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(CP) $(PKG_BUILD_DIR)/userspace_fast_classifier $(1)/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,$(PKG_NAME)))
|
||||
$(eval $(call KernelPackage,$(PKG_NAME)-noload))
|
||||
#$(eval $(call BuildPackage,fast-classifier-example))
|
||||
10
package/lean/fast-classifier/src/Makefile
Normal file
10
package/lean/fast-classifier/src/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
obj-$(CONFIG_FAST_CLASSIFIER) += fast-classifier.o
|
||||
|
||||
ifeq ($(SFE_SUPPORT_IPV6),)
|
||||
SFE_SUPPORT_IPV6=y
|
||||
endif
|
||||
ccflags-$(SFE_SUPPORT_IPV6) += -DSFE_SUPPORT_IPV6
|
||||
|
||||
ccflags-y += -I$(obj)/../shortcut-fe
|
||||
|
||||
obj ?= .
|
||||
1965
package/lean/fast-classifier/src/fast-classifier.c
Normal file
1965
package/lean/fast-classifier/src/fast-classifier.c
Normal file
File diff suppressed because it is too large
Load Diff
57
package/lean/fast-classifier/src/fast-classifier.h
Normal file
57
package/lean/fast-classifier/src/fast-classifier.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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];
|
||||
};
|
||||
281
package/lean/fast-classifier/src/nl_classifier_test.c
Normal file
281
package/lean/fast-classifier/src/nl_classifier_test.c
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
232
package/lean/fast-classifier/src/userspace_example.c
Normal file
232
package/lean/fast-classifier/src/userspace_example.c
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
17
package/lean/luci-app-sfe/Makefile
Normal file
17
package/lean/luci-app-sfe/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for Turbo ACC (SFE)
|
||||
LUCI_DEPENDS:=+kmod-fast-classifier +pdnsd-alt +kmod-tcp-bbr
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=13
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
||||
44
package/lean/luci-app-sfe/luasrc/controller/sfe.lua
Normal file
44
package/lean/luci-app-sfe/luasrc/controller/sfe.lua
Normal file
@ -0,0 +1,44 @@
|
||||
module("luci.controller.sfe", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/sfe") then
|
||||
return
|
||||
end
|
||||
local page
|
||||
page = entry({"admin", "network", "sfe"}, cbi("sfe"), _("Turbo ACC Center"), 100)
|
||||
page.i18n = "sfe"
|
||||
page.dependent = true
|
||||
|
||||
entry({"admin", "network", "sfe", "status"}, call("action_status"))
|
||||
end
|
||||
|
||||
local function is_running()
|
||||
return luci.sys.call("lsmod | grep fast_classifier >/dev/null") == 0
|
||||
end
|
||||
|
||||
local function is_bbr()
|
||||
return luci.sys.call("sysctl net.ipv4.tcp_congestion_control | grep bbr >/dev/null") == 0
|
||||
end
|
||||
|
||||
local function is_fullcone()
|
||||
return luci.sys.call("iptables -t nat -L -n --line-numbers | grep FULLCONENAT >/dev/null") == 0
|
||||
end
|
||||
|
||||
local function is_dns()
|
||||
return luci.sys.call("[ x$(uci get sfe.config.dnscache_enable 2>/dev/null) != x3 ] && pgrep dnscache >/dev/null || pgrep AdGuardHome >/dev/null") == 0
|
||||
end
|
||||
|
||||
local function is_ad()
|
||||
return luci.sys.call("pgrep AdGuardHome >/dev/null") == 0
|
||||
end
|
||||
|
||||
function action_status()
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({
|
||||
run_state = is_running(),
|
||||
down_state = is_bbr(),
|
||||
up_state = is_fullcone(),
|
||||
dns_state = is_dns(),
|
||||
ad_state = is_ad()
|
||||
})
|
||||
end
|
||||
67
package/lean/luci-app-sfe/luasrc/model/cbi/sfe.lua
Normal file
67
package/lean/luci-app-sfe/luasrc/model/cbi/sfe.lua
Normal file
@ -0,0 +1,67 @@
|
||||
local trport = 3001
|
||||
local button = ""
|
||||
if luci.sys.call("pidof AdGuardHome >/dev/null") == 0 then
|
||||
button = " <input type=\"button\" value=\" " .. translate("Open Web Interface") .. " \" onclick=\"window.open('http://'+window.location.hostname+':" .. trport .. "')\"/>"
|
||||
end
|
||||
|
||||
m = Map("sfe")
|
||||
m.title = translate("Turbo ACC Acceleration Settings")
|
||||
m.description = translate("Opensource Qualcomm Shortcut FE driver (Fast Path)")
|
||||
|
||||
m:append(Template("sfe/status"))
|
||||
|
||||
s = m:section(TypedSection, "sfe", "")
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
|
||||
enable = s:option(Flag, "enabled", translate("Enable SFE Fast Path"))
|
||||
enable.default = 0
|
||||
enable.rmempty = false
|
||||
enable.description = translate("Enable Fast Path offloading for connections. (decrease cpu load / increase routing throughput)")
|
||||
|
||||
wifi = s:option(Flag, "wifi", translate("Bridge Acceleration"))
|
||||
wifi.default = 0
|
||||
wifi.rmempty = false
|
||||
wifi.description = translate("Enable Bridge Acceleration (may be functional conflict with bridge-mode VPN Server)")
|
||||
wifi:depends("enabled", 1)
|
||||
|
||||
ipv6 = s:option(Flag, "ipv6", translate("IPv6 Acceleration"))
|
||||
ipv6.default = 0
|
||||
ipv6.rmempty = false
|
||||
ipv6.description = translate("Enable IPv6 Acceleration")
|
||||
ipv6:depends("enabled", 1)
|
||||
|
||||
bbr = s:option(Flag, "bbr", translate("Enable BBR"))
|
||||
bbr.default = 0
|
||||
bbr.rmempty = false
|
||||
bbr.description = translate("Bottleneck Bandwidth and Round-trip propagation time (BBR)")
|
||||
|
||||
dns = s:option(Flag, "dns", translate("DNS Acceleration"))
|
||||
dns.default = 0
|
||||
dns.rmempty = false
|
||||
dns.description = translate("Enable DNS Cache Acceleration and anti ISP DNS pollution")
|
||||
|
||||
o = s:option(ListValue, "dnscache_enable", translate("Resolve Dns Mode"), translate("AdGuardHome's login username/passwd: AdGuardHome, web console addr: IP:3001") .. button)
|
||||
o:value("1", translate("Use Pdnsd query and cache"))
|
||||
if nixio.fs.access("/usr/bin/dnsforwarder") then
|
||||
o:value("2", translate("Use dnsforwarder query and cache"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/AdGuardHome") then
|
||||
o:value("3", translate("Use AdGuardHome query and cache"))
|
||||
end
|
||||
o.default = 1
|
||||
o:depends("dns", 1)
|
||||
|
||||
o = s:option(Value, "dns_server", translate("Upsteam DNS Server"))
|
||||
o.default = "114.114.114.114,114.114.115.115,223.5.5.5,223.6.6.6,180.76.76.76,119.29.29.29,119.28.28.28,1.2.4.8,210.2.4.8"
|
||||
o.description = translate("Muitiple DNS server can saperate with ','")
|
||||
o:depends("dnscache_enable", 1)
|
||||
o:depends("dnscache_enable", 2)
|
||||
|
||||
o = s:option(Value, "ipv6dns_server", translate("Upsteam IPV6 DNS Server"))
|
||||
o.default = "2001:4860:4860::8888,2001:4860:4860::8844,2001:2001::1111,2001:2001::1001,2400:da00::6666,240C::6666,240C::6644"
|
||||
o.description = translate("Muitiple IPV6 DNS server can saperate with ','")
|
||||
o:depends("dnscache_enable", 2)
|
||||
|
||||
return m
|
||||
27
package/lean/luci-app-sfe/luasrc/view/sfe/status.htm
Normal file
27
package/lean/luci-app-sfe/luasrc/view/sfe/status.htm
Normal file
@ -0,0 +1,27 @@
|
||||
<fieldset class="cbi-section">
|
||||
<legend><%:Running Status%></legend>
|
||||
<table width="100%" cellspacing="10" id="_xlnetacc_status_table">
|
||||
<tr><td width="33%">SFE 加速状态</td><td id="_run_state"><em><%:Collecting data...%></em></td></tr>
|
||||
<tr><td width="33%">BBR 加速</td><td id="_down_state"><em><%:Collecting data...%></em></td></tr>
|
||||
<tr><td width="33%">FULLCONE NAT加速</td><td id="_up_state"><em><%:Collecting data...%></em></td></tr>
|
||||
<tr><td width="33%">DNS 加速</td><td id="_dns_state"><em><%:Collecting data...%></em></td></tr>
|
||||
<tr><td width="33%">AdGuardHome 去广告</td><td id="_ad_state"><em><%:Collecting data...%></em></td></tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var run_state = document.getElementById('_run_state');
|
||||
var down_state = document.getElementById('_down_state');
|
||||
var up_state = document.getElementById('_up_state');
|
||||
var dns_state = document.getElementById('_dns_state');
|
||||
var ad_state = document.getElementById('_ad_state');
|
||||
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "sfe", "status")%>', null, function(x, status) {
|
||||
if ( x && x.status == 200 ) {
|
||||
run_state.innerHTML = status.run_state ? '<em><b><font color=green><%:RUNNING%></font></b></em>' : '<em><b><font color=red><%:NOT RUNNING%></font></b></em>';
|
||||
down_state.innerHTML = status.down_state ? '<em><b><font color=green><%:RUNNING%></font></b></em>' : '<em><b><font color=red><%:NOT RUNNING%></font></b></em>';
|
||||
up_state.innerHTML = status.up_state ? '<em><b><font color=green><%:RUNNING%></font></b></em>' : '<em><b><font color=red><%:NOT RUNNING%></font></b></em>';
|
||||
dns_state.innerHTML = status.dns_state ? '<em><b><font color=green><%:RUNNING%></font></b></em>' : '<em><b><font color=red><%:NOT RUNNING%></font></b></em>';
|
||||
ad_state.innerHTML = status.ad_state ? '<em><b><font color=green><%:RUNNING%></font></b></em>' : '<em><b><font color=red><%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
});
|
||||
//]]></script>
|
||||
81
package/lean/luci-app-sfe/po/zh_Hans/sfe.po
Normal file
81
package/lean/luci-app-sfe/po/zh_Hans/sfe.po
Normal file
@ -0,0 +1,81 @@
|
||||
msgid "SFE Acceleration"
|
||||
msgstr "SFE 转发加速"
|
||||
|
||||
msgid "Turbo ACC Center"
|
||||
msgstr "Turbo ACC 网络加速"
|
||||
|
||||
msgid "Turbo ACC Acceleration Settings"
|
||||
msgstr "Turbo ACC 网络加速设置"
|
||||
|
||||
msgid "Shortcut Forwarding Engine Acceleration Settings"
|
||||
msgstr "SFE 转发加速引擎设置"
|
||||
|
||||
msgid "Opensource Qualcomm Shortcut FE driver (Fast Path)"
|
||||
msgstr "来自高通开源的 Shortcut FE 转发加速引擎 (Fast Path)"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Enable SFE Fast Path"
|
||||
msgstr "启用 SFE Fast Path 加速"
|
||||
|
||||
msgid "Enable Fast Path offloading for connections. (decrease cpu load / increase routing throughput)"
|
||||
msgstr "开启 Fast Path 转发加速. (降低CPU占用 / 增强路由转发性能,和多WAN或者QOS功能可能会冲突)"
|
||||
|
||||
msgid "Bridge Acceleration"
|
||||
msgstr "桥接加速"
|
||||
|
||||
msgid "Enable Bridge Acceleration (may be functional conflict with bridge-mode VPN Server)"
|
||||
msgstr "启用桥接加速 (可能会和路由器上桥接模式的VPN服务器冲突)"
|
||||
|
||||
msgid "IPv6 Acceleration"
|
||||
msgstr "IPv6 加速"
|
||||
|
||||
msgid "Enable IPv6 Acceleration"
|
||||
msgstr "开启IPv6加速"
|
||||
|
||||
msgid "Enable BBR"
|
||||
msgstr "启用 BBR"
|
||||
|
||||
msgid "Bottleneck Bandwidth and Round-trip propagation time (BBR)"
|
||||
msgstr "BBR拥塞控制算法可以加强TCP应用表现"
|
||||
|
||||
msgid "DNS Acceleration"
|
||||
msgstr "DNS 加速"
|
||||
|
||||
msgid "Enable DNS Cache Acceleration and anti ISP DNS pollution"
|
||||
msgstr "启用DNS多线程查询、缓存,并防止ISP的DNS广告和域名劫持"
|
||||
|
||||
msgid "Resolve Dns Mode"
|
||||
msgstr "DNS解析方式"
|
||||
|
||||
msgid "Enable dnsmasq killqqad"
|
||||
msgstr "启用dnsmasq去广告"
|
||||
|
||||
msgid "dnsmasq killqqad"
|
||||
msgstr "dnsmasq去广告"
|
||||
|
||||
msgid "Use Pdnsd query and cache"
|
||||
msgstr "使用pdnsd解析"
|
||||
|
||||
msgid "Use dnsforwarder query and cache"
|
||||
msgstr "使用dnsforwarder解析"
|
||||
|
||||
msgid "Use AdGuardHome query and cache"
|
||||
msgstr "使用AdGuardHome解析去广告"
|
||||
|
||||
msgid "Upsteam DNS Server"
|
||||
msgstr "上游 DNS 服务器(国内)"
|
||||
|
||||
msgid "Upsteam IPV6 DNS Server"
|
||||
msgstr "上游 IPV6 DNS 服务器"
|
||||
|
||||
msgid "Muitiple DNS server can saperate with ','"
|
||||
msgstr "支持多个上游DNS服务器,用','分隔(注意用英文逗号).请填写您最快的DNS服务器"
|
||||
|
||||
msgid "Muitiple IPV6 DNS server can saperate with ','"
|
||||
msgstr "支持dnsforwarder解析多个上游IPV6 DNS服务器,用','分隔(注意用英文逗号).请填写您最快的DNS服务器"
|
||||
|
||||
msgid "AdGuardHome's login username/passwd: AdGuardHome, web console addr: IP:3001"
|
||||
msgstr "AdGuardHome 网页控制台地址:IP:3001 登录账号/密码:AdGuardHome"
|
||||
|
||||
11
package/lean/luci-app-sfe/root/etc/config/sfe
Normal file
11
package/lean/luci-app-sfe/root/etc/config/sfe
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
config sfe 'config'
|
||||
option enabled '1'
|
||||
option ipv6 '0'
|
||||
option wifi '0'
|
||||
option bbr '0'
|
||||
option dns '0'
|
||||
option dnscache_enable '1'
|
||||
option dns_server '114.114.114.114,114.114.115.115,223.5.5.5,223.6.6.6,180.76.76.76,119.29.29.29,119.28.28.28,1.2.4.8,210.2.4.8'
|
||||
option ipv6dns_server '240c::6666,240c::6644,2001:da8::666,2001:da8:202:10::36,2001:da8:8000:1:202:120:2:100'
|
||||
|
||||
294
package/lean/luci-app-sfe/root/etc/init.d/sfe
Executable file
294
package/lean/luci-app-sfe/root/etc/init.d/sfe
Executable file
@ -0,0 +1,294 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2007-2012 OpenWrt.org
|
||||
|
||||
START=90
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
|
||||
DNSMASQ_RESTART=N
|
||||
DNS_SERVER="114.114.114.114,114.114.115.115,223.5.5.5,223.6.6.6,180.76.76.76,119.29.29.29,119.28.28.28,1.2.4.8,210.2.4.8"
|
||||
IPV6DNS_SERVER="240c::6666,240c::6644,2001:da8::666,2001:da8:202:10::36,2001:da8:8000:1:202:120:2:100"
|
||||
|
||||
lan_addr=$(uci get network.lan.ipaddr)
|
||||
|
||||
start_pdnsd() {
|
||||
DNS_SERVER=$(uci get sfe.config.dns_server 2>/dev/null)
|
||||
cp -a /usr/sbin/pdnsd /usr/sbin/dnscache
|
||||
sleep 1
|
||||
[ -d /var/etc ] || mkdir -p /var/etc
|
||||
|
||||
if [ ! -f /var/dnscache/pdnsd.cache ]; then
|
||||
mkdir -p /var/dnscache
|
||||
echo -ne "pd13\000\000\000\000" > /var/dnscache/pdnsd.cache
|
||||
chown -R nobody.nogroup /var/dnscache
|
||||
fi
|
||||
|
||||
cat > /var/etc/dnscache.conf <<EOF
|
||||
global {
|
||||
perm_cache=1024; # dns缓存大小,单位KB,建议不要写的太大
|
||||
cache_dir="/var/dnscache"; # 缓存文件的位置
|
||||
pid_file = /var/run/dnscache.pid;
|
||||
server_ip = 0.0.0.0; # pdnsd监听的网卡,0.0.0.0是全部网卡
|
||||
server_port=5333; # pdnsd监听的端口,不要和别的服务冲突即可
|
||||
status_ctl = on;
|
||||
paranoid=on; # 二次请求模式,如果请求主DNS服务器返回的是垃圾地址,就向备用服务器请求
|
||||
query_method=udp_only;
|
||||
neg_domain_pol = off;
|
||||
par_queries = 400; # 最多同时请求数
|
||||
min_ttl = 1h; # DNS结果最短缓存时间
|
||||
max_ttl = 1w; # DNS结果最长缓存时间
|
||||
timeout = 10; # DNS请求超时时间,单位秒
|
||||
}
|
||||
|
||||
server {
|
||||
label = "routine";
|
||||
ip = $DNS_SERVER; # 这里为主要上级 dns 的 ip 地址,建议填写一个当地最快的DNS地址
|
||||
timeout = 5; # DNS请求超时时间
|
||||
reject = 74.125.127.102, # 以下是脏IP,也就是DNS污染一般会返回的结果,如果收到如下DNS结果会触发二次请求(TCP协议一般不会碰到脏IP)
|
||||
74.125.155.102,
|
||||
74.125.39.102,
|
||||
74.125.39.113,
|
||||
209.85.229.138,
|
||||
128.121.126.139,
|
||||
159.106.121.75,
|
||||
169.132.13.103,
|
||||
192.67.198.6,
|
||||
202.106.1.2,
|
||||
202.181.7.85,
|
||||
203.161.230.171,
|
||||
203.98.7.65,
|
||||
207.12.88.98,
|
||||
208.56.31.43,
|
||||
209.145.54.50,
|
||||
209.220.30.174,
|
||||
209.36.73.33,
|
||||
211.94.66.147,
|
||||
213.169.251.35,
|
||||
216.221.188.182,
|
||||
216.234.179.13,
|
||||
243.185.187.39,
|
||||
37.61.54.158,
|
||||
4.36.66.178,
|
||||
46.82.174.68,
|
||||
59.24.3.173,
|
||||
64.33.88.161,
|
||||
64.33.99.47,
|
||||
64.66.163.251,
|
||||
65.104.202.252,
|
||||
65.160.219.113,
|
||||
66.45.252.237,
|
||||
69.55.52.253,
|
||||
72.14.205.104,
|
||||
72.14.205.99,
|
||||
78.16.49.15,
|
||||
8.7.198.45,
|
||||
93.46.8.89,
|
||||
37.61.54.158,
|
||||
243.185.187.39,
|
||||
190.93.247.4,
|
||||
190.93.246.4,
|
||||
190.93.245.4,
|
||||
190.93.244.4,
|
||||
65.49.2.178,
|
||||
189.163.17.5,
|
||||
23.89.5.60,
|
||||
49.2.123.56,
|
||||
54.76.135.1,
|
||||
77.4.7.92,
|
||||
118.5.49.6,
|
||||
159.24.3.173,
|
||||
188.5.4.96,
|
||||
197.4.4.12,
|
||||
220.250.64.24,
|
||||
243.185.187.30,
|
||||
249.129.46.48,
|
||||
253.157.14.165;
|
||||
reject_policy = fail;
|
||||
}
|
||||
|
||||
server {
|
||||
label = "special"; # 这个随便写
|
||||
ip = 208.67.222.222,208.67.220.220; # 这里为备用DNS服务器的 ip 地址
|
||||
port = 5353; # 推荐使用53以外的端口(DNS服务器必须支持)
|
||||
proxy_only = on;
|
||||
timeout = 5;
|
||||
}
|
||||
|
||||
source {
|
||||
owner=localhost;
|
||||
// serve_aliases=on;
|
||||
file="/etc/hosts";
|
||||
}
|
||||
|
||||
rr {
|
||||
name=localhost;
|
||||
reverse=on;
|
||||
a=127.0.0.1;
|
||||
owner=localhost;
|
||||
soa=localhost,root.localhost,42,86400,900,86400,86400;
|
||||
}
|
||||
EOF
|
||||
|
||||
[ -d /var/sbin ] || mkdir -p /var/sbin
|
||||
[ -f /var/sbin/dnscache ] || cp -a /usr/sbin/pdnsd /var/sbin/dnscache
|
||||
/usr/sbin/dnscache -c /var/etc/dnscache.conf &
|
||||
echo "Start DNS Cache"
|
||||
}
|
||||
|
||||
start_dnsforwarder() {
|
||||
DNS_SERVER=$(uci get sfe.config.dns_server 2>/dev/null)
|
||||
IPV6DNS_SERVER=$(uci get sfe.config.ipv6dns_server 2>/dev/null)
|
||||
dnscache_enable=$(uci get sfe.config.dnscache_enable 2>/dev/null)
|
||||
if [ $dnscache_enable = "2" ]; then
|
||||
localserver=0.0.0.0:5333
|
||||
elif [ $dnscache_enable = "3" ]; then
|
||||
localserver=0.0.0.0:5383
|
||||
fi
|
||||
cp -a /usr/bin/dnsforwarder /usr/sbin/dnscache
|
||||
sleep 1
|
||||
DNSCACHE_CONF=/var/run/dnscache/dnscache.conf
|
||||
PID_PATH=/var/run/dnscache
|
||||
PID_FILE=dns.pid
|
||||
mkdir -p $PID_PATH
|
||||
pid=`ps | awk '$5 ~ /\[dnscache\]/ {print $1}'`
|
||||
|
||||
cat > /var/run/dnscache/dnscache.conf <<EOF
|
||||
LogOn false
|
||||
LogFileThresholdLength 102400
|
||||
LogFileFolder /var/run/dnscache
|
||||
UDPLocal $localserver
|
||||
UDPGroup $DNS_SERVER,$IPV6DNS_SERVER * on
|
||||
GroupFile
|
||||
BlockIP 243.185.187.39,46.82.174.68,37.61.54.158,93.46.8.89,59.24.3.173,203.98.7.65,8.7.198.45,78.16.49.15,159.106.121.75,69.63.187.12,31.13.76.8,31.13.64.49
|
||||
IPSubstituting
|
||||
BlockNegativeResponse false
|
||||
Hosts
|
||||
HostsUpdateInterval 18000
|
||||
HostsDownloadPath
|
||||
HostsScript
|
||||
HostsRetryInterval 30
|
||||
AppendHosts
|
||||
BlockIpv6WhenIpv4Exists false
|
||||
UseCache true
|
||||
CacheSize 1048576
|
||||
MemoryCache true
|
||||
CacheFile
|
||||
IgnoreTTL false
|
||||
OverrideTTL -1
|
||||
MultipleTTL 1
|
||||
ReloadCache false
|
||||
OverwriteCache false
|
||||
DisabledType
|
||||
DisabledDomain
|
||||
DisabledList
|
||||
DomainStatistic false
|
||||
DomainStatisticTempletFile
|
||||
StatisticUpdateInterval 29
|
||||
EOF
|
||||
|
||||
dnscache -f $DNSCACHE_CONF &
|
||||
echo "Start DNS Cache"
|
||||
|
||||
}
|
||||
|
||||
stop_dnscache() {
|
||||
kill $(pidof AdGuardHome) >/dev/null 2>&1 || kill -9 $(ps | grep AdGuardHome | grep -v "grep" | awk '{print $1}') >/dev/null 2>&1
|
||||
kill $(pidof dnscache) >/dev/null 2>&1 || kill -9 $(ps | grep dnscache | grep -v "grep" | awk '{print $1}') >/dev/null 2>&1
|
||||
rm -rf /var/run/dnscache
|
||||
rm -rf /var/dnscache
|
||||
echo "Stop DNS Cache"
|
||||
|
||||
}
|
||||
|
||||
change_dns() {
|
||||
uci delete dhcp.@dnsmasq[0].server >/dev/null 2>&1
|
||||
uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#5333
|
||||
uci set dhcp.@dnsmasq[0].noresolv=1
|
||||
uci commit dhcp
|
||||
|
||||
}
|
||||
|
||||
revert_dns() {
|
||||
uci del_list dhcp.@dnsmasq[0].server=127.0.0.1#5333 >/dev/null 2>&1
|
||||
uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto
|
||||
uci set dhcp.@dnsmasq[0].noresolv=0
|
||||
uci commit dhcp
|
||||
|
||||
}
|
||||
|
||||
start_service() {
|
||||
enable=$(uci get sfe.config.enabled 2>/dev/null)
|
||||
wifi=$(uci get sfe.config.wifi)
|
||||
ipv6=$(uci get sfe.config.ipv6)
|
||||
dns=$(uci get sfe.config.dns 2>/dev/null)
|
||||
dnscache_enable=$(uci get sfe.config.dnscache_enable 2>/dev/null)
|
||||
bbr=$(uci get sfe.config.bbr 2>/dev/null)
|
||||
|
||||
if [ $enable -eq 1 ]; then
|
||||
! (lsmod | grep fast_classifier >/dev/null) && (modprobe fast_classifier)
|
||||
if [ $wifi -eq 1 ] ; then
|
||||
echo 1 > /sys/fast_classifier/skip_to_bridge_ingress
|
||||
else
|
||||
echo 0 > /sys/fast_classifier/skip_to_bridge_ingress
|
||||
fi
|
||||
|
||||
if [ $ipv6 -eq 1 ]; then
|
||||
sfe_ipv6=$(cat /sys/sfe_ipv6/debug_dev)
|
||||
[ ! -f /dev/sfe_ipv6 ] && mknod /dev/sfe_ipv6 c $sfe_ipv6 0
|
||||
else
|
||||
rm -f /dev/sfe_ipv6
|
||||
fi
|
||||
else
|
||||
rmmod fast_classifier >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if [ $dns -eq 1 ]; then
|
||||
kill -9 $(ps | grep dnscache-while.sh | grep -v "grep" | awk '{print $1}') >/dev/null 2>&1
|
||||
stop_dnscache
|
||||
sleep 1
|
||||
rm -f /var/log/dnscache.file
|
||||
rm -f /etc/AdGuardHome/data/querylog.json*
|
||||
if [ $dnscache_enable = "1" ]; then
|
||||
start_pdnsd
|
||||
elif [ $dnscache_enable = "2" ]; then
|
||||
start_dnsforwarder
|
||||
elif [ $dnscache_enable = "3" ]; then
|
||||
AdGuardHome -c /etc/AdGuardHome/AdGuardHome.yaml -w /etc/AdGuardHome -h ${lan_addr} -p 3001 --no-check-update &
|
||||
fi
|
||||
change_dns
|
||||
nohup /usr/share/dnscache/dnscache-while.sh > /var/log/dnscache.file 2>&1 &
|
||||
else
|
||||
stop_dnscache
|
||||
revert_dns
|
||||
kill -9 $(ps | grep dnscache-while.sh | grep -v "grep" | awk '{print $1}') >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if [ $bbr -eq 1 ]; then
|
||||
sysctl -w net.ipv4.tcp_congestion_control=bbr
|
||||
else
|
||||
sysctl -w net.ipv4.tcp_congestion_control=cubic
|
||||
fi
|
||||
|
||||
if [ "$DNSMASQ_RESTART" = N ]; then
|
||||
/etc/init.d/dnsmasq restart
|
||||
fi
|
||||
}
|
||||
|
||||
stop_service(){
|
||||
enable=$(uci get sfe.config.enabled 2>/dev/null)
|
||||
[ $enable -ne 1 ] && rmmod fast_classifier >/dev/null 2>&1
|
||||
stop_dnscache
|
||||
revert_dns
|
||||
kill -9 $(ps | grep dnscache-while.sh | grep -v "grep" | awk '{print $1}') >/dev/null 2>&1
|
||||
if [ "$DNSMASQ_RESTART" = N ]; then
|
||||
/etc/init.d/dnsmasq restart
|
||||
fi
|
||||
}
|
||||
|
||||
restart(){
|
||||
DNSMASQ_RESTART=Y
|
||||
stop
|
||||
start
|
||||
/etc/init.d/dnsmasq restart && echo "DNSMASQ restart"
|
||||
}
|
||||
14
package/lean/luci-app-sfe/root/etc/uci-defaults/sfe
Executable file
14
package/lean/luci-app-sfe/root/etc/uci-defaults/sfe
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@sfe[-1]
|
||||
add ucitrack sfe
|
||||
set ucitrack.@sfe[-1].init=sfe
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
[ ! -f /usr/sbin/dnscache ] && ln /usr/sbin/pdnsd /usr/sbin/dnscache
|
||||
/etc/init.d/sfe enable
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
50
package/lean/luci-app-sfe/root/usr/share/dnscache/dnscache-while.sh
Executable file
50
package/lean/luci-app-sfe/root/usr/share/dnscache/dnscache-while.sh
Executable file
@ -0,0 +1,50 @@
|
||||
#!/bin/sh
|
||||
|
||||
sleeptime=30
|
||||
logfile="/var/log/dnscache.file"
|
||||
adg_logfile="/etc/AdGuardHome/data/querylog.json"
|
||||
dns_enable=$(uci get sfe.config.dns 2>/dev/null)
|
||||
dnscache_enable=$(uci get sfe.config.dnscache_enable 2>/dev/null)
|
||||
lan_addr=$(uci get network.lan.ipaddr)
|
||||
|
||||
clean_log(){
|
||||
logrow=$(grep -c "" ${logfile})
|
||||
if [ $logrow -ge 500 ];then
|
||||
cat /dev/null > ${logfile}
|
||||
echo "$curtime Log条数超限,清空处理!" >> ${logfile}
|
||||
fi
|
||||
if [ $dnscache_enable = "3" ];then
|
||||
adg_logrow=$(grep -c "" ${adg_logfile})
|
||||
if [ $adg_logrow -ge 500 ];then
|
||||
cat /dev/null > ${adg_logfile}
|
||||
echo "$curtime Log条数超限,清空处理!" >> ${adg_logfile}
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
while [ $dns_enable -eq 1 ];
|
||||
do
|
||||
curtime=`date "+%H:%M:%S"`
|
||||
echo "$curtime online! "
|
||||
if [ $dns_enable -eq 1 ]; then
|
||||
if [ $dnscache_enable = "3" ]; then
|
||||
if ! pidof AdGuardHome>/dev/null; then
|
||||
AdGuardHome -c /etc/AdGuardHome/AdGuardHome.yaml -w /etc/AdGuardHome -h ${lan_addr} -p 3001 --no-check-update &
|
||||
echo "$curtime 重启服务!" >> ${logfile}
|
||||
fi
|
||||
else
|
||||
if ! pidof dnscache>/dev/null; then
|
||||
if [ $dnscache_enable = "1" ]; then
|
||||
/usr/sbin/dnscache -c /var/etc/dnscache.conf &
|
||||
elif [ $dnscache_enable = "2" ]; then
|
||||
dnscache -f /var/run/dnscache/dnscache.conf &
|
||||
fi
|
||||
echo "$curtime 重启服务!" >> ${logfile}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep ${sleeptime}
|
||||
continue
|
||||
done
|
||||
81
package/lean/shortcut-fe/Makefile
Normal file
81
package/lean/shortcut-fe/Makefile
Normal file
@ -0,0 +1,81 @@
|
||||
#
|
||||
# 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.
|
||||
# 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
|
||||
PKG_RELEASE:=2
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/shortcut-fe
|
||||
SECTION:=kernel
|
||||
CATEGORY:=Kernel modules
|
||||
SUBMENU:=Network Support
|
||||
DEPENDS:=
|
||||
TITLE:=Kernel driver for SFE
|
||||
FILES:=$(PKG_BUILD_DIR)/shortcut-fe.ko $(PKG_BUILD_DIR)/shortcut-fe-ipv6.ko
|
||||
KCONFIG:=CONFIG_NF_CONNTRACK_EVENTS=y \
|
||||
CONFIG_NF_CONNTRACK_TIMEOUT=y \
|
||||
CONFIG_SHORTCUT_FE=y \
|
||||
CONFIG_XFRM=y
|
||||
AUTOLOAD:=$(call AutoLoad,09,shortcut-fe shortcut-fe-ipv6)
|
||||
endef
|
||||
|
||||
define KernelPackage/shortcut-fe/Description
|
||||
Shortcut is an in-Linux-kernel IP packet forwarding engine.
|
||||
endef
|
||||
|
||||
define KernelPackage/shortcut-fe/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/etc/init.d/shortcut-fe $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) ./files/usr/bin/sfe_dump $(1)/usr/bin
|
||||
endef
|
||||
|
||||
define KernelPackage/shortcut-fe-cm
|
||||
SECTION:=kernel
|
||||
CATEGORY:=Kernel modules
|
||||
SUBMENU:=Network Support
|
||||
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
|
||||
endef
|
||||
|
||||
define KernelPackage/shortcut-fe-cm/Description
|
||||
Simple connection manager for the Shortcut forwarding engine.
|
||||
endef
|
||||
|
||||
EXTRA_CFLAGS+=-DSFE_SUPPORT_IPV6
|
||||
|
||||
define Build/Compile
|
||||
+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
$(PKG_MAKE_FLAGS) \
|
||||
M="$(PKG_BUILD_DIR)" \
|
||||
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
|
||||
SFE_SUPPORT_IPV6=1 \
|
||||
modules
|
||||
endef
|
||||
|
||||
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
|
||||
|
||||
$(eval $(call KernelPackage,shortcut-fe))
|
||||
$(eval $(call KernelPackage,shortcut-fe-cm))
|
||||
49
package/lean/shortcut-fe/files/etc/init.d/shortcut-fe
Executable file
49
package/lean/shortcut-fe/files/etc/init.d/shortcut-fe
Executable file
@ -0,0 +1,49 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#
|
||||
# Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
# above copyright notice and this permission notice appear in all copies.
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
#SFE connection manager has a lower priority, it should be started after other connection manager
|
||||
#to detect the existence of connection manager with higher priority
|
||||
START=72
|
||||
|
||||
have_cm() {
|
||||
[ -d "/sys/kernel/debug/ecm" ] && echo 1 && return
|
||||
|
||||
echo 0
|
||||
}
|
||||
|
||||
#load shortcut-fe connection manager
|
||||
load_sfe_cm() {
|
||||
local kernel_version=$(uname -r)
|
||||
|
||||
#shortcut-fe-drv.ko is not needed because other connection manager is not enabled
|
||||
[ -d "/sys/module/shortcut_fe_drv" ] && rmmod shortcut_fe_drv
|
||||
|
||||
[ -e "/lib/modules/$kernel_version/fast-classifier.ko" ] && {
|
||||
[ -d /sys/module/fast_classifier ] || insmod /lib/modules/$kernel_version/fast-classifier.ko && return
|
||||
}
|
||||
|
||||
[ -e "/lib/modules/$kernel_version/shortcut-fe-cm.ko" ] && {
|
||||
[ -d /sys/module/shortcut_fe_cm ] || insmod /lib/modules/$kernel_version/shortcut-fe-cm.ko && return
|
||||
}
|
||||
}
|
||||
|
||||
start() {
|
||||
[ "$(have_cm)" = "1" ] || load_sfe_cm
|
||||
}
|
||||
|
||||
stop() {
|
||||
[ -d /sys/module/shortcut_fe_cm ] && rmmod shortcut_fe_cm
|
||||
[ -d /sys/module/fast_classifier ] && rmmod fast_classifier
|
||||
}
|
||||
35
package/lean/shortcut-fe/files/usr/bin/sfe_dump
Normal file
35
package/lean/shortcut-fe/files/usr/bin/sfe_dump
Normal file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2015 The Linux Foundation. All rights reserved.
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
# above copyright notice and this permission notice appear in all copies.
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
#@sfe_dump
|
||||
#@example : sfe_dump (ipv4|ipv6)
|
||||
sfe_dump(){
|
||||
[ -e "/dev/sfe_ipv4" ] || {
|
||||
dev_num=$(cat /sys/sfe_ipv4/debug_dev)
|
||||
mknod /dev/sfe_ipv4 c $dev_num 0
|
||||
}
|
||||
[ -e "/dev/sfe_ipv6" ] || {
|
||||
dev_num=$(cat /sys/sfe_ipv6/debug_dev)
|
||||
mknod /dev/sfe_ipv6 c $dev_num 0
|
||||
}
|
||||
cat /dev/sfe_$1
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
sfe_dump ipv4
|
||||
sfe_dump ipv6
|
||||
else
|
||||
sfe_dump $1
|
||||
fi
|
||||
14
package/lean/shortcut-fe/src/Kconfig
Normal file
14
package/lean/shortcut-fe/src/Kconfig
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
# Shortcut forwarding engine
|
||||
#
|
||||
|
||||
config SHORTCUT_FE
|
||||
tristate "Shortcut Forwarding Engine"
|
||||
depends on NF_CONNTRACK
|
||||
---help---
|
||||
Shortcut is a fast in-kernel packet forwarding engine.
|
||||
|
||||
To compile this code as a module, choose M here: the module will be
|
||||
called shortcut-fe.
|
||||
|
||||
If unsure, say N.
|
||||
23
package/lean/shortcut-fe/src/Makefile
Normal file
23
package/lean/shortcut-fe/src/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
#
|
||||
# Makefile for Shortcut FE.
|
||||
#
|
||||
|
||||
obj-m += shortcut-fe.o
|
||||
|
||||
ifdef SFE_SUPPORT_IPV6
|
||||
obj-m += shortcut-fe-ipv6.o
|
||||
endif
|
||||
|
||||
obj-m += shortcut-fe-cm.o
|
||||
|
||||
shortcut-fe-objs := \
|
||||
sfe_ipv4.o
|
||||
|
||||
ifdef SFE_SUPPORT_IPV6
|
||||
shortcut-fe-ipv6-objs := \
|
||||
sfe_ipv6.o
|
||||
endif
|
||||
|
||||
shortcut-fe-cm-objs := \
|
||||
sfe_cm.o
|
||||
|
||||
114
package/lean/shortcut-fe/src/sfe.h
Normal file
114
package/lean/shortcut-fe/src/sfe.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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*/
|
||||
195
package/lean/shortcut-fe/src/sfe_backport.h
Normal file
195
package/lean/shortcut-fe/src/sfe_backport.h
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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
|
||||
1143
package/lean/shortcut-fe/src/sfe_cm.c
Normal file
1143
package/lean/shortcut-fe/src/sfe_cm.c
Normal file
File diff suppressed because it is too large
Load Diff
259
package/lean/shortcut-fe/src/sfe_cm.h
Normal file
259
package/lean/shortcut-fe/src/sfe_cm.h
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
3621
package/lean/shortcut-fe/src/sfe_ipv4.c
Normal file
3621
package/lean/shortcut-fe/src/sfe_ipv4.c
Normal file
File diff suppressed because it is too large
Load Diff
3628
package/lean/shortcut-fe/src/sfe_ipv6.c
Normal file
3628
package/lean/shortcut-fe/src/sfe_ipv6.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,236 @@
|
||||
--- a/include/linux/skbuff.h 2019-01-16 20:16:08.325745306 +0800
|
||||
+++ b/include/linux/skbuff.h 2019-01-16 20:31:47.288028493 +0800
|
||||
@@ -783,6 +783,9 @@ struct sk_buff {
|
||||
__u8 tc_from_ingress:1;
|
||||
#endif
|
||||
__u8 gro_skip:1;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ __u8 fast_forwarded:1;
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
__u16 tc_index; /* traffic control index */
|
||||
--- a/include/linux/if_bridge.h 2019-01-16 20:51:47.871445535 +0800
|
||||
+++ b/include/linux/if_bridge.h 2019-01-16 20:52:26.220269649 +0800
|
||||
@@ -54,6 +54,8 @@ struct br_ip_list {
|
||||
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
|
||||
|
||||
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
|
||||
+extern void br_dev_update_stats(struct net_device *dev,
|
||||
+ struct rtnl_link_stats64 *nlstats);
|
||||
|
||||
typedef int br_should_route_hook_t(struct sk_buff *skb);
|
||||
extern br_should_route_hook_t __rcu *br_should_route_hook;
|
||||
--- a/include/linux/timer.h
|
||||
+++ b/include/linux/timer.h
|
||||
@@ -20,6 +20,9 @@ struct timer_list {
|
||||
void (*function)(unsigned long);
|
||||
unsigned long data;
|
||||
u32 flags;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ unsigned long cust_data;
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
struct lockdep_map lockdep_map;
|
||||
--- a/net/Kconfig 2019-01-16 20:36:30.266465286 +0800
|
||||
+++ b/net/Kconfig 2019-01-16 20:36:41.980609067 +0800
|
||||
@@ -463,3 +463,6 @@ config HAVE_CBPF_JIT
|
||||
# Extended BPF JIT (eBPF)
|
||||
config HAVE_EBPF_JIT
|
||||
bool
|
||||
+
|
||||
+config SHORTCUT_FE
|
||||
+ bool "Enables kernel network stack path for Shortcut Forwarding Engine
|
||||
--- a/net/core/dev.c 2019-01-16 20:38:37.274933833 +0800
|
||||
+++ b/net/core/dev.c 2019-01-16 20:44:07.773594898 +0800
|
||||
@@ -3005,8 +3005,17 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
!(skb->imq_flags & IMQ_F_ENQUEUE))
|
||||
#else
|
||||
if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
|
||||
+#endif
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ /* If this skb has been fast forwarded then we don't want it to
|
||||
+ * go to any taps (by definition we're trying to bypass them).
|
||||
+ */
|
||||
+ if (!skb->fast_forwarded) {
|
||||
#endif
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
if (!dev->eth_mangle_tx ||
|
||||
@@ -4315,6 +4324,11 @@ void netdev_rx_handler_unregister(struct
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+int (*athrs_fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
|
||||
+EXPORT_SYMBOL_GPL(athrs_fast_nat_recv);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Limit the use of PFMEMALLOC reserves to those protocols that implement
|
||||
* the special handling of PFMEMALLOC skbs.
|
||||
@@ -4362,6 +4376,9 @@ static int __netif_receive_skb_core(stru
|
||||
bool deliver_exact = false;
|
||||
int ret = NET_RX_DROP;
|
||||
__be16 type;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ int (*fast_recv)(struct sk_buff *skb);
|
||||
+#endif
|
||||
|
||||
net_timestamp_check(!netdev_tstamp_prequeue, skb);
|
||||
|
||||
@@ -4388,6 +4405,16 @@ another_round:
|
||||
goto out;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ fast_recv = rcu_dereference(athrs_fast_nat_recv);
|
||||
+ if (fast_recv) {
|
||||
+ if (fast_recv(skb)) {
|
||||
+ ret = NET_RX_SUCCESS;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (skb_skip_tc_classify(skb))
|
||||
goto skip_classify;
|
||||
|
||||
--- a/net/netfilter/nf_conntrack_proto_tcp.c 2019-01-16 20:47:40.886993297 +0800
|
||||
+++ b/net/netfilter/nf_conntrack_proto_tcp.c 2019-01-16 20:48:57.700570104 +0800
|
||||
@@ -35,11 +35,17 @@
|
||||
|
||||
/* Do not check the TCP window for incoming packets */
|
||||
static int nf_ct_tcp_no_window_check __read_mostly = 1;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check);
|
||||
+#endif
|
||||
|
||||
/* "Be conservative in what you do,
|
||||
be liberal in what you accept from others."
|
||||
If it's non-zero, we mark only out of window RST segments as INVALID. */
|
||||
static int nf_ct_tcp_be_liberal __read_mostly = 0;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_be_liberal);
|
||||
+#endif
|
||||
|
||||
/* If it is set to zero, we disable picking up already established
|
||||
connections. */
|
||||
--- a/net/bridge/br_if.c 2019-01-16 20:54:51.919367044 +0800
|
||||
+++ b/net/bridge/br_if.c 2019-01-16 20:55:53.812401263 +0800
|
||||
@@ -653,3 +653,26 @@ void br_port_flags_change(struct net_bri
|
||||
if (mask & BR_AUTO_MASK)
|
||||
nbp_update_port_count(br);
|
||||
}
|
||||
+
|
||||
+/* Update bridge statistics for bridge packets processed by offload engines */
|
||||
+void br_dev_update_stats(struct net_device *dev,
|
||||
+ struct rtnl_link_stats64 *nlstats)
|
||||
+{
|
||||
+ struct net_bridge *br;
|
||||
+ struct pcpu_sw_netstats *stats;
|
||||
+
|
||||
+ /* Is this a bridge? */
|
||||
+ if (!(dev->priv_flags & IFF_EBRIDGE))
|
||||
+ return;
|
||||
+
|
||||
+ br = netdev_priv(dev);
|
||||
+ stats = this_cpu_ptr(br->stats);
|
||||
+
|
||||
+ u64_stats_update_begin(&stats->syncp);
|
||||
+ stats->rx_packets += nlstats->rx_packets;
|
||||
+ stats->rx_bytes += nlstats->rx_bytes;
|
||||
+ stats->tx_packets += nlstats->tx_packets;
|
||||
+ stats->tx_bytes += nlstats->tx_bytes;
|
||||
+ u64_stats_update_end(&stats->syncp);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(br_dev_update_stats);
|
||||
--- a/net/netfilter/Kconfig 2019-01-16 21:07:34.543460920 +0800
|
||||
+++ b/net/netfilter/Kconfig 2019-01-16 21:08:14.739465937 +0800
|
||||
@@ -146,6 +146,14 @@ config NF_CONNTRACK_TIMEOUT
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
+config NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ bool "Register multiple callbacks to ct events"
|
||||
+ depends on NF_CONNTRACK_EVENTS
|
||||
+ help
|
||||
+ Support multiple registrations.
|
||||
+
|
||||
+ If unsure, say `N'.
|
||||
+
|
||||
config NF_CONNTRACK_TIMESTAMP
|
||||
bool 'Connection tracking timestamping'
|
||||
depends on NETFILTER_ADVANCED
|
||||
--- a/net/netfilter/nf_conntrack_ecache.c 2019-01-16 21:12:22.183462975 +0800
|
||||
+++ b/net/netfilter/nf_conntrack_ecache.c 2019-01-16 21:26:10.379462031 +0800
|
||||
@@ -122,13 +125,17 @@ int nf_conntrack_eventmask_report(unsign
|
||||
{
|
||||
int ret = 0;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
if (!notify)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (!e)
|
||||
@@ -146,7 +153,12 @@ int nf_conntrack_eventmask_report(unsign
|
||||
if (!((eventmask | missed) & e->ctmask))
|
||||
goto out_unlock;
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ eventmask | missed, &item);
|
||||
+#else
|
||||
ret = notify->fcn(eventmask | missed, &item);
|
||||
+#endif
|
||||
if (unlikely(ret < 0 || missed)) {
|
||||
spin_lock_bh(&ct->lock);
|
||||
if (ret < 0) {
|
||||
@@ -179,15 +191,19 @@ void nf_ct_deliver_cached_events(struct
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
unsigned long events, missed;
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
struct nf_ct_event item;
|
||||
int ret;
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
if (notify == NULL)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
@@ -210,7 +226,13 @@ void nf_ct_deliver_cached_events(struct
|
||||
item.portid = 0;
|
||||
item.report = 0;
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ events | missed,
|
||||
+ &item);
|
||||
+#else
|
||||
ret = notify->fcn(events | missed, &item);
|
||||
+#endif
|
||||
|
||||
if (likely(ret == 0 && !missed))
|
||||
goto out_unlock;
|
||||
@ -0,0 +1,236 @@
|
||||
--- a/include/linux/skbuff.h 2019-01-16 20:16:08.325745306 +0800
|
||||
+++ b/include/linux/skbuff.h 2019-01-16 20:31:47.288028493 +0800
|
||||
@@ -783,6 +783,9 @@ struct sk_buff {
|
||||
__u8 tc_from_ingress:1;
|
||||
#endif
|
||||
__u8 gro_skip:1;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ __u8 fast_forwarded:1;
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
__u16 tc_index; /* traffic control index */
|
||||
--- a/include/linux/if_bridge.h 2019-01-16 20:51:47.871445535 +0800
|
||||
+++ b/include/linux/if_bridge.h 2019-01-16 20:52:26.220269649 +0800
|
||||
@@ -54,6 +54,8 @@ struct br_ip_list {
|
||||
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
|
||||
|
||||
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
|
||||
+extern void br_dev_update_stats(struct net_device *dev,
|
||||
+ struct rtnl_link_stats64 *nlstats);
|
||||
|
||||
typedef int br_should_route_hook_t(struct sk_buff *skb);
|
||||
extern br_should_route_hook_t __rcu *br_should_route_hook;
|
||||
--- a/include/linux/timer.h
|
||||
+++ b/include/linux/timer.h
|
||||
@@ -20,6 +20,9 @@ struct timer_list {
|
||||
void (*function)(unsigned long);
|
||||
unsigned long data;
|
||||
u32 flags;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ unsigned long cust_data;
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
struct lockdep_map lockdep_map;
|
||||
--- a/net/Kconfig 2019-01-16 20:36:30.266465286 +0800
|
||||
+++ b/net/Kconfig 2019-01-16 20:36:41.980609067 +0800
|
||||
@@ -463,3 +463,6 @@ config HAVE_CBPF_JIT
|
||||
# Extended BPF JIT (eBPF)
|
||||
config HAVE_EBPF_JIT
|
||||
bool
|
||||
+
|
||||
+config SHORTCUT_FE
|
||||
+ bool "Enables kernel network stack path for Shortcut Forwarding Engine
|
||||
--- a/net/core/dev.c 2019-01-16 20:38:37.274933833 +0800
|
||||
+++ b/net/core/dev.c 2019-01-16 20:44:07.773594898 +0800
|
||||
@@ -3256,8 +3256,17 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
!(skb->imq_flags & IMQ_F_ENQUEUE))
|
||||
#else
|
||||
if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
|
||||
+#endif
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ /* If this skb has been fast forwarded then we don't want it to
|
||||
+ * go to any taps (by definition we're trying to bypass them).
|
||||
+ */
|
||||
+ if (!skb->fast_forwarded) {
|
||||
#endif
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
if (!dev->eth_mangle_tx ||
|
||||
@@ -4315,6 +4324,11 @@ void netdev_rx_handler_unregister(struct
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+int (*athrs_fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
|
||||
+EXPORT_SYMBOL_GPL(athrs_fast_nat_recv);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Limit the use of PFMEMALLOC reserves to those protocols that implement
|
||||
* the special handling of PFMEMALLOC skbs.
|
||||
@@ -4362,6 +4376,9 @@ static int __netif_receive_skb_core(stru
|
||||
bool deliver_exact = false;
|
||||
int ret = NET_RX_DROP;
|
||||
__be16 type;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ int (*fast_recv)(struct sk_buff *skb);
|
||||
+#endif
|
||||
|
||||
net_timestamp_check(!netdev_tstamp_prequeue, skb);
|
||||
|
||||
@@ -4388,6 +4405,16 @@ another_round:
|
||||
goto out;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ fast_recv = rcu_dereference(athrs_fast_nat_recv);
|
||||
+ if (fast_recv) {
|
||||
+ if (fast_recv(skb)) {
|
||||
+ ret = NET_RX_SUCCESS;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (skb_skip_tc_classify(skb))
|
||||
goto skip_classify;
|
||||
|
||||
--- a/net/netfilter/nf_conntrack_proto_tcp.c 2019-01-16 20:47:40.886993297 +0800
|
||||
+++ b/net/netfilter/nf_conntrack_proto_tcp.c 2019-01-16 20:48:57.700570104 +0800
|
||||
@@ -35,11 +35,17 @@
|
||||
|
||||
/* Do not check the TCP window for incoming packets */
|
||||
static int nf_ct_tcp_no_window_check __read_mostly = 1;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check);
|
||||
+#endif
|
||||
|
||||
/* "Be conservative in what you do,
|
||||
be liberal in what you accept from others."
|
||||
If it's non-zero, we mark only out of window RST segments as INVALID. */
|
||||
static int nf_ct_tcp_be_liberal __read_mostly = 0;
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_be_liberal);
|
||||
+#endif
|
||||
|
||||
/* If it is set to zero, we disable picking up already established
|
||||
connections. */
|
||||
--- a/net/bridge/br_if.c 2019-01-16 20:54:51.919367044 +0800
|
||||
+++ b/net/bridge/br_if.c 2019-01-16 20:55:53.812401263 +0800
|
||||
@@ -653,3 +653,26 @@ void br_port_flags_change(struct net_bri
|
||||
if (mask & BR_AUTO_MASK)
|
||||
nbp_update_port_count(br);
|
||||
}
|
||||
+
|
||||
+/* Update bridge statistics for bridge packets processed by offload engines */
|
||||
+void br_dev_update_stats(struct net_device *dev,
|
||||
+ struct rtnl_link_stats64 *nlstats)
|
||||
+{
|
||||
+ struct net_bridge *br;
|
||||
+ struct pcpu_sw_netstats *stats;
|
||||
+
|
||||
+ /* Is this a bridge? */
|
||||
+ if (!(dev->priv_flags & IFF_EBRIDGE))
|
||||
+ return;
|
||||
+
|
||||
+ br = netdev_priv(dev);
|
||||
+ stats = this_cpu_ptr(br->stats);
|
||||
+
|
||||
+ u64_stats_update_begin(&stats->syncp);
|
||||
+ stats->rx_packets += nlstats->rx_packets;
|
||||
+ stats->rx_bytes += nlstats->rx_bytes;
|
||||
+ stats->tx_packets += nlstats->tx_packets;
|
||||
+ stats->tx_bytes += nlstats->tx_bytes;
|
||||
+ u64_stats_update_end(&stats->syncp);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(br_dev_update_stats);
|
||||
--- a/net/netfilter/Kconfig 2019-01-16 21:07:34.543460920 +0800
|
||||
+++ b/net/netfilter/Kconfig 2019-01-16 21:08:14.739465937 +0800
|
||||
@@ -146,6 +146,14 @@ config NF_CONNTRACK_TIMEOUT
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
+config NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ bool "Register multiple callbacks to ct events"
|
||||
+ depends on NF_CONNTRACK_EVENTS
|
||||
+ help
|
||||
+ Support multiple registrations.
|
||||
+
|
||||
+ If unsure, say `N'.
|
||||
+
|
||||
config NF_CONNTRACK_TIMESTAMP
|
||||
bool 'Connection tracking timestamping'
|
||||
depends on NETFILTER_ADVANCED
|
||||
--- a/net/netfilter/nf_conntrack_ecache.c 2019-01-16 21:12:22.183462975 +0800
|
||||
+++ b/net/netfilter/nf_conntrack_ecache.c 2019-01-16 21:26:10.379462031 +0800
|
||||
@@ -122,13 +125,17 @@ int nf_conntrack_eventmask_report(unsign
|
||||
{
|
||||
int ret = 0;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
if (!notify)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (!e)
|
||||
@@ -146,7 +153,12 @@ int nf_conntrack_eventmask_report(unsign
|
||||
if (!((eventmask | missed) & e->ctmask))
|
||||
goto out_unlock;
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ eventmask | missed, &item);
|
||||
+#else
|
||||
ret = notify->fcn(eventmask | missed, &item);
|
||||
+#endif
|
||||
if (unlikely(ret < 0 || missed)) {
|
||||
spin_lock_bh(&ct->lock);
|
||||
if (ret < 0) {
|
||||
@@ -179,15 +191,19 @@ void nf_ct_deliver_cached_events(struct
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
unsigned long events, missed;
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
struct nf_ct_event item;
|
||||
int ret;
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
if (notify == NULL)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
@@ -210,7 +226,13 @@ void nf_ct_deliver_cached_events(struct
|
||||
item.portid = 0;
|
||||
item.report = 0;
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ events | missed,
|
||||
+ &item);
|
||||
+#else
|
||||
ret = notify->fcn(events | missed, &item);
|
||||
+#endif
|
||||
|
||||
if (likely(ret == 0 && !missed))
|
||||
goto out_unlock;
|
||||
@ -0,0 +1,228 @@
|
||||
--- a/include/linux/if_bridge.h
|
||||
+++ b/include/linux/if_bridge.h
|
||||
@@ -52,6 +52,9 @@ struct br_ip_list {
|
||||
|
||||
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
|
||||
|
||||
+extern void br_dev_update_stats(struct net_device *dev,
|
||||
+ struct rtnl_link_stats64 *nlstats);
|
||||
+
|
||||
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
|
||||
int br_multicast_list_adjacent(struct net_device *dev,
|
||||
struct list_head *br_ip_list);
|
||||
--- a/include/linux/skbuff.h
|
||||
+++ b/include/linux/skbuff.h
|
||||
@@ -838,6 +838,10 @@ struct sk_buff {
|
||||
#endif
|
||||
__u8 gro_skip:1;
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ __u8 fast_forwarded:1;
|
||||
+#endif
|
||||
+
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
__u16 tc_index; /* traffic control index */
|
||||
#endif
|
||||
--- a/include/linux/timer.h
|
||||
+++ b/include/linux/timer.h
|
||||
@@ -18,6 +18,10 @@ struct timer_list {
|
||||
void (*function)(struct timer_list *);
|
||||
u32 flags;
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ unsigned long cust_data;
|
||||
+#endif
|
||||
+
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
struct lockdep_map lockdep_map;
|
||||
#endif
|
||||
--- a/net/bridge/br_if.c
|
||||
+++ b/net/bridge/br_if.c
|
||||
@@ -746,6 +746,28 @@ void br_port_flags_change(struct net_bri
|
||||
br_recalculate_neigh_suppress_enabled(br);
|
||||
}
|
||||
|
||||
+void br_dev_update_stats(struct net_device *dev,
|
||||
+ struct rtnl_link_stats64 *nlstats)
|
||||
+{
|
||||
+ struct net_bridge *br;
|
||||
+ struct pcpu_sw_netstats *stats;
|
||||
+
|
||||
+ /* Is this a bridge? */
|
||||
+ if (!(dev->priv_flags & IFF_EBRIDGE))
|
||||
+ return;
|
||||
+
|
||||
+ br = netdev_priv(dev);
|
||||
+ stats = this_cpu_ptr(br->stats);
|
||||
+
|
||||
+ u64_stats_update_begin(&stats->syncp);
|
||||
+ stats->rx_packets += nlstats->rx_packets;
|
||||
+ stats->rx_bytes += nlstats->rx_bytes;
|
||||
+ stats->tx_packets += nlstats->tx_packets;
|
||||
+ stats->tx_bytes += nlstats->tx_bytes;
|
||||
+ u64_stats_update_end(&stats->syncp);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(br_dev_update_stats);
|
||||
+
|
||||
bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag)
|
||||
{
|
||||
struct net_bridge_port *p;
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -3198,9 +3198,17 @@ static int xmit_one(struct sk_buff *skb,
|
||||
if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ /* If this skb has been fast forwarded then we don't want it to
|
||||
+ * go to any taps (by definition we're trying to bypass them).
|
||||
+ */
|
||||
+ if (!skb->fast_forwarded) {
|
||||
+#endif
|
||||
if (dev_nit_active(dev))
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
-
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ }
|
||||
+#endif
|
||||
#ifdef CONFIG_ETHERNET_PACKET_MANGLE
|
||||
if (!dev->eth_mangle_tx ||
|
||||
(skb = dev->eth_mangle_tx(dev, skb)) != NULL)
|
||||
@@ -4694,6 +4702,11 @@ void netdev_rx_handler_unregister(struct
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+int (*athrs_fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
|
||||
+EXPORT_SYMBOL_GPL(athrs_fast_nat_recv);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Limit the use of PFMEMALLOC reserves to those protocols that implement
|
||||
* the special handling of PFMEMALLOC skbs.
|
||||
@@ -4744,6 +4757,10 @@ static int __netif_receive_skb_core(stru
|
||||
int ret = NET_RX_DROP;
|
||||
__be16 type;
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ int (*fast_recv)(struct sk_buff *skb);
|
||||
+#endif
|
||||
+
|
||||
net_timestamp_check(!netdev_tstamp_prequeue, skb);
|
||||
|
||||
trace_netif_receive_skb(skb);
|
||||
@@ -4783,6 +4800,16 @@ another_round:
|
||||
goto out;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+ fast_recv = rcu_dereference(athrs_fast_nat_recv);
|
||||
+ if (fast_recv) {
|
||||
+ if (fast_recv(skb)) {
|
||||
+ ret = NET_RX_SUCCESS;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (skb_skip_tc_classify(skb))
|
||||
goto skip_classify;
|
||||
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -473,3 +473,6 @@ config HAVE_CBPF_JIT
|
||||
# Extended BPF JIT (eBPF)
|
||||
config HAVE_EBPF_JIT
|
||||
bool
|
||||
+
|
||||
+config SHORTCUT_FE
|
||||
+ bool "Enables kernel network stack path for Shortcut Forwarding Engine
|
||||
--- a/net/netfilter/nf_conntrack_proto_tcp.c
|
||||
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
|
||||
@@ -34,11 +34,19 @@
|
||||
/* Do not check the TCP window for incoming packets */
|
||||
static int nf_ct_tcp_no_window_check __read_mostly = 1;
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check);
|
||||
+#endif
|
||||
+
|
||||
/* "Be conservative in what you do,
|
||||
be liberal in what you accept from others."
|
||||
If it's non-zero, we mark only out of window RST segments as INVALID. */
|
||||
static int nf_ct_tcp_be_liberal __read_mostly = 0;
|
||||
|
||||
+#ifdef CONFIG_SHORTCUT_FE
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_be_liberal);
|
||||
+#endif
|
||||
+
|
||||
/* If it is set to zero, we disable picking up already established
|
||||
connections. */
|
||||
static int nf_ct_tcp_loose __read_mostly = 1;
|
||||
--- a/net/netfilter/nf_conntrack_ecache.c
|
||||
+++ b/net/netfilter/nf_conntrack_ecache.c
|
||||
@@ -153,13 +153,17 @@ int nf_conntrack_eventmask_report(unsign
|
||||
{
|
||||
int ret = 0;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
if (!notify)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (!e)
|
||||
@@ -177,7 +181,12 @@ int nf_conntrack_eventmask_report(unsign
|
||||
if (!((eventmask | missed) & e->ctmask))
|
||||
goto out_unlock;
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ eventmask | missed, &item);
|
||||
+#else
|
||||
ret = notify->fcn(eventmask | missed, &item);
|
||||
+#endif
|
||||
if (unlikely(ret < 0 || missed)) {
|
||||
spin_lock_bh(&ct->lock);
|
||||
if (ret < 0) {
|
||||
@@ -252,15 +261,19 @@ void nf_ct_deliver_cached_events(struct
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
unsigned long events, missed;
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
struct nf_ct_event item;
|
||||
int ret;
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
if (notify == NULL)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
@@ -283,7 +296,13 @@ void nf_ct_deliver_cached_events(struct
|
||||
item.portid = 0;
|
||||
item.report = 0;
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ events | missed,
|
||||
+ &item);
|
||||
+#else
|
||||
ret = notify->fcn(events | missed, &item);
|
||||
+#endif
|
||||
|
||||
if (likely(ret == 0 && !missed))
|
||||
goto out_unlock;
|
||||
Loading…
Reference in New Issue
Block a user