netfilter: add cttimeout infrastructure for fine timeout tuning
[platform/kernel/linux-arm64.git] / net / netfilter / nf_conntrack_proto_generic.c
index 0e6c545..835e24c 100644 (file)
@@ -65,6 +65,45 @@ static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
        return true;
 }
 
+#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_cttimeout.h>
+
+static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+{
+       unsigned int *timeout = data;
+
+       if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT])
+               *timeout =
+                   ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
+       else {
+               /* Set default generic timeout. */
+               *timeout = nf_ct_generic_timeout;
+       }
+
+       return 0;
+}
+
+static int
+generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
+{
+       const unsigned int *timeout = data;
+
+       NLA_PUT_BE32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ));
+
+       return 0;
+
+nla_put_failure:
+        return -ENOSPC;
+}
+
+static const struct nla_policy
+generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
+       [CTA_TIMEOUT_GENERIC_TIMEOUT]   = { .type = NLA_U32 },
+};
+#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+
 #ifdef CONFIG_SYSCTL
 static struct ctl_table_header *generic_sysctl_header;
 static struct ctl_table generic_sysctl_table[] = {
@@ -102,6 +141,15 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
        .packet                 = generic_packet,
        .get_timeouts           = generic_get_timeouts,
        .new                    = generic_new,
+#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+       .ctnl_timeout           = {
+               .nlattr_to_obj  = generic_timeout_nlattr_to_obj,
+               .obj_to_nlattr  = generic_timeout_obj_to_nlattr,
+               .nlattr_max     = CTA_TIMEOUT_GENERIC_MAX,
+               .obj_size       = sizeof(unsigned int),
+               .nla_policy     = generic_timeout_nla_policy,
+       },
+#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 #ifdef CONFIG_SYSCTL
        .ctl_table_header       = &generic_sysctl_header,
        .ctl_table              = generic_sysctl_table,