linux/net/netfilter/nf_conntrack_proto_generic.c
<<
>>
Prefs
   1/* (C) 1999-2001 Paul `Rusty' Russell
   2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8
   9#include <linux/types.h>
  10#include <linux/jiffies.h>
  11#include <linux/timer.h>
  12#include <linux/netfilter.h>
  13#include <net/netfilter/nf_conntrack_l4proto.h>
  14
  15static const unsigned int nf_ct_generic_timeout = 600*HZ;
  16
  17static bool nf_generic_should_process(u8 proto)
  18{
  19        switch (proto) {
  20#ifdef CONFIG_NF_CT_PROTO_GRE_MODULE
  21        case IPPROTO_GRE:
  22                return false;
  23#endif
  24        default:
  25                return true;
  26        }
  27}
  28
  29static inline struct nf_generic_net *generic_pernet(struct net *net)
  30{
  31        return &net->ct.nf_ct_proto.generic;
  32}
  33
  34static bool generic_pkt_to_tuple(const struct sk_buff *skb,
  35                                 unsigned int dataoff,
  36                                 struct net *net, struct nf_conntrack_tuple *tuple)
  37{
  38        tuple->src.u.all = 0;
  39        tuple->dst.u.all = 0;
  40
  41        return true;
  42}
  43
  44static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple,
  45                                 const struct nf_conntrack_tuple *orig)
  46{
  47        tuple->src.u.all = 0;
  48        tuple->dst.u.all = 0;
  49
  50        return true;
  51}
  52
  53static unsigned int *generic_get_timeouts(struct net *net)
  54{
  55        return &(generic_pernet(net)->timeout);
  56}
  57
  58/* Returns verdict for packet, or -1 for invalid. */
  59static int generic_packet(struct nf_conn *ct,
  60                          const struct sk_buff *skb,
  61                          unsigned int dataoff,
  62                          enum ip_conntrack_info ctinfo,
  63                          unsigned int *timeout)
  64{
  65        nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
  66        return NF_ACCEPT;
  67}
  68
  69/* Called when a new connection for this protocol found. */
  70static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
  71                        unsigned int dataoff, unsigned int *timeouts)
  72{
  73        bool ret;
  74
  75        ret = nf_generic_should_process(nf_ct_protonum(ct));
  76        if (!ret)
  77                pr_warn_once("conntrack: generic helper won't handle protocol %d. Please consider loading the specific helper module.\n",
  78                             nf_ct_protonum(ct));
  79        return ret;
  80}
  81
  82#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
  83
  84#include <linux/netfilter/nfnetlink.h>
  85#include <linux/netfilter/nfnetlink_cttimeout.h>
  86
  87static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
  88                                         struct net *net, void *data)
  89{
  90        unsigned int *timeout = data;
  91        struct nf_generic_net *gn = generic_pernet(net);
  92
  93        if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT])
  94                *timeout =
  95                    ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
  96        else {
  97                /* Set default generic timeout. */
  98                *timeout = gn->timeout;
  99        }
 100
 101        return 0;
 102}
 103
 104static int
 105generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
 106{
 107        const unsigned int *timeout = data;
 108
 109        if (nla_put_be32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ)))
 110                goto nla_put_failure;
 111
 112        return 0;
 113
 114nla_put_failure:
 115        return -ENOSPC;
 116}
 117
 118static const struct nla_policy
 119generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
 120        [CTA_TIMEOUT_GENERIC_TIMEOUT]   = { .type = NLA_U32 },
 121};
 122#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 123
 124#ifdef CONFIG_SYSCTL
 125static struct ctl_table generic_sysctl_table[] = {
 126        {
 127                .procname       = "nf_conntrack_generic_timeout",
 128                .maxlen         = sizeof(unsigned int),
 129                .mode           = 0644,
 130                .proc_handler   = proc_dointvec_jiffies,
 131        },
 132        { }
 133};
 134#endif /* CONFIG_SYSCTL */
 135
 136static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn,
 137                                        struct nf_generic_net *gn)
 138{
 139#ifdef CONFIG_SYSCTL
 140        pn->ctl_table = kmemdup(generic_sysctl_table,
 141                                sizeof(generic_sysctl_table),
 142                                GFP_KERNEL);
 143        if (!pn->ctl_table)
 144                return -ENOMEM;
 145
 146        pn->ctl_table[0].data = &gn->timeout;
 147#endif
 148        return 0;
 149}
 150
 151static int generic_init_net(struct net *net, u_int16_t proto)
 152{
 153        struct nf_generic_net *gn = generic_pernet(net);
 154        struct nf_proto_net *pn = &gn->pn;
 155
 156        gn->timeout = nf_ct_generic_timeout;
 157
 158        return generic_kmemdup_sysctl_table(pn, gn);
 159}
 160
 161static struct nf_proto_net *generic_get_net_proto(struct net *net)
 162{
 163        return &net->ct.nf_ct_proto.generic.pn;
 164}
 165
 166const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic =
 167{
 168        .l3proto                = PF_UNSPEC,
 169        .l4proto                = 255,
 170        .pkt_to_tuple           = generic_pkt_to_tuple,
 171        .invert_tuple           = generic_invert_tuple,
 172        .packet                 = generic_packet,
 173        .get_timeouts           = generic_get_timeouts,
 174        .new                    = generic_new,
 175#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
 176        .ctnl_timeout           = {
 177                .nlattr_to_obj  = generic_timeout_nlattr_to_obj,
 178                .obj_to_nlattr  = generic_timeout_obj_to_nlattr,
 179                .nlattr_max     = CTA_TIMEOUT_GENERIC_MAX,
 180                .obj_size       = sizeof(unsigned int),
 181                .nla_policy     = generic_timeout_nla_policy,
 182        },
 183#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 184        .init_net               = generic_init_net,
 185        .get_net_proto          = generic_get_net_proto,
 186};
 187