blob: 4789e021263c517c4f0bc38902ad325798cea7a0 [file] [log] [blame]
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)