root/net/netfilter/nf_conntrack_proto_generic.c
// SPDX-License-Identifier: GPL-2.0-only
/* (C) 1999-2001 Paul `Rusty' Russell
 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
 */

#include <linux/types.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/netfilter.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_timeout.h>

static const unsigned int nf_ct_generic_timeout = 600*HZ;

#ifdef CONFIG_NF_CONNTRACK_TIMEOUT

#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>

static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
                                         struct net *net, void *data)
{
        struct nf_generic_net *gn = nf_generic_pernet(net);
        unsigned int *timeout = data;

        if (!timeout)
                timeout = &gn->timeout;

        if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT])
                *timeout =
                    ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
        else {
                /* Set default generic timeout. */
                *timeout = gn->timeout;
        }

        return 0;
}

static int
generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
{
        const unsigned int *timeout = data;

        if (nla_put_be32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ)))
                goto nla_put_failure;

        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_CONNTRACK_TIMEOUT */

void nf_conntrack_generic_init_net(struct net *net)
{
        struct nf_generic_net *gn = nf_generic_pernet(net);

        gn->timeout = nf_ct_generic_timeout;
}

const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic =
{
        .l4proto                = 255,
        .allow_clash            = true,
#ifdef CONFIG_NF_CONNTRACK_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_CONNTRACK_TIMEOUT */
};