From d073f650cdef24dce957099e55b660124fe2e0a4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 23 Mar 2018 12:53:44 +0100 Subject: [PATCH] kernel: add support for enabling hardware flow offload via iptables Signed-off-by: Felix Fietkau --- .../patches/800-flowoffload_target.patch | 87 +++++++++++++++++-- .../650-netfilter-add-xt_OFFLOAD-target.patch | 35 +++++++- 2 files changed, 116 insertions(+), 6 deletions(-) diff --git a/package/network/utils/iptables/patches/800-flowoffload_target.patch b/package/network/utils/iptables/patches/800-flowoffload_target.patch index c6fe65cd3e..2f79ee835a 100644 --- a/package/network/utils/iptables/patches/800-flowoffload_target.patch +++ b/package/network/utils/iptables/patches/800-flowoffload_target.patch @@ -1,14 +1,71 @@ --- /dev/null +++ b/extensions/libxt_FLOWOFFLOAD.c -@@ -0,0 +1,15 @@ +@@ -0,0 +1,72 @@ ++#include +#include ++#include ++ ++enum { ++ O_HW, ++}; ++ ++static void offload_help(void) ++{ ++ printf( ++"FLOWOFFLOAD target options:\n" ++" --hw Enable hardware offload\n" ++ ); ++} ++ ++static const struct xt_option_entry offload_opts[] = { ++ {.name = "hw", .id = O_HW, .type = XTTYPE_NONE}, ++ XTOPT_TABLEEND, ++}; ++ ++static void offload_parse(struct xt_option_call *cb) ++{ ++ struct xt_flowoffload_target_info *info = cb->data; ++ ++ xtables_option_parse(cb); ++ switch (cb->entry->id) { ++ case O_HW: ++ info->flags |= XT_FLOWOFFLOAD_HW; ++ break; ++ } ++} ++ ++static void offload_print(const void *ip, const struct xt_entry_target *target, int numeric) ++{ ++ const struct xt_flowoffload_target_info *info = ++ (const struct xt_flowoffload_target_info *)target->data; ++ ++ printf(" FLOWOFFLOAD"); ++ if (info->flags & XT_FLOWOFFLOAD_HW) ++ printf(" hw"); ++} ++ ++static void offload_save(const void *ip, const struct xt_entry_target *target) ++{ ++ const struct xt_flowoffload_target_info *info = ++ (const struct xt_flowoffload_target_info *)target->data; ++ ++ if (info->flags & XT_FLOWOFFLOAD_HW) ++ printf(" --hw"); ++} + +static struct xtables_target offload_tg_reg[] = { + { -+ .family = NFPROTO_UNSPEC, -+ .name = "FLOWOFFLOAD", -+ .revision = 0, -+ .version = XTABLES_VERSION, ++ .family = NFPROTO_UNSPEC, ++ .name = "FLOWOFFLOAD", ++ .revision = 0, ++ .version = XTABLES_VERSION, ++ .size = XT_ALIGN(sizeof(struct xt_flowoffload_target_info)), ++ .userspacesize = sizeof(struct xt_flowoffload_target_info), ++ .help = offload_help, ++ .print = offload_print, ++ .save = offload_save, ++ .x6_parse = offload_parse, ++ .x6_options = offload_opts, + }, +}; + @@ -16,3 +73,23 @@ +{ + xtables_register_targets(offload_tg_reg, ARRAY_SIZE(offload_tg_reg)); +} +--- /dev/null ++++ b/include/linux/netfilter/xt_FLOWOFFLOAD.h +@@ -0,0 +1,17 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef _XT_FLOWOFFLOAD_H ++#define _XT_FLOWOFFLOAD_H ++ ++#include ++ ++enum { ++ XT_FLOWOFFLOAD_HW = 1 << 0, ++ ++ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW ++}; ++ ++struct xt_flowoffload_target_info { ++ __u32 flags; ++}; ++ ++#endif /* _XT_FLOWOFFLOAD_H */ diff --git a/target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch b/target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch index 7296cfa6c4..a322e605a2 100644 --- a/target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch +++ b/target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch @@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o --- /dev/null +++ b/net/netfilter/xt_FLOWOFFLOAD.c -@@ -0,0 +1,351 @@ +@@ -0,0 +1,364 @@ +/* + * Copyright (C) 2018 Felix Fietkau + * @@ -109,6 +109,7 @@ Signed-off-by: Felix Fietkau +#include +#include +#include ++#include +#include +#include +#include @@ -335,6 +336,7 @@ Signed-off-by: Felix Fietkau +static unsigned int +flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par) +{ ++ const struct xt_flowoffload_target_info *info = par->targinfo; + enum ip_conntrack_info ctinfo; + enum ip_conntrack_dir dir; + struct nf_flow_route route; @@ -387,6 +389,9 @@ Signed-off-by: Felix Fietkau + xt_flowoffload_check_device(xt_in(par)); + xt_flowoffload_check_device(xt_out(par)); + ++ if (info->flags & XT_FLOWOFFLOAD_HW) ++ nf_flow_offload_hw_add(xt_net(par), flow, ct); ++ + return XT_CONTINUE; + +err_flow_add: @@ -401,6 +406,11 @@ Signed-off-by: Felix Fietkau + +static int flowoffload_chk(const struct xt_tgchk_param *par) +{ ++ struct xt_flowoffload_target_info *info = par->targinfo; ++ ++ if (info->flags & ~XT_FLOWOFFLOAD_MASK) ++ return -EINVAL; ++ + return 0; +} + @@ -408,6 +418,8 @@ Signed-off-by: Felix Fietkau + .family = NFPROTO_UNSPEC, + .name = "FLOWOFFLOAD", + .revision = 0, ++ .targetsize = sizeof(struct xt_flowoffload_target_info), ++ .usersize = sizeof(struct xt_flowoffload_target_info), + .checkentry = flowoffload_chk, + .target = flowoffload_tg, + .me = THIS_MODULE, @@ -415,6 +427,7 @@ Signed-off-by: Felix Fietkau + +static int xt_flowoffload_table_init(struct nf_flowtable *table) +{ ++ table->flags = NF_FLOWTABLE_F_HW; + nf_flow_table_init(table); + return 0; +} @@ -460,3 +473,23 @@ Signed-off-by: Felix Fietkau #include #include #include +--- /dev/null ++++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h +@@ -0,0 +1,17 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef _XT_FLOWOFFLOAD_H ++#define _XT_FLOWOFFLOAD_H ++ ++#include ++ ++enum { ++ XT_FLOWOFFLOAD_HW = 1 << 0, ++ ++ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW ++}; ++ ++struct xt_flowoffload_target_info { ++ __u32 flags; ++}; ++ ++#endif /* _XT_FLOWOFFLOAD_H */ -- 2.30.2