mirror of
https://github.com/Ysurac/openmptcprouter-feeds.git
synced 2025-03-09 15:40:03 +00:00
Merge branch 'develop' into ipq60xx
This commit is contained in:
commit
c9fa38bd28
44 changed files with 25642 additions and 173 deletions
10
fast-classifier/Makefile
Normal file
10
fast-classifier/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 ?= .
|
1892
fast-classifier/fast-classifier.c
Normal file
1892
fast-classifier/fast-classifier.c
Normal file
File diff suppressed because it is too large
Load diff
57
fast-classifier/fast-classifier.h
Normal file
57
fast-classifier/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
fast-classifier/nl_classifier_test.c
Normal file
281
fast-classifier/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
fast-classifier/userspace_example.c
Normal file
232
fast-classifier/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;
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=https-dns-proxy
|
||||
PKG_VERSION:=2021-06-03
|
||||
PKG_RELEASE:=1
|
||||
PKG_VERSION:=2021-11-22
|
||||
PKG_RELEASE:=3
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy
|
||||
PKG_SOURCE_DATE:=2021-06-03
|
||||
PKG_SOURCE_VERSION:=5651b984f770a8bcecb14aeffc224703f8f82586
|
||||
PKG_MIRROR_HASH:=b65161936269aa3117debad0fcfce157024726b78d7e7da77c226f7aa8da5b4d
|
||||
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net>
|
||||
PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy/
|
||||
PKG_SOURCE_DATE:=2021-11-22
|
||||
PKG_SOURCE_VERSION:=9336fd6272d67e8bb6e304fa54f3139a3d26f08f
|
||||
PKG_MIRROR_HASH:=60b1ddabaf1db3a9ee19f3294a1df714364d580cef5e3c2161363c371a557456
|
||||
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
|
@ -38,7 +38,10 @@ define Package/https-dns-proxy/conffiles
|
|||
endef
|
||||
|
||||
define Package/https-dns-proxy/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d ${1}/etc/config
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) ${1}/etc/config
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/https_dns_proxy $(1)/usr/sbin/https-dns-proxy
|
||||
$(INSTALL_BIN) ./files/https-dns-proxy.init $(1)/etc/init.d/https-dns-proxy
|
||||
$(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/https-dns-proxy
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
config main 'config'
|
||||
option update_dnsmasq_config '*'
|
||||
|
||||
config https-dns-proxy
|
||||
option bootstrap_dns '8.8.8.8,8.8.4.4'
|
||||
option resolver_url 'https://dns.google/dns-query'
|
||||
option listen_addr '127.0.0.1'
|
||||
option listen_port '5053'
|
||||
option user 'nobody'
|
||||
option group 'nogroup'
|
||||
option force_dns '1'
|
||||
list force_dns_port '53'
|
||||
list force_dns_port '853'
|
||||
# ports listed below are used by some
|
||||
# of the dnscrypt-proxy v1 resolvers
|
||||
# list force_dns_port '553'
|
||||
# list force_dns_port '1443'
|
||||
# list force_dns_port '4343'
|
||||
# list force_dns_port '4434'
|
||||
# list force_dns_port '5443'
|
||||
# list force_dns_port '8443'
|
||||
|
||||
config https-dns-proxy
|
||||
option bootstrap_dns '1.1.1.1,1.0.0.1'
|
||||
|
@ -16,3 +19,11 @@ config https-dns-proxy
|
|||
option listen_port '5054'
|
||||
option user 'nobody'
|
||||
option group 'nogroup'
|
||||
|
||||
config https-dns-proxy
|
||||
option bootstrap_dns '8.8.8.8,8.8.4.4'
|
||||
option resolver_url 'https://dns.google/dns-query'
|
||||
option listen_addr '127.0.0.1'
|
||||
option listen_port '5053'
|
||||
option user 'nobody'
|
||||
option group 'nogroup'
|
||||
|
|
6
https-dns-proxy/files/https-dns-proxy.hotplug.iface
Normal file
6
https-dns-proxy/files/https-dns-proxy.hotplug.iface
Normal file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ "$ACTION" = 'ifup' ] && [ "$INTERFACE" = 'wan' ] && /etc/init.d/https-dns-proxy enabled; then
|
||||
logger -t "https-dns-proxy" "Restarting https-dns-proxy due to $ACTION of $INTERFACE"
|
||||
/etc/init.d/https-dns-proxy restart
|
||||
fi
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
# Copyright 2019-2020 Stan Grishin (stangri@melmac.net)
|
||||
# shellcheck disable=SC2039,SC3043,SC3060
|
||||
# Copyright 2019-2022 Stan Grishin (stangri@melmac.ca)
|
||||
# shellcheck disable=SC1091,SC2039,SC3043,SC3060
|
||||
PKG_VERSION='dev-test'
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
|
@ -15,9 +15,52 @@ else
|
|||
EXTRA_COMMANDS='version'
|
||||
fi
|
||||
|
||||
readonly packageName='https-dns-proxy'
|
||||
readonly serviceName="$packageName $PKG_VERSION"
|
||||
readonly sharedMemoryOutput="/dev/shm/$packageName-output"
|
||||
readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m'
|
||||
readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m'
|
||||
readonly PROG=/usr/sbin/https-dns-proxy
|
||||
readonly DEFAULT_BOOTSTRAP='1.1.1.1,1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001,8.8.8.8,8.8.4.4,2001:4860:4860::8888,2001:4860:4860::8844'
|
||||
readonly canaryDomains='use-application-dns.net'
|
||||
dnsmasqConfig=''; forceDNS=''; forceDNSPorts='';
|
||||
|
||||
str_contains() { [ -n "$1" ] &&[ -n "$2" ] && [ "${1//$2}" != "$1" ]; }
|
||||
is_mac_address() { expr "$1" : '[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]$' >/dev/null; }
|
||||
is_ipv4() { expr "$1" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; }
|
||||
is_ipv6() { ! is_mac_address "$1" && str_contains "$1" ":"; }
|
||||
output() {
|
||||
local msg memmsg logmsg
|
||||
[ -t 1 ] && printf "%b" "$@"
|
||||
msg="${1//$serviceName /service }";
|
||||
if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then
|
||||
[ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")"
|
||||
logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')"
|
||||
logger -t "$packageName" "$(printf "%b" "$logmsg")"
|
||||
rm -f "$sharedMemoryOutput"
|
||||
else
|
||||
printf "%b" "$msg" >> "$sharedMemoryOutput"
|
||||
fi
|
||||
}
|
||||
output_ok() { output "$_OK_"; }
|
||||
output_okn() { output "${_OK_}\\n"; }
|
||||
output_fail() { output "$_FAIL_"; }
|
||||
output_failn() { output "${_FAIL_}\\n"; }
|
||||
uci_add_list_if_new() {
|
||||
local key="$1" value="$2" i
|
||||
if [ -z "$value" ]; then
|
||||
value="${key#*=}"
|
||||
key="${key%=*}"
|
||||
fi
|
||||
[ -n "$key" ] && [ -n "$value" ] || return 1
|
||||
for i in $(uci -q get "$key"); do
|
||||
[ "$i" = "$value" ] && return 0
|
||||
done
|
||||
uci -q add_list "${key}=${value}"
|
||||
}
|
||||
|
||||
dnsmasq_restart() { [ -x /etc/init.d/dnsmasq ] || return 0; /etc/init.d/dnsmasq restart >/dev/null 2>&1; }
|
||||
|
||||
version() { echo "$PKG_VERSION"; }
|
||||
|
||||
xappend() { param="$param $1"; }
|
||||
|
@ -26,11 +69,10 @@ append_bool() {
|
|||
local section="$1"
|
||||
local option="$2"
|
||||
local value="$3"
|
||||
local default="$4"
|
||||
local default="${4:-0}"
|
||||
local _loctmp
|
||||
[ -z "$default" ] && default="0"
|
||||
config_get_bool _loctmp "$section" "$option" "$default"
|
||||
[ "$_loctmp" != "0" ] && xappend "$value"
|
||||
[ "$_loctmp" -ne 0 ] && xappend "$value"
|
||||
}
|
||||
|
||||
append_parm() {
|
||||
|
@ -40,137 +82,191 @@ append_parm() {
|
|||
local default="$4"
|
||||
local _loctmp
|
||||
config_get _loctmp "$section" "$option" "$default"
|
||||
[ -n "$_loctmp" ] && xappend "$switch $_loctmp"
|
||||
}
|
||||
|
||||
append_counter() {
|
||||
local section="$1"
|
||||
local option="$2"
|
||||
local switch="$3"
|
||||
local default="${4:-0}"
|
||||
local _loctmp i
|
||||
config_get _loctmp "$section" "$option" "$default"
|
||||
# shellcheck disable=SC2086,SC2154
|
||||
for i in $(seq 1 $_loctmp); do
|
||||
xappend '-v'
|
||||
done
|
||||
}
|
||||
|
||||
append_bootstrap() {
|
||||
local section="$1"
|
||||
local option="$2"
|
||||
local switch="$3"
|
||||
local default="$4"
|
||||
local _old_ifs="$IFS"
|
||||
local _loctmp _newtmp i
|
||||
config_get _loctmp "$section" "$option" "$default"
|
||||
[ -z "$_loctmp" ] && return 0
|
||||
xappend "$switch $_loctmp"
|
||||
IFS=" ,"
|
||||
for i in $_loctmp; do
|
||||
if { [ "$ipv6_resolvers_only" -eq 0 ] && is_ipv4 "$i"; } || \
|
||||
{ [ "$ipv6_resolvers_only" -ne 0 ] && is_ipv6 "$i"; }; then
|
||||
[ -z "$_newtmp" ] && _newtmp="$i" || _newtmp="${_newtmp},${i}"
|
||||
fi
|
||||
done
|
||||
IFS="$_old_ifs"
|
||||
[ -n "$_newtmp" ] && xappend "$switch $_newtmp"
|
||||
[ "$ipv6_resolvers_only" -eq 0 ] && xappend '-4'
|
||||
}
|
||||
|
||||
start_instance() {
|
||||
local cfg="$1" param listen_addr listen_port i
|
||||
local cfg="$1" param listen_addr listen_port ipv6_resolvers_only p
|
||||
config_get_bool ipv6_resolvers_only "$cfg" 'use_ipv6_resolvers_only' '0'
|
||||
append_parm "$cfg" 'resolver_url' '-r'
|
||||
append_parm "$cfg" 'polling_interval' '-i'
|
||||
append_parm "$cfg" 'listen_addr' '-a' '127.0.0.1'
|
||||
append_parm "$cfg" 'listen_port' '-p' "$p"
|
||||
append_parm "$cfg" 'listen_port' '-p' "$port"
|
||||
append_parm "$cfg" 'dscp_codepoint' '-c'
|
||||
append_parm "$cfg" 'bootstrap_dns' '-b'
|
||||
append_bootstrap "$cfg" 'bootstrap_dns' '-b' "$DEFAULT_BOOTSTRAP"
|
||||
append_parm "$cfg" 'user' '-u' 'nobody'
|
||||
append_parm "$cfg" 'group' '-g' 'nogroup'
|
||||
append_parm "$cfg" 'proxy_server' '-t'
|
||||
append_parm "$cfg" 'logfile' '-l'
|
||||
append_bool "$cfg" 'use_http1' '-x'
|
||||
config_get_bool ipv6_resolvers_only "$cfg" 'use_ipv6_resolvers_only' '0'
|
||||
config_get verbosity "$cfg" 'verbosity' '0'
|
||||
|
||||
# shellcheck disable=SC2086,SC2154
|
||||
for i in $(seq 1 $verbosity); do
|
||||
xappend '-v'
|
||||
done
|
||||
# shellcheck disable=SC2154
|
||||
if [ "$ipv6_resolvers_only" = 0 ]; then
|
||||
xappend '-4'
|
||||
fi
|
||||
append_counter "$cfg" 'verbosity' '-v' '0'
|
||||
|
||||
procd_open_instance
|
||||
# shellcheck disable=SC2086
|
||||
procd_set_param command ${PROG} ${param}
|
||||
procd_set_param command $PROG $param
|
||||
procd_set_param stderr 1
|
||||
procd_set_param stdout 1
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
|
||||
config_get listen_addr "$cfg" 'listen_addr' '127.0.0.1'
|
||||
config_get listen_port "$cfg" 'listen_port' "$p"
|
||||
|
||||
if [ "$dnsmasqConfig" = "*" ]; then
|
||||
config_load 'dhcp'
|
||||
config_foreach dnsmasq_add_doh_server 'dnsmasq' "${listen_addr}" "${listen_port}"
|
||||
elif [ -n "$dnsmasqConfig" ]; then
|
||||
for i in $dnsmasqConfig; do
|
||||
dnsmasq_add_doh_server "@dnsmasq[${i}]" "${listen_addr}" "${listen_port}"
|
||||
done
|
||||
fi
|
||||
p="$((p+1))"
|
||||
}
|
||||
|
||||
is_force_dns_active() { iptables-save | grep -q -w -- '--dport 53'; }
|
||||
|
||||
start_service() {
|
||||
local p=5053 c
|
||||
config_load 'https-dns-proxy'
|
||||
config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*'
|
||||
config_get_bool forceDNS 'config' 'force_dns' '1'
|
||||
config_get forceDNSPorts 'config' 'force_dns_port' '53 853'
|
||||
dhcp_backup 'create'
|
||||
config_load 'https-dns-proxy'
|
||||
config_foreach start_instance 'https-dns-proxy'
|
||||
if [ "$forceDNS" -ne 0 ]; then
|
||||
procd_open_instance 'main'
|
||||
procd_set_param command /bin/true
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_open_data
|
||||
json_add_array firewall
|
||||
for c in $forceDNSPorts; do
|
||||
if netstat -tuln | grep 'LISTEN' | grep ":${c}" >/dev/null 2>&1 || [ "$c" = "53" ]; then
|
||||
json_add_object ""
|
||||
for p in $forceDNSPorts; do
|
||||
if netstat -tuln | grep 'LISTEN' | grep ":${p}" >/dev/null 2>&1 || [ "$p" = '53' ]; then
|
||||
json_add_object ''
|
||||
json_add_string type redirect
|
||||
json_add_string target DNAT
|
||||
json_add_string src lan
|
||||
json_add_string proto "tcp udp"
|
||||
json_add_string src_dport "$c"
|
||||
json_add_string dest_port "$c"
|
||||
json_add_string proto 'tcp udp'
|
||||
json_add_string src_dport "$p"
|
||||
json_add_string dest_port "$p"
|
||||
json_add_boolean reflection 0
|
||||
json_close_object
|
||||
else
|
||||
json_add_object ""
|
||||
json_add_object ''
|
||||
json_add_string type rule
|
||||
json_add_string src lan
|
||||
json_add_string dest "*"
|
||||
json_add_string proto "tcp udp"
|
||||
json_add_string dest_port "$c"
|
||||
json_add_string dest '*'
|
||||
json_add_string proto 'tcp udp'
|
||||
json_add_string dest_port "$p"
|
||||
json_add_string target REJECT
|
||||
json_close_object
|
||||
fi
|
||||
done
|
||||
json_close_array
|
||||
procd_close_data
|
||||
procd_close_instance
|
||||
fi
|
||||
if [ -n "$(uci -q changes dhcp)" ]; then
|
||||
uci -q commit dhcp
|
||||
[ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq restart >/dev/null 2>&1
|
||||
procd_close_instance
|
||||
|
||||
if [ "$?" ]; then
|
||||
config_get listen_addr "$cfg" 'listen_addr' '127.0.0.1'
|
||||
config_get listen_port "$cfg" 'listen_port' "$port"
|
||||
if [ "$dnsmasqConfig" = '*' ]; then
|
||||
config_load 'dhcp'
|
||||
config_foreach dnsmasq_doh_server 'dnsmasq' 'add' "${listen_addr}" "${listen_port}"
|
||||
elif [ -n "$dnsmasqConfig" ]; then
|
||||
for i in $dnsmasqConfig; do
|
||||
if [ -n "$(uci -q get "dhcp.@dnsmasq[$i]")" ]; then
|
||||
dnsmasq_doh_server "@dnsmasq[$i]" 'add' "${listen_addr}" "${listen_port}"
|
||||
elif [ -n "$(uci -q get "dhcp.${i}")" ]; then
|
||||
dnsmasq_doh_server "${i}" 'add' "${listen_addr}" "${listen_port}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
output_ok
|
||||
port="$((port+1))"
|
||||
forceDNS=0
|
||||
else
|
||||
output_fail
|
||||
fi
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local port=5053
|
||||
output "Starting $serviceName "
|
||||
config_load "$packageName"
|
||||
config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*'
|
||||
config_get_bool forceDNS 'config' 'force_dns' '1'
|
||||
config_get forceDNSPorts 'config' 'force_dns_port' '53 853'
|
||||
dhcp_backup 'create'
|
||||
config_load "$packageName"
|
||||
config_foreach start_instance "$packageName"
|
||||
if [ -n "$(uci -q changes dhcp)" ]; then
|
||||
uci -q commit dhcp
|
||||
dnsmasq_restart
|
||||
fi
|
||||
output "\\n"
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
config_load 'https-dns-proxy'
|
||||
local s=0
|
||||
output "Stopping $serviceName "
|
||||
config_load "$packageName"
|
||||
config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*'
|
||||
dhcp_backup 'restore'
|
||||
if [ -n "$(uci -q changes dhcp)" ]; then
|
||||
uci -q commit dhcp
|
||||
[ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq restart >/dev/null 2>&1
|
||||
dnsmasq_restart || s=1
|
||||
fi
|
||||
# shellcheck disable=SC2015
|
||||
[ "$s" -eq 0 ] && output_okn || output_failn
|
||||
}
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
service_triggers() {
|
||||
procd_add_config_trigger "config.change" "https-dns-proxy" /etc/init.d/https-dns-proxy reload
|
||||
local iface
|
||||
. /lib/functions/network.sh
|
||||
network_flush_cache
|
||||
network_find_wan iface
|
||||
iface="${iface:-wan}"
|
||||
if [ -n "$iface" ]; then
|
||||
procd_add_interface_trigger "interface.*" "$iface" "/etc/init.d/${packageName}" restart
|
||||
fi
|
||||
procd_add_config_trigger "config.change" "$packageName" "/etc/init.d/${packageName}" restart
|
||||
}
|
||||
|
||||
service_started() { procd_set_config_changed firewall; }
|
||||
service_stopped() { procd_set_config_changed firewall; }
|
||||
|
||||
dnsmasq_add_doh_server() {
|
||||
local cfg="$1" address="$2" port="$3"
|
||||
case $address in
|
||||
0.0.0.0|::ffff:0.0.0.0) address='127.0.0.1';;
|
||||
::) address='::1';;
|
||||
dnsmasq_doh_server() {
|
||||
local cfg="$1" param="$2" address="${3:-127.0.0.1}" port="$4" i
|
||||
case "$param" in
|
||||
add)
|
||||
if [ "$forceDNS" -ne 0 ]; then
|
||||
for i in $canaryDomains; do
|
||||
uci_add_list_if_new "dhcp.${cfg}.server" "/${i}/"
|
||||
done
|
||||
fi
|
||||
case $address in
|
||||
0.0.0.0|::ffff:0.0.0.0) address='127.0.0.1';;
|
||||
::) address='::1';;
|
||||
esac
|
||||
uci_add_list_if_new "dhcp.${cfg}.server" "${address}#${port}"
|
||||
;;
|
||||
remove)
|
||||
eval "$(ubus call service list "{ 'verbose': true, 'name': '$packageName' }" | jsonfilter -F '# ' -e 'TUPLES=@[*].instances[*].command[4,6]')"
|
||||
for i in $TUPLES; do
|
||||
uci -q del_list "dhcp.${cfg}.server=${i}"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
uci -q del_list "dhcp.${cfg}.server=${address}#${port}"
|
||||
uci -q add_list "dhcp.${cfg}.server=${address}#${port}"
|
||||
}
|
||||
|
||||
dnsmasq_create_server_backup() {
|
||||
local cfg="$1"
|
||||
local i
|
||||
local cfg="$1" i
|
||||
uci -q get "dhcp.${cfg}" >/dev/null || return 1
|
||||
if ! uci -q get "dhcp.${cfg}.doh_backup_noresolv" >/dev/null; then
|
||||
if [ -z "$(uci -q get "dhcp.${cfg}.noresolv")" ]; then
|
||||
|
@ -196,8 +292,7 @@ dnsmasq_create_server_backup() {
|
|||
}
|
||||
|
||||
dnsmasq_restore_server_backup() {
|
||||
local cfg="$1"
|
||||
local i
|
||||
local cfg="$1" i
|
||||
uci -q get "dhcp.${cfg}" >/dev/null || return 0
|
||||
if uci -q get "dhcp.${cfg}.doh_backup_noresolv" >/dev/null; then
|
||||
if [ "$(uci -q get "dhcp.${cfg}.doh_backup_noresolv")" = "0" ]; then
|
||||
|
@ -208,11 +303,11 @@ dnsmasq_restore_server_backup() {
|
|||
uci -q del "dhcp.${cfg}.doh_backup_noresolv"
|
||||
fi
|
||||
if uci -q get "dhcp.${cfg}.doh_backup_server" >/dev/null; then
|
||||
uci -q del "dhcp.${cfg}.server"
|
||||
dnsmasq_doh_server "$cfg" 'remove'
|
||||
for i in $(uci -q get "dhcp.${cfg}.doh_backup_server"); do
|
||||
uci -q add_list "dhcp.${cfg}.server=$i"
|
||||
uci_add_list_if_new "dhcp.${cfg}.server" "$i"
|
||||
done
|
||||
uci -q del "dhcp.${cfg}.doh_backup_server"
|
||||
uci -q del "dhcp.${cfg}.doh_backup_server"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -225,8 +320,11 @@ dhcp_backup() {
|
|||
config_foreach dnsmasq_create_server_backup 'dnsmasq'
|
||||
elif [ -n "$dnsmasqConfig" ]; then
|
||||
for i in $dnsmasqConfig; do
|
||||
dnsmasq_create_server_backup "@dnsmasq[${i}]" || \
|
||||
if [ -n "$(uci -q get "dhcp.@dnsmasq[$i]")" ]; then
|
||||
dnsmasq_create_server_backup "@dnsmasq[$i]"
|
||||
elif [ -n "$(uci -q get "dhcp.${i}")" ]; then
|
||||
dnsmasq_create_server_backup "$i"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
;;
|
||||
|
|
15
https-dns-proxy/patches/010-fix-cmakelists.patch
Normal file
15
https-dns-proxy/patches/010-fix-cmakelists.patch
Normal file
|
@ -0,0 +1,15 @@
|
|||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -21,9 +21,9 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "Setting build type to '${CMAKE_BUILD_TYPE}' as none was specified.")
|
||||
endif()
|
||||
|
||||
-set(CMAKE_C_FLAGS "-Wall -Wextra --pedantic -Wno-strict-aliasing -Wno-variadic-macros")
|
||||
-set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
|
||||
-set(CMAKE_C_FLAGS_RELEASE "-O2")
|
||||
+#set(CMAKE_C_FLAGS "-Wall -Wextra --pedantic -Wno-strict-aliasing -Wno-variadic-macros")
|
||||
+#set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
|
||||
+#set(CMAKE_C_FLAGS_RELEASE "-O2")
|
||||
|
||||
if ((CMAKE_C_COMPILER_ID MATCHES GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 9) OR
|
||||
(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10))
|
8
netmaker-openwrt/LICENSE
Normal file
8
netmaker-openwrt/LICENSE
Normal file
|
@ -0,0 +1,8 @@
|
|||
MIT License
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
111
netmaker-openwrt/README.md
Normal file
111
netmaker-openwrt/README.md
Normal file
|
@ -0,0 +1,111 @@
|
|||
# Netmaker-OpenWRT
|
||||
|
||||
[Netmaker](https://github.com/gravitl/netmaker) is a platform for creating and managing fast, secure, and dynamic virtual overlay networks using WireGuard. This project offers OpenWRT packages for Netmaker.
|
||||
|
||||
## Installing package
|
||||
|
||||
Download the prebuild package and copy it onto your OpenWRT installation, preferably into the `/tmp` folder.
|
||||
|
||||
Then install the ipk package file:
|
||||
|
||||
```bash
|
||||
opkg install netmaker_*.ipk
|
||||
```
|
||||
|
||||
Now start `netclient` of Netmaker:
|
||||
|
||||
```bash
|
||||
/etc/init.d/netclient start
|
||||
```
|
||||
|
||||
## Compiling from Sources
|
||||
|
||||
To include Netmaker into your OpenWRT image or to create an `.ipk` package (equivalent to Debians .deb files), you have to build an OpenWRT image.
|
||||
|
||||
Now prepare OpenWRT:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/openwrt/openwrt
|
||||
cd openwrt
|
||||
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
```
|
||||
|
||||
To build Netmaker for OpenWRT, you need to have Golang with OpenWRT build envirment. Then, you can insert the Netmaker package using a package feed or add the package manually.
|
||||
|
||||
### Add package by feed
|
||||
|
||||
A feed is the standard way packages are made available to the OpenWRT build system.
|
||||
|
||||
Put this line in your feeds list file (e.g. feeds.conf.default)
|
||||
|
||||
```bash
|
||||
src-git netmaker http://github.com/sbilly/netmaker-openwrt.git
|
||||
```
|
||||
|
||||
Update and install the new feed
|
||||
|
||||
```bash
|
||||
./scripts/feeds update netmaker
|
||||
./scripts/feeds install netmaker
|
||||
```
|
||||
|
||||
Now continue with the building packages section.
|
||||
|
||||
## Building Packages
|
||||
|
||||
Configure packages:
|
||||
|
||||
```bash
|
||||
make menuconfig
|
||||
```
|
||||
|
||||
Now select the appropiate "Target System" and "Target Profile" depending on what target chipset/router you want to build for. Also mark the Netmaker package under `Network ---> VPN ---> <*> netmaker`.
|
||||
|
||||
Now compile/build everything:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
The images and all *.ipk packages are now inside the bin/ folder, including the netmaker package. You can install the Netmaker .ipk on the target device using opkg install <ipkg-file>.
|
||||
|
||||
For details please check the OpenWRT documentation.
|
||||
|
||||
## Build bulk packages
|
||||
|
||||
For a release, it is useful the build packages at a bulk for multiple targets:
|
||||
|
||||
```shell
|
||||
#!/bin/sh
|
||||
|
||||
# dump-target-info.pl is used to get all targets configurations:
|
||||
# https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=scripts/dump-target-info.pl
|
||||
|
||||
./scripts/dump-target-info.pl architectures | while read pkgarch target1 rest; do
|
||||
echo "CONFIG_TARGET_${target1%/*}=y" > .config
|
||||
echo "CONFIG_TARGET_${target1%/*}_${target1#*/}=y" >> .config
|
||||
echo "CONFIG_PACKAGE_example1=y" >> .config
|
||||
|
||||
# Debug output
|
||||
echo "pkgarch: $pkgarch, target1: $target1"
|
||||
|
||||
make defconfig
|
||||
make -j4 tools/install
|
||||
make -j4 toolchain/install
|
||||
|
||||
# Build package
|
||||
make package/netmaker/{clean,compile}
|
||||
|
||||
# Free space (optional)
|
||||
rm -rf build_dir/target-*
|
||||
rm -rf build_dir/toolchain-*
|
||||
done
|
||||
```
|
||||
|
||||
## Thanks
|
||||
|
||||
- [netmaker](https://github.com/gravitl/netmaker)
|
||||
- [zerotier-openwrt](https://github.com/mwarning/zerotier-openwrt)
|
||||
- [openwrt-golang-package-test-feed](https://github.com/jefferyto/openwrt-golang-package-test-feed)
|
93
netmaker-openwrt/netmaker/Makefile
Normal file
93
netmaker-openwrt/netmaker/Makefile
Normal file
|
@ -0,0 +1,93 @@
|
|||
#
|
||||
# Copyright (C) 2019 sbilly <superli_1980@hotmail.com>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=netmaker
|
||||
PKG_VERSION:=0.9.4
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/gravitl/netmaker.git
|
||||
PKG_SOURCE_VERSION:=e9bce264719f88c30e252ecc754d08f422f4c080
|
||||
PKG_SOURCE_DATE:=20220117
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=sbilly <superli_1980@hotmail.com>
|
||||
|
||||
PKG_BUILD_DEPENDS:=golang/host
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
GO_PKG:=github.com/gravitl/netmaker
|
||||
GO_PKG_INSTALL_EXTRA:=extra/file extra/dir
|
||||
GO_PKG_EXCLUDES:=excluded
|
||||
GO_PKG_LDFLAGS:=-s -w
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
|
||||
|
||||
define Package/netmaker
|
||||
$(call Package/netmaker/Default)
|
||||
$(call GoPackage/GoSubMenu)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=VPN
|
||||
endef
|
||||
|
||||
define Package/netmaker/Default
|
||||
TITLE:=Netmaker for OpenWRT
|
||||
URL:=https://github.com/gravitl/netmaker
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS)
|
||||
MAINTAINER:=sbilly <superli_1980@hotmail.com>
|
||||
endef
|
||||
|
||||
define Package/netmaker/Default/description
|
||||
Netmaker is a platform for creating and managing fast, secure, and
|
||||
dynamic virtual overlay networks using WireGuard. This project offers
|
||||
OpenWRT packages for Netmaker.
|
||||
endef
|
||||
|
||||
define Package/netmaker/description
|
||||
$(call Package/netmaker/Default/description)
|
||||
|
||||
This package contains the binaries.
|
||||
endef
|
||||
|
||||
define Package/netmaker-dev
|
||||
TITLE+= (source files)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=VPN
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/netmaker-dev/description
|
||||
$(call Package/netmaker/Default/description)
|
||||
|
||||
This package provides the source files.
|
||||
endef
|
||||
|
||||
define Package/netmaker/install
|
||||
$(INSTALL_DIR) $(1)/etc/netclient/
|
||||
$(INSTALL_DIR) $(1)/etc/netclient/config
|
||||
$(INSTALL_DIR) $(1)/etc/systemd/
|
||||
$(INSTALL_DIR) $(1)/etc/systemd/system
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/netmaker $(1)/usr/bin/
|
||||
$(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/netclient $(1)/usr/bin/
|
||||
$(CP) ./root/* $(1)/
|
||||
$(LN) netclient $(1)/etc/netclient/netclient
|
||||
endef
|
||||
|
||||
$(eval $(call GoBinPackage,netmaker))
|
||||
$(eval $(call BuildPackage,netmaker))
|
||||
|
||||
$(eval $(call GoSrcPackage,netmaker-dev))
|
||||
$(eval $(call BuildPackage,netmaker-dev))
|
42
netmaker-openwrt/netmaker/root/etc/init.d/netclient
Normal file
42
netmaker-openwrt/netmaker/root/etc/init.d/netclient
Normal file
|
@ -0,0 +1,42 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
#Created by oycol<oycol527@outlook.com>
|
||||
|
||||
EXTRA_COMMANDS="status"
|
||||
EXTRA_HELP=" status Check service is running"
|
||||
START=99
|
||||
|
||||
LOG_FILE="/tmp/netclient.logs"
|
||||
|
||||
start() {
|
||||
mkdir -p /etc/netclient/config
|
||||
mkdir -p /etc/systemd/system
|
||||
|
||||
if [ ! -f "${LOG_FILE}" ];then
|
||||
touch "${LOG_FILE}"
|
||||
fi
|
||||
local PID=$(ps|grep "netclient checkin -n all"|grep -v grep|awk '{print $1}')
|
||||
if [ "${PID}" ];then
|
||||
echo "service is running"
|
||||
return
|
||||
fi
|
||||
/bin/sh -c "while [ 1 ]; do netclient checkin -n all >> ${LOG_FILE} 2>&1;sleep 15;\
|
||||
if [ $(ls -l ${LOG_FILE}|awk '{print $5}') -gt 10240000 ];then tar zcf "${LOG_FILE}.tar" -C / "tmp/netclient.logs" && > $LOG_FILE;fi;done &"
|
||||
echo "start"
|
||||
}
|
||||
|
||||
stop() {
|
||||
local PID=$(ps|grep "netclient checkin -n all"|grep -v grep|awk '{print $1}')
|
||||
if [ "${PID}" ];then
|
||||
kill "${PID}"
|
||||
fi
|
||||
echo "stop"
|
||||
}
|
||||
|
||||
status() {
|
||||
local PID=$(ps|grep "netclient checkin -n all"|grep -v grep|awk '{print $1}')
|
||||
if [ "${PID}" ];then
|
||||
echo -e "netclient[${PID}] is running \n"
|
||||
else
|
||||
echo -e "netclient is not running \n"
|
||||
fi
|
||||
}
|
177
netmaker-openwrt/scripts/build_ipk.sh
Normal file
177
netmaker-openwrt/scripts/build_ipk.sh
Normal file
|
@ -0,0 +1,177 @@
|
|||
#!/bin/bash
|
||||
|
||||
# setting working directory
|
||||
WORK_DIR="/home/user"
|
||||
|
||||
# setting branch
|
||||
if [ "${OPENWRT_BRANCH}" = "" ]
|
||||
then
|
||||
DEFAULT_OPENWRT_BRANCH="openwrt-21.02"
|
||||
else
|
||||
DEFAULT_OPENWRT_BRANCH="${OPENWRT_BRANCH}"
|
||||
fi
|
||||
|
||||
download_openwrt() {
|
||||
cd ${WORK_DIR}
|
||||
|
||||
# pull code
|
||||
if [ ! -d "openwrt" ]; then
|
||||
git clone https://git.openwrt.org/openwrt/openwrt.git
|
||||
fi
|
||||
}
|
||||
|
||||
change_openwrt_branch() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
if [ "${1}" = "" ]
|
||||
then
|
||||
echo "Building ${DEFAULT_OPENWRT_BRANCH}"
|
||||
git checkout -B ${DEFAULT_OPENWRT_BRANCH} origin/${DEFAULT_OPENWRT_BRANCH}
|
||||
else
|
||||
echo "Building ${1}"
|
||||
git checkout -B ${1} origin/${1}
|
||||
fi
|
||||
}
|
||||
|
||||
init_openwrt_branch() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
git stash
|
||||
git pull --all
|
||||
git pull --tags
|
||||
}
|
||||
|
||||
init_openwrt_link() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
sudo chown 1000:1000 /src -R
|
||||
|
||||
mkdir -p /src/dl
|
||||
mkdir -p /src/staging_dir
|
||||
mkdir -p /src/build_dir
|
||||
mkdir -p /src/tmp
|
||||
mkdir -p /src/bin
|
||||
|
||||
ln -s /src/dl ${WORK_DIR}/openwrt/dl
|
||||
ln -s /src/staging_dir ${WORK_DIR}/openwrt/staging_dir
|
||||
ln -s /src/build_dir ${WORK_DIR}/openwrt/build_dir
|
||||
ln -s /src/tmp ${WORK_DIR}/openwrt/tmp
|
||||
}
|
||||
|
||||
update_install_openwrt_feeds() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
}
|
||||
|
||||
openwrt_init_config() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
echo "CONFIG_TARGET_x86=y" > ${WORK_DIR}/openwrt/.config
|
||||
echo "CONFIG_TARGET_x86_64=y" >> ${WORK_DIR}/openwrt/.config
|
||||
}
|
||||
|
||||
openwrt_make_build_env() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
make defconfig
|
||||
make -j4 download
|
||||
make -j4 tools/install
|
||||
make -j4 toolchain/install
|
||||
}
|
||||
|
||||
openwrt_make() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
make -j4
|
||||
}
|
||||
|
||||
openwrt_install_netmaker_feeds() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
echo "src-git netmaker http://github.com/sbilly/netmaker-openwrt.git" >> feeds.conf.default
|
||||
|
||||
./scripts/feeds update netmaker
|
||||
./scripts/feeds install netmaker
|
||||
}
|
||||
|
||||
openwrt_install_package_netmaker_config() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
echo "CONFIG_FEED_netmaker=y" >> ${WORK_DIR}/openwrt/.config
|
||||
echo "CONFIG_PACKAGE_netmaker=m" >> ${WORK_DIR}/openwrt/.config
|
||||
echo "CONFIG_PACKAGE_netmaker-dev=m" >> ${WORK_DIR}/openwrt/.config
|
||||
}
|
||||
|
||||
|
||||
openwrt_patch_golang_host() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
echo "patching ${1}"
|
||||
|
||||
if [ "${1}" = "openwrt-19.07" ]
|
||||
then
|
||||
sed -i 's/5fb43171046cf8784325e67913d55f88a683435071eef8e9da1aa8a1588fcf5d/2255eb3e4e824dd7d5fcdc2e7f84534371c186312e546fb1086a34c17752f431/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang/Makefile
|
||||
sed -i 's/1.13/1.17/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang-version.mk
|
||||
sed -i 's/15/2/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang-version.mk
|
||||
fi
|
||||
|
||||
if [ "${1}" = "openwrt-18.06" ]
|
||||
then
|
||||
sed -i 's/6faf74046b5e24c2c0b46e78571cca4d65e1b89819da1089e53ea57539c63491/2255eb3e4e824dd7d5fcdc2e7f84534371c186312e546fb1086a34c17752f431/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang/Makefile
|
||||
sed -i 's/1.10/1.17/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang-version.mk
|
||||
sed -i 's/8/2/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang-version.mk
|
||||
fi
|
||||
}
|
||||
|
||||
openwrt_make_netmaker_package() {
|
||||
cd ${WORK_DIR}/openwrt
|
||||
|
||||
make defconfig
|
||||
make toolchain/gcc/final/compile
|
||||
make package/netmaker/clean
|
||||
find ./ -type d | xargs -n1 sudo chmod 755 -R
|
||||
make package/netmaker/compile V=s
|
||||
}
|
||||
|
||||
|
||||
openwrt_copy_pacage() {
|
||||
echo ${1}
|
||||
echo > /tmp/copy.sh
|
||||
|
||||
cd ${WORK_DIR}/openwrt/bin/packages/x86_64/netmaker/
|
||||
|
||||
for ipk in ./*.ipk
|
||||
do
|
||||
if [ -f "$ipk" ]
|
||||
then
|
||||
echo ${ipk} | gawk -F".ipk" -v BRANCH=${1} '{ print "cp -rfv "$0" /src/bin/"$1"-"BRANCH".ipk" }' >> /tmp/copy.sh
|
||||
fi
|
||||
done
|
||||
|
||||
/bin/bash /tmp/copy.sh
|
||||
}
|
||||
|
||||
download_openwrt
|
||||
|
||||
change_openwrt_branch ${DEFAULT_OPENWRT_BRANCH}
|
||||
|
||||
init_openwrt_branch
|
||||
|
||||
init_openwrt_link
|
||||
|
||||
openwrt_install_netmaker_feeds
|
||||
|
||||
update_install_openwrt_feeds
|
||||
|
||||
openwrt_init_config
|
||||
|
||||
openwrt_install_package_netmaker_config
|
||||
|
||||
openwrt_patch_golang_host ${DEFAULT_OPENWRT_BRANCH}
|
||||
|
||||
openwrt_make_netmaker_package
|
||||
|
||||
openwrt_copy_pacage ${DEFAULT_OPENWRT_BRANCH}
|
||||
|
||||
ls -alF ${WORK_DIR}/openwrt/bin/ /src/bin
|
5
shortcut-fe/.gitignore
vendored
Normal file
5
shortcut-fe/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Ouptut files
|
||||
|
||||
*.o
|
||||
*.s
|
||||
|
14
shortcut-fe/Kconfig
Normal file
14
shortcut-fe/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
shortcut-fe/Makefile
Normal file
23
shortcut-fe/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
|
||||
|
122
shortcut-fe/README
Normal file
122
shortcut-fe/README
Normal file
|
@ -0,0 +1,122 @@
|
|||
Shortcut Forwarding Engine
|
||||
--------------------------
|
||||
|
||||
Welcome to "Shortcut" :-)
|
||||
|
||||
Here's a quick FAQ:
|
||||
|
||||
|
||||
Q) What is Shortcut?
|
||||
|
||||
A) Shortcut is an in-Linux-kernel IP packet forwarding engine. It's designed
|
||||
to offer very high speed IP packet forwarding based on IP connection tracking.
|
||||
It's dramatically faster than the standard netfilter-based NAT forwarding path
|
||||
but is designed to synchronise state back to netfilter/conntrack so that it
|
||||
doesn't need to deal with all of the complexities of special cases.
|
||||
|
||||
|
||||
Q) What versions of IP does it support?
|
||||
|
||||
A) The current version only supports IPv4 but will be extended to support IPv6 in
|
||||
the future.
|
||||
|
||||
|
||||
Q) What transport protocols does it support?
|
||||
|
||||
A) TCP and UDP. It also knows enough about ICMP to spot ICMP error messages
|
||||
related to TCP and UDP and handle things accordingly.
|
||||
|
||||
|
||||
Q) Is there a design spec for this software?
|
||||
|
||||
A) Not at the moment. I'll write one when I get more time. The code is
|
||||
intended to be a good tutorial though - it's very heavily commented. If you
|
||||
find yourself reading something and not understanding it then I take that to
|
||||
mean I've probably not done a sufficently good job of explaining what it's
|
||||
doing in the comments. Let me know - I will try to fix it :-)
|
||||
|
||||
|
||||
Q) Why was it written?
|
||||
|
||||
A) It was written as a demonstration of what can be done to provide high
|
||||
performance forwarding inside the kernel. There were two initial motivations:
|
||||
|
||||
1) To provide a platform to enable research into how QoS analysis systems can
|
||||
offload work and avoid huge Linux overheads.
|
||||
|
||||
2) To provide a tool to investigate the behaviour of various processors, SoCs
|
||||
and software sets so that we can characterize and design new network processor
|
||||
SoCs.
|
||||
|
||||
|
||||
Q) How much faster is it than the Linux kernel forwarding path?
|
||||
|
||||
A) At the time of pushing this to github it's been tested on a QCA AP135.
|
||||
This has a Scorpion (QCA Scopion, not the QMC one :-)) SoC, QCA9550. The
|
||||
SoC's processor is a MIPS74K running at 720 MHz and with a DDR2 memory
|
||||
subsystem that offers a peak of 600 MT/s (16-bit transfers).
|
||||
|
||||
Running IPv4 NAT forwarding of UDP between the board's 2 GMAC ports and
|
||||
using a SmartBits 200 as a traffic generator Linux is able to forward 70k PPS.
|
||||
Once the SFE code is invoked this will increase to 350k PPS!
|
||||
|
||||
There's also a slightly hacky mode which causes SFE to bypass the Linux
|
||||
bridge layer, but this isn't really ready for use because it doesn't have
|
||||
sufficient MAC address checks or integration of statistics back to the
|
||||
Ethernet bridge, but that runs at 436k PPS.
|
||||
|
||||
|
||||
Q) Are there any diagnostics?
|
||||
|
||||
A) Yes, this is a research tool after all! There's a complex way to do this
|
||||
that's more general purpose and a simple one - here's the simple one:
|
||||
|
||||
mknod /dev/sfe c 253 0
|
||||
|
||||
The file /dev/sfe is an XML-ish output and provides details of all the
|
||||
network connections currently being offloaded. It also reports the numbers
|
||||
of packets that took various "exception" paths within the code. In addition
|
||||
it provides a summary of the number of connections, attempts to accelerate
|
||||
connections, cancel accelerations, etc. It also reports the numbers of
|
||||
packets that were forwarded and not forwarded by the engine and has some
|
||||
stats on the effectiveness of the hashing algorithm it uses.
|
||||
|
||||
|
||||
Q) How does the code interact with Linux?
|
||||
|
||||
A) There are four minor patches required to make this software run with
|
||||
Linux. These are currently against a 3.3.8 or 3.4.0 kernel:
|
||||
|
||||
* (net/core/dev.c) adds a hook to allow packets to be extracted out.
|
||||
|
||||
* (net/netfilter/nf_conntrack_proto_tcp.c) exposes a state variable inside
|
||||
netfilter that's necessary to enable TCP sequence and ACK checking within
|
||||
the offload path. Note that this specific patch is against the QCA QSDK
|
||||
patched version of 3.3.8 - there's a slightly braindead "performance"
|
||||
patch in that kernel, courtesy of the OpenWrt community that makes the
|
||||
Linux forwarding path slightly faster at the expense of losing
|
||||
functionality :-(
|
||||
|
||||
* (net/Kconfig) adds the shortcut-fe option.
|
||||
|
||||
* (net/Makefile) adds the shortcut-fe build support.
|
||||
|
||||
Once these are applied and the module is loaded then everything else
|
||||
is automatic :-) The patches are in this git repo.
|
||||
|
||||
|
||||
Q) Are any of the pieces reused from other projects?
|
||||
|
||||
A) Yes! Some of the forwarding concepts are reused from the Ubicom Network
|
||||
Accelerator that morphed into part of the Akronite NSS. This code has all
|
||||
been substantially changed though to accomodate Linux's needs.
|
||||
|
||||
There are also some pieces that I borrowed from the QCA "FastNAT" software
|
||||
written by Xiaoping Fan <xfan@qca.qualcomm.com>. Xiaoping's code was the
|
||||
first actual demonstration within QCA that this in-kernel concept could yield
|
||||
signficant performance gains.
|
||||
|
||||
|
||||
Enjoy!
|
||||
Dave Hudson <dhudson@qti.qualcomm.com>
|
||||
|
1892
shortcut-fe/fast-classifier/fast-classifier.c
Normal file
1892
shortcut-fe/fast-classifier/fast-classifier.c
Normal file
File diff suppressed because it is too large
Load diff
57
shortcut-fe/fast-classifier/fast-classifier.h
Normal file
57
shortcut-fe/fast-classifier/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
shortcut-fe/fast-classifier/nl_classifier_test.c
Normal file
281
shortcut-fe/fast-classifier/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
shortcut-fe/fast-classifier/userspace_example.c
Normal file
232
shortcut-fe/fast-classifier/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;
|
||||
}
|
12
shortcut-fe/patches/Kconfig.patch
Normal file
12
shortcut-fe/patches/Kconfig.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
diff --git a/net/Kconfig b/net/Kconfig
|
||||
index 976cb63..4a7b0af 100644
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -236,6 +236,7 @@ source "net/dcb/Kconfig"
|
||||
source "net/dns_resolver/Kconfig"
|
||||
source "net/batman-adv/Kconfig"
|
||||
source "net/openvswitch/Kconfig"
|
||||
+source "net/shortcut-fe/Kconfig"
|
||||
|
||||
config RPS
|
||||
boolean "RPS"
|
10
shortcut-fe/patches/Makefile.patch
Normal file
10
shortcut-fe/patches/Makefile.patch
Normal file
|
@ -0,0 +1,10 @@
|
|||
diff --git a/net/Makefile b/net/Makefile
|
||||
index 6865dab..a8f0091 100644
|
||||
--- a/net/Makefile
|
||||
+++ b/net/Makefile
|
||||
@@ -71,3 +71,5 @@ obj-$(CONFIG_BATMAN_ADV) += batman-adv/
|
||||
obj-$(CONFIG_NFC) += nfc/
|
||||
obj-$(CONFIG_OPENVSWITCH) += openvswitch/
|
||||
obj-$(CONFIG_NET_ACTIVITY_STATS) += activity_stats.o
|
||||
+obj-$(CONFIG_SHORTCUT_FE) += shortcut-fe/
|
||||
+
|
43
shortcut-fe/patches/dev.c.patch
Normal file
43
shortcut-fe/patches/dev.c.patch
Normal file
|
@ -0,0 +1,43 @@
|
|||
diff --git a/net/core/dev.c b/net/core/dev.c
|
||||
index d23742f..1f0415f 100644
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -3168,6 +3168,9 @@ void netdev_rx_handler_unregister(struct net_device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
|
||||
|
||||
+int (*athrs_fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
|
||||
+EXPORT_SYMBOL_GPL(athrs_fast_nat_recv);
|
||||
+
|
||||
static int __netif_receive_skb(struct sk_buff *skb)
|
||||
{
|
||||
struct packet_type *ptype, *pt_prev;
|
||||
@@ -3177,6 +3180,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
|
||||
bool deliver_exact = false;
|
||||
int ret = NET_RX_DROP;
|
||||
__be16 type;
|
||||
+ int (*fast_recv)(struct sk_buff *skb);
|
||||
|
||||
net_timestamp_check(!netdev_tstamp_prequeue, skb);
|
||||
|
||||
@@ -3194,10 +3198,18 @@ static int __netif_receive_skb(struct sk_buff *skb)
|
||||
skb_reset_transport_header(skb);
|
||||
skb_reset_mac_len(skb);
|
||||
|
||||
- pt_prev = NULL;
|
||||
-
|
||||
rcu_read_lock();
|
||||
|
||||
+ fast_recv = rcu_dereference(athrs_fast_nat_recv);
|
||||
+ if (fast_recv) {
|
||||
+ if (fast_recv(skb)) {
|
||||
+ rcu_read_unlock();
|
||||
+ return NET_RX_SUCCESS;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pt_prev = NULL;
|
||||
+
|
||||
another_round:
|
||||
|
||||
__this_cpu_inc(softnet_data.processed);
|
25
shortcut-fe/patches/nf_conntrack_proto_tcp.c.patch
Normal file
25
shortcut-fe/patches/nf_conntrack_proto_tcp.c.patch
Normal file
|
@ -0,0 +1,25 @@
|
|||
--- /home/dhudson/mips-orig/nf_conntrack_proto_tcp.c 2013-05-07 21:32:57.153896922 +0100
|
||||
+++ nf_conntrack_proto_tcp.c 2013-06-13 16:37:40.137102438 +0100
|
||||
@@ -27,18 +27,20 @@
|
||||
#include <net/netfilter/nf_conntrack_ecache.h>
|
||||
#include <net/netfilter/nf_log.h>
|
||||
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
|
||||
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
|
||||
|
||||
/* Do not check the TCP window for incoming packets */
|
||||
-static int nf_ct_tcp_no_window_check __read_mostly = 1;
|
||||
+int nf_ct_tcp_no_window_check __read_mostly = 0;
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check);
|
||||
|
||||
/* "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;
|
||||
+int nf_ct_tcp_be_liberal __read_mostly = 0;
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_be_liberal);
|
||||
|
||||
/* If it is set to zero, we disable picking up already established
|
||||
connections. */
|
||||
static int nf_ct_tcp_loose __read_mostly = 1;
|
||||
|
||||
/* Max number of the retransmitted packets without receiving an (acceptable)
|
114
shortcut-fe/sfe.h
Normal file
114
shortcut-fe/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
shortcut-fe/sfe_backport.h
Normal file
195
shortcut-fe/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, addr)
|
||||
#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
|
1154
shortcut-fe/sfe_cm.c
Normal file
1154
shortcut-fe/sfe_cm.c
Normal file
File diff suppressed because it is too large
Load diff
259
shortcut-fe/sfe_cm.h
Normal file
259
shortcut-fe/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);
|
||||
}
|
3610
shortcut-fe/sfe_ipv4.c
Normal file
3610
shortcut-fe/sfe_ipv4.c
Normal file
File diff suppressed because it is too large
Load diff
3617
shortcut-fe/sfe_ipv6.c
Normal file
3617
shortcut-fe/sfe_ipv6.c
Normal file
File diff suppressed because it is too large
Load diff
14
shortcut-fe/shortcut-fe/Kconfig
Normal file
14
shortcut-fe/shortcut-fe/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.
|
114
shortcut-fe/shortcut-fe/sfe.h
Normal file
114
shortcut-fe/shortcut-fe/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
shortcut-fe/shortcut-fe/sfe_backport.h
Normal file
195
shortcut-fe/shortcut-fe/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, addr)
|
||||
#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
|
1154
shortcut-fe/shortcut-fe/sfe_cm.c
Normal file
1154
shortcut-fe/shortcut-fe/sfe_cm.c
Normal file
File diff suppressed because it is too large
Load diff
259
shortcut-fe/shortcut-fe/sfe_cm.h
Normal file
259
shortcut-fe/shortcut-fe/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);
|
||||
}
|
3610
shortcut-fe/shortcut-fe/sfe_ipv4.c
Normal file
3610
shortcut-fe/shortcut-fe/sfe_ipv4.c
Normal file
File diff suppressed because it is too large
Load diff
3617
shortcut-fe/shortcut-fe/sfe_ipv6.c
Normal file
3617
shortcut-fe/shortcut-fe/sfe_ipv6.c
Normal file
File diff suppressed because it is too large
Load diff
1323
shortcut-fe/simulated-driver/sfe_drv.c
Normal file
1323
shortcut-fe/simulated-driver/sfe_drv.c
Normal file
File diff suppressed because it is too large
Load diff
553
shortcut-fe/simulated-driver/sfe_drv.h
Normal file
553
shortcut-fe/simulated-driver/sfe_drv.h
Normal file
|
@ -0,0 +1,553 @@
|
|||
/*
|
||||
* sfe_drv.h
|
||||
* simulated driver headers for shortcut forwarding engine.
|
||||
*
|
||||
* Copyright (c) 2015,2016 The Linux Foundation. All rights reserved.
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all copies.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __SFE_DRV_H
|
||||
#define __SFE_DRV_H
|
||||
|
||||
#define MAX_VLAN_DEPTH 2
|
||||
#define SFE_VLAN_ID_NOT_CONFIGURED 0xfff
|
||||
#define SFE_MC_IF_MAX 16
|
||||
|
||||
#define SFE_SPECIAL_INTERFACE_BASE 0x7f00
|
||||
#define SFE_SPECIAL_INTERFACE_IPV4 (SFE_SPECIAL_INTERFACE_BASE + 1)
|
||||
#define SFE_SPECIAL_INTERFACE_IPV6 (SFE_SPECIAL_INTERFACE_BASE + 2)
|
||||
#define SFE_SPECIAL_INTERFACE_IPSEC (SFE_SPECIAL_INTERFACE_BASE + 3)
|
||||
#define SFE_SPECIAL_INTERFACE_L2TP (SFE_SPECIAL_INTERFACE_BASE + 4)
|
||||
#define SFE_SPECIAL_INTERFACE_PPTP (SFE_SPECIAL_INTERFACE_BASE + 5)
|
||||
|
||||
/**
|
||||
* Rule creation & rule update flags.
|
||||
*/
|
||||
#define SFE_RULE_CREATE_FLAG_NO_SEQ_CHECK (1<<0) /**< Do not perform TCP sequence number checks */
|
||||
#define SFE_RULE_CREATE_FLAG_BRIDGE_FLOW (1<<1) /**< This is a pure bridge forwarding flow */
|
||||
#define SFE_RULE_CREATE_FLAG_ROUTED (1<<2) /**< Rule is for a routed connection */
|
||||
#define SFE_RULE_CREATE_FLAG_DSCP_MARKING (1<<3) /**< Rule has for a DSCP marking configured*/
|
||||
#define SFE_RULE_CREATE_FLAG_VLAN_MARKING (1<<4) /**< Rule has for a VLAN marking configured*/
|
||||
#define SFE_RULE_UPDATE_FLAG_CHANGE_MTU (1<<5) /**< Update MTU of connection interfaces */
|
||||
#define SFE_RULE_CREATE_FLAG_ICMP_NO_CME_FLUSH (1<<6)/**< Rule for not flushing CME on ICMP pkt */
|
||||
#define SFE_RULE_CREATE_FLAG_L2_ENCAP (1<<7) /**< consists of an encapsulating protocol that carries an IPv4 payload within it. */
|
||||
#define SFE_RULE_CREATE_FLAG_MC_JOIN (1<<8) /**< Interface has joined the flow */
|
||||
#define SFE_RULE_CREATE_FLAG_MC_LEAVE (1<<9) /**< Interface has left the flow */
|
||||
#define SFE_RULE_CREATE_FLAG_MC_UPDATE (1<<10)/**< Multicast Rule update */
|
||||
/**
|
||||
* Rule creation validity flags.
|
||||
*/
|
||||
#define SFE_RULE_CREATE_CONN_VALID (1<<0) /**< IPv4 Connection is valid */
|
||||
#define SFE_RULE_CREATE_TCP_VALID (1<<1) /**< TCP Protocol fields are valid */
|
||||
#define SFE_RULE_CREATE_PPPOE_VALID (1<<2) /**< PPPoE fields are valid */
|
||||
#define SFE_RULE_CREATE_QOS_VALID (1<<3) /**< QoS fields are valid */
|
||||
#define SFE_RULE_CREATE_VLAN_VALID (1<<4) /**< VLAN fields are valid */
|
||||
#define SFE_RULE_CREATE_DSCP_MARKING_VALID (1<<5) /**< DSCP marking fields are valid */
|
||||
#define SFE_RULE_CREATE_VLAN_MARKING_VALID (1<<6) /**< VLAN marking fields are valid */
|
||||
#define SFE_RULE_CREATE_MC_NAT_VALID (1<<7) /**< Interface is configured with Source-NAT */
|
||||
#define SFE_RULE_CREATE_DIRECTION_VALID (1<<8) /**< specify acceleration directions */
|
||||
|
||||
/*
|
||||
* 32/64 bits pointer type
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
typedef uint64_t sfe_ptr_t;
|
||||
#else
|
||||
typedef uint32_t sfe_ptr_t;
|
||||
#endif
|
||||
|
||||
typedef enum sfe_rule_sync_reason {
|
||||
SFE_RULE_SYNC_REASON_STATS, /* Sync is to synchronize stats */
|
||||
SFE_RULE_SYNC_REASON_FLUSH, /* Sync is to flush a entry */
|
||||
SFE_RULE_SYNC_REASON_EVICT, /* Sync is to evict a entry */
|
||||
SFE_RULE_SYNC_REASON_DESTROY /* Sync is to destroy a entry(requested by connection manager) */
|
||||
|
||||
} sfe_rule_sync_reason_t;
|
||||
|
||||
/**
|
||||
* Tx command status
|
||||
*/
|
||||
typedef enum {
|
||||
SFE_TX_SUCCESS = 0, /**< Success */
|
||||
SFE_TX_FAILURE, /**< Command failure other than descriptor not available */
|
||||
SFE_TX_FAILURE_QUEUE, /**< Command failure due to descriptor not available */
|
||||
SFE_TX_FAILURE_NOT_READY, /**< Command failure due to SFE state uninitialized */
|
||||
SFE_TX_FAILURE_TOO_LARGE, /**< Command is too large to fit in one message */
|
||||
SFE_TX_FAILURE_TOO_SHORT, /**< Command/Packet is shorter than expected size */
|
||||
SFE_TX_FAILURE_NOT_SUPPORTED, /**< Command/Packet not accepted for forwarding */
|
||||
SFE_TX_FAILURE_BAD_PARAM, /**< Command failure due to bad parameters */
|
||||
SFE_TX_FAILURE_NOT_ENABLED, /**< Command failure due to SFE feature is not enabled */
|
||||
} sfe_tx_status_t;
|
||||
|
||||
/**
|
||||
* Common response structure
|
||||
*/
|
||||
enum sfe_cmn_response {
|
||||
SFE_CMN_RESPONSE_ACK, /**< Message Acknowledge */
|
||||
SFE_CMN_RESPONSE_EVERSION, /**< Message Version Error */
|
||||
SFE_CMN_RESPONSE_EINTERFACE, /**< Message Interface Error */
|
||||
SFE_CMN_RESPONSE_ELENGTH, /**< Message Length Error */
|
||||
SFE_CMN_RESPONSE_EMSG, /**< Message Error */
|
||||
SFE_CMM_RESPONSE_NOTIFY, /**< Message Independant of Request */
|
||||
SFE_CMN_RESPONSE_LAST
|
||||
};
|
||||
|
||||
/**
|
||||
* IPv4 bridge/route rule messages
|
||||
*/
|
||||
enum sfe_message_types {
|
||||
SFE_TX_CREATE_RULE_MSG, /**< IPv4/6 create rule message */
|
||||
SFE_TX_DESTROY_RULE_MSG, /**< IPv4/6 destroy rule message */
|
||||
SFE_RX_CONN_STATS_SYNC_MSG, /**< IPv4/6 connection stats sync message */
|
||||
SFE_TX_CREATE_MC_RULE_MSG, /**< IPv4/6 multicast create rule message */
|
||||
SFE_TUN6RD_ADD_UPDATE_PEER, /**< Add/update peer for 6rd tunnel */
|
||||
SFE_MAX_MSG_TYPES, /**< IPv4/6 message max type number */
|
||||
};
|
||||
|
||||
/**
|
||||
* Common message structure
|
||||
*/
|
||||
struct sfe_cmn_msg {
|
||||
u16 version; /**< Version id for main message format */
|
||||
u16 interface; /**< Primary Key for all messages */
|
||||
enum sfe_cmn_response response; /**< Primary response */
|
||||
u32 type; /**< Decetralized request #, to be used to match response # */
|
||||
u32 error; /**< Decentralized specific error message, response == EMSG */
|
||||
sfe_ptr_t cb; /**< Place for callback pointer */
|
||||
sfe_ptr_t app_data; /**< Place for app data */
|
||||
u32 len; /**< What is the length of the message excluding this header */
|
||||
};
|
||||
|
||||
/**
|
||||
* Common 5 tuple structure
|
||||
*/
|
||||
struct sfe_ipv4_5tuple {
|
||||
__be32 flow_ip; /**< Flow IP address */
|
||||
__be32 return_ip; /**< Return IP address */
|
||||
__be16 flow_ident; /**< Flow ident (e.g. TCP/UDP port) */
|
||||
__be16 return_ident; /**< Return ident (e.g. TCP/UDP port) */
|
||||
u8 protocol; /**< Protocol number */
|
||||
u8 reserved[3]; /**< Padded for alignment */
|
||||
};
|
||||
|
||||
/**
|
||||
* Common 5 tuple structure
|
||||
*/
|
||||
struct sfe_ipv6_5tuple {
|
||||
__be32 flow_ip[4]; /**< Flow IP address */
|
||||
__be32 return_ip[4]; /**< Return IP address */
|
||||
__be16 flow_ident; /**< Flow ident (e.g. TCP/UDP port) */
|
||||
__be16 return_ident; /**< Return ident (e.g. TCP/UDP port) */
|
||||
u8 protocol; /**< Protocol number */
|
||||
u8 reserved[3]; /**< Padded for alignment */
|
||||
};
|
||||
|
||||
/**
|
||||
* Connection create structure
|
||||
*/
|
||||
struct sfe_ipv4_connection_rule {
|
||||
u8 flow_mac[6]; /**< Flow MAC address */
|
||||
u8 return_mac[6]; /**< Return MAC address */
|
||||
s32 flow_interface_num; /**< Flow interface number */
|
||||
s32 return_interface_num; /**< Return interface number */
|
||||
s32 flow_top_interface_num; /* Top flow interface number */
|
||||
s32 return_top_interface_num;/* Top return interface number */
|
||||
u32 flow_mtu; /**< Flow interface`s MTU */
|
||||
u32 return_mtu; /**< Return interface`s MTU */
|
||||
__be32 flow_ip_xlate; /**< Translated flow IP address */
|
||||
__be32 return_ip_xlate; /**< Translated return IP address */
|
||||
__be16 flow_ident_xlate; /**< Translated flow ident (e.g. port) */
|
||||
__be16 return_ident_xlate; /**< Translated return ident (e.g. port) */
|
||||
};
|
||||
|
||||
/**
|
||||
* Connection create structure
|
||||
*/
|
||||
struct sfe_ipv6_connection_rule {
|
||||
u8 flow_mac[6]; /**< Flow MAC address */
|
||||
u8 return_mac[6]; /**< Return MAC address */
|
||||
s32 flow_interface_num; /**< Flow interface number */
|
||||
s32 return_interface_num; /**< Return interface number */
|
||||
s32 flow_top_interface_num; /* Top flow interface number */
|
||||
s32 return_top_interface_num;/* Top return interface number */
|
||||
u32 flow_mtu; /**< Flow interface's MTU */
|
||||
u32 return_mtu; /**< Return interface's MTU */
|
||||
};
|
||||
|
||||
/**
|
||||
* TCP connection rule structure
|
||||
*/
|
||||
struct sfe_protocol_tcp_rule {
|
||||
u32 flow_max_window; /**< Flow direction's largest seen window */
|
||||
u32 return_max_window; /**< Return direction's largest seen window */
|
||||
u32 flow_end; /**< Flow direction's largest seen sequence + segment length */
|
||||
u32 return_end; /**< Return direction's largest seen sequence + segment length */
|
||||
u32 flow_max_end; /**< Flow direction's largest seen ack + max(1, win) */
|
||||
u32 return_max_end; /**< Return direction's largest seen ack + max(1, win) */
|
||||
u8 flow_window_scale; /**< Flow direction's window scaling factor */
|
||||
u8 return_window_scale; /**< Return direction's window scaling factor */
|
||||
u16 reserved; /**< Padded for alignment */
|
||||
};
|
||||
|
||||
/**
|
||||
* PPPoE connection rules structure
|
||||
*/
|
||||
struct sfe_pppoe_rule {
|
||||
u16 flow_pppoe_session_id; /**< Flow direction`s PPPoE session ID. */
|
||||
u16 flow_pppoe_remote_mac[3]; /**< Flow direction`s PPPoE Server MAC address */
|
||||
u16 return_pppoe_session_id; /**< Return direction's PPPoE session ID. */
|
||||
u16 return_pppoe_remote_mac[3]; /**< Return direction's PPPoE Server MAC address */
|
||||
};
|
||||
|
||||
/**
|
||||
* QoS connection rule structure
|
||||
*/
|
||||
struct sfe_qos_rule {
|
||||
u32 flow_qos_tag; /**< QoS tag associated with this rule for flow direction */
|
||||
u32 return_qos_tag; /**< QoS tag associated with this rule for return direction */
|
||||
};
|
||||
|
||||
/**
|
||||
* DSCP connection rule structure
|
||||
*/
|
||||
struct sfe_dscp_rule {
|
||||
u8 flow_dscp; /**< Egress DSCP value for flow direction */
|
||||
u8 return_dscp; /**< Egress DSCP value for return direction */
|
||||
u8 reserved[2]; /**< Padded for alignment */
|
||||
};
|
||||
|
||||
/**
|
||||
* VLAN connection rule structure
|
||||
*/
|
||||
struct sfe_vlan_rule {
|
||||
u32 ingress_vlan_tag; /**< VLAN Tag for the ingress packets */
|
||||
u32 egress_vlan_tag; /**< VLAN Tag for egress packets */
|
||||
};
|
||||
|
||||
/**
|
||||
* Acceleration direction rule structure
|
||||
* Sometimes we just want to accelerate traffic in one direction but not in another.
|
||||
*/
|
||||
struct sfe_acceleration_direction_rule {
|
||||
u8 flow_accel; /**< Accelerate in flow direction */
|
||||
u8 return_accel; /**< Accelerate in return direction */
|
||||
u8 reserved[2]; /**< Padded for alignment */
|
||||
};
|
||||
|
||||
/**
|
||||
* The IPv4 rule create sub-message structure.
|
||||
*/
|
||||
struct sfe_ipv4_rule_create_msg {
|
||||
/* Request */
|
||||
u16 valid_flags; /**< Bit flags associated with the validity of parameters */
|
||||
u16 rule_flags; /**< Bit flags associated with the rule */
|
||||
|
||||
struct sfe_ipv4_5tuple tuple; /**< Holds values of the 5 tuple */
|
||||
|
||||
struct sfe_ipv4_connection_rule conn_rule; /**< Basic connection specific data */
|
||||
struct sfe_protocol_tcp_rule tcp_rule; /**< TCP related accleration parameters */
|
||||
struct sfe_pppoe_rule pppoe_rule; /**< PPPoE related accleration parameters */
|
||||
struct sfe_qos_rule qos_rule; /**< QoS related accleration parameters */
|
||||
struct sfe_dscp_rule dscp_rule; /**< DSCP related accleration parameters */
|
||||
struct sfe_vlan_rule vlan_primary_rule; /**< Primary VLAN related accleration parameters */
|
||||
struct sfe_vlan_rule vlan_secondary_rule; /**< Secondary VLAN related accleration parameters */
|
||||
#ifdef CONFIG_XFRM
|
||||
struct sfe_acceleration_direction_rule direction_rule;/* Direction related accleration parameters*/
|
||||
#endif
|
||||
/* Response */
|
||||
u32 index; /**< Slot ID for cache stats to host OS */
|
||||
};
|
||||
|
||||
/**
|
||||
* The IPv4 rule destroy sub-message structure.
|
||||
*/
|
||||
struct sfe_ipv4_rule_destroy_msg {
|
||||
struct sfe_ipv4_5tuple tuple; /**< Holds values of the 5 tuple */
|
||||
};
|
||||
|
||||
/**
|
||||
* The SFE IPv4 rule sync structure.
|
||||
*/
|
||||
struct sfe_ipv4_conn_sync {
|
||||
u32 index; /**< Slot ID for cache stats to host OS */
|
||||
u8 protocol; /**< Protocol number */
|
||||
__be32 flow_ip; /**< Flow IP address */
|
||||
__be32 flow_ip_xlate; /**< Translated flow IP address */
|
||||
__be16 flow_ident; /**< Flow ident (e.g. port) */
|
||||
__be16 flow_ident_xlate; /**< Translated flow ident (e.g. port) */
|
||||
u32 flow_max_window; /**< Flow direction's largest seen window */
|
||||
u32 flow_end; /**< Flow direction's largest seen sequence + segment length */
|
||||
u32 flow_max_end; /**< Flow direction's largest seen ack + max(1, win) */
|
||||
u32 flow_rx_packet_count; /**< Flow interface's RX packet count */
|
||||
u32 flow_rx_byte_count; /**< Flow interface's RX byte count */
|
||||
u32 flow_tx_packet_count; /**< Flow interface's TX packet count */
|
||||
u32 flow_tx_byte_count; /**< Flow interface's TX byte count */
|
||||
u16 flow_pppoe_session_id; /**< Flow interface`s PPPoE session ID. */
|
||||
u16 flow_pppoe_remote_mac[3];
|
||||
/**< Flow interface's PPPoE remote server MAC address if there is any */
|
||||
__be32 return_ip; /**< Return IP address */
|
||||
__be32 return_ip_xlate; /**< Translated return IP address */
|
||||
__be16 return_ident; /**< Return ident (e.g. port) */
|
||||
__be16 return_ident_xlate; /**< Translated return ident (e.g. port) */
|
||||
u32 return_max_window; /**< Return direction's largest seen window */
|
||||
u32 return_end; /**< Return direction's largest seen sequence + segment length */
|
||||
u32 return_max_end; /**< Return direction's largest seen ack + max(1, win) */
|
||||
u32 return_rx_packet_count;
|
||||
/**< Return interface's RX packet count */
|
||||
u32 return_rx_byte_count; /**< Return interface's RX byte count */
|
||||
u32 return_tx_packet_count;
|
||||
/**< Return interface's TX packet count */
|
||||
u32 return_tx_byte_count; /**< Return interface's TX byte count */
|
||||
u16 return_pppoe_session_id;
|
||||
/**< Return interface`s PPPoE session ID. */
|
||||
u16 return_pppoe_remote_mac[3];
|
||||
/**< Return interface's PPPoE remote server MAC address if there is any */
|
||||
u32 inc_ticks; /**< Number of ticks since the last sync */
|
||||
u32 reason; /**< Reason for the sync */
|
||||
|
||||
u8 flags; /**< Bit flags associated with the rule */
|
||||
u32 qos_tag; /**< QoS Tag */
|
||||
u32 cause; /**< Flush Cause */
|
||||
};
|
||||
|
||||
/*
|
||||
* Message structure to send/receive IPv4 bridge/route commands
|
||||
*/
|
||||
struct sfe_ipv4_msg {
|
||||
struct sfe_cmn_msg cm; /**< Message Header */
|
||||
union {
|
||||
struct sfe_ipv4_rule_create_msg rule_create; /**< Message: rule create */
|
||||
struct sfe_ipv4_rule_destroy_msg rule_destroy; /**< Message: rule destroy */
|
||||
struct sfe_ipv4_conn_sync conn_stats; /**< Message: connection stats sync */
|
||||
} msg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to be called when IPv4 message is received
|
||||
*/
|
||||
typedef void (*sfe_ipv4_msg_callback_t)(void *app_data, struct sfe_ipv4_msg *msg);
|
||||
|
||||
/**
|
||||
* The IPv6 rule create sub-message structure.
|
||||
*/
|
||||
struct sfe_ipv6_rule_create_msg {
|
||||
/*
|
||||
* Request
|
||||
*/
|
||||
u16 valid_flags; /**< Bit flags associated with the validity of parameters */
|
||||
u16 rule_flags; /**< Bit flags associated with the rule */
|
||||
struct sfe_ipv6_5tuple tuple; /**< Holds values of the 5 tuple */
|
||||
struct sfe_ipv6_connection_rule conn_rule; /**< Basic connection specific data */
|
||||
struct sfe_protocol_tcp_rule tcp_rule; /**< Protocol related accleration parameters */
|
||||
struct sfe_pppoe_rule pppoe_rule; /**< PPPoE related accleration parameters */
|
||||
struct sfe_qos_rule qos_rule; /**< QoS related accleration parameters */
|
||||
struct sfe_dscp_rule dscp_rule; /**< DSCP related accleration parameters */
|
||||
struct sfe_vlan_rule vlan_primary_rule; /**< VLAN related accleration parameters */
|
||||
struct sfe_vlan_rule vlan_secondary_rule; /**< VLAN related accleration parameters */
|
||||
#ifdef CONFIG_XFRM
|
||||
struct sfe_acceleration_direction_rule direction_rule;/* Direction related accleration parameters*/
|
||||
#endif
|
||||
/*
|
||||
* Response
|
||||
*/
|
||||
u32 index; /**< Slot ID for cache stats to host OS */
|
||||
};
|
||||
|
||||
/**
|
||||
* The IPv6 rule destroy sub-message structure.
|
||||
*/
|
||||
struct sfe_ipv6_rule_destroy_msg {
|
||||
struct sfe_ipv6_5tuple tuple; /**< Holds values of the 5 tuple */
|
||||
};
|
||||
|
||||
/**
|
||||
* The SFE IPv6 rule sync structure.
|
||||
*/
|
||||
struct sfe_ipv6_conn_sync {
|
||||
u32 index; /**< Slot ID for cache stats to host OS */
|
||||
u8 protocol; /**< Protocol number */
|
||||
__be32 flow_ip[4]; /**< Flow IP address */
|
||||
__be16 flow_ident; /**< Flow ident (e.g. port) */
|
||||
u32 flow_max_window; /**< Flow direction's largest seen window */
|
||||
u32 flow_end; /**< Flow direction's largest seen sequence + segment length */
|
||||
u32 flow_max_end; /**< Flow direction's largest seen ack + max(1, win) */
|
||||
u32 flow_rx_packet_count; /**< Flow interface's RX packet count */
|
||||
u32 flow_rx_byte_count; /**< Flow interface's RX byte count */
|
||||
u32 flow_tx_packet_count; /**< Flow interface's TX packet count */
|
||||
u32 flow_tx_byte_count; /**< Flow interface's TX byte count */
|
||||
u16 flow_pppoe_session_id; /**< Flow interface`s PPPoE session ID. */
|
||||
u16 flow_pppoe_remote_mac[3];
|
||||
/**< Flow interface's PPPoE remote server MAC address if there is any */
|
||||
__be32 return_ip[4]; /**< Return IP address */
|
||||
__be16 return_ident; /**< Return ident (e.g. port) */
|
||||
u32 return_max_window; /**< Return direction's largest seen window */
|
||||
u32 return_end; /**< Return direction's largest seen sequence + segment length */
|
||||
u32 return_max_end; /**< Return direction's largest seen ack + max(1, win) */
|
||||
u32 return_rx_packet_count;
|
||||
/**< Return interface's RX packet count */
|
||||
u32 return_rx_byte_count; /**< Return interface's RX byte count */
|
||||
u32 return_tx_packet_count;
|
||||
/**< Return interface's TX packet count */
|
||||
u32 return_tx_byte_count; /**< Return interface's TX byte count */
|
||||
u16 return_pppoe_session_id;
|
||||
/**< Return interface`s PPPoE session ID. */
|
||||
u16 return_pppoe_remote_mac[3];
|
||||
/**< Return interface's PPPoE remote server MAC address if there is any */
|
||||
u32 inc_ticks; /**< Number of ticks since the last sync */
|
||||
u32 reason; /**< Reason for the sync */
|
||||
u8 flags; /**< Bit flags associated with the rule */
|
||||
u32 qos_tag; /**< QoS Tag */
|
||||
u32 cause; /**< Flush cause associated with the rule */
|
||||
};
|
||||
|
||||
/**
|
||||
* Message structure to send/receive IPv6 bridge/route commands
|
||||
*/
|
||||
struct sfe_ipv6_msg {
|
||||
struct sfe_cmn_msg cm; /**< Message Header */
|
||||
union {
|
||||
struct sfe_ipv6_rule_create_msg rule_create; /**< Message: rule create */
|
||||
struct sfe_ipv6_rule_destroy_msg rule_destroy; /**< Message: rule destroy */
|
||||
struct sfe_ipv6_conn_sync conn_stats; /**< Message: stats sync */
|
||||
} msg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to be called when IPv6 message is received
|
||||
*/
|
||||
typedef void (*sfe_ipv6_msg_callback_t)(void *app_data, struct sfe_ipv6_msg *msg);
|
||||
|
||||
/**
|
||||
* 6rd tunnel peer addr.
|
||||
*/
|
||||
struct sfe_tun6rd_set_peer_msg {
|
||||
__be32 ipv6_address[4]; /* The peer's ipv6 addr*/
|
||||
__be32 dest; /* The peer's ipv4 addr*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Message structure to send/receive 6rd tunnel messages
|
||||
*/
|
||||
struct sfe_tun6rd_msg {
|
||||
struct sfe_cmn_msg cm; /* Message Header */
|
||||
union {
|
||||
struct sfe_tun6rd_set_peer_msg peer; /* Message: add/update peer */
|
||||
} msg;
|
||||
};
|
||||
|
||||
/*
|
||||
* sfe driver context instance
|
||||
*/
|
||||
struct sfe_drv_ctx_instance {
|
||||
int not_used;
|
||||
};
|
||||
|
||||
/*
|
||||
* sfe_drv_ipv4_max_conn_count()
|
||||
* Return the maximum number of IPv4 connections that the sfe acceleration engine supports
|
||||
*
|
||||
* @return int The number of connections that can be accelerated by the sfe
|
||||
*/
|
||||
int sfe_drv_ipv4_max_conn_count(void);
|
||||
|
||||
/*
|
||||
* sfe_drv_ipv4_tx()
|
||||
* Transmit an IPv4 message to the sfe
|
||||
*
|
||||
* @param sfe_drv_ctx sfe driver context
|
||||
* @param msg The IPv4 message
|
||||
*
|
||||
* @return sfe_tx_status_t The status of the Tx operation
|
||||
*/
|
||||
extern sfe_tx_status_t sfe_drv_ipv4_tx(struct sfe_drv_ctx_instance *sfe_drv_ctx, struct sfe_ipv4_msg *msg);
|
||||
|
||||
/*
|
||||
* sfe_drv_ipv4_notify_register()
|
||||
* Register a notifier callback for IPv4 messages from sfe driver
|
||||
*
|
||||
* @param cb The callback pointer
|
||||
* @param app_data The application context for this message
|
||||
*
|
||||
* @return struct sfe_drv_ctx_instance * The sfe driver context
|
||||
*/
|
||||
extern struct sfe_drv_ctx_instance *sfe_drv_ipv4_notify_register(sfe_ipv4_msg_callback_t cb, void *app_data);
|
||||
|
||||
/*
|
||||
* sfe_drv_ipv4_notify_unregister()
|
||||
* Un-Register a notifier callback for IPv4 messages from sfe driver
|
||||
*/
|
||||
extern void sfe_drv_ipv4_notify_unregister(void);
|
||||
|
||||
/*
|
||||
* sfe_ipv4_msg_init()
|
||||
* IPv4 message init
|
||||
*/
|
||||
extern void sfe_ipv4_msg_init(struct sfe_ipv4_msg *nim, u16 if_num, u32 type, u32 len,
|
||||
sfe_ipv4_msg_callback_t cb, void *app_data);
|
||||
|
||||
/*
|
||||
* sfe_drv_ipv6_max_conn_count()
|
||||
* Return the maximum number of IPv6 connections that the sfe acceleration engine supports
|
||||
*
|
||||
* @return int The number of connections that can be accelerated by the sfe
|
||||
*/
|
||||
int sfe_drv_ipv6_max_conn_count(void);
|
||||
|
||||
/*
|
||||
* sfe_drv_ipv6_tx()
|
||||
* Transmit an IPv6 message to the sfe
|
||||
*
|
||||
* @param sfe_drv_ctx sfe driver context
|
||||
* @param msg The IPv6 message
|
||||
*
|
||||
* @return sfe_tx_status_t The status of the Tx operation
|
||||
*/
|
||||
extern sfe_tx_status_t sfe_drv_ipv6_tx(struct sfe_drv_ctx_instance *sfe_drv_ctx, struct sfe_ipv6_msg *msg);
|
||||
|
||||
/*
|
||||
* sfe_drv_ipv6_notify_register()
|
||||
* Register a notifier callback for IPv6 messages from sfe driver
|
||||
*
|
||||
* @param cb The callback pointer
|
||||
* @param app_data The application context for this message
|
||||
*
|
||||
* @return struct sfe_drv_ctx_instance * The sfe driver context
|
||||
*/
|
||||
extern struct sfe_drv_ctx_instance *sfe_drv_ipv6_notify_register(sfe_ipv6_msg_callback_t cb, void *app_data);
|
||||
|
||||
/*
|
||||
* sfe_drv_ipv6_notify_unregister()
|
||||
* Un-Register a notifier callback for IPv6 messages from sfe driver
|
||||
*/
|
||||
extern void sfe_drv_ipv6_notify_unregister(void);
|
||||
|
||||
/*
|
||||
* sfe_ipv6_msg_init()
|
||||
* IPv6 message init
|
||||
*/
|
||||
extern void sfe_ipv6_msg_init(struct sfe_ipv6_msg *nim, u16 if_num, u32 type, u32 len,
|
||||
sfe_ipv6_msg_callback_t cb, void *app_data);
|
||||
|
||||
/*
|
||||
* sfe_tun6rd_tx()
|
||||
* Transmit a tun6rd message to sfe engine
|
||||
*/
|
||||
sfe_tx_status_t sfe_tun6rd_tx(struct sfe_drv_ctx_instance *sfe_ctx, struct sfe_tun6rd_msg *msg);
|
||||
|
||||
/*
|
||||
* sfe_tun6rd_msg_init()
|
||||
* Initialize sfe_tun6rd msg.
|
||||
*/
|
||||
void sfe_tun6rd_msg_init(struct sfe_tun6rd_msg *ncm, u16 if_num, u32 type, u32 len,
|
||||
void *cb, void *app_data);
|
||||
|
||||
#endif /* __SFE_DRV_H */
|
|
@ -1,60 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2015,2016 The Linux Foundation. All rights reserved.
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
# above copyright notice and this permission notice appear in all copies.
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=shortcut-fe-simulated-driver
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/shortcut-fe
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2021-03-17
|
||||
PKG_SOURCE_VERSION:=697977d8d0ccf0ab596e5692d08608a75dd7f33d
|
||||
PKG_MIRROR_HASH:=659fa82a431e15af797a6c7069faeee02810453ad8b576c51c29f95a1761a045
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/shortcut-fe-drv
|
||||
SECTION:=kernel
|
||||
CATEGORY:=Kernel modules
|
||||
SUBMENU:=Network Support
|
||||
DEPENDS:=@TARGET_ipq60xx||@TARGET_ipq806x||TARGET_ipq807x +kmod-shortcut-fe
|
||||
KCONFIG:= \
|
||||
CONFIG_NET_CLS_ACT=y \
|
||||
CONFIG_XFRM=y
|
||||
TITLE:=Simulated sfe driver for ECM
|
||||
FILES:=$(PKG_BUILD_DIR)/simulated-driver/shortcut-fe-drv.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/shortcut-fe-drv/Description
|
||||
Simulated sfe driver which act as an adapter to convert message
|
||||
between a connection manager and the SFE core engine.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
$(PKG_MAKE_FLAGS) \
|
||||
M="$(PKG_BUILD_DIR)/simulated-driver" \
|
||||
EXTRA_CFLAGS="-DSFE_SUPPORT_IPV6" \
|
||||
modules
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include/shortcut-fe
|
||||
$(CP) -rf $(PKG_BUILD_DIR)/simulated-driver/sfe_drv.h $(1)/usr/include/shortcut-fe
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,shortcut-fe-drv))
|
|
@ -1,11 +0,0 @@
|
|||
--- ./simulated-driver/sfe_drv.c.orig 2020-06-16 12:49:47.680153371 +0800
|
||||
+++ ./simulated-driver/sfe_drv.c 2020-06-16 12:50:18.540153371 +0800
|
||||
@@ -1167,7 +1167,7 @@ int sfe_drv_recv(struct sk_buff *skb)
|
||||
* If ingress Qdisc configured, and packet not processed by ingress Qdisc yet
|
||||
* We can not accelerate this packet.
|
||||
*/
|
||||
- if (dev->ingress_queue && !(skb->tc_verd & TC_NCLS)) {
|
||||
+ if (dev->ingress_queue && !(skb->tc_verd_qca_nss & TC_NCLS)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue