[][MAC80211][hnat][Add Netfilter Netlink Ftnl package]
[Description]
Add Netfilter Netlink Ftnl package.
- Delete specific PPE entry: ftnl -D --sip=192.168.1.3 --dip=10.10.10.3
--proto=tcp --sport=1234 --dport=5678
- Flush all PPE entries: ftnl -F
If without this patch, user cannot delete or fluse PPE entries manually.
[Release-log]
N/A
Change-Id: I5d50840e5565b100421ded580ed0f68fe7d08edc
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7190260
diff --git a/autobuild_mac80211_release/0005-add-netfilter-netlink-ftnl-package.patch b/autobuild_mac80211_release/0005-add-netfilter-netlink-ftnl-package.patch
new file mode 100644
index 0000000..4789e02
--- /dev/null
+++ b/autobuild_mac80211_release/0005-add-netfilter-netlink-ftnl-package.patch
@@ -0,0 +1,393 @@
+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)