| diff --git a/package/libs/libnfnetlink/patches/101-flowtable-support.patch b/package/libs/libnfnetlink/patches/101-flowtable-support.patch |
| new file mode 100644 |
| index 00000000..2ba78022 |
| --- /dev/null |
| +++ b/package/libs/libnfnetlink/patches/101-flowtable-support.patch |
| @@ -0,0 +1,12 @@ |
| +Index: libnfnetlink-1.0.1/include/libnfnetlink/linux_nfnetlink.h |
| +=================================================================== |
| +--- libnfnetlink-1.0.1.orig/include/libnfnetlink/linux_nfnetlink.h 2008-06-18 20:36:57.000000000 +0800 |
| ++++ libnfnetlink-1.0.1/include/libnfnetlink/linux_nfnetlink.h 2019-08-30 18:04:36.026372012 +0800 |
| +@@ -47,6 +47,7 @@ |
| + #define NFNL_SUBSYS_QUEUE 3 |
| + #define NFNL_SUBSYS_ULOG 4 |
| + #define NFNL_SUBSYS_COUNT 5 |
| ++#define NFNL_SUBSYS_FLOWTABLE 12 |
| + |
| + #ifdef __KERNEL__ |
| + |
| diff --git a/package/mtk/applications/flowtable/Makefile b/package/mtk/applications/flowtable/Makefile |
| new file mode 100755 |
| index 00000000..150a1a3b |
| --- /dev/null |
| +++ b/package/mtk/applications/flowtable/Makefile |
| @@ -0,0 +1,51 @@ |
| +# |
| +# Copyright (C) 2009-2013 OpenWrt.org |
| +# |
| +# This is free software, licensed under the GNU General Public License v2. |
| +# See /LICENSE for more information. |
| +# |
| + |
| +include $(TOPDIR)/rules.mk |
| + |
| +PKG_NAME:=netfilter_flowtable |
| +PKG_VERSION:=1.0 |
| +PKG_RELEASE:=1 |
| + |
| +PKG_LICENSE:=GPL-2.0+ |
| +#PKG_INSTALL:=1 |
| + |
| +include $(INCLUDE_DIR)/package.mk |
| + |
| +define Package/netfilter-flowtable |
| + SECTION:=MTK Properties |
| + CATEGORY:=MTK Properties |
| + DEPENDS:=+libnfnetlink +libmnl +kmod-nf-flow-netlink |
| + TITLE:=API to the in-kernel flow offload table |
| + SUBMENU:=Applications |
| +endef |
| + |
| +define Package/netfilter-flowtable/description |
| + API to the in-kernel flow offload table |
| +endef |
| + |
| +TARGET_CFLAGS += $(FPIC) |
| + |
| +TARGET_CPPFLAGS := \ |
| + -D_GNU_SOURCE \ |
| + -I$(LINUX_DIR)/user_headers/include \ |
| + -I$(PKG_BUILD_DIR) \ |
| + $(TARGET_CPPFLAGS) \ |
| + |
| +define Build/Compile |
| + CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ |
| + $(MAKE) -C $(PKG_BUILD_DIR) \ |
| + $(TARGET_CONFIGURE_OPTS) \ |
| + LIBS="$(TARGET_LDFLAGS) -lnfnetlink -lm" |
| +endef |
| + |
| +define Package/netfilter-flowtable/install |
| + $(INSTALL_DIR) $(1)/usr/bin |
| + $(CP) $(PKG_BUILD_DIR)/ftnl $(1)/usr/bin/ |
| +endef |
| + |
| +$(eval $(call BuildPackage,netfilter-flowtable)) |
| \ No newline at end of file |
| diff --git a/package/mtk/applications/flowtable/src/Makefile b/package/mtk/applications/flowtable/src/Makefile |
| new file mode 100644 |
| index 00000000..3f450ad2 |
| --- /dev/null |
| +++ b/package/mtk/applications/flowtable/src/Makefile |
| @@ -0,0 +1,9 @@ |
| +EXEC = ftnl |
| +SRC = api.c ftnl.c |
| + |
| +all:$(EXEC) |
| +$(EXEC):$(SRC) |
| + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(SRC) $(LDLIBS) $(LIBS) |
| + |
| +clean: |
| + -rm -f $(EXEC) *.elf *.gdb *.o |
| diff --git a/package/mtk/applications/flowtable/src/api.c b/package/mtk/applications/flowtable/src/api.c |
| new file mode 100644 |
| index 00000000..17b88b43 |
| --- /dev/null |
| +++ b/package/mtk/applications/flowtable/src/api.c |
| @@ -0,0 +1,106 @@ |
| +#include <stdio.h> |
| +#include <stdlib.h> |
| +#include <string.h> |
| +#include "netfilter_flowtable.h" |
| + |
| +static void attr_dump(struct nfattr *attr) |
| +{ |
| + char *data = nla_data(attr); |
| + int i = 0; |
| + |
| + while (i < nal_len(attr)) { |
| + printf("%x ", *(data + i)); |
| + i++; |
| + if (i % 16 == 0) |
| + printf("\n"); |
| + } |
| + printf("\n"); |
| +} |
| + |
| +struct ftnl_handle* ftnl_open(void) |
| +{ |
| + struct ftnl_handle *h = NULL; |
| + |
| + h = malloc(sizeof(struct ftnl_handle)); |
| + if (!h) |
| + return NULL; |
| + |
| + h->nfnlh = nfnl_open(); |
| + if (!h->nfnlh) { |
| + printf("nfnl open fail\n"); |
| + free(h); |
| + return NULL; |
| + } |
| + |
| + h->ftnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_FLOWTABLE, 1, 0); |
| + if (!h->ftnlssh) { |
| + nfnl_close(h->nfnlh); |
| + printf("subsys open fail\n"); |
| + free(h); |
| + return NULL; |
| + } |
| + |
| + return h; |
| +} |
| + |
| +void ftnl_close(struct ftnl_handle *h) |
| +{ |
| + nfnl_subsys_close(h->ftnlssh); |
| + nfnl_close(h->nfnlh); |
| + free(h); |
| +} |
| + |
| +static void build_tuple(struct nlmsghdr *nlh,size_t size, struct flow_tuple *tuple) |
| +{ |
| + struct nfattr *nest_tuple, *nest_ip, *nest_proto; |
| + |
| + nest_tuple = nfnl_nest(nlh, size, FTA_TUPLE); |
| + |
| + nest_ip = nfnl_nest(nlh, size, FTA_TUPLE_IP); |
| + nfnl_addattr_l(nlh, size, FTA_IP_V4_SRC, &tuple->sip4, sizeof(uint32_t)); |
| + nfnl_addattr_l(nlh, size, FTA_IP_V4_DST, &tuple->dip4, sizeof(uint32_t)); |
| + nfnl_nest_end(nlh, nest_ip); |
| + |
| + nest_proto = nfnl_nest(nlh, size, FTA_TUPLE_PROTO); |
| + nfnl_addattr_l(nlh, size, FTA_PROTO_NUM, &tuple->proto, sizeof(uint8_t)); |
| + nfnl_addattr_l(nlh, size, FTA_PROTO_SPORT, &tuple->sport, sizeof(uint16_t)); |
| + nfnl_addattr_l(nlh, size, FTA_PROTO_DPORT, &tuple->dport, sizeof(uint16_t)); |
| + nfnl_nest_end(nlh, nest_proto); |
| + |
| + nfnl_nest_end(nlh,nest_tuple); |
| +// attr_dump(nest_tuple); |
| +} |
| + |
| +int ftnl_flush_table(struct ftnl_handle *h) |
| +{ |
| + struct nlmsghdr nlh; |
| + int ret; |
| + |
| + /* construct msg */ |
| + nfnl_fill_hdr(h->ftnlssh, &nlh, 0, AF_INET, 0, |
| + FT_MSG_FLUSH, NLM_F_REQUEST | NLM_F_ACK); |
| + |
| + /* send msg */ |
| + ret = nfnl_send(h->nfnlh, &nlh); |
| + return ret; |
| +} |
| + |
| +int ftnl_del_flow(struct ftnl_handle *h, struct flow_tuple *tuple) |
| +{ |
| + const int size = 256; |
| + union { |
| + char buffer[size]; |
| + struct nlmsghdr nlh; |
| + } u; |
| + int ret; |
| + |
| + /* construct msg */ |
| + nfnl_fill_hdr(h->ftnlssh, &u.nlh, 0, AF_INET, 0, |
| + FT_MSG_DEL, NLM_F_REQUEST|NLM_F_ACK); |
| + build_tuple(&u.nlh, size, tuple); |
| + |
| + /* send msg */ |
| + ret = nfnl_send(h->nfnlh, &u.nlh); |
| + |
| + return ret; |
| +} |
| diff --git a/package/mtk/applications/flowtable/src/ftnl.c b/package/mtk/applications/flowtable/src/ftnl.c |
| new file mode 100644 |
| index 00000000..30352b29 |
| --- /dev/null |
| +++ b/package/mtk/applications/flowtable/src/ftnl.c |
| @@ -0,0 +1,92 @@ |
| +#include <stdio.h> |
| +#include <stdlib.h> |
| +#include <string.h> |
| +#include <errno.h> |
| +#include <unistd.h> |
| +#include <getopt.h> |
| + |
| +#include "netfilter_flowtable.h" |
| + |
| +void usage(void) |
| +{ |
| + printf("#########flush flow table\n"); |
| + printf("ftnl -F\n"); |
| + printf("#########del flow from offload table\n"); |
| + printf("ftnl -D [sip] [dip] [proto] [sport] [dport]\n"); |
| +} |
| + |
| +int main (int argc, char *argv[]) |
| +{ |
| + struct ftnl_handle *h; |
| + struct flow_tuple tuple = {0}; |
| + int msg = -1; |
| + int c; |
| + int ret = -1; |
| + const char* optstring = "FD"; |
| + struct option opts[] = { |
| + {"sip", required_argument, NULL, 's'}, |
| + {"dip", required_argument, NULL, 'd'}, |
| + {"proto", required_argument, NULL, 'p'}, |
| + {"sport", required_argument, NULL, 'm'}, |
| + {"dport", required_argument, NULL, 'n'} |
| + }; |
| + |
| + /* open netlink socket */ |
| + h = ftnl_open(); |
| + if (!h) |
| + return ret; |
| + |
| + /* parse arg */ |
| + while ((c = getopt_long(argc, argv, optstring, opts, NULL)) != -1) { |
| + switch (c) { |
| + case 'F': |
| + msg = FT_MSG_FLUSH; |
| + break; |
| + case 'D': |
| + msg = FT_MSG_DEL; |
| + break; |
| + case 's': |
| + inet_aton(optarg, &tuple.sip4); |
| + break; |
| + case 'd': |
| + inet_aton(optarg, &tuple.dip4); |
| + break; |
| + case 'p': |
| + if (!strcmp(optarg, "tcp")) |
| + tuple.proto = IPPROTO_TCP; |
| + else if (!strcmp(optarg, "udp")) |
| + tuple.proto = IPPROTO_UDP; |
| + else { |
| + printf("proto bad value " |
| + "pls set proto to udp or tcp " |
| + "arg : %s\n", optarg); |
| + goto out; |
| + } |
| + break; |
| + case 'm': |
| + tuple.sport = htons(atoi(optarg)); |
| + break; |
| + case 'n': |
| + tuple.dport = htons(atoi(optarg)); |
| + break; |
| + default: |
| + usage(); |
| + goto out; |
| + } |
| + } |
| + |
| + switch (msg) { |
| + case FT_MSG_FLUSH: |
| + ftnl_flush_table(h); |
| + break; |
| + case FT_MSG_DEL: |
| + ftnl_del_flow(h, &tuple); |
| + break; |
| + default: |
| + break; |
| + } |
| + |
| +out: |
| + ftnl_close(h); |
| + return ret; |
| +} |
| diff --git a/package/mtk/applications/flowtable/src/netfilter_flowtable.h b/package/mtk/applications/flowtable/src/netfilter_flowtable.h |
| new file mode 100644 |
| index 00000000..3ea8916e |
| --- /dev/null |
| +++ b/package/mtk/applications/flowtable/src/netfilter_flowtable.h |
| @@ -0,0 +1,63 @@ |
| +#include <netinet/in.h> |
| +#include <arpa/inet.h> |
| +#include <libnfnetlink/libnfnetlink.h> |
| + |
| +struct ftnl_handle { |
| + struct nfnl_handle *nfnlh; |
| + struct nfnl_subsys_handle *ftnlssh; |
| +}; |
| + |
| +struct flow_tuple { |
| + struct in_addr sip4; |
| + struct in_addr dip4; |
| + unsigned char proto; |
| + unsigned short int sport; |
| + unsigned short int dport; |
| +}; |
| + |
| +enum ft_msg_types{ |
| + FT_MSG_DEL, |
| + FT_MSG_ADD, //not support now |
| + FT_MSG_FLUSH, |
| + FT_MSG_MAX |
| +}; |
| + |
| +enum ftattr_type { |
| + FTA_UNSPEC, |
| + FTA_TUPLE, |
| + __FTA_MAX |
| +}; |
| +#define FTA_MAX (__FTA_MAX - 1) |
| + |
| +enum ftattr_tuple { |
| + FTA_TUPLE_UNSPEC, |
| + FTA_TUPLE_IP, |
| + FTA_TUPLE_PROTO, |
| + FTA_TUPLE_ZONE, |
| + __FTA_TUPLE_MAX |
| +}; |
| +#define FTA_TUPLE_MAX (__FTA_TUPLE_MAX - 1) |
| + |
| +enum ftattr_ip { |
| + FTA_IP_UNSPEC, |
| + FTA_IP_V4_SRC, |
| + FTA_IP_V4_DST, |
| + FTA_IP_V6_SRC, |
| + FTA_IP_V6_DST, |
| + __FTA_IP_MAX |
| +}; |
| +#define FTA_IP_MAX (__FTA_IP_MAX - 1) |
| + |
| +enum ftattr_l4proto { |
| + FTA_PROTO_UNSPEC, |
| + FTA_PROTO_NUM, |
| + FTA_PROTO_SPORT, |
| + FTA_PROTO_DPORT, |
| + __FTA_PROTO_MAX |
| +}; |
| +#define FTA_PROTO_MAX (__FTA_PROTO_MAX - 1) |
| + |
| +struct ftnl_handle* ftnl_open(void); |
| +void ftnl_close(struct ftnl_handle *h); |
| +int ftnl_flush_table(struct ftnl_handle *h); |
| +int ftnl_del_flow(struct ftnl_handle *h, struct flow_tuple *tuple); |
| diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk |
| index 97153e5c..e30484b7 100644 |
| --- a/package/kernel/linux/modules/netfilter.mk |
| +++ b/package/kernel/linux/modules/netfilter.mk |
| @@ -161,6 +161,18 @@ endef |
| |
| $(eval $(call KernelPackage,nf-flow)) |
| |
| +define KernelPackage/nf-flow-netlink |
| + SUBMENU:=$(NF_MENU) |
| + TITLE:=Netfilter flowtable netlink support |
| + KCONFIG:= \ |
| + CONFIG_NF_FLOW_TABLE_NETLINK |
| + DEPENDS:=+kmod-nf-flow +kmod-nfnetlink |
| + FILES:= \ |
| + $(LINUX_DIR)/net/netfilter/nf_flow_table_netlink.ko |
| + AUTOLOAD:=$(call AutoProbe,nf_flow_table_netlink) |
| +endef |
| + |
| +$(eval $(call KernelPackage,nf-flow-netlink)) |
| |
| define AddDepends/ipt |
| SUBMENU:=$(NF_MENU) |